From 2d13f9a9d7ce507e92bbaa659b85a228b91acea9 Mon Sep 17 00:00:00 2001 From: avolkov Date: Thu, 10 Dec 2009 04:38:35 +0000 Subject: [PATCH] Music fade task retired; also absolve audio drivers from managing the stream decoder task git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3411 8092fc87-c524-0410-9efc-e669fe64eaf9 --- .../sound/mixer/nosound/audiodrv_nosound.c | 18 ++-- sc2/src/libs/sound/mixer/sdl/audiodrv_sdl.c | 23 ++--- sc2/src/libs/sound/openal/audiodrv_openal.c | 24 +++-- sc2/src/libs/sound/sound.c | 61 ++---------- sc2/src/libs/sound/stream.c | 98 ++++++++++++++++++- sc2/src/libs/sound/stream.h | 7 +- 6 files changed, 146 insertions(+), 85 deletions(-) diff --git a/sc2/src/libs/sound/mixer/nosound/audiodrv_nosound.c b/sc2/src/libs/sound/mixer/nosound/audiodrv_nosound.c index 4b9f1301d..3182f4e84 100644 --- a/sc2/src/libs/sound/mixer/nosound/audiodrv_nosound.c +++ b/sc2/src/libs/sound/mixer/nosound/audiodrv_nosound.c @@ -25,7 +25,6 @@ #include -static Task StreamDecoderTask; static Task PlaybackTask; static uint32 nosound_freq = 22050; @@ -138,14 +137,21 @@ noSound_Init (audio_Driver *driver, sint32 flags) soundSource[i].stream_mutex = CreateMutex ("Nosound stream mutex", SYNC_CLASS_AUDIO); } + if (InitStreamDecoder ()) + { + log_add (log_Error, "Stream decoder initialization failed."); + // TODO: cleanup source mutexes [or is it "muti"? :) ] + SoundDecoder_Uninit (); + mixer_Uninit (); + return -1; + } + atexit (unInitAudio); SetSFXVolume (sfxVolumeScale); SetSpeechVolume (speechVolumeScale); SetMusicVolume ((COUNT)musicVolume); - StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024, - "audio stream decoder"); PlaybackTask = AssignTask (PlaybackTaskFunc, 1024, "nosound audio playback"); @@ -157,11 +163,7 @@ noSound_Uninit (void) { int i; - if (StreamDecoderTask) - { - ConcludeTask (StreamDecoderTask); - StreamDecoderTask = NULL; - } + UninitStreamDecoder (); for (i = 0; i < NUM_SOUNDSOURCES; ++i) { diff --git a/sc2/src/libs/sound/mixer/sdl/audiodrv_sdl.c b/sc2/src/libs/sound/mixer/sdl/audiodrv_sdl.c index 718501c65..72a1c2443 100644 --- a/sc2/src/libs/sound/mixer/sdl/audiodrv_sdl.c +++ b/sc2/src/libs/sound/mixer/sdl/audiodrv_sdl.c @@ -19,14 +19,11 @@ #include "audiodrv_sdl.h" #include "../../sndintrn.h" -#include "libs/tasklib.h" #include "libs/log.h" #include "libs/memlib.h" #include -static Task StreamDecoderTask; - static const audio_Driver mixSDL_Driver = { mixSDL_Uninit, @@ -202,15 +199,23 @@ mixSDL_Init (audio_Driver *driver, sint32 flags) soundSource[i].stream_mutex = CreateMutex ("MixSDL stream mutex", SYNC_CLASS_AUDIO); } + if (InitStreamDecoder ()) + { + log_add (log_Error, "Stream decoder initialization failed."); + // TODO: cleanup source mutexes [or is it "muti"? :) ] + SDL_CloseAudio (); + SoundDecoder_Uninit (); + mixer_Uninit (); + SDL_QuitSubSystem (SDL_INIT_AUDIO); + return -1; + } + atexit (unInitAudio); SetSFXVolume (sfxVolumeScale); SetSpeechVolume (speechVolumeScale); SetMusicVolume ((COUNT)musicVolume); - StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024, - "audio stream decoder"); - SDL_PauseAudio (0); return 0; @@ -221,11 +226,7 @@ mixSDL_Uninit (void) { int i; - if (StreamDecoderTask) - { - ConcludeTask (StreamDecoderTask); - StreamDecoderTask = NULL; - } + UninitStreamDecoder (); for (i = 0; i < NUM_SOUNDSOURCES; ++i) { diff --git a/sc2/src/libs/sound/openal/audiodrv_openal.c b/sc2/src/libs/sound/openal/audiodrv_openal.c index dec3d154f..149617a4a 100644 --- a/sc2/src/libs/sound/openal/audiodrv_openal.c +++ b/sc2/src/libs/sound/openal/audiodrv_openal.c @@ -22,7 +22,6 @@ #include "audiodrv_openal.h" #include "../sndintrn.h" -#include "libs/tasklib.h" #include "libs/log.h" #include "libs/memlib.h" #include @@ -34,7 +33,6 @@ ALfloat defaultPos[] = {0.0f, 0.0f, -1.0f}; ALfloat listenerPos[] = {0.0f, 0.0f, 0.0f}; ALfloat listenerVel[] = {0.0f, 0.0f, 0.0f}; ALfloat listenerOri[] = {0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f}; -static Task StreamDecoderTask; static const audio_Driver openAL_Driver = { @@ -185,6 +183,19 @@ openAL_Init (audio_Driver *driver, sint32 flags) soundSource[i].stream_mutex = CreateMutex ("OpenAL stream mutex", SYNC_CLASS_AUDIO); } + + if (InitStreamDecoder ()) + { + log_add (log_Error, "Stream decoder initialization failed."); + // TODO: cleanup source mutexes [or is it "muti"? :) ] + SoundDecoder_Uninit (); + alcMakeContextCurrent (NULL); + alcDestroyContext (alcContext); + alcContext = NULL; + alcCloseDevice (alcDevice); + alcDevice = NULL; + return -1; + } SetSFXVolume (sfxVolumeScale); SetSpeechVolume (speechVolumeScale); @@ -195,9 +206,6 @@ openAL_Init (audio_Driver *driver, sint32 flags) else alDistanceModel (AL_NONE); - StreamDecoderTask = AssignTask (StreamDecoderTaskFunc, 1024, - "audio stream decoder"); - (void) driver; // eat compiler warning return 0; @@ -208,11 +216,7 @@ openAL_Uninit (void) { int i; - if (StreamDecoderTask) - { - ConcludeTask (StreamDecoderTask); - StreamDecoderTask = NULL; - } + UninitStreamDecoder (); for (i = 0; i < NUM_SOUNDSOURCES; ++i) { diff --git a/sc2/src/libs/sound/sound.c b/sc2/src/libs/sound/sound.c index 137f4fd6e..f2a790e9b 100644 --- a/sc2/src/libs/sound/sound.c +++ b/sc2/src/libs/sound/sound.c @@ -19,15 +19,10 @@ #include "sound.h" #include "sndintrn.h" #include "libs/compiler.h" -#include "libs/tasklib.h" #include "libs/inplib.h" #include "libs/memlib.h" -static Task FadeTask; -static SIZE TTotal; -static SIZE volume_end; - int musicVolume = NORMAL_VOLUME; float musicVolumeScale; float sfxVolumeScale; @@ -160,66 +155,24 @@ SetSpeechVolume (float volume) audio_Sourcef (soundSource[SPEECH_SOURCE].handle, audio_GAIN, volume); } -static int -fade_task (void *data) -{ - SIZE TDelta, volume_beg; - DWORD StartTime, CurTime; - Task task = (Task) data; - - volume_beg = musicVolume; - StartTime = CurTime = GetTimeCounter (); - do - { - SleepThreadUntil (CurTime + ONE_SECOND / 120); - CurTime = GetTimeCounter (); - if ((TDelta = (SIZE) (CurTime - StartTime)) > TTotal) - TDelta = TTotal; - - SetMusicVolume ((COUNT) (volume_beg + (SIZE) - ((long) (volume_end - volume_beg) * TDelta / TTotal))); - } while (TDelta < TTotal); - - FadeTask = 0; - FinishTask (task); - return 1; -} - DWORD FadeMusic (BYTE end_vol, SIZE TimeInterval) { - DWORD TimeOut; - if (QuitPosted) // Don't make users wait for fades TimeInterval = 0; - if (FadeTask) - { - volume_end = musicVolume; - TTotal = 1; - do - TaskSwitch (); - while (FadeTask); - TaskSwitch (); - } + if (TimeInterval < 0) + TimeInterval = 0; - TTotal = TimeInterval; - if (TTotal <= 0) - TTotal = 1; /* prevent divide by zero and negative fade */ - volume_end = end_vol; - - if (TTotal > 1 && (FadeTask = AssignTask (fade_task, 0, - "fade music"))) - { - TimeOut = GetTimeCounter () + TTotal + 1; + if (!SetMusicStreamFade (TimeInterval, end_vol)) + { // fade rejected, maybe due to TimeInterval==0 + SetMusicVolume (end_vol); + return GetTimeCounter (); } else { - SetMusicVolume (end_vol); - TimeOut = GetTimeCounter (); + return GetTimeCounter () + TimeInterval + 1; } - - return TimeOut; } diff --git a/sc2/src/libs/sound/stream.c b/sc2/src/libs/sound/stream.c index f8c82276c..8fe0be2da 100644 --- a/sc2/src/libs/sound/stream.c +++ b/sc2/src/libs/sound/stream.c @@ -21,10 +21,21 @@ #include "sound.h" #include "sndintrn.h" #include "libs/tasklib.h" +#include "libs/timelib.h" +#include "libs/threadlib.h" #include "libs/log.h" #include "libs/memlib.h" +static Task decoderTask; + +static TimeCount musicFadeStartTime; +static sint32 musicFadeInterval; +static int musicFadeStartVolume; +static int musicFadeDelta; +// Mutex protects fade structures +static Mutex fade_mutex; + static void add_scope_data (TFB_SoundSource *source, uint32 bytes); @@ -491,7 +502,37 @@ process_stream (TFB_SoundSource *source) } } -int +static void +processMusicFade (void) +{ + TimeCount Now; + sint32 elapsed; + int newVolume; + + LockMutex (fade_mutex); + + if (!musicFadeInterval) + { // there is no fade set + UnlockMutex (fade_mutex); + return; + } + + Now = GetTimeCounter (); + elapsed = Now - musicFadeStartTime; + if (elapsed > musicFadeInterval) + elapsed = musicFadeInterval; + + newVolume = musicFadeStartVolume + (long)musicFadeDelta * elapsed + / musicFadeInterval; + SetMusicVolume (newVolume); + + if (elapsed >= musicFadeInterval) + musicFadeInterval = 0; // fade is over + + UnlockMutex (fade_mutex); +} + +static int StreamDecoderTaskFunc (void *data) { Task task = (Task)data; @@ -502,6 +543,8 @@ StreamDecoderTaskFunc (void *data) { active_streams = 0; + processMusicFade (); + for (i = MUSIC_SOURCE; i < NUM_SOUNDSOURCES; ++i) { TFB_SoundSource *source = &soundSource[i]; @@ -719,3 +762,56 @@ GraphForegroundStream (uint8 *data, sint32 width, sint32 height) return 1; } +// This function is normally called on the Starcon2Main thread +bool +SetMusicStreamFade (sint32 howLong, int endVolume) +{ + bool ret = true; + + LockMutex (fade_mutex); + + if (howLong < 0) + howLong = 0; + + musicFadeStartTime = GetTimeCounter (); + musicFadeInterval = howLong; + musicFadeStartVolume = musicVolume; + musicFadeDelta = endVolume - musicFadeStartVolume; + if (!musicFadeInterval) + ret = false; // reject + + UnlockMutex (fade_mutex); + + return ret; +} + +int +InitStreamDecoder (void) +{ + fade_mutex = CreateMutex ("Stream fade mutex", SYNC_CLASS_AUDIO); + if (!fade_mutex) + return -1; + + decoderTask = AssignTask (StreamDecoderTaskFunc, 1024, + "audio stream decoder"); + if (!decoderTask) + return -1; + + return 0; +} + +void +UninitStreamDecoder (void) +{ + if (decoderTask) + { + ConcludeTask (decoderTask); + decoderTask = NULL; + } + + if (fade_mutex) + { + DestroyMutex (fade_mutex); + fade_mutex = NULL; + } +} diff --git a/sc2/src/libs/sound/stream.h b/sc2/src/libs/sound/stream.h index 65db328c5..e71ae4b97 100644 --- a/sc2/src/libs/sound/stream.h +++ b/sc2/src/libs/sound/stream.h @@ -17,6 +17,9 @@ #ifndef STREAM_H #define STREAM_H +int InitStreamDecoder (void); +void UninitStreamDecoder (void); + void PlayStream (TFB_SoundSample *sample, uint32 source, bool looping, bool scope, bool rewind); void StopStream (uint32 source); @@ -24,8 +27,10 @@ void PauseStream (uint32 source); void ResumeStream (uint32 source); void SeekStream (uint32 source, uint32 pos); BOOLEAN PlayingStream (uint32 source); -int StreamDecoderTaskFunc (void *data); int GraphForegroundStream (uint8 *data, sint32 width, sint32 height); +// returns TRUE if the fade was accepted by stream decoder +bool SetMusicStreamFade (sint32 howLong, int endVolume); + #endif