Click here to Skip to main content
15,885,054 members
Articles / Desktop Programming / MFC
Article

DLL To Decode MP3 To WAV/PCM

Rate me:
Please Sign up or sign in to vote.
4.56/5 (19 votes)
12 Jul 20043 min read 381.7K   9.2K   83   98
Source code to produce a DLL that converts MP3 files to WAV or PCM. It is based on the open source library libmad.

Sample Image - madlldlib.gif

Introduction

libmad is a powerful open source library written in C that decodes MP3 files to uncompressed PCM data. However, it compiles as a static library, limiting its access to C/C++. I have written code (based on the source madlld) that compiles to a DLL, enabling other languages (i.e., C#, Visual Basic etc.) to access the libmad library using the simple interface I've provided.

Programming the API

The DLL source is well documented, so I will concentrate on using the API, and allow the curious to poke around the guts on their own (it is likely that the API is of most interest to most people). However, a brief overview of the source is in order.

madlldlib is codified into a single, simple interface, consisting of just one function, CbMpegAudioDecoder(), which takes the names of the input and output files, and a callback function as parameters. The callback function is passed information about the decoding process (such as total bytes converted and frame count) as it decodes, which in turn can be used to update decoding status in whatever interface the developer chooses.

There is a small file, test.cpp, included in the source which demonstrates the API. It is kept as simple as possible to make it easy to understand.

First, test.cpp defines a function called mycb(). This function is the callback (function pointer) that madlldlib will send decoding status to. It is within this function that you will update status in your application. test.cpp merely formats the output and prints it to STDOUT.

C++
void __stdcall mycb (unsigned long fcnt, 
   unsigned long bcnt, struct mad_header *mhdr) {

    /*
     * If this is the first iteration (frame count is one)
     * then print out the MP3 layer information. Using this logic
     * one can retrieve information about the MP3 file, such as 
     * channels, layer, etc., that might be useful to the calling
     * code.
     */    
    if (fcnt == 1) {
        printf("frame:%d, tot. bytes:%d, layer:%d\n",fcnt,bcnt,mhdr->layer);
    }
    else {
        printf("frame:%d, tot. bytes:%d\n",fcnt,bcnt);
    }
    
}

As you can see, the output is very simple. You must define a function in your code with exactly the parameter types that mycb() has defined above (the names of the parameters, obviously, are up to you).

Next, we move into the main() function. After checking arguments and handling filenames, it calls the decoding function CbMpegAudioDecoder() with the given parameters.

C++
/* call the decoding function with input file,
 * output file, and callback (defined above). */
if (strcmp(argv[2], "pcm")==0) {        /* output raw PCM */
    status = CbMpegAudioDecoder(argv[1], outf, 0, statmsg, mycb);
}
else {                                    /* output as WAV */
    status = CbMpegAudioDecoder(argv[1], outf, 1, statmsg, mycb);
}

Note that it passed our callback function mycb() to CbMpegAudioDecoder(), which will send it information every decoding loop. The other item of interest is the parameter statmsg, which is used to relay any error messages our function may encounter. If, say, the MP3 file is corrupt, this message will end up in statmsg, which you can use to pass on to the user of your application.

The two files, armslen.cpp and armslen_test.cpp, give an example of decoding while sending status via a named pipe. This way you do not have to use madlldlib as a DLL in your project if you don't desire to. armslen.cpp compiles to an executable that takes parameters similar to test.cpp (input filename, output filename, output format). It then generates a named pipe server, and waits until a client program connects (armslen_test.cpp). Once the client makes the connection, armslen.cpp sends the decoding update status to the named pipe while it decodes the MP3. The client can then pick up, parse, and use the status to update its interface.

Source and Contact

The most current code will always be here.

If you have comments or questions, you can direct them to the mailing list madlldlib-dev.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralRe: Decode mp3 to wav on visual basic 6 - code sample for DLL Pin
Pappsegull13-Feb-11 15:29
Pappsegull13-Feb-11 15:29 
GeneralRe: Decode mp3 to wav on visual basic 6 - code sample for DLL Pin
Member 1200655723-Sep-15 6:27
Member 1200655723-Sep-15 6:27 
Generalconvert and return blocks[] Pin
donperry26-Dec-06 6:01
donperry26-Dec-06 6:01 
GeneralRe: convert and return blocks[] Pin
gilad-ap29-Jan-07 9:45
gilad-ap29-Jan-07 9:45 
GeneralLEC Pin
chenjunxuman19-Oct-06 14:37
chenjunxuman19-Oct-06 14:37 
GeneralExample in C# Pin
SuPeRRuZaFa19-Jun-06 2:05
SuPeRRuZaFa19-Jun-06 2:05 
GeneralRe: Example in C# Pin
gilad-ap11-Jul-06 6:32
gilad-ap11-Jul-06 6:32 
GeneralRe: Example in C# Pin
ddecoy1-Dec-09 2:06
ddecoy1-Dec-09 2:06 
public partial class Form1 : Form
   {
       [MarshalAs(UnmanagedType.LPStr)] private StringBuilder strBuilder = new StringBuilder("",11000);
       MadlldlibWrapper.Callback updateFunction ;
       string mp3File = "";
       string wavFile = "";
       Boolean bCancel = false;
       OpenFileDialog Dialog = new OpenFileDialog();

       public Form1()
       {
           InitializeComponent();
           updateFunction  = new MadlldlibWrapper.Callback(updateFunctionMethod);
       }

       private Boolean updateFunctionMethod(uint frameCount, uint byteCount,ref Mp3Decoder.MadlldlibWrapper.mad_header madHeader)
       {
           if (frameCount == 1)
           {
               this.label1.Text = "Sampelrate: " + madHeader.samplerate.ToString() +
                   " Bitrate: " + madHeader.bitrate.ToString() +
                   " Duration: " + madHeader.duration +
                   " Layer: " + madHeader.layer.ToString();
               Application.DoEvents();
           }
           this.label3.Text = "frame:= " + frameCount.ToString() + " byte:= " + byteCount.ToString();
           Application.DoEvents();
           if (bCancel) {
               return false;
               }
           else { return true; }
       }


       private void selectMp3ToolStripMenuItem1_Click(object sender, EventArgs e)
       {
           Dialog.Filter = "mp3 files (*.mp3)|*.mp3";
           Dialog.Multiselect = false;
           Dialog.ShowDialog();
           if (Dialog.FileName != "") {
               this.label3.Text = "";
               mp3File = Dialog.FileName;
               this.textBox1.Text = Dialog.FileName;
               wavFile = Dialog.FileName.Remove(Dialog.FileName.LastIndexOf("."), Dialog.FileName.Length - Dialog.FileName.LastIndexOf(".")) + ".wav";
           }
       }

       private void exitToolStripMenuItem_Click(object sender, EventArgs e)
       {
           this.Close();
       }

       private void button1_Click(object sender, EventArgs e)
       {
           MadlldlibWrapper.DecodeMP3(mp3File, wavFile, 1, strBuilder, updateFunction);
           this.label3.Text = "Conversion done!";
       }

       private void button2_Click(object sender, EventArgs e)
       {
           this.bCancel = true;
       }
   }


°°°°°°°°°°°°°°°°°°°°°°°
-- Inter Access Belgium --

GeneralRe: Example in C# Pin
ddecoy1-Dec-09 2:08
ddecoy1-Dec-09 2:08 
QuestionCan I set a Bit Rate of output wave file? Pin
kom200217-Apr-06 23:27
kom200217-Apr-06 23:27 
AnswerRe: Can I set a Bit Rate of output wave file? Pin
gilad-ap11-Jul-06 6:29
gilad-ap11-Jul-06 6:29 
Questioncan i set the sample rate and resulotion ? Pin
h1322-Feb-06 20:42
h1322-Feb-06 20:42 
AnswerRe: can i set the sample rate and resulotion ? Pin
gilad-ap23-Feb-06 4:30
gilad-ap23-Feb-06 4:30 
GeneralRe: can i set the sample rate and resulotion ? Pin
h1324-Feb-06 16:41
h1324-Feb-06 16:41 
GeneralProblem in using madlldlib.dll Pin
srimayank11_codeproject7-Feb-06 0:21
srimayank11_codeproject7-Feb-06 0:21 
GeneralConfused like me? A message to codeproject users. Pin
Brit25-Sep-05 12:46
Brit25-Sep-05 12:46 
GeneralRe: Confused like me? A message to codeproject users. Pin
gilad-ap26-Sep-05 6:04
gilad-ap26-Sep-05 6:04 
GeneralWriting own dll Pin
Veera Raghavendra30-Jun-05 17:28
Veera Raghavendra30-Jun-05 17:28 
GeneralRe: Writing own dll Pin
gilad-ap12-Jul-05 6:16
gilad-ap12-Jul-05 6:16 
Generalnot found mad.h Pin
Veera Raghavendra29-Jun-05 19:50
Veera Raghavendra29-Jun-05 19:50 
GeneralRe: not found mad.h Pin
gilad-ap30-Jun-05 6:18
gilad-ap30-Jun-05 6:18 
GeneralRe: not found mad.h Pin
YakovT28-Jun-06 22:27
YakovT28-Jun-06 22:27 
QuestionHow to use Pin
Veera Raghavendra24-Jun-05 16:57
Veera Raghavendra24-Jun-05 16:57 
AnswerRe: How to use Pin
gilad-ap25-Jun-05 11:22
gilad-ap25-Jun-05 11:22 
GeneralRe: How to use Pin
Veera Raghavendra26-Jun-05 19:12
Veera Raghavendra26-Jun-05 19:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.