Skip to main content
Email Password   helpLost your password?

Sample Image - Aumplib.gif

Introduction

Aumplib (fully qualified name: Arbingersys.Audio.Aumplib) is a namespace of various classes that provide audio conversion capabilities, and can convert between many audio formats, including MP3. Aumplib provides an OO interface to several prominent Open Source projects, using P/Invoke. These projects are LAME (MP3 encoding), libsndfile (non-MP3 audio formats), and madlldlib/libmad (MP3 decoding). It supports conversion between a large number of audio formats, and in the future should support even more.

Background

Aumplib was designed to provide a clean, easy, and powerful audio conversion interface in C# to prominent Open Source audio conversion libraries (which were written in C/C++). These libraries have existed on the Internet for some time, but were not readily usable by C# programmers because the data structures were not clearly mapped or they were not in DLL form. Aumplib "wraps" these libraries using P/Invoke and offers various objects that simplify using them.

Using the code

Aumplib is made up of various "wrapper" classes that communicate with the third-party DLLs, and Aumpel, the main interface class, which "wraps the wrapper" classes to make conversion as simple a task as possible. An example, TestForm.cs, is included in the source that demonstrates using the Aumpel class. We will make a brief study of this since it is the primary interface. Each of the wrapper classes can be used individually, but for most purposes Aumpel should suffice.

TestForm.cs defines a class called TestForm which is derived from the "Systems.Windows.Forms" class; basically, it is a window rather than a console application. As you scan down the source, you will see that it first declares variables, most of which are window controls (i.e., ComboBox, ProgressBar). The constructor TestForm() instantiates the controls, defines their properties, sets up event handlers, and adds them to the form. To understand this portion, it would be best to reference some documentation on creating a Windows application in C#.

Three private variables are declared that are important further on in the code. These are audioConverter, an Aumpel object, and two Aumpel.soundFormat types that are used to determine the input and output sound file formats.

private Aumpel audioConverter = new Aumpel();
private Aumpel.soundFormat inputFileFormat;
private Aumpel.soundFormat outputFileFormat;

As we scan further, we reach the definitions of the delegate functions. These are crucial to the operation of Aumplib. The delegates do two things:

  1. They receive updates from Aumplib (i.e., how many bytes have been processed in the current conversion) that you will use to update status of your application, and
  2. reference either structures or Aumpel itself, giving you the ability to garner further information, change settings, or cancel a conversion.

If you want MP3 decoding capabilities in your class, you will have to define at least two delegates (the MP3 decoding delegate takes slightly different parameters).

// Conversion callback (lame,libsndfile)

private static void
ReportStatus(int totalBytes, 
    int processedBytes, Aumpel aumpelObj)
{
     progressBar1.Value = (int)(((float)processedBytes/(float)totalBytes)*100);
}

The first delegate, ReportStatus, handles status updates for both MP3 encoding and non-MP3 conversions (i.e., WAV, AIFF, AU, etc). As you can see, it is very simple. All it really does is take the parameters totalBytes (total bytes to process), and processedBytes (how many of the total have been converted), and updates the progress bar from a calculation based on them. The aumpelObj parameter is a reference to the Aumpel object. It can be used for cancellation of a conversion.

// Decoding callback (madlldlib)


private static bool 

ReportStatusMad(uint frameCount, 
        uint byteCount, ref MadlldlibWrapper.mad_header mh) 
{

    progressBar1.Value = (int)(((float)byteCount/(float)soundFileSize)*100);
    return true;
}

The second delegate we declare, ReportStatusMad, handles status updates for the MP3 decoding. Its parameters are frameCount (how many MP3 frames processed), byteCount (total bytes processed), and a reference to the MadlldlibWrapper.mad_header structure. This structure is a mapping to a structure in the DLL and provides information specific to the MP3 file (i.e., layer, frequency). Because only the bytes processed are returned each time this delegate is called, we have to use another "class" variable, soundFileSize to give us the total size of the file in bytes (it is calculated when the input file is selected). We then use it in the calculation to update the progress bar. If this method returns false, the conversion will abort.

Next, we come upon the event handlers of the form. First, we define the handlers for sourceFileButton and destFileButton, which use a dialog box to select an input file (file to convert) and an output file. After that comes the method that invokes Aumpel, the handler for convertButton, convertButton_Click(). We will study it in pieces below, since it contains the bulk of the conversion code.

protected void
convertButton_Click (object sender, System.EventArgs e)
{

    // Set conversion type


    switch((string)comboBox1.SelectedItem)
    {
        case "WAV":
            outputFileFormat = Aumpel.soundFormat.WAV;
            break;
        case "MP3":
            outputFileFormat = Aumpel.soundFormat.MP3;
            break;
        case "AU":
            outputFileFormat = Aumpel.soundFormat.AU;
            break;
        case "AIFF":
            outputFileFormat = Aumpel.soundFormat.AIFF;
            break;
        default:
            MessageBox.Show("You must select a type to convert to.",
                "Error", MessageBoxButtons.OK);
            return;
    }

...

First, convertButton_Click() checks the control comboBox1 to see what output sound format the user specified. If none is specified, the user is notified, and the method returns. If one is, it assigns outputFileFormat a value Aumpel understands. Then we check outputFileFormat to determine what type of conversion is needed.

...
 
  // Convert to MP3


  if ( (int)outputFileFormat == (int)Aumpel.soundFormat.MP3 )
  {

      try
      {

          Aumpel.Reporter defaultCallback = new Aumpel.Reporter(ReportStatus);

          audioConverter.Convert(inputFile, 
                  (int)inputFileFormat, outputFile, 
                  (int)outputFileFormat, defaultCallback);

          progressBar1.Value = 0;

          destFileLabel.Text = outputFile = "";
          sourceFileLabel.Text = inputFile = "";
          
          MessageBox.Show("Conversion finished.", "Done.", MessageBoxButtons.OK);

      }
      catch (Exception ex)
      {
          ShowExceptionMsg(ex);
          return;
      }

  }

...

Using outputFileFormat, we check to see what kind of conversion needs to be done: to MP3, from MP3, or non-MP3 (WAV, AIFF...). If the output format specified was MP3, then the block of code above executes. First, it defines defaultCallback from the delegate definition ReportStatus, and then calls the overload of the Aumplib.Convert() method that handles MP3 encoding. One of the parameters to this method is the delegate we have defined, as you can see. The entire thing is wrapped in a try/catch clause, and any exceptions are caught and displayed to the user.

...

   // From MP3:


  else if ( (int)inputFileFormat == (int)Aumpel.soundFormat.MP3 )
  {

      try
      {

          MadlldlibWrapper.Callback defaultCallback = 
              new MadlldlibWrapper.Callback(ReportStatusMad);

          // Determine file size

          FileInfo fi = new FileInfo(inputFile);
          soundFileSize = (int)fi.Length;

          audioConverter.Convert(inputFile, 
              outputFile, outputFileFormat, defaultCallback);
          progressBar1.Value = 0;

          destFileLabel.Text = outputFile = "";
          sourceFileLabel.Text = inputFile = "";

          MessageBox.Show("Conversion finished.", "Done.", MessageBoxButtons.OK);

      }
      catch (Exception ex)
      {
          ShowExceptionMsg(ex);
          return;
      }

  }

...

If you are decoding from MP3 to WAV, the above code executes. Notice that where the MP3 encoding block defines defaultCallback as an Aumpel.Reporter delegate, this block defines defaultCallback using MadlldlibWrapper.Callback, passing it the delegate definition ReportStatusMad which we defined above. This is the reason the definitions of the two delegates are different. Other than that difference, this block of code behaves essentially the same as the first one; it calls an overload of the Aumpel.Convert() method and waits until the conversion is finished. Note that in this overload of Aumpel.Convert(), the inputFileFormat parameter is missing. This is because the source file format is implied (MP3).

...

  // Non-MP3 soundfile conversion:


  else
  {

      try
      {

          Aumpel.Reporter defaultCallback = new Aumpel.Reporter(ReportStatus);

          audioConverter.Convert(inputFile, 
                  (int)inputFileFormat, 
                  outputFile, 
                  (int)(outputFileFormat | Aumpel.soundFormat.PCM_16), 
                  defaultCallback);

          progressBar1.Value = 0;

          destFileLabel.Text = outputFile = "";
          sourceFileLabel.Text = inputFile = "";
          
          MessageBox.Show("Conversion finished.", "Done.", MessageBoxButtons.OK);

      }
      catch (Exception ex)
      {
          ShowExceptionMsg(ex);
          return;
      }

  }

}

If neither conversion to MP3 nor from MP3 is specified, then a non-MP3 conversion is attempted. Again, an overload of the Aumpel.Convert() method is used. The ReportStatus delegate is used for this conversion as well. The only significant difference between this block and the "conversion-to-MP3" block above is that a sub-type is used with the outputFileFormat parameter that is combined via the | operator. (The Aumpel.soundFormat types are basically just int, and can be treated as such.) In the code above, we are specifying an output of 16-bit PCM and whatever file format we have selected (outputFileFormat): WAV, AIFF, or AU.

That's basically it. When the "Convert" button is pressed, the above code begins to fire, and if everything is set appropriately, the conversion will take place, showing you its progress via the progress bar.

Notes

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
Generallibnsdfile dll not loading Pin
soumyakumkumkar85
19:19 5 Oct '09  
GeneralIt does not contain a sln Pin
asimkhatri
8:14 10 Sep '09  
GeneralI have some problem when running TestForm Pin
kienct00339
19:20 28 Jul '09  
GeneralWMA to other format conversion. Pin
alok.mailbox
4:43 20 Mar '09  
Questionhint for reading WMA Pin
sagaert
12:55 17 Nov '08  
GeneralDownload Error - Please Help Pin
asaeed123
1:51 15 Oct '08  
GeneralRe: Download Error - Please Help Pin
asaeed123
10:57 15 Oct '08  
NewsBig help Pin
towerturtle
14:17 11 Aug '08  
GeneralRe: Big help Pin
jacob00
6:59 11 Nov '08  
GeneralRe: Big help Pin
towerturtle
12:36 11 Nov '08  
QuestionHelp, dll problem Pin
towerturtle
14:14 11 Aug '08  
AnswerRe: Help, dll problem Pin
Mohammad Dayyan
2:37 7 Nov '08  
QuestionConvert Stereo Wav to Mono MP3? Pin
Loony09
14:07 21 Jul '08  
QuestionTrying to get this project to work - 2 small problems - please help! Pin
LosBear
9:51 10 Jul '08  
AnswerRe: Trying to get this project to work - 2 small problems - please help! Pin
towerturtle
14:16 11 Aug '08  
Generalconverting video file to mp3,mp4 format Pin
ravurirkk
19:45 19 Jun '08  
GeneralAny chance on supporting CCITT U-Law encoded wav files? Pin
Member 1367689
14:27 6 Mar '08  
GeneralRe: Any chance on supporting CCITT U-Law encoded wav files? Pin
Alexander Zhuang
14:26 18 Apr '08  
GeneralRe: Any chance on supporting CCITT U-Law encoded wav files? Pin
Ram. S
3:05 30 Sep '09  
QuestionConversion stops at half file [modified] Pin
thrasher0815
6:54 30 Oct '07  
GeneralUsing on web server? Pin
Mr Delphi Developer
14:35 9 Oct '07  
GeneralRe: Using on web server? Pin
gilad-ap
8:07 12 Oct '07  
GeneralRe: Using on web server? Pin
MrBaseball34
9:46 12 Oct '07  
QuestionSample Rate Pin
Oscar1986
22:28 23 Sep '07  
AnswerRe: Sample Rate Pin
gilad-ap
5:43 26 Sep '07  


Last Updated 12 Oct 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009