Problem converting MP3 to WAV file using Naudio
Naudio Library: http://naudio.codeplex.com/
I am trying to convert an MP3 file to WAV file, but I am facing a small error. I know what's going wrong, but I really don't know how to fix it.
Here is the piece of code I'm running:
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 () goes into the Mp3FileReader class and the method looks like this:
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 is an object of class Stream.
Problem: I am getting an ArgumentException. MSDN says this is because the sum of the offsets and numBytes is greater than the length of the sampleBuffer.
Documentation: http://msdn.microsoft.com/en-us/library/system.io.stream.read.aspx
This is because I increment the counter each time, but the size of the byte array test
remains the same.
I was wondering: Do I need to increase the size of the array dynamically or do I need to know the required size at the beginning and set it right away?
Also, instead of 512, the method in Mp3FileReader returns 365 the first time. What is the size of the whole block. But I'm writing a full 512. I just use read to check if I'm still left at the end of the file. Do I need to catch the return value and do something about it, or am I good here?
a source to share
You need to use the return value of Read () to determine how many bytes you received. It doesn't have to be 512, you've already discovered that. And keep in mind that you are working with streams, not arrays. Make it look like this:
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);
}
}
}
a source to share
In your example, you are not actually doing the conversion from MP3 to WAV. You need WaveFormatConversionStream. Try something like this:
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);
}
}
}
a source to share