C# – MP3/WAV Converter with Lame/NAudio

Converting between music formats is common user activity when they want to play musics on many portable devices. As you know the current most popular format is being supported on many portable devices, is MP3. This audio encoding format uses a form of lossy data compression which reduces strongly the amount of data required for representing audio. However it keeps sound like a faithful reproduction of the original uncompressed audio for most listeners. The standard bitrate of a MP3 file ist about 128 kbits (11 times smaller than CD file from original source as stated in Wikipedia http://en.wikipedia.org/wiki/MP3).

Cause of demand above, in this blog post, I would like to demonstrate a small code snippet for converting between MP3/WAV so that we can write our own tools for converting to MP3 with some code lines instead of spending a lot of time for searching for a freeware, downloading and installing … In this example I’ll use two open source MP3 Encoders for demonstrating – LAME (http://lame.sourceforge.net/) and NAUDIO (http://naudio.codeplex.com/).

The package of LAME includes 2 files (lame.exe and lame_enc.dll coded by C++). You can write a C# Wrapper for the DLL and using it directly in your solution but I see that it takes so much time if I write a wrapper and use it directly in my solution because this DLL exports only some functions below which servicing only for stream encoding. That means I must take care of the task for conversion “How should the stream be converted?”, “How many bitrates should be used”…. and it turns to be not a simple code block anymore. It is also not worth to invent the wheel which is “lame.exe” in this case.

__declspec(dllexport) BE_ERR	beInitStream(PBE_CONFIG pbeConfig, PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream);
__declspec(dllexport) BE_ERR	beEncodeChunk(HBE_STREAM hbeStream, DWORD nSamples, PSHORT pSamples, PBYTE pOutput, PDWORD pdwOutput);
__declspec(dllexport) BE_ERR	beEncodeChunkFloatS16NI(HBE_STREAM hbeStream, DWORD nSamples, PFLOAT buffer_l, PFLOAT buffer_r, PBYTE pOutput, PDWORD pdwOutput);
__declspec(dllexport) BE_ERR	beDeinitStream(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput);
__declspec(dllexport) BE_ERR	beCloseStream(HBE_STREAM hbeStream);
__declspec(dllexport) VOID		beVersion(PBE_VERSION pbeVersion);
__declspec(dllexport) BE_ERR	beWriteVBRHeader(LPCSTR lpszFileName);
__declspec(dllexport) BE_ERR	beFlushNoGap(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput);
__declspec(dllexport) BE_ERR	beWriteInfoTag( HBE_STREAM hbeStream, LPCSTR lpszFileName );

Therefore I decide to use the perfect programmed “lame.exe” for conversion.

 private static void LameWavToMp3(string wavFile, string outmp3File)
{
	ProcessStartInfo psi = new ProcessStartInfo();
	psi.FileName = @"..\..\Lame\lame.exe";
	psi.Arguments = "-V2 " + wavFile + " " + outmp3File;
	psi.WindowStyle = ProcessWindowStyle.Hidden;
	Process p = Process.Start(psi);
	p.WaitForExit();
}

private static void LameMp3ToWav(string mp3File, string outwavFile)
{
	ProcessStartInfo psi = new ProcessStartInfo();
	psi.FileName = @"..\..\Lame\lame.exe";
	psi.Arguments = mp3File + " " + outwavFile;
	psi.WindowStyle = ProcessWindowStyle.Hidden;
	Process p = Process.Start(psi);
	p.WaitForExit();
}

It works perfectly. For converting to MP3 I would like to choose V2 of MP3 which is recommended by LAME. In comparision to V3 I can not realize which is better but just use as recommendation.

One of alternatives to LAME for converting MP3 to WAV is NAUDIO. It is also an open-source library and written in C#. However it’s not a MP3 Encoder therefore it does not support converting from WAV to MP3. Using this library we just simply add a reference to it in solution and write a function as below to convert from MP3 to WAV

private static void NAudioMp3ToWav(string mp3File, string outwavFile)
{
	using (Mp3FileReader reader = new Mp3FileReader(mp3File))
	{
		using (WaveStream pcmStream = WaveFormatConversionStream.CreatePcmStream(reader))
		{
			WaveFileWriter.CreateWaveFile(outwavFile, pcmStream);
		}
	}
}

Bring all these 3 functions to test if they really work

static void Main(string[] args)
{
	Console.WriteLine("MP3/WAV CONVERTER");
	Console.WriteLine("Using LAME");
	Console.Write("     WAV TO MP3");
	LameWavToMp3(@"..\..\Sample\testcase.wav", @"..\..\Output\testcaselame.mp3");
	Console.WriteLine(" : Successfully");
	Console.Write("     MP3 TO WAV");
	LameMp3ToWav(@"..\..\Sample\testcase.mp3", @"..\..\Output\testcaselame.wav");
	Console.WriteLine(" : Successfully");
	Console.WriteLine("Using NAUDIO");
	Console.Write("     MP3 TO WAV");
	NAudioMp3ToWav(@"..\..\Sample\testcase.mp3", @"..\..\Output\testcasenaudio.wav");
	Console.WriteLine(" : Successfully");
	Console.WriteLine("Finished");
	Console.ReadLine();
}

The complete solution you can download MP3-WAV Converter with LAME/Audio.

UPDATE 20.08.2013
For converting file from Ogg to Wav, we can combine Nvorbis http://nvorbis.codeplex.com/ with NAudio to get a perfect result with following code

private static void NAudioOggToWav(string oggFile, string wavFile)
{
	using (var vorbis = new NVorbis.NAudioSupport.VorbisWaveReader(oggFile))
	{
		WaveFileWriter.CreateWaveFile(wavFile, vorbis);
	}
}