![]() |
Multimedia »
Audio and Video »
Audio
Intermediate
Aumplib: C# Namespace And Classes For Audio ConversionBy gilad-apA namespace of various classes that provide audio conversion capabilities, and can convert between many audio formats, including MP3. |
C#.NET1.0, .NET1.1, Win2K, WinXP, Win2003VS.NET2003, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

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.
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.
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:
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.
General
News
Question
Answer
Joke
Rant
Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads.
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 12 Oct 2004 Editor: Smitha Vijayan |
Copyright 2004 by gilad-ap Everything else Copyright © CodeProject, 1999-2010 Web18 | Advertise on the Code Project |