diff --git a/sc2/src/sc2code/libs/sound/mixsdl/mixer.c b/sc2/src/sc2code/libs/sound/mixsdl/mixer.c index 64c8c93fa..4681f4fb8 100644 --- a/sc2/src/sc2code/libs/sound/mixsdl/mixer.c +++ b/sc2/src/sc2code/libs/sound/mixsdl/mixer.c @@ -472,14 +472,22 @@ mixSDL_Sourcei (mixSDL_Object srcobj, mixSDL_SourceProp pname, src->looping = value; break; case MIX_BUFFER: - if (src->cqueued > 0) - mixSDL_SourceUnqueueAll (src); + { + mixSDL_Buffer *buf = (mixSDL_Buffer *) value; - src->firstqueued = (mixSDL_Buffer *) value; - src->nextqueued = src->firstqueued; - src->lastqueued = src->nextqueued; - if (src->lastqueued) - src->lastqueued->next = 0; + if (src->cqueued > 0) + mixSDL_SourceUnqueueAll (src); + + if (buf && !mixSDL_CheckBufferState (buf, "mixSDL_Sourcei")) + break; + + src->firstqueued = buf; + src->nextqueued = src->firstqueued; + src->lastqueued = src->nextqueued; + if (src->lastqueued) + src->lastqueued->next = 0; + src->cqueued = 1; + } break; case MIX_SOURCE_STATE: #ifdef DEBUG @@ -812,30 +820,9 @@ mixSDL_SourceQueueBuffers (mixSDL_Object srcobj, uint32 n, for (i = n, pobj = pbufobj; i; i--, pobj++) { mixSDL_Buffer *buf = (mixSDL_Buffer *) *pobj; - if (!buf || buf->magic != mixSDL_bufMagic) + if (!buf || !mixSDL_CheckBufferState (buf, + "mixSDL_SourceQueueBuffers")) { - mixSDL_SetError (MIX_INVALID_NAME); -#ifdef DEBUG - fprintf (stderr, "mixSDL_SourceQueueBuffers(): not a buffer\n"); -#endif - break; - } - else if (buf->locked) - { - mixSDL_SetError (MIX_INVALID_OPERATION); -#ifdef DEBUG - fprintf (stderr, "mixSDL_SourceQueueBuffers(): " - "locked buffer attempted\n"); -#endif - break; - } - else if (buf->state != MIX_BUF_FILLED) - { - mixSDL_SetError (MIX_INVALID_OPERATION); -#ifdef DEBUG - fprintf (stderr, "mixSDL_SourceQueueBuffers(): " - "invalid buffer attempted\n"); -#endif break; } } @@ -1625,6 +1612,41 @@ mixSDL_ConvertBuffer (uint32 srcfmt, void* srcdata, uint32 srcsize, * Buffer internals */ +static __inline__ bool +mixSDL_CheckBufferState (mixSDL_Buffer *buf, const char* FuncName) +{ + if (!buf) + return false; + + if (buf->magic != mixSDL_bufMagic) + { + mixSDL_SetError (MIX_INVALID_NAME); +#ifdef DEBUG + fprintf (stderr, "%s(): not a buffer\n", FuncName); +#endif + return false; + } + + if (buf->locked) + { + mixSDL_SetError (MIX_INVALID_OPERATION); +#ifdef DEBUG + fprintf (stderr, "%s(): locked buffer attempted\n", FuncName); +#endif + return false; + } + + if (buf->state != MIX_BUF_FILLED) + { + mixSDL_SetError (MIX_INVALID_OPERATION); +#ifdef DEBUG + fprintf (stderr, "%s: invalid buffer attempted\n", FuncName); +#endif + return false; + } + return true; +} + static void mixSDL_ConvertBuffer_internal (mixSDL_Convertion *conv) { diff --git a/sc2/src/sc2code/libs/sound/mixsdl/mixerint.h b/sc2/src/sc2code/libs/sound/mixsdl/mixerint.h index 4a77ef805..9d764cdc9 100644 --- a/sc2/src/sc2code/libs/sound/mixsdl/mixerint.h +++ b/sc2/src/sc2code/libs/sound/mixsdl/mixerint.h @@ -79,6 +79,8 @@ static void mixSDL_SourceStop_internal (mixSDL_Source *src); static void mixSDL_SourceActivate (mixSDL_Source* src); static void mixSDL_SourceDeactivate (mixSDL_Source* src); +static __inline__ bool mixSDL_CheckBufferState (mixSDL_Buffer *buf, + const char* FuncName); /* Reentrant mutex */ typedef struct diff --git a/sc2/src/sc2code/libs/sound/sfx.c b/sc2/src/sc2code/libs/sound/sfx.c index 10bd80eb9..d043a6c2a 100644 --- a/sc2/src/sc2code/libs/sound/sfx.c +++ b/sc2/src/sc2code/libs/sound/sfx.c @@ -28,15 +28,16 @@ PlayChannel (COUNT channel, PVOID sample, COUNT sample_length, COUNT loop_begin, { TFB_SoundSample *tfb_sample = *(TFB_SoundSample**) sample; soundSource[channel].sample = tfb_sample; - TFBSound_SourceRewind (soundSource[channel].handle); - TFBSound_Sourcei (soundSource[channel].handle, TFBSOUND_BUFFER, tfb_sample->buffer[0]); + TFBSound_SourceStop (soundSource[channel].handle); + TFBSound_Sourcei (soundSource[channel].handle, TFBSOUND_BUFFER, + tfb_sample->buffer[0]); TFBSound_SourcePlay (soundSource[channel].handle); } void -StopChannel(COUNT channel, unsigned char Priority) +StopChannel (COUNT channel, unsigned char Priority) { - TFBSound_SourceRewind (soundSource[channel].handle); + StopSource (channel); } BOOLEAN @@ -44,7 +45,8 @@ ChannelPlaying (COUNT WhichChannel) { TFBSound_IntVal state; - TFBSound_GetSourcei (soundSource[WhichChannel].handle, TFBSOUND_SOURCE_STATE, &state); + TFBSound_GetSourcei (soundSource[WhichChannel].handle, + TFBSOUND_SOURCE_STATE, &state); if (state == TFBSOUND_PLAYING) return TRUE; return FALSE; @@ -236,7 +238,10 @@ _ReleaseSoundBankData (MEM_HANDLE Snd) for (i = 0; i < NUM_SOUNDSOURCES; ++i) { if (soundSource[i].sample == (*sptr)) + { + StopSource (i); soundSource[i].sample = NULL; + } } if ((*sptr)->decoder) diff --git a/sc2/src/sc2code/libs/sound/sound.c b/sc2/src/sc2code/libs/sound/sound.c index 6bf46190f..4e661af7c 100644 --- a/sc2/src/sc2code/libs/sound/sound.c +++ b/sc2/src/sc2code/libs/sound/sound.c @@ -29,7 +29,26 @@ StopSound (void) for (i = FIRST_SFX_SOURCE; i <= LAST_SFX_SOURCE; ++i) { - TFBSound_SourceRewind (soundSource[i].handle); + StopSource (i); + } +} + +void +StopSource (int iSource) +{ + TFBSound_IntVal processed; + + TFBSound_SourceStop (soundSource[iSource].handle); + TFBSound_GetSourcei (soundSource[iSource].handle, + TFBSOUND_BUFFERS_PROCESSED, &processed); + + if (processed != 0) + { + TFBSound_Object *buffer = (TFBSound_Object *) + HMalloc (sizeof (TFBSound_Object) * processed); + TFBSound_SourceUnqueueBuffers (soundSource[iSource].handle, + processed, buffer); + HFree (buffer); } } diff --git a/sc2/src/sc2code/libs/sound/sound.h b/sc2/src/sc2code/libs/sound/sound.h index 9974cbdbc..ab55280a0 100644 --- a/sc2/src/sc2code/libs/sound/sound.h +++ b/sc2/src/sc2code/libs/sound/sound.h @@ -89,6 +89,8 @@ typedef struct tfb_soundsource extern TFB_SoundSource soundSource[]; +void StopSource (int iSource); + void SetSFXVolume (float volume); void SetSpeechVolume (float volume); void DoTrackTag (TFB_SoundTag *tag); diff --git a/sc2/src/sc2code/libs/sound/stream.c b/sc2/src/sc2code/libs/sound/stream.c index 5b80b7100..c944a84e2 100644 --- a/sc2/src/sc2code/libs/sound/stream.c +++ b/sc2/src/sc2code/libs/sound/stream.c @@ -111,9 +111,6 @@ PlayStream (TFB_SoundSample *sample, uint32 source, bool looping, bool scope, bo void StopStream (uint32 source) { - TFBSound_IntVal queued, processed; - uint32 *buffer; - soundSource[source].stream_should_be_playing = FALSE; soundSource[source].sample = NULL; @@ -127,18 +124,7 @@ StopStream (uint32 source) soundSource[source].sbuf_size = 0; soundSource[source].sbuf_offset = 0; - TFBSound_SourceStop (soundSource[source].handle); - TFBSound_GetSourcei (soundSource[source].handle, TFBSOUND_BUFFERS_PROCESSED, &processed); - TFBSound_GetSourcei (soundSource[source].handle, TFBSOUND_BUFFERS_QUEUED, &queued); - - //fprintf (stderr, "StopStream(): source %d processed %d queued %d num_buffers %d\n", source, processed, queued, soundSource[source].sample->num_buffers); - - if (processed != 0) - { - buffer = (uint32 *) HMalloc (sizeof (uint32) * processed); - TFBSound_SourceUnqueueBuffers (soundSource[source].handle, processed, buffer); - HFree (buffer); - } + StopSource (source); } void