From 2acbcc2963ca7e4c369f0b0a70818dcd3b8dd8d4 Mon Sep 17 00:00:00 2001 From: opa Date: Thu, 29 Aug 2024 02:14:06 +0900 Subject: [PATCH 1/5] Call AudioManager::init/deinit when ES starts/ends and game ends --- es-app/src/FileData.cpp | 1 + es-app/src/main.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 1aa4f0f07..6303412b8 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -311,6 +311,7 @@ void FileData::launchGame(Window* window) window->init(); InputManager::getInstance()->init(); VolumeControl::getInstance()->init(); + AudioManager::getInstance()->init(); window->normalizeNextUpdate(); //update number of times the game has been launched diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 437b23b19..58550bf1e 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -17,6 +17,7 @@ #include "Settings.h" #include "SystemData.h" #include "SystemScreenSaver.h" +#include "AudioManager.h" #include #include #include @@ -395,6 +396,7 @@ int main(int argc, char* argv[]) window.renderLoadingScreen("Done."); InputManager::getInstance()->init(); + AudioManager::getInstance()->init(); //choose which GUI to open depending on if an input configuration already exists if(errorMsg == NULL) @@ -467,6 +469,7 @@ int main(int argc, char* argv[]) while(window.peekGui() != ViewController::get()) delete window.peekGui(); + AudioManager::getInstance()->deinit(); InputManager::getInstance()->deinit(); window.deinit(); From 46db31adca065fcd87889e422e965af76a61e975 Mon Sep 17 00:00:00 2001 From: opa Date: Thu, 29 Aug 2024 15:44:00 +0900 Subject: [PATCH 2/5] Do not duplicate AudioManager::init/deinit --- es-core/src/AudioManager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/es-core/src/AudioManager.cpp b/es-core/src/AudioManager.cpp index 1d0f8ac49..56b45c371 100644 --- a/es-core/src/AudioManager.cpp +++ b/es-core/src/AudioManager.cpp @@ -72,6 +72,9 @@ std::shared_ptr & AudioManager::getInstance() void AudioManager::init() { + if(sInstance) + return; + if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) { LOG(LogError) << "Error initializing SDL audio!\n" << SDL_GetError(); @@ -103,6 +106,9 @@ void AudioManager::init() void AudioManager::deinit() { + if(!sInstance) + return; + //stop all playback stop(); //completely tear down SDL audio. else SDL hogs audio resources and emulators might fail to start... From 3e1bf4068dcf14559f523e2e3b9b5917e412c88c Mon Sep 17 00:00:00 2001 From: opa Date: Thu, 29 Aug 2024 16:25:59 +0900 Subject: [PATCH 3/5] VolumeControl also initialized at startup / InputManager is improved --- es-app/src/main.cpp | 3 +++ es-core/src/InputManager.cpp | 14 +++++++++----- es-core/src/InputManager.h | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 58550bf1e..67e74a804 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -18,6 +18,7 @@ #include "SystemData.h" #include "SystemScreenSaver.h" #include "AudioManager.h" +#include "VolumeControl.h" #include #include #include @@ -396,6 +397,7 @@ int main(int argc, char* argv[]) window.renderLoadingScreen("Done."); InputManager::getInstance()->init(); + VolumeControl::getInstance()->init(); AudioManager::getInstance()->init(); //choose which GUI to open depending on if an input configuration already exists @@ -470,6 +472,7 @@ int main(int argc, char* argv[]) delete window.peekGui(); AudioManager::getInstance()->deinit(); + VolumeControl::getInstance()->deinit(); InputManager::getInstance()->deinit(); window.deinit(); diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index 67a8901c4..be2456938 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -29,7 +29,7 @@ int SDL_USER_CECBUTTONDOWN = -1; int SDL_USER_CECBUTTONUP = -1; -InputManager* InputManager::mInstance = NULL; +InputManager* InputManager::sInstance = NULL; InputManager::InputManager() : mKeyboardInputConfig(NULL) { @@ -42,16 +42,16 @@ InputManager::~InputManager() InputManager* InputManager::getInstance() { - if(!mInstance) - mInstance = new InputManager(); + if(!sInstance) + sInstance = new InputManager(); - return mInstance; + return sInstance; } void InputManager::init() { if(initialized()) - deinit(); + return; SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, Settings::getInstance()->getBool("BackgroundJoystickInput") ? "1" : "0"); @@ -93,6 +93,10 @@ void InputManager::addJoystickByDeviceIndex(int id) // add it to our list so we can close it again later SDL_JoystickID joyId = SDL_JoystickInstanceID(joy); + + if(mJoysticks.count(joyId) > 0) + return; // already added + mJoysticks[joyId] = joy; char guid[65]; diff --git a/es-core/src/InputManager.h b/es-core/src/InputManager.h index 388358d21..f46fa2ebd 100644 --- a/es-core/src/InputManager.h +++ b/es-core/src/InputManager.h @@ -16,7 +16,7 @@ class InputManager private: InputManager(); - static InputManager* mInstance; + static InputManager* sInstance; static const int DEADZONE = 23000; From 33c83d7098643493733b0b63b2045e1ce9b82360 Mon Sep 17 00:00:00 2001 From: opa Date: Thu, 29 Aug 2024 16:30:55 +0900 Subject: [PATCH 4/5] Delete unused members of VolumeControl --- es-app/src/VolumeControl.cpp | 36 ++---------------------------------- es-app/src/VolumeControl.h | 5 ----- 2 files changed, 2 insertions(+), 39 deletions(-) diff --git a/es-app/src/VolumeControl.cpp b/es-app/src/VolumeControl.cpp index 80d18dfdc..7b01b5e9c 100644 --- a/es-app/src/VolumeControl.cpp +++ b/es-app/src/VolumeControl.cpp @@ -20,49 +20,19 @@ std::weak_ptr VolumeControl::sInstance; VolumeControl::VolumeControl() - : originalVolume(0), internalVolume(0) #if defined (__APPLE__) #error TODO: Not implemented for MacOS yet!!! #elif defined(__linux__) - , mixerIndex(0), mixerHandle(nullptr), mixerElem(nullptr), mixerSelemId(nullptr) + : mixerIndex(0), mixerHandle(nullptr), mixerElem(nullptr), mixerSelemId(nullptr) #elif defined(WIN32) || defined(_WIN32) - , mixerHandle(nullptr), endpointVolume(nullptr) + : mixerHandle(nullptr), endpointVolume(nullptr) #endif { init(); - - //get original volume levels for system - originalVolume = getVolume(); -} - -VolumeControl::VolumeControl(const VolumeControl & right): - originalVolume(0), internalVolume(0) -#if defined (__APPLE__) - #error TODO: Not implemented for MacOS yet!!! -#elif defined(__linux__) - , mixerIndex(0), mixerHandle(nullptr), mixerElem(nullptr), mixerSelemId(nullptr) -#elif defined(WIN32) || defined(_WIN32) - , mixerHandle(nullptr), endpointVolume(nullptr) -#endif -{ - (void)right; - sInstance = right.sInstance; -} - -VolumeControl & VolumeControl::operator=(const VolumeControl & right) -{ - if (this != &right) { - sInstance = right.sInstance; - } - - return *this; } VolumeControl::~VolumeControl() { - //set original volume levels for system - //setVolume(originalVolume); - deinit(); } @@ -347,8 +317,6 @@ void VolumeControl::setVolume(int volume) { volume = 100; } - //store values in internal variables - internalVolume = volume; #if defined (__APPLE__) #error TODO: Not implemented for MacOS yet!!! #elif defined(__linux__) diff --git a/es-app/src/VolumeControl.h b/es-app/src/VolumeControl.h index a2e420e7e..c8d79f2f7 100644 --- a/es-app/src/VolumeControl.h +++ b/es-app/src/VolumeControl.h @@ -36,14 +36,9 @@ class VolumeControl IAudioEndpointVolume * endpointVolume; #endif - int originalVolume; - int internalVolume; - static std::weak_ptr sInstance; VolumeControl(); - VolumeControl(const VolumeControl & right); - VolumeControl & operator=(const VolumeControl & right); public: static std::shared_ptr & getInstance(); From d022c7690994bb1a9c7a6dc675edddcc02294fd6 Mon Sep 17 00:00:00 2001 From: opa Date: Thu, 29 Aug 2024 16:39:42 +0900 Subject: [PATCH 5/5] Improvements VolumeControl on Windows --- es-app/src/VolumeControl.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/es-app/src/VolumeControl.cpp b/es-app/src/VolumeControl.cpp index 7b01b5e9c..825388104 100644 --- a/es-app/src/VolumeControl.cpp +++ b/es-app/src/VolumeControl.cpp @@ -122,16 +122,18 @@ void VolumeControl::init() } #elif defined(WIN32) || defined(_WIN32) //get windows version information - OSVERSIONINFOEXA osVer = {sizeof(OSVERSIONINFO)}; - ::GetVersionExA(reinterpret_cast(&osVer)); + OSVERSIONINFO osVer = {sizeof(OSVERSIONINFO)}; + GetVersionEx(&osVer); //check windows version if(osVer.dwMajorVersion < 6) { //Windows older than Vista. use mixer API. open default mixer if (mixerHandle == nullptr) { + LOG(LogDebug) << "VolumeControl::init() - Attempt to use mixer API"; if (mixerOpen(&mixerHandle, 0, NULL, 0, 0) == MMSYSERR_NOERROR) { + LOG(LogDebug) << "VolumeControl::init() - Opened mixer API"; //retrieve info on the volume slider control for the "Speaker Out" line MIXERLINECONTROLS mixerLineControls; mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS); @@ -141,7 +143,11 @@ void VolumeControl::init() mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; //Get volume control mixerLineControls.pamxctrl = &mixerControl; mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL); - if (mixerGetLineControls((HMIXEROBJ)mixerHandle, &mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE) != MMSYSERR_NOERROR) + if (mixerGetLineControls((HMIXEROBJ)mixerHandle, &mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE) == MMSYSERR_NOERROR) + { + LOG(LogDebug) << "VolumeControl::init() - Mixer initialized"; + } + else { LOG(LogError) << "VolumeControl::init() - Failed to get mixer volume control!"; mixerClose(mixerHandle); @@ -159,19 +165,26 @@ void VolumeControl::init() //Windows Vista or above. use EndpointVolume API. get device enumerator if (endpointVolume == nullptr) { + LOG(LogDebug) << "VolumeControl::init() - Attempt to use EndpointVolume API"; CoInitialize(nullptr); IMMDeviceEnumerator * deviceEnumerator = nullptr; CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator); if (deviceEnumerator != nullptr) { + LOG(LogDebug) << "VolumeControl::init() - MMDevice enumerate succeeded"; //get default endpoint IMMDevice * defaultDevice = nullptr; deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice); if (defaultDevice != nullptr) { + LOG(LogDebug) << "VolumeControl::init() - Acquired default audio endpoint"; //retrieve endpoint volume defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, nullptr, (LPVOID *)&endpointVolume); - if (endpointVolume == nullptr) + if (endpointVolume != nullptr) + { + LOG(LogDebug) << "VolumeControl::init() - Volume initialized"; + } + else { LOG(LogError) << "VolumeControl::init() - Failed to get default audio endpoint volume!"; } @@ -285,7 +298,7 @@ int VolumeControl::getVolume() const if (endpointVolume->GetMasterVolumeLevelScalar(&floatVolume) == S_OK) { volume = (int)Math::round(floatVolume * 100.0f); - LOG(LogInfo) << " getting volume as " << volume << " ( from float " << floatVolume << ")"; + LOG(LogDebug) << " getting volume as " << volume << " (from float " << floatVolume << ")"; } else {