[SDL] SDL_MixAudio() crash when trying to play converted audio data

Hongli Lai h.lai at chello.nl
Tue Jul 9 04:23:01 PDT 2002


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;
}







More information about the SDL mailing list