Playing Ogg Vorbis Files With Allegro
Playing Ogg Vorbis Files With Allegro
Ogg Vorbis is an open-source, royalty-free audio compression format. From my (limited) experience, the quality is as good or better than mp3, and the compression is slightly better (smaller files.) Unlike mp3, however, it is totally free and unpatented (mp3 uses Fraunhofer compression, which is patented.) Because of the open and free nature of Ogg Vorbis, I am going to focus on that as the audio format, so you won't have to worry about any copyright infringements.
There are a number of ways to stream an Ogg Vorbis file in your application. You can develop your own routines from the vorbis library, use the Allegro audio routines, or use a library by Vincent Penquerc'h to simplify working with Vorbis files and Allegro. Guess which one we're going with…
Requirements
-
Ogg library NOTE: It appears the Vorbis SDK is no longer linked on the site. Here is a direct link to the Vorbis SDK.
Alogg can be compiled with options for fixed-point support (useful for mobile devices), URL support, and threaded streaming. We'll start without any of these options so we can just get an audio file playing.
Assuming you have Dev-C++ and Allegro installed, it is now time to install Alogg. Download and decompress the files to a temporary folder. Before going any further, lets build the documentation.
Build Alogg Documentation
You will need the makedoc.exe utility that came with Allegro (it will be in the \Allegro\docs\ folder,) so copy that to the alogg source directory. Open a DOS prompt and go to the directory containing the alogg files. type make docs type=html or make docs type=texi and the documentation will be created. You can refer to this for more assistance in setting up alogg in your environment.
Setup the Ogg/Vorbis Library
In order to build (and use) Alogg, we are going to need the Ogg/Vorbis library. The simplest thing to do is to download the Win32 SDK from http://www.vorbis.com. Extract the contents of this file, and move the contents of the include folder to your Dev-C++ include path and copy the contents of the lib file to your Dev-C++ library path. Maintain the directory structure with the header files (i.e. \include\ogg\ogg.h.) Also, copy the binary files (in the bin folder) to your \windows\system32 directory.
Compile Alogg
Simply type make then make install to compile and install the alogg library. You may get errors about a missing _G_config.h header file. It is in the GCC-2.95.3 package, located here (not sure why its not in the more recent packages.) Unzip the package, and copy the file to your include directory.
That's all you need to do to install the basic alogg library. Now lets put it to use.
Your First Alogg Project
For our example of playing an Ogg/Vorbis audio file, we will do nothing more than create a window with Allegro, then play a hard-coded audio file. For kicks, we can display the name of the file on the screen. As an exercise, you might want to play with playing a file specified on the command line. Or not.
Create a Project
Create an Allegro file as described in the <a rel="nofollow" title="http://dratek.com/component/option,com_openwiki/Itemid,52/id,tutorial:tut_devcpp_allegro_intro/" class="urlextern" href="../../../../../../../component/option,com_openwiki/Itemid,52/id,tutorial:tut_devcpp_allegro_intro/">Dev-C++ and Allegro tutorial</a> (you can even use my template to generate the project.
Get an Ogg File
Kinda basic, but necessary. I'll pretty much leave this up to you, but you can check out http://www.vorbis.com for some samples. I'll be using Mists of Time for this example. Once you have the file, copy it to your project directory.
Include the Alogg Library
At the top of your code, where you are placing your includes, add the following line:
#include <alogg\alogg.h>Define the Size of an Audio Block
The block size will determine how much of the audio is read into memory at a time. A small block size will use less memory, and load fast, but could sound choppy. A large block size will sound good (usually,) but requires more memory and more time to load. You may need to play with this (or make it user definable) in order to get the right value.
#define BLOCK_SIZE 4096Declare Audio Stream Variables
At the start of the main procedure, declare the following variables:
// Streaming audio variables: struct alogg_stream *pStream; int iStreamUpdate = 1; // Initialize to >0 char pszAudioFile[ 256 ];
Specify the name of the Audio File
We need to fill in the audio file name variable with the name we are using. This will be the full name of the file you are using.
// Specify the name of the audio file: sprintf( pszAudioFile, "Mists_of_Time-4T.ogg" );
Initialize the Alogg Library
Just after initializing Allegro, initialize Alogg:
// Initialize Alogg: alogg_init();
Display The Name Of The Audio File (optional)
Just for fun, go to the method that displays the welcome message (if you are using the template) and change it to display the name of the audio file:
textout_centre( screen, font, pszAudioFile, SCREEN_W / 2.0, SCREEN_H / 2.0, makecol( 255, 255, 255 ) );
Set the Per-Voice Volume
As more voices are reserved for the digital sound driver, Allegro reduces the volume of each in order to (hopefully) avoid distortion. Check out the Allegro documentation for more, but by using a value of 0, we can play all samples at the maximum value without distortion.
// Set the per-voice volume: set_volume_per_voice( 0 );
Initialize the Sound Module
The following parameters are generally sufficient for initializing the audio. If the return value is less than 0, then the sound initialization failed.
// Initialize the sound module: if ( install_sound( DIGI_AUTODETECT, MIDI_AUTODETECT, NULL ) < 0 ) { fprintf(stderr,"Failed to initialize sound module\n"); alogg_exit(); exit(1); }
Begin Streaming
Grab the first block of audio data, and start streaming the audio file:
// Start streaming the audio: if ( !( pStream = alogg_start_streaming( pszAudioFile, BLOCK_SIZE ) ) ) { fprintf( stderr, "Failed to start streaming %s\n", pszAudioFile ); alogg_exit(); exit(1); }
Loop Until the User Presses ''ESC''
If you are using the template from the Dev-C++ and Allegro tutorial, replace the call to readkey() with a while loop. We will stay in the loop until the escape key is pressed:
while ( !key[ KEY_ESC ] ) {
Read the Next Block
If we haven't reached the end of the stream yet, update the stream and read another block of audio data:
// If iStreamUpdate is greater than 0, then there is still // more audio data to stream. If it is 0, then we've come // to the end of the file, and if its less than 0, there // was an error. if ( iStreamUpdate > 0 ) { iStreamUpdate = alogg_update_streaming( pStream ); } }
Cleanup
After the user presses the escape key, we need to shutdown the audio processing. First we stop streaming the Ogg file, then we exit the Alogg library:
// Stop the audio streaming: alogg_stop_streaming( pStream ); // Exit the alogg library: alogg_exit();
Set Linker Parameters
The following linker parameters must be added under project options:
-lalogg
-lalleg
-lvorbisfile
-lvorbis
-logg
When using the above method of streaming, you will need to make sure you either update the stream often enough, or that your block size is large enough, so that the audio plays smoothly. In a game, it might be a good idea to simply update the audio stream every frame.
Build and Run
You should now be ready to build the application and run it to listen to your audio file.
Downloads
| MyFirstAlogg.zip | The above application, ready for Dev-C++. |
| DevCpp_AloggStreaming_template.zip | A project template for Dev-C++ to generate a simple Alogg application, like the one above. |
