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