[Prev]
Table Of Contents
[Next]
Using the Simple DirectMedia Layer API
Sound
You need to have a callback function written which
mixed your audio data and puts it in the audio
stream. After that, choose your desired audio format
and rate, and open the audio device.
The audio won't actually start playing until you
call SDL_PauseAudio(0), allowing you to perform other
audio initialization as needed before your callback
function is run. After you are done using the sound
output, you should close it with the SDL_CloseAudio()
function.
|
Tip:
If your application can handle different audio formats,
pass a second SDL_AudioSpec pointer to SDL_OpenAudio() to
get the actual hardware audio format. If you leave the
second pointer NULL, the audio data will be converted to
the hardware audio format at runtime. |
Example:
#include "SDL.h"
#include "SDL_audio.h"
{
extern void mixaudio(void *unused, Uint8 *stream, int len);
SDL_AudioSpec fmt;
/* Set 16-bit stereo audio at 22Khz */
fmt.freq = 22050;
fmt.format = AUDIO_S16;
fmt.channels = 2;
fmt.samples = 512; /* A good value for games */
fmt.callback = mixaudio;
fmt.userdata = NULL;
/* Open the audio device and start playing sound! */
if ( SDL_OpenAudio(&fmt, NULL) < 0 ) {
fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
exit(1);
}
SDL_PauseAudio(0);
...
SDL_CloseAudio();
}
|
- Loading and playing sounds
SDL provides a single sound loading routine for
your convenience, SDL_LoadWAV(). After you load your
sounds, you should convert them to the audio format
of the sound output using SDL_ConvertAudio(), and
make them available to your mixing function.
|
Tip:
SDL audio facilities are designed for a low level
software audio mixer. A complete example mixer
implementation available under the LGPL license can be
found in the SDL demos archive. |
Example:
#define NUM_SOUNDS 2
struct sample {
Uint8 *data;
Uint32 dpos;
Uint32 dlen;
} sounds[NUM_SOUNDS];
void mixaudio(void *unused, Uint8 *stream, int len)
{
int i;
Uint32 amount;
for ( i=0; i<NUM_SOUNDS; ++i ) {
amount = (sounds[i].dlen-sounds[i].dpos);
if ( amount > len ) {
amount = len;
}
SDL_MixAudio(stream, &sounds[i].data[sounds[i].dpos], amount, SDL_MIX_MAXVOLUME);
sounds[i].dpos += amount;
}
}
void PlaySound(char *file)
{
int index;
SDL_AudioSpec wave;
Uint8 *data;
Uint32 dlen;
SDL_AudioCVT cvt;
/* Look for an empty (or finished) sound slot */
for ( index=0; index<NUM_SOUNDS; ++index ) {
if ( sounds[index].dpos == sounds[index].dlen ) {
break;
}
}
if ( index == NUM_SOUNDS )
return;
/* Load the sound file and convert it to 16-bit stereo at 22kHz */
if ( SDL_LoadWAV(file, &wave, &data, &dlen) == NULL ) {
fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
return;
}
SDL_BuildAudioCVT(&cvt, wave.format, wave.channels, wave.freq,
AUDIO_S16, 2, 22050);
cvt.buf = malloc(dlen*cvt.len_mult);
memcpy(cvt.buf, data, dlen);
cvt.len = dlen;
SDL_ConvertAudio(&cvt);
SDL_FreeWAV(data);
/* Put the sound data in the slot (it starts playing immediately) */
if ( sounds[index].data ) {
free(sounds[index].data);
}
SDL_LockAudio();
sounds[index].data = cvt.buf;
sounds[index].dlen = cvt.len_cvt;
sounds[index].dpos = 0;
SDL_UnlockAudio();
}
|
[Prev]
Table Of Contents
[Next]
|