diff --git a/src/common/AudioQueue.hxx b/src/common/AudioQueue.hxx index 5dd223489..a57b64ab6 100644 --- a/src/common/AudioQueue.hxx +++ b/src/common/AudioQueue.hxx @@ -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 diff --git a/src/common/SoundNull.hxx b/src/common/SoundNull.hxx index 5007bf49c..d5726d7c4 100644 --- a/src/common/SoundNull.hxx +++ b/src/common/SoundNull.hxx @@ -59,12 +59,6 @@ class SoundNull : public Sound */ void open(shared_ptr, 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 diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index 9e07564e3..3bee69bcf 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -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, 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, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -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; } diff --git a/src/common/SoundSDL2.hxx b/src/common/SoundSDL2.hxx index 016d1a612..d477dc88b 100644 --- a/src/common/SoundSDL2.hxx +++ b/src/common/SoundSDL2.hxx @@ -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 diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 95064c502..c19d20bdb 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -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()) diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 11ebdd3f0..ff182a041 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -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; diff --git a/src/emucore/Sound.hxx b/src/emucore/Sound.hxx index 6e5543205..29ff70278 100644 --- a/src/emucore/Sound.hxx +++ b/src/emucore/Sound.hxx @@ -55,12 +55,6 @@ class Sound */ virtual void open(shared_ptr, 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 diff --git a/src/os/libretro/SoundLIBRETRO.hxx b/src/os/libretro/SoundLIBRETRO.hxx index aa20237f2..8c1485b3d 100644 --- a/src/os/libretro/SoundLIBRETRO.hxx +++ b/src/os/libretro/SoundLIBRETRO.hxx @@ -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.