2016-03-06 2 views
1

Мне нужно преобразовать wav-файл в 8000Hz 16Bit Mono Wav. У меня уже есть код, который хорошо работает с библиотекой NAudio, но я хочу использовать MemoryStream вместо временного файла.Преобразование wav-файла в 8000Hz 16Bit Mono Wav

using System.IO; 
using NAudio.Wave; 

    static void Main() 
    { 
     var input = File.ReadAllBytes("C:/input.wav"); 
     var output = ConvertWavTo8000Hz16BitMonoWav(input); 
     File.WriteAllBytes("C:/output.wav", output); 
    } 

    public static byte[] ConvertWavTo8000Hz16BitMonoWav(byte[] inArray) 
    { 
     using (var mem = new MemoryStream(inArray)) 
     using (var reader = new WaveFileReader(mem)) 
     using (var converter = WaveFormatConversionStream.CreatePcmStream(reader)) 
     using (var upsampler = new WaveFormatConversionStream(new WaveFormat(8000, 16, 1), converter)) 
     { 
      // todo: without saving to file using MemoryStream or similar 
      WaveFileWriter.CreateWaveFile("C:/tmp_pcm_8000_16_mono.wav", upsampler); 
      return File.ReadAllBytes("C:/tmp_pcm_8000_16_mono.wav"); 
     } 
    } 
+0

Вы можете использовать один из конструкторов 'WaveFi leWriter', который берет поток для аргумента. Взято из [NAudio исходного кода] (https://github.com/naudio/NAudio/blob/master/NAudio/Wave/WaveOutputs/WaveFileWriter.cs#LC63) – bob1024

+0

@ bob1024 Я уже пробовал, но нет никакого параметра для конвертер ... или, возможно, я чего-то не хватает –

+0

Вы можете указать скорость, биты и каналы в переменной WaveFormat и передать ее конструктору 'WaveFileWriter' – bob1024

ответ

1

Не уверен, что это оптимальный способ, но он работает ...

public static byte[] ConvertWavTo8000Hz16BitMonoWav(byte[] inArray) 
    { 
     using (var mem = new MemoryStream(inArray)) 
     { 
      using (var reader = new WaveFileReader(mem)) 
      { 
       using (var converter = WaveFormatConversionStream.CreatePcmStream(reader)) 
       { 
        using (var upsampler = new WaveFormatConversionStream(new WaveFormat(8000, 16, 1), converter)) 
        { 
         byte[] data; 
         using (var m = new MemoryStream()) 
         { 
          upsampler.CopyTo(m); 
          data = m.ToArray(); 
         } 
         using (var m = new MemoryStream()) 
         { 
          // to create a propper WAV header (44 bytes), which begins with RIFF 
          var w = new WaveFileWriter(m, upsampler.WaveFormat); 
          // append WAV data body 
          w.Write(data,0,data.Length); 
          return m.ToArray(); 
         } 
        } 
       } 
      } 
     } 
    } 
1

Это может быть добавлен и жаль, что я не могу пока комментировать в связи с отсутствием точек. Что NAudio ВСЕГДА пишет 46 байтовых заголовков, которые в определенных ситуациях могут привести к сбоям. Я хочу добавить это в случае, если кто-то соберёт это при поиске подсказки, почему файлы waw wav только начинают сбой определенных программ.

Я воспользовался этой проблемой после выяснения способа преобразования и/или выборки wav с помощью NAudio и застрял после этого в течение 2 дней и только разобрался с шестнадцатеричным редактором.

(2 Дополнительные байты расположены в байте 37 и 38 непосредственно перед subchunck данных [г, а, т, а, размер < 4 байта>]. Here is a comparison of two wave file headers left is saved by NAudio 46 bytes; right by Audacity 44 bytes

Вы можете проверить это обратно, глядя на NASO src в WaveFormat.cs at line 310, где вместо 16 байтов для fmt chunck 18 + extra зарезервированы (+ дополнительно, потому что есть некоторые wav-файлы, которые даже содержат более крупные заголовки, чем 46 байт), но NAudio всегда, кажется, пишет 46 байтовых заголовков и никогда не 44 (MS). Также можно отметить, что на самом деле NAudio умеет читать 44 байтовые заголовки (строка 210 в WaveFormat.cs)