diff --git a/sc2/src/sc2code/libs/sound/mixsdl/mixer.c b/sc2/src/sc2code/libs/sound/mixsdl/mixer.c index 445204ac6..64c8c93fa 100644 --- a/sc2/src/sc2code/libs/sound/mixsdl/mixer.c +++ b/sc2/src/sc2code/libs/sound/mixsdl/mixer.c @@ -33,6 +33,20 @@ #define DEBUG +/* stanard SDL_audio driver */ +static const +mixSDL_DriverInfo mixer_SDLdriver = +{ + mixSDL_DriverGetName, + mixSDL_DriverGetError, + mixSDL_DriverOpenAudio, + SDL_CloseAudio, + SDL_PauseAudio +}; +/* SDL_audio driver is the default */ +static mixSDL_Driver mixer_driver = &mixer_SDLdriver; +static mixSDL_DriverFlags mixer_driverflags = 0; + static uint32 audio_opened = 0; static SDL_AudioSpec mixer_spec; static uint32 last_error = MIX_NO_ERROR; @@ -118,6 +132,25 @@ mixSDL_SetError (uint32 error) last_error = error; } +static const char* +mixSDL_DriverGetName () +{ + return "SDL_audio"; +} + +static const char* +mixSDL_DriverGetError (void) +{ + return SDL_GetError(); +} + +static int +mixSDL_DriverOpenAudio (void *desired, void *obtained) +{ + return SDL_OpenAudio ((SDL_AudioSpec *) desired, + (SDL_AudioSpec *) obtained); +} + /************************************************* * General interface */ @@ -130,9 +163,23 @@ mixSDL_GetError (void) return error; } +void +mixSDL_UseDriver (mixSDL_Driver driver, mixSDL_DriverFlags flags) +{ + if (!driver) + return; + + if (driver == (mixSDL_Driver)~0) + driver = &mixer_SDLdriver; /* default */ + + mixer_driver = driver; + mixer_driverflags = flags; +} + /* Open the mixer with a certain desired audio format */ bool -mixSDL_OpenAudio (uint32 frequency, uint32 format, uint32 samples_buf) +mixSDL_OpenAudio (uint32 frequency, uint32 format, uint32 samples_buf, + mixSDL_Quality quality) { SDL_AudioSpec desired; @@ -158,14 +205,22 @@ mixSDL_OpenAudio (uint32 frequency, uint32 format, uint32 samples_buf) return false; } + fprintf (stderr, "MixSDL using driver '%s'\n", + mixer_driver->GetDriverName()); + /* Set the desired format and frequency */ desired.freq = frequency; desired.samples = samples_buf; - desired.callback = mixSDL_mix_channels; + if (mixer_driverflags & MIX_DRIVER_FAKE_PLAY) + desired.callback = mixSDL_mix_fake; + else if (quality == MIX_QUALITY_LOW) + desired.callback = mixSDL_mix_lowq; + else + desired.callback = mixSDL_mix_channels; desired.userdata = NULL; /* Accept nearly any audio format */ - if (SDL_OpenAudio (&desired, &mixer_spec) < 0) + if (mixer_driver->OpenAudio (&desired, &mixer_spec) < 0) { mixSDL_SetError (MIX_SDL_FAILURE); return false; @@ -188,7 +243,7 @@ mixSDL_OpenAudio (uint32 frequency, uint32 format, uint32 samples_buf) mixer_spec.channels < 1 || mixer_spec.channels > 2) { mixSDL_SetError (MIX_SDL_FAILURE); - SDL_CloseAudio (); + mixer_driver->CloseAudio (); fprintf (stderr, "mixSDL_OpenAudio: unable to aquire " "desired format\n"); return false; @@ -208,7 +263,7 @@ mixSDL_OpenAudio (uint32 frequency, uint32 format, uint32 samples_buf) mixSDL_InitMutex (act_mutex, "mixSDL_ActiveMutex"); audio_opened = 1; - SDL_PauseAudio (0); + mixer_driver->PauseAudio (0); return true; } @@ -1066,6 +1121,10 @@ mixSDL_SourceStop_internal (mixSDL_Source *src) static __inline__ bool mixSDL_SourceGetNextSample (mixSDL_Source *src, sint32* psamp) { + /* fake the data if requested */ + if (mixer_driverflags & MIX_DRIVER_FAKE_DATA) + return mixSDL_SourceGetFakeSample (src, psamp); + while (src->nextqueued) { mixSDL_Buffer *buf = src->nextqueued; @@ -1133,6 +1192,42 @@ mixSDL_SourceGetNextSample (mixSDL_Source *src, sint32* psamp) return false; } +/* fake the next sample, but process buffers and states */ +static __inline__ bool +mixSDL_SourceGetFakeSample (mixSDL_Source *src, sint32* psamp) +{ + while (src->nextqueued) + { + mixSDL_Buffer *buf = src->nextqueued; + + *psamp = 0; + src->curbufofs += mixer_chansize; + + if (src->curbufofs >= buf->size) + { + /* buffer exhausted, go next */ + buf->state = MIX_BUF_PROCESSED; + src->curbufofs = 0; + src->nextqueued = src->nextqueued->next; + src->cprocessed++; + } + else + { + buf->state = MIX_BUF_PLAYING; + } + + return true; + } + + /* no more playable buffers */ + if (src->state >= MIX_PLAYING) + mixSDL_SourceDeactivate (src); + + src->state = MIX_STOPPED; + + return false; +} + /************************************************* * Buffers interface */ @@ -1406,45 +1501,49 @@ mixSDL_BufferData (mixSDL_Object bufobj, uint32 format, void* data, MIX_FORMAT_SAMPSIZE (mixer_format); buf->size = dstsize; - buf->data = HMalloc (dstsize); + /* only copy/convert the data if not faking */ + if (! (mixer_driverflags & MIX_DRIVER_FAKE_DATA)) + { + buf->data = HMalloc (dstsize); - if (format == mixer_format && freq == mixer_freq) - { - /* format identical to internal */ - buf->locked = true; - mixSDL_UnlockMutex (buf_mutex); - - memcpy (buf->data, data, size); - if (MIX_FORMAT_SAMPSIZE (mixer_format) == 1) + if (format == mixer_format && freq == mixer_freq) { - /* convert buffer to S8 format internally */ - uint8* dst; - for (dst = buf->data; dstsize; dstsize--, dst++) - *dst ^= 0x80; + /* format identical to internal */ + buf->locked = true; + mixSDL_UnlockMutex (buf_mutex); + + memcpy (buf->data, data, size); + if (MIX_FORMAT_SAMPSIZE (mixer_format) == 1) + { + /* convert buffer to S8 format internally */ + uint8* dst; + for (dst = buf->data; dstsize; dstsize--, dst++) + *dst ^= 0x80; + } + + mixSDL_LockMutex (buf_mutex); + buf->locked = false; } + else + { + /* needs convertion */ + conv.srcfmt = format; + conv.srcdata = data; + conv.srcsize = size; + conv.srcfreq = freq; + conv.dstfmt = mixer_format; + conv.dstdata = buf->data; + conv.dstsize = dstsize; + conv.dstfreq = mixer_freq; - mixSDL_LockMutex (buf_mutex); - buf->locked = false; - } - else - { - /* needs convertion */ - conv.srcfmt = format; - conv.srcdata = data; - conv.srcsize = size; - conv.srcfreq = freq; - conv.dstfmt = mixer_format; - conv.dstdata = buf->data; - conv.dstsize = dstsize; - conv.dstfreq = mixer_freq; + buf->locked = true; + mixSDL_UnlockMutex (buf_mutex); - buf->locked = true; - mixSDL_UnlockMutex (buf_mutex); - - mixSDL_ConvertBuffer_internal (&conv); - - mixSDL_LockMutex (buf_mutex); - buf->locked = false; + mixSDL_ConvertBuffer_internal (&conv); + + mixSDL_LockMutex (buf_mutex); + buf->locked = false; + } } buf->state = MIX_BUF_FILLED; @@ -1880,7 +1979,7 @@ mixSDL_mix_channels (void *userdata, uint8 *stream, sint32 len) fprintf (stderr, "mixSDL_mix_channels(): " "WARNING: work-buffer too small\n"); #endif - mixSDL_mix_lowq (stream, len); + mixSDL_mix_lowq (userdata, stream, len); } /* keep this order or die */ @@ -1939,7 +2038,7 @@ mixSDL_mix_channels (void *userdata, uint8 *stream, sint32 len) mixSDL_UnlockMutex (buf_mutex); mixSDL_UnlockMutex (src_mutex); - (void)userdata; // satisfying compiler + (void) userdata; // satisfying compiler - unused arg } /* data unclipping - smooth out the areas that need to be clipped */ @@ -2027,7 +2126,7 @@ mixSDL_UnclipWorkBuffer (sint32 *data, sint32 *end_data, uint32 step) /* low quality faster version */ static void -mixSDL_mix_lowq (uint8 *stream, sint32 len) +mixSDL_mix_lowq (void *userdata, uint8 *stream, sint32 len) { uint8 *end_stream = stream + len; @@ -2088,4 +2187,44 @@ mixSDL_mix_lowq (uint8 *stream, sint32 len) mixSDL_UnlockMutex (act_mutex); mixSDL_UnlockMutex (buf_mutex); mixSDL_UnlockMutex (src_mutex); + + (void) userdata; // satisfying compiler - unused arg +} + +/* fake mixer -- only process buffer and source states */ +static void +mixSDL_mix_fake (void *userdata, uint8 *stream, sint32 len) +{ + uint8 *end_stream = stream + len; + + /* keep this order or die */ + mixSDL_LockMutex (src_mutex); + mixSDL_LockMutex (buf_mutex); + mixSDL_LockMutex (act_mutex); + + for (; stream < end_stream; stream += mixer_chansize) + { + uint32 i; + + for (i = 0; i < MAX_SOURCES; i++) + { + mixSDL_Source *src; + sint32 samp; + + /* find next source */ + for (; i < MAX_SOURCES && ( + (src = active_sources[i]) == 0 + || src->state != MIX_PLAYING + || !mixSDL_SourceGetFakeSample (src, &samp)); + i++) + ; + } + } + + /* keep this order or die */ + mixSDL_UnlockMutex (act_mutex); + mixSDL_UnlockMutex (buf_mutex); + mixSDL_UnlockMutex (src_mutex); + + (void) userdata; // satisfying compiler - unused arg } diff --git a/sc2/src/sc2code/libs/sound/mixsdl/mixer.h b/sc2/src/sc2code/libs/sound/mixsdl/mixer.h index 7d5686077..8508c2503 100644 --- a/sc2/src/sc2code/libs/sound/mixsdl/mixer.h +++ b/sc2/src/sc2code/libs/sound/mixsdl/mixer.h @@ -134,6 +134,25 @@ typedef enum } mixSDL_Format; +typedef enum +{ + MIX_QUALITY_LOW = 0, + MIX_QUALITY_MEDIUM, + MIX_QUALITY_HIGH, + MIX_QUALITY_DEFAULT = MIX_QUALITY_MEDIUM, + MIX_QUALITY_COUNT + +} mixSDL_Quality; + +typedef enum +{ + MIX_DRIVER_NOFLAGS = 0, + MIX_DRIVER_FAKE_DATA = 1, + MIX_DRIVER_FAKE_PLAY = 2, + MIX_DRIVER_FAKE_ALL = MIX_DRIVER_FAKE_DATA | MIX_DRIVER_FAKE_PLAY + +} mixSDL_DriverFlags; + /************************************************* * Interface Types */ @@ -179,12 +198,26 @@ typedef struct #define mixSDL_srcMagic 0x5358494DU /* MIXS in LSB */ +typedef struct +{ + const char* (* GetDriverName) (void); + const char* (* GetError) (void); + /* see SDL for description of these functions */ + int (* OpenAudio) (void *desired, void *obtained); + void (* CloseAudio) (void); + void (* PauseAudio) (int pause_on); + +} mixSDL_DriverInfo; +typedef const mixSDL_DriverInfo *mixSDL_Driver; + /************************************************* * General interface */ uint32 mixSDL_GetError (void); +void mixSDL_UseDriver (mixSDL_Driver driver, mixSDL_DriverFlags flags); -bool mixSDL_OpenAudio (uint32 freq, uint32 format, uint32 samples_buf); +bool mixSDL_OpenAudio (uint32 freq, uint32 format, uint32 samples_buf, + mixSDL_Quality quality); void mixSDL_CloseAudio (void); bool mixSDL_QuerySpec (uint32 *freq, uint32 *format, uint32 *channels); diff --git a/sc2/src/sc2code/libs/sound/mixsdl/mixerint.h b/sc2/src/sc2code/libs/sound/mixsdl/mixerint.h index b4b97152f..4a77ef805 100644 --- a/sc2/src/sc2code/libs/sound/mixsdl/mixerint.h +++ b/sc2/src/sc2code/libs/sound/mixsdl/mixerint.h @@ -116,10 +116,18 @@ static void mixSDL_UnlockMutex (mixSDL_Mutex mtx); /* The Mixer */ static void mixSDL_mix_channels (void *userdata, uint8 *stream, sint32 len); +static void mixSDL_mix_lowq (void *userdata, uint8 *stream, sint32 len); +static void mixSDL_mix_fake (void *userdata, uint8 *stream, sint32 len); static void mixSDL_UnclipWorkBuffer (sint32 *data, sint32 *end_data, uint32 step); -static void mixSDL_mix_lowq (uint8 *stream, sint32 len); static __inline__ bool mixSDL_SourceGetNextSample (mixSDL_Source *src, sint32* samp); +static __inline__ bool mixSDL_SourceGetFakeSample (mixSDL_Source *src, + sint32* psamp); + +/* SDL driver */ +static const char* mixSDL_DriverGetName (void); +static const char* mixSDL_DriverGetError (void); +static int mixSDL_DriverOpenAudio (void *desired, void *obtained); #endif /* MIXERINT_H */ diff --git a/sc2/src/sc2code/libs/sound/mixsdl/sound_mixsdl.c b/sc2/src/sc2code/libs/sound/mixsdl/sound_mixsdl.c index 94c99a032..889d93586 100644 --- a/sc2/src/sc2code/libs/sound/mixsdl/sound_mixsdl.c +++ b/sc2/src/sc2code/libs/sound/mixsdl/sound_mixsdl.c @@ -16,16 +16,56 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "libs/graphics/sdl/sdl_common.h" +//#include "libs/graphics/sdl/sdl_common.h" +#include "SDL.h" #include "libs/sound/sound.h" +#include "libs/tasklib.h" + static Task StreamDecoderTask; +/******************************************************************* + * NoSound driver for MixSDL - declarations + */ + +static const char* NoSound_GetDriverName (void); +static const char* NoSound_GetError (void); +static int NoSound_OpenAudio (void *desired, void *obtained); +static void NoSound_CloseAudio (void); +static void NoSound_PauseAudio (int pause_on); + +/* The nosound driver */ +static const +mixSDL_DriverInfo NoSound_driver = +{ + NoSound_GetDriverName, + NoSound_GetError, + NoSound_OpenAudio, + NoSound_CloseAudio, + NoSound_PauseAudio +}; +static SDL_AudioSpec NoSound_spec; +static Task NoSound_PlaybackTask; +static bool NoSound_Paused = true; +static const char* NoSound_ErrorStr = ""; + +/******************************************************************* + * Other stuff + */ +static int current_driver = 0; + +int TFB_NoSound_InitSound (int driver, int flags); + +/******************************************************************* + * Normal MixSDL sound + */ + int TFB_mixSDL_InitSound (int driver, int flags) { int i; char SoundcardName[256]; uint32 audio_rate, audio_channels, audio_bufsize, audio_format; + mixSDL_Quality audio_quality; TFB_DecoderFormats formats = { MIX_IS_BIG_ENDIAN, MIX_WANT_BIG_ENDIAN, @@ -37,34 +77,39 @@ TFB_mixSDL_InitSound (int driver, int flags) if ((SDL_InitSubSystem(SDL_INIT_AUDIO)) == -1) { fprintf (stderr, "Couldn't initialize audio subsystem: %s\n", SDL_GetError()); - exit(-1); + return -1; } fprintf (stderr, "SDL audio subsystem initialized.\n"); if (flags & TFB_SOUNDFLAGS_HQAUDIO) { + audio_quality = MIX_QUALITY_HIGH; audio_rate = 44100; audio_bufsize = 2048; } else if (flags & TFB_SOUNDFLAGS_LQAUDIO) { + audio_quality = MIX_QUALITY_LOW; audio_rate = 22050; audio_bufsize = 1024; } else { + audio_quality = MIX_QUALITY_DEFAULT; audio_rate = 44100; audio_bufsize = 2048; } - fprintf (stderr, "Initializing internal Mixer for SDL_audio.\n"); - if (!mixSDL_OpenAudio(audio_rate, MIX_FORMAT_STEREO16, audio_bufsize)) + fprintf (stderr, "Initializing MixSDL mixer.\n"); + if (!mixSDL_OpenAudio(audio_rate, MIX_FORMAT_STEREO16, + audio_bufsize, audio_quality)) { fprintf (stderr, "Unable to open audio: %x, %s\n", mixSDL_GetError (), SDL_GetError ()); - exit (-1); + SDL_QuitSubSystem (SDL_INIT_AUDIO); + return -1; } - fprintf (stderr, "Mixer for SDL_audio initialized.\n"); + fprintf (stderr, "MixSDL Mixer initialized.\n"); atexit (TFB_UninitSound); @@ -98,6 +143,8 @@ TFB_mixSDL_InitSound (int driver, int flags) StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024, "audio stream decoder"); + current_driver = driver; + return 0; } @@ -128,3 +175,170 @@ TFB_mixSDL_UninitSound (void) SoundDecoder_Uninit (); mixSDL_CloseAudio (); } + +/******************************************************************* + * NoSound driver for MixSDL + */ + +int +TFB_NoSound_InitSound (int driver, int flags) +{ + int i; + uint32 audio_rate, audio_channels, audio_bufsize, audio_format; + TFB_DecoderFormats formats = + { + 0, 0, /* do not care about endianness */ + MIX_FORMAT_MONO8, MIX_FORMAT_STEREO8, + MIX_FORMAT_MONO16, MIX_FORMAT_STEREO16 + }; + + if (flags & TFB_SOUNDFLAGS_HQAUDIO) + { + audio_rate = 44100; + audio_bufsize = 2048; + } + else if (flags & TFB_SOUNDFLAGS_LQAUDIO) + { + audio_rate = 22050; + audio_bufsize = 1024; + } + else + { + audio_rate = 44100; + audio_bufsize = 2048; + } + + fprintf (stderr, "Initializing MixSDL mixer.\n"); + mixSDL_UseDriver (&NoSound_driver, MIX_DRIVER_FAKE_ALL); + if (!mixSDL_OpenAudio (audio_rate, MIX_FORMAT_STEREO16, + audio_bufsize, MIX_QUALITY_DEFAULT)) + { + fprintf (stderr, "Unable to open audio: %x, %s\n", + mixSDL_GetError (), SDL_GetError ()); + return -1; + } + fprintf (stderr, "MixSDL mixer initialized.\n"); + + atexit (TFB_UninitSound); + + mixSDL_QuerySpec (&audio_rate, &audio_format, &audio_channels); + fprintf (stderr, " opened 'fake' " + "at %d Hz %d bit %s, %d samples audio buffer\n", + audio_rate, audio_format & 0xFF, + audio_channels > 1 ? "stereo" : "mono", audio_bufsize); + + fprintf (stderr, "Initializing sound decoders.\n"); + SoundDecoder_Init (flags, &formats); + fprintf (stderr, "Sound decoders initialized.\n"); + + for (i = 0; i < NUM_SOUNDSOURCES; ++i) + { + mixSDL_GenSources (1, &soundSource[i].handle); + + soundSource[i].sample = NULL; + soundSource[i].stream_should_be_playing = FALSE; + soundSource[i].stream_mutex = CreateMutex (); + soundSource[i].sbuffer = NULL; + soundSource[i].sbuf_start = 0; + soundSource[i].sbuf_size = 0; + soundSource[i].sbuf_offset = 0; + } + + SetSFXVolume (sfxVolumeScale); + SetSpeechVolume (speechVolumeScale); + SetMusicVolume ((COUNT)musicVolume); + + StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024, + "audio stream decoder"); + + current_driver = driver; + + return 0; +} + +void +TFB_NoSound_UninitSound (void) +{ + TFB_mixSDL_UninitSound (); +} + +int +NoSound_PlaybackTaskFunc (void *data) +{ + Task task = (Task)data; + uint8 *stream; + uint32 entryTime; + sint32 period, delay; + + stream = (uint8 *) HMalloc (NoSound_spec.size); + period = 1000 * NoSound_spec.samples / NoSound_spec.freq; + + while (!Task_ReadState (task, TASK_EXIT)) + { + entryTime = SDL_GetTicks (); + + if (!NoSound_Paused) + { + NoSound_spec.callback (NoSound_spec.userdata, + stream, NoSound_spec.size); + } + + delay = period - (SDL_GetTicks () - entryTime); + if (delay > 0) + SDL_Delay (delay); + } + + FinishTask (task); + return 0; +} + +static const char* +NoSound_GetDriverName () +{ + return "NoSound"; +} + +static const char* +NoSound_GetError () +{ + return NoSound_ErrorStr; +} + +static int +NoSound_OpenAudio (void *desired, void *obtained) +{ + /* we accept anything - copy the format verbatim */ + memcpy (&NoSound_spec, desired, sizeof (SDL_AudioSpec)); + /* calculate the requested PCM-buffer size and silence val */ + NoSound_spec.size = (NoSound_spec.format & 0x003f) / 8 + * NoSound_spec.channels * NoSound_spec.samples; + NoSound_spec.silence = ((NoSound_spec.format >> 8) & 0x80) ^ 0x80; + + memcpy (obtained, &NoSound_spec, sizeof (SDL_AudioSpec)); + + NoSound_PlaybackTask = AssignTask (NoSound_PlaybackTaskFunc, 1024, + "nosound audio playback"); + if (!NoSound_PlaybackTask) + { + NoSound_ErrorStr = "Could not start Playback Task"; + return -1; + } + + return 0; +} + +static void +NoSound_CloseAudio (void) +{ + if (NoSound_PlaybackTask) + { + ConcludeTask (NoSound_PlaybackTask); + NoSound_PlaybackTask = 0; + } +} + +static void +NoSound_PauseAudio (int pause_on) +{ + NoSound_Paused = pause_on; +} diff --git a/sc2/src/sc2code/libs/sound/openal/sound_openal.c b/sc2/src/sc2code/libs/sound/openal/sound_openal.c index e6835215e..7b94c1c8a 100644 --- a/sc2/src/sc2code/libs/sound/openal/sound_openal.c +++ b/sc2/src/sc2code/libs/sound/openal/sound_openal.c @@ -38,8 +38,6 @@ TFB_alInitSound (int driver, int flags) }; fprintf (stderr, "Initializing OpenAL.\n"); - atexit (TFB_UninitSound); - #ifdef WIN32 alcDevice = alcOpenDevice ((ALubyte*)"DirectSound3D"); #else @@ -49,9 +47,11 @@ TFB_alInitSound (int driver, int flags) if (!alcDevice) { fprintf (stderr,"Couldn't initialize OpenAL: %d\n", alcGetError (NULL)); - exit (-1); + return -1; } + atexit (TFB_UninitSound); + alcContext = alcCreateContext (alcDevice, NULL); if (!alcContext) { diff --git a/sc2/src/sc2code/libs/sound/sound_chooser.c b/sc2/src/sc2code/libs/sound/sound_chooser.c index 8e9ba2701..3bb37d664 100644 --- a/sc2/src/sc2code/libs/sound/sound_chooser.c +++ b/sc2/src/sc2code/libs/sound/sound_chooser.c @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Mixer abstraction layer for MixSDL +/* Mixer abstraction layer */ #ifdef HAVE_OPENAL @@ -32,6 +32,13 @@ unsigned int TFBSOUND_FORMAT_STEREO16; unsigned int TFBSOUND_FORMAT_STEREO8; unsigned int TFBSOUND_FORMAT_MONO8; +int TFB_mixSDL_InitSound (int driver, int flags); +int TFB_NoSound_InitSound (int driver, int flags); +#ifdef HAVE_OPENAL +int TFB_alInitSound (int driver, int flags); +#endif + + /************************************************* * General interface */ @@ -241,9 +248,10 @@ TFBSound_ConvertBuffer (uint32 srcfmt, void* srcdata, uint32 srcsize, int TFB_choose_InitSound (int driver, int flags) { + SoundDriver = driver; + if (driver == TFB_SOUNDDRIVER_OPENAL) { - SoundDriver = driver; tfb_enum_lookup[TFBSOUND_GAIN] = AL_GAIN; tfb_enum_lookup[TFBSOUND_BUFFER] = AL_BUFFER; tfb_enum_lookup[TFBSOUND_SOURCE_STATE] = AL_SOURCE_STATE; @@ -262,7 +270,7 @@ TFB_choose_InitSound (int driver, int flags) } else { - SoundDriver = driver; + /* NoSound uses MixSDL, common values */ tfb_enum_lookup[TFBSOUND_GAIN] = MIX_GAIN; tfb_enum_lookup[TFBSOUND_BUFFER] = MIX_BUFFER; tfb_enum_lookup[TFBSOUND_SOURCE_STATE] = MIX_SOURCE_STATE; @@ -277,7 +285,11 @@ TFB_choose_InitSound (int driver, int flags) TFBSOUND_FORMAT_STEREO16 = MIX_FORMAT_STEREO16; TFBSOUND_FORMAT_MONO8 = MIX_FORMAT_MONO8; TFBSOUND_FORMAT_STEREO8 = MIX_FORMAT_STEREO8; - return (TFB_mixSDL_InitSound (driver, flags)); + + if (driver == TFB_SOUNDDRIVER_MIXSDL) + return (TFB_mixSDL_InitSound (driver, flags)); + else + return (TFB_NoSound_InitSound (driver, flags)); } } diff --git a/sc2/src/sc2code/libs/sound/sound_chooser.h b/sc2/src/sc2code/libs/sound/sound_chooser.h index 488c94d96..fa73879ef 100644 --- a/sc2/src/sc2code/libs/sound/sound_chooser.h +++ b/sc2/src/sc2code/libs/sound/sound_chooser.h @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Simple mixer for use with SDL_audio +/* Mixer abstraction layer */ #ifndef SOUNDCHOOSER_H @@ -33,18 +33,6 @@ #include "types.h" -int TFB_mixSDL_InitSound (int driver, int flags); -#ifdef HAVE_OPENAL -int TFB_choose_InitSound (int driver, int flags); -int TFB_alInitSound (int driver, int flags); -#endif - -void TFB_mixSDL_UninitSound (void); -#ifdef HAVE_OPENAL -void TFB_alUninitSound (void); -#endif - - /************************************************* * Interface Types */ diff --git a/sc2/src/sc2code/libs/sound/sound_common.c b/sc2/src/sc2code/libs/sound/sound_common.c index 2dc7711a9..cfe391936 100644 --- a/sc2/src/sc2code/libs/sound/sound_common.c +++ b/sc2/src/sc2code/libs/sound/sound_common.c @@ -32,6 +32,21 @@ static Task FadeTask; static SIZE TTotal; static SIZE volume_end; + +int TFB_mixSDL_InitSound (int driver, int flags); +int TFB_NoSound_InitSound (int driver, int flags); +#ifdef HAVE_OPENAL +int TFB_choose_InitSound (int driver, int flags); +int TFB_alInitSound (int driver, int flags); +#endif + +void TFB_mixSDL_UninitSound (void); +void TFB_NoSound_UninitSound (void); +#ifdef HAVE_OPENAL +void TFB_alUninitSound (void); +#endif + + static int fade_task (void *data) { @@ -93,28 +108,54 @@ FadeMusic (BYTE end_vol, SIZE TimeInterval) int TFB_InitSound (int driver, int flags) { + int ret; + #ifdef HAVE_OPENAL - return (TFB_choose_InitSound (driver, flags)); + ret = TFB_choose_InitSound (driver, flags); #else - if (driver == TFB_SOUNDDRIVER_OPENAL) + SoundDriver = driver; + if (SoundDriver == TFB_SOUNDDRIVER_OPENAL) { fprintf (stderr, "OpenAL driver not compiled in, so using MixSDL\n"); - driver = TFB_SOUNDDRIVER_MIXSDL; + SoundDriver = TFB_SOUNDDRIVER_MIXSDL; } - return (TFB_mixSDL_InitSound (driver, flags)); + if (SoundDriver == TFB_SOUNDDRIVER_MIXSDL) + ret = TFB_mixSDL_InitSound (SoundDriver, flags); + else + ret = TFB_NoSound_InitSound (SoundDriver, flags); #endif + if (ret != 0) + { + fprintf (stderr, "Sound driver initialization failed.\n" + "This may happen when a soundcard is " + "not present or not available.\n" + "NOTICE: Try running UQM with '--sound=none' option\n"); + exit (-1); + } + + return ret; } void TFB_UninitSound (void) { -#ifdef HAVE_OPENAL - if (SoundDriver == TFB_SOUNDDRIVER_OPENAL) + switch (SoundDriver) + { + case TFB_SOUNDDRIVER_OPENAL: +#ifdef HAVE_OPENAL TFB_alUninitSound (); - else - TFB_mixSDL_UninitSound (); #else - TFB_mixSDL_UninitSound (); + fprintf (stderr, "TFB_UninitSound(): driver is set to OpenAL" + "while OpenAL driver is not compiled in\n"); #endif -} + break; + case TFB_SOUNDDRIVER_MIXSDL: + TFB_mixSDL_UninitSound (); + break; + + case TFB_SOUNDDRIVER_NOSOUND: + TFB_NoSound_UninitSound (); + break; + } +} diff --git a/sc2/src/sc2code/libs/sound/sound_common.h b/sc2/src/sc2code/libs/sound/sound_common.h index 27e9913e1..91f264dbc 100644 --- a/sc2/src/sc2code/libs/sound/sound_common.h +++ b/sc2/src/sc2code/libs/sound/sound_common.h @@ -23,6 +23,7 @@ enum { TFB_SOUNDDRIVER_MIXSDL, + TFB_SOUNDDRIVER_NOSOUND, TFB_SOUNDDRIVER_OPENAL }; extern int SoundDriver;