| Games and SDL SDL Installation SDL for Embedded SDL API SDL Events | SDL Graphics SDL Threads Thread Example SDL Animation SDL Sound | Raw Video Player Video Formats Video Compression | Game Trees About The Author |
| 1 | 2 |
Sound programming is a crucial component in game programming. Without sound effects, many popular games may become bore and uninterested.
Digital Audio Formats
There exists many different digital audio formats, many of which are created by commercial organizations. Industrial groups like MPEG have created open standards and the most well-known one may be the MP3 audio format. The SDL sound library does not support MP3 format and a user cannot play an MP3 file using only the SDL sound library, which actually only supports Microsoft's WAV format. To play sound files other than WAV, one has to use the SDL mixer library.
PCM
Sound is produced by the vibration of a media like air or water. Audio refers to the sound within the range of human hearing. Naturally, a sound signal is analog, which is continuous in both time and amplitude. To store and process sound information in a computer or to transmit it through a computer network, we must first convert the analog signal to digital form using an analog-to-digital converter ( ADC ); the conversion involves two steps: (1) sampling, and (2) quantization. Different encoding schemes can be used to quantize the sound data. PCM ( Pulse Code Modulation ) is the simplest and most fundamental method of representing the quantized data in digital format.
Sampling is the process of examining the value of a continuous function at regular intervals ( see Figure below ). We might measure the voltage of an analog waveform every millisecond, or measure the brightness of a photograph every millimeter, horizontally and vertically. Sampling usually occurs at uniform intervals, which are referred to as sampling intervals. The reciprocal of sampling interval is referred to as the sampling frequency or sampling rate. If the sampling is done in time domain, the unit of sampling interval is second and the unit of sampling rate is Hz, which means cycles per second. A higher sampling rate usually allows for a better representation of the original sound wave. However, when the sampling rate is increased up to a certain value ( twice as fast as the highest frequecy of the signal ), no further improvement can be made by further increasing the sampleing rate and at this value, the original sound wave can be completely reconstructed from the samples. This is known as the Nyquist Theorem.

Quantization is the process of limiting the value of a sample of a continuous function to one of a predetermined number of allowed values, which can then be represented by a finite number of bits in the digital world. The following figure shows the quantization of the same signal shown above. The dashed curve is the original signal and the vertical bars show the quantized values. As shown in the figure, the height of each vertical bar can only take on certain values, shown by horizontal dashed lines. In the figure, 11 quantization levels are used and thus 4 bits are required to encode each sample. In PCM, the height of each bar is translated into a digital number. The difference between a quantized representation and an original analog signal is referred to as the quantization noise.

In the gaming environment, a PCM sample is usally 8 or 16 bits for each channel ( one channel for mono, two channeles for stereo ) and the data are sampled at a rate of 22,050 or 44,100 Hz. The CD-quality audio use 44,100 Hz sampling rate and 16 bits amplitude. Thus, the resulting bit rate of a stereo ( 2 channels ) CD-audio stream will be
Just as raw pixel data are often saved in .bmp format, raw PCM sound samples are often saved in .wav format. SDL can read a .wav file with the SDL_LoadWAV() function.
Currently, there are two popular sets of competing Linux sound system drivers. The Open Sound System ( OSS ) consists of a set of kernel modules to provide a common interface to different kinds of sound cards; some of the modules are distributed along with the Linux kernel. The Advanced Linux Sound Architecture ( ALSA ) provides an alternate set of Linux sound drivers. On the other hand, higher-level libraries such as SDL and OpenAL ( Open Audio Library ) provide higher-level APIs for users to utilize Linux sound features. To produce sound in the SDL environment, you have to install the SDL_sound-* package. However, the SDL_sound library only supports Microsoft's .wav format and only has a limited number of functions. Practically, to integrate sound inot your application, you also need the mixer library of the package SDL_mixer-*. To distinguish functions from SDL_sound-* and those from SDL_mixer-*, the former start with prefix SDL_ while the latter starts with Mix_.
To use the SDL sound library, you have to include in your program the header file "SDL_sound.h" by adding the statment,
The following table lists all the functions provided by the SDL_sound library.
| SDL_AudioSpec() | Audio Specification Structure | |
| SDL_OpenAudio() | Opens the audio device with the desired parameters. | |
| SDL_PauseAudio() | Pauses and unpauses the audio callback processing | |
| SDL_GetAudioStatus() | Gets the current audio state | |
| SDL_LoadWAV() | Loads a WAVE file | |
| SDL_FreeWAV() | Frees previously opened WAV data | |
| SDL_AudioCVT() | Audio Conversion Structure | |
| SDL_BuildAudioCVT() | Initializes a SDL_AudioCVT structure for conversion | |
| SDL_ConvertAudio() | Converts audio data to a desired audio format. | |
| SDL_MixAudio() | Mixes audio data | |
| SDL_LockAudio() | Locks out the callback function | |
| SDL_UnlockAudio() | Unlocks the callback function | |
| SDL_CloseAudio() | Shuts down audio processing and closes the audio device. |
Listed below are some of the functions that are used more often.
| Synopsis |
#include "SDL.h"
SDL_AudioSpec *SDL_LoadWAV(const char *file, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len); |
|
|---|---|---|
| Description | Loads a WAVE file into memory. If succeeds, it returns the given SDL_AudioSpec, filled with the audio data format of the wave data, and sets audio_buf to a malloc'd buffer containing the audio data, and sets audio_len to the length of that audio buffer, in bytes. You need to free the audio buffer with SDL_FreeWAV when you are done with it. | |
| Returns | This function returns NULL and sets the SDL error message if the wave file cannot be opened, of if it uses an unknown data format, or is corrupt. Currently raw, MS-ADPCM and IMA-ADPCM WAVE files are supported. If succeeds, it returns the given SDL_AudioSpec. |
| Synopsis |
#include "SDL.h"
void SDL_MixAudio(Uint8 *dst, Uint8 *src, Uint32 len, int volume); |
|
|---|---|---|
| Description | This function takes two audio buffers of len bytes each of the playing audio format and mixes them, performing addition, volume adjustment, and overflow clipping. The volume ranges from 0 to SDL_MIX_MAXVOLUME and should be set to the maximum value for full audio volume. Note this does not change hardware volume. | |
| Returns | None. |
The following section presents some examples on using the SDL_sound library to process audio data; some of them are adopted from the SDL site: http://www.libsdl.org/cgi/docwiki.cgi/Audio_20Examples
Opening Audio Device
The following piece of code opens the audio device and sets the desired audio parameters.
SDL_AudioSpec wanted;
// Set the audio format
wanted.freq = 22050;
wanted.format = AUDIO_S16SYS;
wanted.channels = 2; // 1 = mono, 2 = stereo
wanted.samples = 1024; // Good low-latency value for callback
wanted.callback = fill_audio;
wanted.userdata = NULL;
// Open the audio device, forcing the desired format
if ( SDL_OpenAudio(&wanted, NULL) < 0 ) {
fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
return(-1);
}
return(0);
|
Playing Audio
static Uint8 *audio_chunk;
static Uint32 audio_len;
static Uint8 *audio_pos;
/* The audio function callback takes the following parameters:
stream: A pointer to the audio buffer to be filled
len: The length (in bytes) of the audio buffer
*/
void fill_audio(void *udata, Uint8 *stream, int len)
{
// Only play if we have data left
if ( audio_len == 0 )
return;
// Mix as much data as possible
len = ( len > audio_len ? audio_len : len );
SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);
audio_pos += len;
audio_len -= len;
}
// Load the audio data ...
;;;;;
audio_pos = audio_chunk;
// Let the callback function play the audio chunk
SDL_PauseAudio(0);
/* Do some processing */
;;;;;
// Wait for sound to complete
while ( audio_len > 0 ) {
SDL_Delay(100); // Sleep 100 ms
}
SDL_CloseAudio();
|
The SDL_sound-xxx package has some sample programs that come with the package; the programs demonstrate how to use the SDL sound library.