Separate sound mute and enable functionality.

Mute simply changes the sound level; disabling sound completely is now done separately.
This commit is contained in:
Stephen Anthony 2022-10-09 21:28:35 -02:30
parent 4044af5770
commit 7de717114c
8 changed files with 31 additions and 79 deletions

View File

@ -24,7 +24,7 @@
#include "StaggeredLogger.hxx"
/**
This class implements a an audio queue that acts both like a ring buffer
This class implements an audio queue that acts both like a ring buffer
and a pool of audio fragments. The TIA emulation core fills a fragment
with samples and then returns it to the queue, receiving a new fragment
in return. The sound driver removes fragments for playback from the

View File

@ -59,12 +59,6 @@ class SoundNull : public Sound
*/
void open(shared_ptr<AudioQueue>, EmulationTiming*) override { }
/**
Should be called to close the sound device. Once called the sound
device can be started again using the initialize method.
*/
void close() override { }
/**
Sets the sound mute state; sound processing continues. When turned
off, sound volume is 0; when turned on, sound volume returns to

View File

@ -141,7 +141,6 @@ bool SoundSDL2::openDevice()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::setEnabled(bool enable)
{
cerr << "setEnabled: " << enable << endl;
mute(!enable);
pause(!enable);
}
@ -164,7 +163,6 @@ void SoundSDL2::open(shared_ptr<AudioQueue> audioQueue,
Logger::debug("SoundSDL2::open started ...");
myAudioSettings.setEnabled(true);
audioQueue->ignoreOverflows(!myAudioSettings.enabled());
if(!myAudioSettings.enabled())
{
@ -193,22 +191,9 @@ void SoundSDL2::open(shared_ptr<AudioQueue> audioQueue,
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::close()
void SoundSDL2::mute(bool enable)
{
if(!myIsInitializedFlag)
return;
if(myAudioQueue)
myAudioQueue->closeSink(myCurrentFragment);
myAudioQueue.reset();
myCurrentFragment = nullptr;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::mute(bool state)
{
myAudioSettings.setEnabled(!state);
if(state)
if(enable)
myVolumeFactor = 0;
else
setVolume(myAudioSettings.volume());
@ -217,27 +202,29 @@ void SoundSDL2::mute(bool state)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL2::toggleMute()
{
const bool state = !myAudioSettings.enabled();
mute(!state);
const bool wasMuted = myVolumeFactor == 0;
mute(!wasMuted);
string message = "Sound ";
message += state ? "unmuted" : "muted";
message += !myAudioSettings.enabled()
? "disabled"
: (wasMuted ? "unmuted" : "muted");
myOSystem.frameBuffer().showTextMessage(message);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool SoundSDL2::pause(bool state)
bool SoundSDL2::pause(bool enable)
{
ASSERT_MAIN_THREAD;
const bool oldstate = SDL_GetAudioDeviceStatus(myDevice) == SDL_AUDIO_PAUSED;
const bool wasPaused = SDL_GetAudioDeviceStatus(myDevice) == SDL_AUDIO_PAUSED;
if(myIsInitializedFlag)
{
SDL_PauseAudioDevice(myDevice, state ? 1 : 0);
myWavHandler.pause(state);
SDL_PauseAudioDevice(myDevice, enable ? 1 : 0);
myWavHandler.pause(enable);
}
return oldstate;
return wasPaused;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -386,7 +373,7 @@ void SoundSDL2::callback(void* object, uInt8* stream, int len)
const uInt32 length = len >> 2;
self->myResampler->fillFragment(s, length);
for(uInt32 i = 0; i < length; ++i) // TODO - perhaps move into Resampler
for(uInt32 i = 0; i < length; ++i)
s[i] *= SoundSDL2::myVolumeFactor;
}
else
@ -452,8 +439,9 @@ bool SoundSDL2::WavHandlerSDL2::play(
myDevice = SDL_OpenAudioDevice(device, 0, &mySpec, nullptr, 0);
if(!myDevice)
return false;
// Play audio
SDL_PauseAudioDevice(myDevice, 0);
pause(false);
}
return true;
}

View File

@ -66,19 +66,13 @@ class SoundSDL2 : public Sound
EmulationTiming* emulationTiming) override;
/**
Should be called to close the sound device. Once called the sound
device can be started again using the open method.
*/
void close() override;
Sets the sound mute state; sound processing continues. When enabled,
sound volume is 0; when disabled, sound volume returns to previously
set level.
/**
Sets the sound mute state; sound processing continues. When turned
off, sound volume is 0; when turned on, sound volume returns to
previously set level.
@param state Mutes sound if true, unmute if false
@param enable Mutes sound if true, unmute if false
*/
void mute(bool state) override;
void mute(bool enable) override;
/**
Toggles the sound mute state; sound processing continues.
@ -91,11 +85,11 @@ class SoundSDL2 : public Sound
neither played nor processed (ie, the sound subsystem is temporarily
disabled).
@param state Pause sound if true, unpause if false
@param enable Pause sound if true, unpause if false
@return The previous (old) pause state
*/
bool pause(bool state) override;
bool pause(bool enable) override;
/**
Sets the volume of the sound device to the specified level. The

View File

@ -250,10 +250,12 @@ Console::~Console()
myLeftControl->close();
myRightControl->close();
// Close audio to prevent invalid access to myConsoleTiming from the audio
// callback
myOSystem.sound().close();
myOSystem.sound().stopWav();
// Close audio to prevent invalid access in the audio callback
if(myAudioQueue)
{
myAudioQueue->closeSink(nullptr); // TODO: is this needed?
myAudioQueue.reset();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -335,12 +337,10 @@ void Console::redetectFrameLayout()
{
Serializer s;
myOSystem.sound().close();
save(s);
autodetectFrameLayout(false);
load(s);
initializeAudio();
}
@ -691,8 +691,6 @@ FBInitStatus Console::initializeVideo(bool full)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::initializeAudio()
{
myOSystem.sound().close();
myEmulationTiming
.updatePlaybackRate(myAudioSettings.sampleRate())
.updatePlaybackPeriod(myAudioSettings.fragmentSize())

View File

@ -572,7 +572,7 @@ bool OSystem::createLauncher(const string& startdir)
closeConsole();
if(mySound)
mySound->close();
mySound->pause(true);
mySettings->setValue("tmpromdir", startdir);
bool status = false;

View File

@ -55,12 +55,6 @@ class Sound
*/
virtual void open(shared_ptr<AudioQueue>, EmulationTiming*) = 0;
/**
Should be called to stop the sound system. Once called the sound
device can be started again using the ::open() method.
*/
virtual void close() = 0;
/**
Sets the sound mute state; sound processing continues. When turned
off, sound volume is 0; when turned on, sound volume returns to

View File

@ -80,22 +80,6 @@ class SoundLIBRETRO : public Sound
myIsInitializedFlag = true;
}
/**
Should be called to close the sound device. Once called the sound
device can be started again using the open method.
*/
void close() override
{
if (!myIsInitializedFlag)
return;
if (myAudioQueue)
myAudioQueue->closeSink(myCurrentFragment);
myAudioQueue.reset();
myCurrentFragment = nullptr;
Logger::debug("SoundLIBRETRO::close");
}
/**
Empties the playback buffer.