I’m trying to write a game, so I’m experimenting with SDL’s sound API
and SDL_sound. I want to play a 22 khz mono wav file on an audio device
opened as 44 khz 2 stereo, so I use SDL_BuildCVT() and
SDL_ConvertAudio().
However, doing that makes SDL_MixAudio() crash, and I can’t find out the
reason.
44 khz stereo MP3s play just fine.
Can anybody help me?
Here’s the source code (the comments contain more details about the
problem):
#include “SDL.h”
#include “SDL_sound.h”
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int done = 0;
void
mix_audio (void *user_data, Uint8 *stream, int len)
{
Uint32 amount;
Sound_Sample *sample;
Sound_AudioInfo *info;
SDL_AudioCVT cvt;
sample = (Sound_Sample *) user_data;
if (done)
return;
/* Decode the sound file */
Sound_SetBufferSize (sample, len);
amount = Sound_Decode (sample);
/* If end-of-file has been reached, free the sound data */
if (amount < sample->buffer_size
&& (sample->flags & SOUND_SAMPLEFLAG_EOF))
{
done = 1;
}
/* Convert the audio data (sample rate, channels, etc.) and mix
it */
info = &sample->actual;
SDL_BuildAudioCVT (&cvt,
info->format, info->channels, info->rate,
AUDIO_S16, 2, 44100);
cvt.buf = (Uint8 *) malloc (amount * cvt.len_mult);
memcpy (cvt.buf, sample->buffer, amount);
cvt.len = amount;
SDL_ConvertAudio (&cvt);
/* This function makes the program crash when playing the
22khz wav file, but works just fine when playing a 44khz MP3;
when commented out, the program doesn't crash */
SDL_MixAudio (stream, cvt.buf, amount * cvt.len_mult,
SDL_MIX_MAXVOLUME);
if (done)
Sound_FreeSample (sample);
}
int
main (int argc, char *argv[])
{
SDL_AudioSpec spec;
Sound_Sample *sample;
/* Initialize SDL and SDL_sound */
SDL_Init (SDL_INIT_AUDIO);
atexit (SDL_Quit);
Sound_Init ();
if (argc > 1)
{
sample = Sound_NewSampleFromFile (argv[1], NULL,
1024 * 4);
}
else
{
/* Open a 22khz 1 channel wav file */
sample = Sound_NewSampleFromFile ("gunshot.wav", NULL,
1024 * 4);
}
/* Open audio device */
spec.freq = 44100;
spec.format = AUDIO_S16;
spec.channels = 2;
spec.samples = 1024 * 4;
spec.callback = mix_audio;
spec.userdata = sample;
SDL_OpenAudio (&spec, NULL);
/* Play the wav file */
SDL_PauseAudio (0);
while (!done)
usleep (100000);
/* Shutdown audio system */
SDL_CloseAudio ();
Sound_Quit ();
SDL_QuitSubSystem (SDL_INIT_AUDIO);
return 0;
}