This project has moved. For the latest updates, please go here.

Converting from WAV to MP3

Mar 29, 2010 at 12:02 AM

I started using DirectShowLib to implement MP3 to WAV conversion and vice versa then I stumbled upon NAudio which on the whole I feel is far cleaner and far easier to use.

I quickly modified the ACM Format Conversion sample to convert from MP3 to WAV, however when attempting to convert a WAV file back to MP3 the WaveFileWriter throws a Divide By Zero exception from the Dispose method.

Do you have a sample to show how to convert from WAV to MP3 ?

Thanks

Steve

Coordinator
Mar 29, 2010 at 9:36 AM

I've never used NAudio to convert to MP3. I see you are wrapping the MP3 in a WAV file container, which is slightly unconventional but should work in theory.

Are you able to post a little bit of sample code and the full stack trace of the exception?

Mark

Mar 29, 2010 at 11:37 AM

 

Exception Message: Attempted to divide by zero.
Stack Trace:    at NAudio.Wave.WaveFileWriter.Dispose(Boolean disposing) in C:\Users\Steve Wilkinson\Documents\Visual Studio 2005\Projects\NAudio-1-3\Source Code\NAudio\Wave\WaveOutputs\WaveFileWriter.cs:line 243
   at NAudio.Wave.WaveFileWriter.Dispose() in C:\Users\Steve Wilkinson\Documents\Visual Studio 2005\Projects\NAudio-1-3\Source Code\NAudio\Wave\WaveOutputs\WaveFileWriter.cs:line 217
   at NAudio.Wave.WaveFileWriter.CreateWaveFile(String filename, WaveStream stream) in C:\Users\Steve Wilkinson\Documents\Visual Studio 2005\Projects\NAudio-1-3\Source Code\NAudio\Wave\WaveOutputs\WaveFileWriter.cs:line 36

   at NAudioDemo.AcmForm.EncodeFile() in C:\Users\Steve Wilkinson\Documents\Visual Studio 2005\Projects\NAudio-1-3\Source Code\NAudioDemo\AcmForm.cs:line 134

 

 

Mark,

Apart from modifying the filter strings in GetInputFileName() and GetOutputFileName() functions to select/choose Mp3 files the only other modifiecations I made were to the DecodeFile() function in the AcmForm.cs class to implicitly use Mp3FileReader.  The DecodeFile() function is as follows:

 

       private void DecodeFile()

        {

            try

            {

                string inputFileName = GetInputFileName("Select an MP3 file to decode");

                if (inputFileName == null)

                    return;

 

                // Open the MP3

                using (Mp3FileReader reader = new Mp3FileReader(inputFileName))

                {

                    // Check the encoding is MP3

                    if (reader.WaveFormat.Encoding != WaveFormatEncoding.MpegLayer3)

                    {

                        MessageBox.Show("Please select an MP3 file to decode");

                        return;

                    }

 

                    // Default to PCM 44.1kHz 16-bit stereo

                    WaveFormat targetFormat = new WaveFormat();

                    if (targetFormat == null)

                    {

                        return;

                    }

                    string outputFileName = GetOutputFileName("Select Output File Name");

                    if (outputFileName == null)

                    {

                        return;

                    }

                    using (WaveStream convertedStream = new WaveFormatConversionStream(targetFormat, reader))

                    {

                        WaveFileWriter.CreateWaveFile(outputFileName, convertedStream);

                    }

 

                    if (checkBoxAutoLaunchConvertedFile.Checked)

                    {

                        System.Diagnostics.Process.Start(outputFileName);

                    }

                }

            }

            catch (Exception ex)

            {

                System.Console.WriteLine(string.Format("Exception Message: {0}\n\nStack Trace: {1}", 

                    ex.Message, ex.StackTrace));

            }

        }

 

 

Converting from MP3 to WAV works fine using this modification, do you foresee any problems using this approach ?  Would the same modifications work for other formats e.g. OGG albeit not using the MP3FileReader.

The EncodeFile() function remains unchanged.  Basically I select the WAV file I've just decoded and then set the output format for the target file to MP3 (e.g. 192 Kbits/s 44.100 Hz Stereo).  At this point the Attempted to divide by zero exception is thrown.

The full exception and stack trace is as follows:

Exception Message: Attempted to divide by zero.

Stack Trace:    at NAudio.Wave.WaveFileWriter.Dispose(Boolean disposing) in C:\Users\Steve\Documents\Visual Studio 2005\Projects\NAudio-1-3\Source Code\NAudio\Wave\WaveOutputs\WaveFileWriter.cs:line 243

   at NAudio.Wave.WaveFileWriter.Dispose() in C:\Users\Steve\Documents\Visual Studio 2005\Projects\NAudio-1-3\Source Code\NAudio\Wave\WaveOutputs\WaveFileWriter.cs:line 217

   at NAudio.Wave.WaveFileWriter.CreateWaveFile(String filename, WaveStream stream) in C:\Users\Steve\Documents\Visual Studio 2005\Projects\NAudio-1-3\Source Code\NAudio\Wave\WaveOutputs\WaveFileWriter.cs:line 36

   at NAudioDemo.AcmForm.EncodeFile() in C:\Users\Steve\Documents\Visual Studio 2005\Projects\NAudio-1-3\Source Code\NAudioDemo\AcmForm.cs:line 134

Note the machine is running Windows 7 and has both the "Fraunhofer IIS MPEG-Layer3 Codec (decode only)" and  "Fraunhofer IIS MPEG-Layer3 Codec (professional)" codecs installed.  I think the professional codec is shipped with the latest incarnation of Windows Media Player.  I tried a second machine (running Vista) and the professional codec wasn't installed but was present on the system.  I used the information at the following link to http://www.looprecorder.de/tut_l3codec.php to enable the professional codec on the Vista machine.
When you said "I see you are wrapping the MP3 in a WAV file container, which is slightly unconventional but should work in theory" I presume you are referring to the use of the WaveFileWriter.  Just in general what are the principles for converting from WAV to another format in terms of the target files ?  Do you have to derive a class capable of writing the encoded data or does the library/codec deal with this ?
Many thanks for you help, if you need any further information just let me know.
Steve

 

Coordinator
Mar 29, 2010 at 11:52 AM

It seems like you are in fact trying to convert from MP3 to WAV, not from WAV to MP3 as the title of this post says?

Have a look elsewhere in the NAudio demo at the use of MP3FileReader and WaveFormatConversionStream. For example on the playback demo page you can play MP3s which essentially does this conversion. You will see that this code uses the BlockAlignmentReductionStream which should get round any problems you have been experiencing

Mark

 

 

 

Mar 29, 2010 at 12:56 PM

Mark,

Thanks for the help, I guess the title should have read "Converting from WAV to MP3 and back again".

Thanks

Steve

Mar 29, 2010 at 1:42 PM

Mark,

Just looking through the area of code that you suggested, this relates to playback and decoding from MP3 to WAV.  This all works perfectly, the main problem I have is in taking a WAV file and converting it back to MP3.  I need to be able to convert files from WAV to MP3 and vice versa.

Does the library have any support to save out/encode MP3 files ?

Thanks

Steve

Coordinator
Mar 29, 2010 at 1:43 PM

For WAV to MP3 I always use LAME.exe - makes life a lot simpler. NAudio doesn't have the ability to create MP3 files at the moment.

Mark

 

Mar 9, 2011 at 2:16 PM

Hi,

I have started using NAudio for a project of mine and have really benifited from discussions here and at stackoverflow and also Mark's and OpenSebJ's blogs. I should say, NAudio is really programmer friendly and I got the hang of it in less than in a week and am now close to completing my project which I believe would have taken longer otherwise.

But now I too face a similar situation as the OS here. I read some files (in this case wav, mp3 and ogg) perform some operations and then save them back. For the writing back part, I see that wav is default, ogg support is provided by someone (http://daisy.trac.cvsdude.com/urakawa-sdk/browser/trunk/csharp/audio/NAudio/FileFormats?rev=1346), but I could not find any MP3 encoding help.

So, I am looking at other alternatives here. I can save the file as wave and then as per Mark's suggestion use Lame.exe to convert it to mp3. But I would still prefer an alternative that gives me more control over this process. Specifically, I wanted to know if there is any wrapper for any mp3 encoding library that can seamlessly work with NAudio? Or if not seamlessly, at least a library that converts wave to mp3?

It would be really if someone can point me in the right direction.

Thanks.

Coordinator
Mar 10, 2011 at 9:43 AM

Unfortunately there doesn't seem to be any good solutions for encoding MP3s from C# at the moment.

Mark