From 7de717114cff4013d2427989adb3366ebdbca49e Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 9 Oct 2022 21:28:35 -0230 Subject: [PATCH 1/3] Separate sound mute and enable functionality. Mute simply changes the sound level; disabling sound completely is now done separately. --- src/common/AudioQueue.hxx | 2 +- src/common/SoundNull.hxx | 6 ----- src/common/SoundSDL2.cxx | 42 +++++++++++-------------------- src/common/SoundSDL2.hxx | 20 ++++++--------- src/emucore/Console.cxx | 16 ++++++------ src/emucore/OSystem.cxx | 2 +- src/emucore/Sound.hxx | 6 ----- src/os/libretro/SoundLIBRETRO.hxx | 16 ------------ 8 files changed, 31 insertions(+), 79 deletions(-) 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. From 7b5d25d9f10bd8c8a1da2150dfdb6b131867531a Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Sun, 9 Oct 2022 21:50:57 -0230 Subject: [PATCH 2/3] Fix minor warning from clang-tidy. --- src/emucore/PlusROM.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emucore/PlusROM.cxx b/src/emucore/PlusROM.cxx index ccc3c1e2e..9ccb8117d 100644 --- a/src/emucore/PlusROM.cxx +++ b/src/emucore/PlusROM.cxx @@ -99,7 +99,7 @@ class PlusROMRequest { client.set_write_timeout(milliseconds(WRITE_TIMEOUT_MSEC)); auto response = client.Post( - myDestination.path.c_str(), + myDestination.path, headers, reinterpret_cast(myRequest.data()), myRequestSize, From d7d73234ff9ca516148d54ad6995dc8b2c4ecd89 Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Mon, 10 Oct 2022 19:15:55 +0200 Subject: [PATCH 3/3] Add a GitHub action to build on Linux and macOS (#935) As with Travis CI, the test is only deemed successful on each platform if the Stella build completes successfully. For Linux, the test runs on Ubuntu with the toolchain test build repository, using G++ 9, and the packaged version of SDL2, which is guaranteed to be at least 2.0.10. For macOS, SDL2 2.0.10 is still built from the upstream source code; however that no longer builds with the newer Xcode versions available in GHAs, so the build now uses "Unix-style" ./configure && make. The runners provide two cores on Linux and three cores on macOS, so the compile stages use the appropriate -j setting to build in parallel. Signed-off-by: Stephen Kitt Signed-off-by: Stephen Kitt --- .github/workflows/build.yml | 39 +++++++++++++++++++++++ .travis.yml | 63 ------------------------------------- 2 files changed, 39 insertions(+), 63 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..f5dd58cab --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,39 @@ +--- +name: Build + +on: + pull_request: + +permissions: {} + +jobs: + linux: + name: Linux + runs-on: ubuntu-latest + steps: + - name: Check out the repository + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + - name: Install GCC 9 and SDL2 + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo apt update + sudo apt install g++-9 libsdl2-dev + - name: Build Stella + run: | + ./configure && make -j2 all + + macos: + name: macOS + runs-on: macos-latest + steps: + - name: Check out the repository + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + - name: Install SDL2 + run: | + curl https://www.libsdl.org/release/SDL2-2.0.10.tar.gz | tar xzf - + mkdir SDL2-2.0.10/build + cd SDL2-2.0.10/build + ../configure && make -j3 && sudo make install + - name: Build Stella + run: | + ./configure && make -j3 all diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index bca11dee4..000000000 --- a/.travis.yml +++ /dev/null @@ -1,63 +0,0 @@ -# Build matrix / environment variables are explained on: -# http://about.travis-ci.org/docs/user/build-configuration/ -# This file can be validated on: http://lint.travis-ci.org/ - - -language: cpp - - -matrix: - include: - - os: linux - dist: xenial - compiler: gcc - env: GCC=9 CC=gcc-9 CXX=g++-9 - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-9 - - g++-9 - update: true - - - - os: osx - osx_image: xcode11.3 - compiler: clang - addons: - homebrew: - update: true - - -install: - - | - old_cwd=$(pwd) - cd ~ - - if [[ "$HOST" == macosx-* ]]; then - curl -O https://www.libsdl.org/release/SDL2-2.0.10.tar.gz - tar xzf SDL2-2.0.10.tar.gz - cd SDL2-2.0.10/Xcode/SDL - sed -i -e 's/@rpath//g' SDL.xcodeproj/project.pbxproj - xcodebuild -configuration Release - mkdir -p ~/Library/Frameworks/ - ln -s `pwd`/build/Release/SDL2.framework ~/Library/Frameworks/ - else - curl -O https://www.libsdl.org/release/SDL2-2.0.10.tar.gz - tar xzf SDL2-2.0.10.tar.gz - cd SDL2-2.0.10 - mkdir build - cd build - ../configure - make - sudo make install - fi - - cd $old_cwd - - -script: - - | - ./configure - make all