[SDL] Re: 1.2.0 audio problems.

Lee Haywood sdl at ksl2.freeserve.co.uk
Wed Apr 25 13:16:04 PDT 2001


> > If the user tries to enable audio and the sound card is busy they get the
> > expected error.  When the sound device is free again SDL_OpenAudio() just
> > fails immediately with the previous error and the application has to be
> > restarted to get it working again.

> Can you post a minimal code sample that we can use to reproduce the
> problem?

Okay, here's the test program, effectively the sample program from the SDL
documentation.  Press Return 3 times to hear a sample you provide
(test.wav) 3 times.

Perform the following steps to recreate the problem.

* Press Return to play the test sample (to confirm that it can be played).
* Start a sound with another application.
* Once that's started, press Return again and you get the "No available
  audio device" error as expected.
* Stop the external sound.
* Press Return to trying to play the test sample again.  It doesn't work
  even though the sound device is no longer busy.

As I mentioned before, this works if used with 1.0.8, not under 1.2.0.

Ta.

- Deth -

=== Makefile ========================================================

CC=gcc
CFLAGS=-Wall -O2 -pipe
SDL_CFLAGS := $(shell sdl-config --cflags)
SDL_LDFLAGS := $(shell sdl-config --libs)

default: test

test: test.c
      $(CC) test.c $(CFLAGS) $(SDL_CFLAGS) $(SDL_LDFLAGS) -o test

=== test.c ==========================================================

#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL_audio.h>

#define SAMPLE_FILE "test.wav"

#define SYSTEM_ERROR 2

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

typedef int bool;

/* Global variables.  */

Uint8 *Data;
Uint32 Position;
Uint32 Length;

/* Local function prototype.  */

static bool Play_Sound();
static void Mix_Audio( void *Unused, Uint8 *Stream, int Length );



/* Main processing.  */

int main( int argc, char *argv[] )
{
    SDL_AudioSpec AudioSpec;
    int Count;

    /* Access the SDL library.  */
    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        fprintf( stderr, "Unable to initialise SDL library,\n\t%s\n",
                 SDL_GetError() );
        return SYSTEM_ERROR;
    }

    /* Ensure that SDL is closed when the program ends.  */
    if ( atexit( SDL_Quit ) )
    {
        perror( "atexit" );
        fprintf( stderr, "Failed to register shut-down handler.\n" );
    }

    /* Set 16-bit stereo audio at 22Khz.  */
    AudioSpec.freq = 22050;
    AudioSpec.format = AUDIO_S16;
    AudioSpec.channels = 2;
    AudioSpec.samples = 512;
    AudioSpec.callback = Mix_Audio;
    AudioSpec.userdata = NULL;

    /* Attempt to play a sample 3 times...  */
    for ( Count = 1; Count <= 3; Count++ )
    {
        /* Wait for the user to signal that a sound is playing.  */
        printf( "Press Return to play sound.  " );
        fflush( stdout );
        (void) fgetc( stdin );

        /* Open the audio device, display error if unavailable...  */
        if ( SDL_OpenAudio( &AudioSpec, NULL ) < 0 )
        {
            fprintf( stderr, "Unable to open audio.  %s.\n",
                     SDL_GetError() );
        }
        /* Otherwise, if successful...  */
        else
        {
            /* Activate playback.  */
            Length = 0;
            SDL_PauseAudio( 0 );

            /* Load a sample and start it playing.  */
            if ( Play_Sound() )
            {
                return SYSTEM_ERROR;
            }

            /* Deactivate audio device.  */
            SDL_CloseAudio();
        }
    }

    /* Return successfully.  */
    return 0;
}

/* Loads the sample and sets it playing.  */

static bool Play_Sound()
{
    SDL_AudioSpec Wave;
    SDL_AudioCVT Audio;
    Uint8 *Buffer;
    Uint32 Size;

    /* Load the sound file and convert it to the correct frequency.  */
    if ( SDL_LoadWAV( SAMPLE_FILE, &Wave, &Buffer, &Size ) == NULL )
    {
        fprintf( stderr, "Couldn't load audio file '%s' - %s.\n",
                 SAMPLE_FILE, SDL_GetError() );
        return TRUE;
    }
    if ( SDL_BuildAudioCVT( &Audio, Wave.format, Wave.channels, Wave.freq,
                            AUDIO_S16, 2, 22050 ) != 1 )
    {
        fprintf( stderr, "Failed to build audio filter.\n" );
        return TRUE;
    }
    Audio.buf = malloc( Size * Audio.len_mult );
    memcpy( Audio.buf, Buffer, Size );
    Audio.len = Size;
    SDL_ConvertAudio( &Audio );
    SDL_FreeWAV( Buffer );

    /* Pass sound data to mixer.  */
    SDL_LockAudio();
    Data = Audio.buf;
    Length = Audio.len_cvt;
    Position = 0;
    SDL_UnlockAudio();

    /* Wait until sample has finished playing.  */
    do
    {
        SDL_Delay( 1 );
    }
    while ( Position < Length );

    /* Return successfully.  */
    return FALSE;
}

/* Combines requested amount of sample data from sound that is playing.  */

static void Mix_Audio( void *Unused, Uint8 *Stream, int RequestLength )
{
    Uint32 Amount;

    /* Determine the amount of sample data to be mixed.  */
    Amount = Length - Position;
    if ( Amount > RequestLength )
    {
        Amount = RequestLength;
    }

    /* If data is available to be mixed...  */
    if ( Amount )
    {
        /* Mix the data into a single stream.  */
        SDL_MixAudio( Stream, &Data[ Position ], Amount,
                      SDL_MIX_MAXVOLUME );

        /* Advance sample position.  */
        Position += Amount;
    }
}






More information about the SDL mailing list