Improve audio and volume handling.

Prevent a deadlock in AudioManager mixer callback when stopping sounds.
Detach and free mixer handle before closing it in
VolumeControl::deinit().
This commit is contained in:
Bim Overbohm 2013-06-12 11:48:53 +02:00
parent c8bf0cf652
commit 850147016f
3 changed files with 10 additions and 9 deletions

View file

@ -28,17 +28,13 @@ void AudioManager::mixAudio(void *unused, Uint8 *stream, int len)
}
//mix sample into stream
SDL_MixAudio(stream, &(sound->getData()[sound->getPosition()]), restLength, SDL_MIX_MAXVOLUME);
if (sound->getPosition() + restLength >= sound->getLength())
{
//if the position is beyond the end of the buffer, stop playing the sample
sound->stop();
}
else
if (sound->getPosition() + restLength < sound->getLength())
{
//sample hasn't ended yet
sound->setPosition(sound->getPosition() + restLength);
stillPlaying = true;
}
//set new sound position. if this is at or beyond the end of the sample, it will stop automatically
sound->setPosition(sound->getPosition() + restLength);
}
//advance to next sound
++soundIt;

View file

@ -82,18 +82,19 @@ void Sound::play()
if(mSampleData == NULL)
return;
SDL_LockAudio();
if (playing)
{
//replay from start. rewind the sample to the beginning
SDL_LockAudio();
mSamplePos = 0;
SDL_UnlockAudio();
}
else
{
//flag our sample as playing
playing = true;
}
SDL_UnlockAudio();
//tell the AudioManager to start playing samples
AudioManager::getInstance()->play();
}
@ -126,6 +127,8 @@ void Sound::setPosition(Uint32 newPosition)
{
mSamplePos = newPosition;
if (mSamplePos >= mSampleLength) {
//got to or beyond the end of the sample. stop playing
playing = false;
mSamplePos = 0;
}
}

View file

@ -215,6 +215,8 @@ void VolumeControl::deinit()
#error TODO: Not implemented for MacOS yet!!!
#elif defined(__linux__)
if (mixerHandle != nullptr) {
snd_mixer_detach(mixerHandle, mixerCard);
snd_mixer_free(mixerHandle);
snd_mixer_close(mixerHandle);
mixerHandle = nullptr;
mixerElem = nullptr;