2010-05-08 2 views
2

NAudio Library: http://naudio.codeplex.com/Проблема преобразования файлов MP3 в файл WAV с помощью NAudio

Я пытаюсь преобразовать файл MP3 в файл WAV, но я бежал, чтобы небольшая ошибка. Я знаю, что происходит не так, но я не знаю, как это исправить.

Вот кусок кода, я бегу:

private void button1_Click(object sender, EventArgs e) { 
    using(Mp3FileReader reader = new Mp3FileReader(@"path\to\MP3")) { 
     using(WaveFileWriter writer = new WaveFileWriter(@"C:\test.wav", new WaveFormat())) { 
      int counter = 0; 
      while(reader.Read(test, counter, test.Length + counter) != 0) { 
       writer.WriteData(test, counter, test.Length + counter); 
       counter += 512; 
      } 
     } 
    } 
} 

reader.Read() переходит в класс Mp3FileReader и метод выглядит следующим образом:

public override int Read(byte[] sampleBuffer, int offset, int numBytes) 
{ 
    if (numBytes % waveFormat.BlockAlign != 0) 
     //throw new ApplicationException("Must read complete blocks"); 
     numBytes -= (numBytes % waveFormat.BlockAlign); 
    return mp3Stream.Read(sampleBuffer, offset, numBytes); 
} 

mp3Stream является объектом класса Stream.

Проблема в следующем: я получаю исключение ArgumentException. MSDN говорит, что это связано с тем, что сумма смещений и numBytes больше длины sampleBuffer.

Документация: http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx

Это происходит потому, что я увеличиваю счетчик каждый раз, но размер массива байтов test остается неизменным.

Что мне было интересно: нужно ли увеличить размер массива динамически или мне нужно выяснить необходимый размер в начале и сразу установить его?

А также, вместо 512, метод в Mp3FileReader возвращает 365 в первый раз. Каков размер целого блока. Но я пишу полный 512. Я просто использую чтение, чтобы проверить, не осталось ли я еще в конце файла. Нужно ли мне улавливать возвращаемое значение и что-то делать с этим, или я здесь хорош?

ответ

4

Вам нужно использовать возвращаемое значение Read(), чтобы определить, сколько байтов вы действительно получили. Это не должно быть 512, вы уже обнаружили это. И имейте в виду, что вы работаете с потоками, а не с массивами. Сделайте так, чтобы он выглядел примерно так:

using (var reader = new Mp3FileReader(@"path\to\MP3")) { 
     using (var writer = new WaveFileWriter(@"C:\test.wav", new WaveFormat())) { 
      var buf = new byte[4096]; 
      for (;;) { 
       var cnt = reader.Read(buf, 0, buf.Length); 
       if (cnt == 0) break; 
       writer.WriteData(buf, 0, cnt); 
      } 
     } 
    } 
+0

Хорошо, я делаю это сейчас, и в результате возникает много статического шума. Тем не менее, это совершенно другая проблема. – KdgDev

+0

попытаться изменить байт [] buf = новый байт [4096]; вместо байта buf = новый байт [4096]; – fyasar

+0

Это не работает для приложения Windows 8.1 Store, которое я пытаюсь. Можете ли вы опубликовать обновленный метод или привести меня к соответствующей ссылке? – Wajahat

1

В вашем примере вы фактически не конвертируете MP3 в WAV. Вам нужен WaveFormatConversionStream. Попробуйте что-то вроде этого:

private void button1_Click(object sender, EventArgs e) { 
    using(Mp3FileReader reader = new Mp3FileReader(@"path\to\MP3")) { 
     using (WaveStream convertedStream = WaveFormatConversionStream.CreatePcmStream(reader)) { 
      WaveFileWriter.CreateWaveFile(outputFileName, convertedStream); 
     } 
    } 
} 
+0

Выглядит хорошо, но он не будет работать. Я продолжаю получать исключение «AcmNotPossible call acmStreamOpen». – KdgDev

+0

, вероятно, потому, что ваш целевой формат не соответствует естественному преобразованному формату MP3. Я обновлю пример кода –