From 33c4516e7258a0b08075a8fad4ad5c6e33d823f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 11 Feb 2025 18:34:37 -0600 Subject: [PATCH 1/5] Implement new volume conversion functions, add test --- Core/Config.cpp | 28 ++++++++++++++++++++++++++++ Core/ConfigValues.h | 15 +++++---------- unittest/UnitTest.cpp | 15 +++++++++++++++ 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 118c9de5ad..f56e92175f 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -2092,3 +2092,31 @@ bool PlayTimeTracker::GetPlayedTimeString(const std::string &gameId, std::string *str = ApplySafeSubstitutions(ga->T("Time Played: %1h %2m %3s"), hours, minutes, seconds); return true; } + +// This matches exactly the old shift-based curve. +float Volume10ToMultiplier(int volume) { + // Allow muting entirely. + if (volume <= 0) { + return 0.0f; + } + return powf(2.0f, (float)(volume - 10)); +} + +// NOTE: This is used for new volume parameters. +// It uses a more intuitive-feeling curve. +float Volume100ToMultiplier(int volume) { + // Switch to linear above the 1.0f point. + if (volume > 100) { + return volume / 100.0f; + } + return powf(volume * 0.01f, 1.75f); +} + +// Used for migration from the old settings. +int MultiplierToVolume100(float multiplier) { + // Switch to linear above the 1.0f point. + if (multiplier > 1.0f) { + return multiplier * 100; + } + return (int)(powf(multiplier, 1.0f / 1.75f) * 100.f + 0.5f); +} diff --git a/Core/ConfigValues.h b/Core/ConfigValues.h index 1fefc2d03f..1dd1fc88b4 100644 --- a/Core/ConfigValues.h +++ b/Core/ConfigValues.h @@ -34,19 +34,14 @@ constexpr int VOLUME_FULL = 10; constexpr int VOLUMEHI_FULL = 100; // for newer volume params. will convert them all later // This matches exactly the old shift-based curve. -inline float Volume10ToMultiplier(int volume) { - // Allow muting entirely. - if (volume <= 0) { - return 0.0f; - } - return powf(2.0f, (float)(volume - 10)); -} +float Volume10ToMultiplier(int volume); // NOTE: This is used for new volume parameters. // It uses a more intuitive-feeling curve. -inline float Volume100ToMultiplier(int volume) { - return powf(volume * 0.01f, 1.75f); -} +float Volume100ToMultiplier(int volume); + +// Used for migration from the old settings. +int MultiplierToVolume100(float multiplier); struct ConfigTouchPos { float x; diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index 52a72f36fc..733bb10884 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -1218,6 +1218,20 @@ bool TestCrossSIMD() { return true; } +bool TestVolumeFunc() { + for (int i = 0; i <= 20; i++) { + float mul = Volume10ToMultiplier(i); + + int vol100 = MultiplierToVolume100(mul); + float mul2 = Volume100ToMultiplier(vol100); + + bool smaller = (fabsf(mul2 - mul) < 0.02f); + EXPECT_TRUE(smaller); + // printf("%d -> %f -> %d -> %f\n", i, mul, vol100, mul2); + } + return true; +} + typedef bool (*TestFunc)(); struct TestItem { const char *name; @@ -1282,6 +1296,7 @@ TestItem availableTests[] = { TEST_ITEM(Buffer), TEST_ITEM(SIMD), TEST_ITEM(CrossSIMD), + TEST_ITEM(VolumeFunc), }; int main(int argc, const char *argv[]) { From fef4a86225b73422b50c2ac1381e0990a9e4d2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 12 Feb 2025 09:49:30 -0600 Subject: [PATCH 2/5] Upgrade the game volume setting to the new format --- Core/Config.cpp | 18 +++++++++++++++++- Core/Config.h | 3 ++- Core/HLE/__sceAudio.cpp | 2 +- UI/GameSettingsScreen.cpp | 2 +- headless/Headless.cpp | 2 +- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index f56e92175f..38fe0bd669 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -745,12 +745,24 @@ static const ConfigSetting graphicsSettings[] = { ConfigSetting("DisplayRefreshRate", &g_Config.iDisplayRefreshRate, g_Config.iDisplayRefreshRate, CfgFlag::PER_GAME), }; +static int LegacyVolumeToNewVolume(int legacy, int max) { + float multiplier = Volume10ToMultiplier(legacy); + return std::clamp(MultiplierToVolume100(multiplier), 0, max); +} + +static int DefaultGameVolume() { + return LegacyVolumeToNewVolume(g_Config.iLegacyGameVolume, 100); +} + static const ConfigSetting soundSettings[] = { ConfigSetting("Enable", &g_Config.bEnableSound, true, CfgFlag::PER_GAME), ConfigSetting("AudioBackend", &g_Config.iAudioBackend, 0, CfgFlag::PER_GAME), ConfigSetting("ExtraAudioBuffering", &g_Config.bExtraAudioBuffering, false, CfgFlag::DEFAULT), - ConfigSetting("GlobalVolume", &g_Config.iGameVolume, VOLUME_FULL, CfgFlag::PER_GAME), + // Legacy volume settings, these get auto upgraded through default handlers on the new settings. NOTE: Must be before the new ones in the order here. + ConfigSetting("GlobalVolume", &g_Config.iLegacyGameVolume, VOLUME_FULL, CfgFlag::PER_GAME | CfgFlag::DONT_SAVE), + + ConfigSetting("GameVolume", &g_Config.iGameVolume, &DefaultGameVolume, CfgFlag::PER_GAME), ConfigSetting("ReverbVolume", &g_Config.iReverbVolume, VOLUME_FULL, CfgFlag::PER_GAME), ConfigSetting("AltSpeedRelativeVolume", &g_Config.iAltSpeedVolume, VOLUMEHI_FULL, CfgFlag::PER_GAME), ConfigSetting("AchievementSoundVolume", &g_Config.iAchievementSoundVolume, 6, CfgFlag::PER_GAME), @@ -1468,6 +1480,7 @@ bool Config::Save(const char *saveReason) { return true; } +// A lot more cleanup tasks should be moved into here, and some of these are severely outdated. void Config::PostLoadCleanup(bool gameSpecific) { // Override ppsspp.ini JIT value to prevent crashing jitForcedOff = DefaultCpuCore() != (int)CPUCore::JIT && (g_Config.iCpuCore == (int)CPUCore::JIT || g_Config.iCpuCore == (int)CPUCore::JIT_IR); @@ -1502,6 +1515,9 @@ void Config::PostLoadCleanup(bool gameSpecific) { if (g_Config.sCustomDriver == "Default") { g_Config.sCustomDriver = ""; } + + // Convert old volume settings. + } void Config::PreSaveCleanup(bool gameSpecific) { diff --git a/Core/Config.h b/Core/Config.h index cb82528598..a82c6f8e48 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -281,12 +281,13 @@ public: int iAudioBackend; // Volume settings, 0-10 - int iGameVolume; + int iLegacyGameVolume; int iReverbVolume; int iAltSpeedVolume; int iAchievementSoundVolume; // Newer volume settings, 0-100 + int iGameVolume; int iUIVolume; bool bExtraAudioBuffering; // For bluetooth diff --git a/Core/HLE/__sceAudio.cpp b/Core/HLE/__sceAudio.cpp index 19e389ad0b..269b75bf2d 100644 --- a/Core/HLE/__sceAudio.cpp +++ b/Core/HLE/__sceAudio.cpp @@ -414,7 +414,7 @@ void __AudioUpdate(bool resetRecording) { } if (g_Config.bEnableSound) { - float multiplier = Volume10ToMultiplier(std::clamp(g_Config.iGameVolume, 0, VOLUME_FULL)); + float multiplier = Volume100ToMultiplier(std::clamp(g_Config.iGameVolume, 0, VOLUMEHI_FULL)); if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL || PSP_CoreParameter().fastForward) { if (g_Config.iAltSpeedVolume != -1) { // Multiply in the alt speed volume instead of replacing like before. diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 52402ccb5a..8f941b11af 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -656,7 +656,7 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) { // This is here because it now only applies to in-game. Muting the menu sounds is separate. CheckBox *enableSound = audioSettings->Add(new CheckBox(&g_Config.bEnableSound, a->T("Enable Sound"))); - PopupSliderChoice *volume = audioSettings->Add(new PopupSliderChoice(&g_Config.iGameVolume, VOLUME_OFF, VOLUME_FULL, VOLUME_FULL, a->T("Game volume"), screenManager())); + PopupSliderChoice *volume = audioSettings->Add(new PopupSliderChoice(&g_Config.iGameVolume, VOLUME_OFF, VOLUMEHI_FULL, VOLUMEHI_FULL, a->T("Game volume"), screenManager())); volume->SetEnabledPtr(&g_Config.bEnableSound); volume->SetZeroLabel(a->T("Mute")); diff --git a/headless/Headless.cpp b/headless/Headless.cpp index e671293f99..59bc9c8772 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -527,7 +527,7 @@ int main(int argc, const char* argv[]) g_Config.sMACAddress = "12:34:56:78:9A:BC"; g_Config.iFirmwareVersion = PSP_DEFAULT_FIRMWARE; g_Config.iPSPModel = PSP_MODEL_SLIM; - g_Config.iGameVolume = VOLUME_FULL; + g_Config.iGameVolume = VOLUMEHI_FULL; g_Config.iReverbVolume = VOLUME_FULL; g_Config.internalDataDirectory.clear(); g_Config.bUseExperimentalAtrac = newAtrac; From 62e01d37a5f907f5351f69de5c8ee0fff102e99d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 12 Feb 2025 10:09:37 -0600 Subject: [PATCH 3/5] Upgrade reverb volume to the new format --- Core/Config.cpp | 8 +++++++- Core/Config.h | 5 +++-- Core/HW/SasAudio.cpp | 2 +- Core/HW/SasReverb.cpp | 14 ++++++++------ Core/HW/SasReverb.h | 4 ++-- UI/GameSettingsScreen.cpp | 2 +- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 38fe0bd669..bc605badc5 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -754,16 +754,22 @@ static int DefaultGameVolume() { return LegacyVolumeToNewVolume(g_Config.iLegacyGameVolume, 100); } +static int DefaultReverbVolume() { + return LegacyVolumeToNewVolume(g_Config.iLegacyReverbVolume, 200); +} + static const ConfigSetting soundSettings[] = { ConfigSetting("Enable", &g_Config.bEnableSound, true, CfgFlag::PER_GAME), ConfigSetting("AudioBackend", &g_Config.iAudioBackend, 0, CfgFlag::PER_GAME), ConfigSetting("ExtraAudioBuffering", &g_Config.bExtraAudioBuffering, false, CfgFlag::DEFAULT), // Legacy volume settings, these get auto upgraded through default handlers on the new settings. NOTE: Must be before the new ones in the order here. + // The default settings here are still relevant, they will get propagated into the new ones. ConfigSetting("GlobalVolume", &g_Config.iLegacyGameVolume, VOLUME_FULL, CfgFlag::PER_GAME | CfgFlag::DONT_SAVE), + ConfigSetting("ReverbVolume", &g_Config.iLegacyReverbVolume, VOLUME_FULL, CfgFlag::PER_GAME | CfgFlag::DONT_SAVE), ConfigSetting("GameVolume", &g_Config.iGameVolume, &DefaultGameVolume, CfgFlag::PER_GAME), - ConfigSetting("ReverbVolume", &g_Config.iReverbVolume, VOLUME_FULL, CfgFlag::PER_GAME), + ConfigSetting("ReverbRelativeVolume", &g_Config.iReverbVolume, &DefaultReverbVolume, CfgFlag::PER_GAME), ConfigSetting("AltSpeedRelativeVolume", &g_Config.iAltSpeedVolume, VOLUMEHI_FULL, CfgFlag::PER_GAME), ConfigSetting("AchievementSoundVolume", &g_Config.iAchievementSoundVolume, 6, CfgFlag::PER_GAME), ConfigSetting("UIVolume", &g_Config.iUIVolume, 70, CfgFlag::DEFAULT), diff --git a/Core/Config.h b/Core/Config.h index a82c6f8e48..2f9465511f 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -280,14 +280,15 @@ public: bool bEnableSound; int iAudioBackend; - // Volume settings, 0-10 + // Legacy volume settings, 0-10. These get auto-upgraded and should not be used. int iLegacyGameVolume; - int iReverbVolume; + int iLegacyReverbVolume; int iAltSpeedVolume; int iAchievementSoundVolume; // Newer volume settings, 0-100 int iGameVolume; + int iReverbVolume; int iUIVolume; bool bExtraAudioBuffering; // For bluetooth diff --git a/Core/HW/SasAudio.cpp b/Core/HW/SasAudio.cpp index 81b9132b8f..081469c1ef 100644 --- a/Core/HW/SasAudio.cpp +++ b/Core/HW/SasAudio.cpp @@ -729,7 +729,7 @@ void SasInstance::ApplyWaveformEffect() { } // Volume max is 0x1000, while our factor is up to 0x8000. Shifting left by 3 fixes that. - reverb_.ProcessReverb(sendBufferProcessed, sendBufferDownsampled, grainSize / 2, waveformEffect.leftVol << 3, waveformEffect.rightVol << 3); + reverb_.ProcessReverb(sendBufferProcessed, sendBufferDownsampled, grainSize / 2, (uint16_t)(waveformEffect.leftVol << 3), (uint16_t)(waveformEffect.rightVol << 3)); } void SasInstance::DoState(PointerWrap &p) { diff --git a/Core/HW/SasReverb.cpp b/Core/HW/SasReverb.cpp index c67de0abdd..090cb5667b 100644 --- a/Core/HW/SasReverb.cpp +++ b/Core/HW/SasReverb.cpp @@ -207,7 +207,7 @@ private: int size_; }; -void SasReverb::ProcessReverb(int16_t *output, const int16_t *input, size_t inputSize, uint16_t volLeft, uint16_t volRight) { +void SasReverb::ProcessReverb(int16_t *output, const int16_t *input, size_t inputSize, int volLeft, int volRight) { // This means replicate the input signal in the processed buffer. // Can also be used to verify that the error is in here... if (preset_ == -1) { @@ -221,13 +221,15 @@ void SasReverb::ProcessReverb(int16_t *output, const int16_t *input, size_t inpu return; } - const uint8_t reverbVolume = Clamp(g_Config.iReverbVolume, 0, 25); + const float reverbVolumeMultiplier = Volume100ToMultiplier(g_Config.iReverbVolume); // Standard volume is 10, which pairs with a normal shift of 15. - const uint8_t finalShift = 25 - reverbVolume; - if (reverbVolume == 0) { + if (reverbVolumeMultiplier <= 0.0f) { // Force to zero output, which is not the same as "Off." memset(output, 0, inputSize * 4); return; + } else { + volLeft *= reverbVolumeMultiplier; + volRight *= reverbVolumeMultiplier; } const SasReverbData &d = presets[preset_]; @@ -266,8 +268,8 @@ void SasReverb::ProcessReverb(int16_t *output, const int16_t *input, size_t inpu b[d.mRAPF2] = clamp_s16(Rout - (d.vAPF2*b[(d.mRAPF2 - d.dAPF2)] >> 15)); Rout = b[(d.mRAPF2 - d.dAPF2)] + (b[d.mRAPF2] * d.vAPF2 >> 15); // ___Output to Mixer(Output volume multiplied with input from APF2)___________ - output[i * 4 + 0] = clamp_s16((Lout * volLeft) >> finalShift); - output[i * 4 + 1] = clamp_s16((Rout * volRight) >> finalShift); + output[i * 4 + 0] = clamp_s16((Lout * volLeft) >> 15); + output[i * 4 + 1] = clamp_s16((Rout * volRight) >> 15); output[i * 4 + 2] = 0; output[i * 4 + 3] = 0; diff --git a/Core/HW/SasReverb.h b/Core/HW/SasReverb.h index da0fd5f7f9..f34074940b 100644 --- a/Core/HW/SasReverb.h +++ b/Core/HW/SasReverb.h @@ -31,7 +31,7 @@ public: // Input should be a mixdown of all the channels that have reverb enabled, at 22khz. // Output is written back at 44khz. - void ProcessReverb(int16_t *output, const int16_t *input, size_t inputSize, uint16_t volLeft, uint16_t volRight); + void ProcessReverb(int16_t *output, const int16_t *input, size_t inputSize, int volLeft, int volRight); private: enum { @@ -41,4 +41,4 @@ private: int16_t *workspace_; int preset_; int pos_; -}; \ No newline at end of file +}; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 8f941b11af..0999ba8630 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -660,7 +660,7 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) { volume->SetEnabledPtr(&g_Config.bEnableSound); volume->SetZeroLabel(a->T("Mute")); - PopupSliderChoice *reverbVolume = audioSettings->Add(new PopupSliderChoice(&g_Config.iReverbVolume, VOLUME_OFF, 2 * VOLUME_FULL, VOLUME_FULL, a->T("Reverb volume"), screenManager())); + PopupSliderChoice *reverbVolume = audioSettings->Add(new PopupSliderChoice(&g_Config.iReverbVolume, VOLUME_OFF, 2 * VOLUMEHI_FULL, VOLUMEHI_FULL, a->T("Reverb volume"), screenManager())); reverbVolume->SetEnabledPtr(&g_Config.bEnableSound); reverbVolume->SetZeroLabel(a->T("Disabled")); From aad3aa02e77be0394a23b5dce0ce7c244be91ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 12 Feb 2025 10:23:26 -0600 Subject: [PATCH 4/5] Upgrade the achievement sound volume setting to the new format --- Core/Config.cpp | 12 ++++++++++-- Core/Config.h | 5 +++-- UI/BackgroundAudio.cpp | 4 ++-- UI/EmuScreen.cpp | 2 +- UI/GameSettingsScreen.cpp | 4 +++- UI/RetroAchievementScreens.cpp | 9 +++++---- headless/Headless.cpp | 2 +- 7 files changed, 25 insertions(+), 13 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index bc605badc5..5a4a520c01 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -758,6 +758,12 @@ static int DefaultReverbVolume() { return LegacyVolumeToNewVolume(g_Config.iLegacyReverbVolume, 200); } +static int DefaultAchievementVolume() { + // NOTE: The old achievemnt volume was a straight percentage so it doesn't convert + // the same as the others. + return MultiplierToVolume100((float)g_Config.iLegacyAchievementVolume / 10.0f); +} + static const ConfigSetting soundSettings[] = { ConfigSetting("Enable", &g_Config.bEnableSound, true, CfgFlag::PER_GAME), ConfigSetting("AudioBackend", &g_Config.iAudioBackend, 0, CfgFlag::PER_GAME), @@ -767,12 +773,14 @@ static const ConfigSetting soundSettings[] = { // The default settings here are still relevant, they will get propagated into the new ones. ConfigSetting("GlobalVolume", &g_Config.iLegacyGameVolume, VOLUME_FULL, CfgFlag::PER_GAME | CfgFlag::DONT_SAVE), ConfigSetting("ReverbVolume", &g_Config.iLegacyReverbVolume, VOLUME_FULL, CfgFlag::PER_GAME | CfgFlag::DONT_SAVE), + ConfigSetting("AchievementSoundVolume", &g_Config.iLegacyAchievementVolume, 6, CfgFlag::PER_GAME | CfgFlag::DONT_SAVE), + // Current volume settings. ConfigSetting("GameVolume", &g_Config.iGameVolume, &DefaultGameVolume, CfgFlag::PER_GAME), ConfigSetting("ReverbRelativeVolume", &g_Config.iReverbVolume, &DefaultReverbVolume, CfgFlag::PER_GAME), ConfigSetting("AltSpeedRelativeVolume", &g_Config.iAltSpeedVolume, VOLUMEHI_FULL, CfgFlag::PER_GAME), - ConfigSetting("AchievementSoundVolume", &g_Config.iAchievementSoundVolume, 6, CfgFlag::PER_GAME), - ConfigSetting("UIVolume", &g_Config.iUIVolume, 70, CfgFlag::DEFAULT), + ConfigSetting("AchievementVolume", &g_Config.iAchievementVolume, &DefaultAchievementVolume, CfgFlag::PER_GAME), + ConfigSetting("UIVolume", &g_Config.iUIVolume, 75, CfgFlag::DEFAULT), ConfigSetting("AudioDevice", &g_Config.sAudioDevice, "", CfgFlag::DEFAULT), ConfigSetting("AutoAudioDevice", &g_Config.bAutoAudioDevice, true, CfgFlag::DEFAULT), diff --git a/Core/Config.h b/Core/Config.h index 2f9465511f..706fcce91b 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -283,13 +283,14 @@ public: // Legacy volume settings, 0-10. These get auto-upgraded and should not be used. int iLegacyGameVolume; int iLegacyReverbVolume; - int iAltSpeedVolume; - int iAchievementSoundVolume; + int iLegacyAchievementVolume; // Newer volume settings, 0-100 int iGameVolume; int iReverbVolume; int iUIVolume; + int iAchievementVolume; + int iAltSpeedVolume; bool bExtraAudioBuffering; // For bluetooth std::string sAudioDevice; diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 8dc33b8797..a4adcc444f 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -534,9 +534,9 @@ void SoundEffectMixer::Mix(int16_t *buffer, int sz, int sampleRateHz) { } } -void SoundEffectMixer::Play(UI::UISound sfx, float volume) { +void SoundEffectMixer::Play(UI::UISound sfx, float multiplier) { std::lock_guard guard(mutex_); - queue_.push_back(PlayInstance{ sfx, 0, (int)(255.0f * volume), false }); + queue_.push_back(PlayInstance{ sfx, 0, (int)(255.0f * multiplier), false }); } void SoundEffectMixer::UpdateSample(UI::UISound sound, Sample *sample) { diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index b2d409e898..befe5a13a2 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -630,7 +630,7 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) { } } else if (message == UIMessage::REQUEST_PLAY_SOUND) { if (g_Config.bAchievementsSoundEffects && g_Config.bEnableSound) { - float achievementVolume = Volume10ToMultiplier(g_Config.iAchievementSoundVolume) * Volume100ToMultiplier(g_Config.iGameVolume); + float achievementVolume = Volume100ToMultiplier(g_Config.iAchievementVolume) * Volume100ToMultiplier(g_Config.iGameVolume); // TODO: Handle this some nicer way. if (!strcmp(value, "achievement_unlocked")) { g_BackgroundAudio.SFX().Play(UI::UISound::ACHIEVEMENT_UNLOCKED, achievementVolume); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 0999ba8630..7c8c02a6b9 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -661,6 +661,7 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) { volume->SetZeroLabel(a->T("Mute")); PopupSliderChoice *reverbVolume = audioSettings->Add(new PopupSliderChoice(&g_Config.iReverbVolume, VOLUME_OFF, 2 * VOLUMEHI_FULL, VOLUMEHI_FULL, a->T("Reverb volume"), screenManager())); + reverbVolume->SetFormat("%d%%"); reverbVolume->SetEnabledPtr(&g_Config.bEnableSound); reverbVolume->SetZeroLabel(a->T("Disabled")); @@ -669,7 +670,8 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) { altVolume->SetEnabledPtr(&g_Config.bEnableSound); altVolume->SetZeroLabel(a->T("Mute")); - PopupSliderChoice *achievementVolume = audioSettings->Add(new PopupSliderChoice(&g_Config.iAchievementSoundVolume, VOLUME_OFF, VOLUME_FULL, VOLUME_FULL, ac->T("Achievement sound volume"), screenManager())); + PopupSliderChoice *achievementVolume = audioSettings->Add(new PopupSliderChoice(&g_Config.iAchievementVolume, VOLUME_OFF, VOLUMEHI_FULL, MultiplierToVolume100(0.6f), ac->T("Achievement sound volume"), screenManager())); + achievementVolume->SetFormat("%d%%"); achievementVolume->SetEnabledPtr(&g_Config.bEnableSound); achievementVolume->SetZeroLabel(a->T("Mute")); diff --git a/UI/RetroAchievementScreens.cpp b/UI/RetroAchievementScreens.cpp index ac740185cb..0017211a37 100644 --- a/UI/RetroAchievementScreens.cpp +++ b/UI/RetroAchievementScreens.cpp @@ -36,7 +36,7 @@ AudioFileChooser::AudioFileChooser(RequesterToken token, std::string *value, std layoutParams_->height = ITEM_HEIGHT; } Add(new Choice(ImageID("I_PLAY"), new LinearLayoutParams(ITEM_HEIGHT, ITEM_HEIGHT)))->OnClick.Add([=](UI::EventParams &) { - float achievementVolume = g_Config.iAchievementSoundVolume * 0.1f; + float achievementVolume = Volume100ToMultiplier(g_Config.iAchievementVolume); g_BackgroundAudio.SFX().Play(sound_, achievementVolume); return UI::EVENT_DONE; }); @@ -363,9 +363,10 @@ void RetroAchievementsSettingsScreen::CreateCustomizeTab(UI::ViewGroup *viewGrou viewGroup->Add(new AudioFileChooser(GetRequesterToken(), &g_Config.sAchievementsUnlockAudioFile, ac->T("Achievement unlocked"), UISound::ACHIEVEMENT_UNLOCKED)); viewGroup->Add(new AudioFileChooser(GetRequesterToken(), &g_Config.sAchievementsLeaderboardSubmitAudioFile, ac->T("Leaderboard score submission"), UISound::LEADERBOARD_SUBMITTED)); } - PopupSliderChoice *volume = viewGroup->Add(new PopupSliderChoice(&g_Config.iAchievementSoundVolume, VOLUME_OFF, VOLUME_FULL, VOLUME_FULL, ac->T("Achievement sound volume"), screenManager())); - volume->SetEnabledPtr(&g_Config.bEnableSound); - volume->SetZeroLabel(a->T("Mute")); + PopupSliderChoice *achievementVolume = viewGroup->Add(new PopupSliderChoice(&g_Config.iAchievementVolume, VOLUME_OFF, VOLUMEHI_FULL, MultiplierToVolume100(0.6f), ac->T("Achievement sound volume"), screenManager())); + achievementVolume->SetFormat("%d%%"); + achievementVolume->SetEnabledPtr(&g_Config.bEnableSound); + achievementVolume->SetZeroLabel(a->T("Mute")); static const char *positions[] = { "None", "Bottom Left", "Bottom Center", "Bottom Right", "Top Left", "Top Center", "Top Right", "Center Left", "Center Right" }; diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 59bc9c8772..53f41c6516 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -528,7 +528,7 @@ int main(int argc, const char* argv[]) g_Config.iFirmwareVersion = PSP_DEFAULT_FIRMWARE; g_Config.iPSPModel = PSP_MODEL_SLIM; g_Config.iGameVolume = VOLUMEHI_FULL; - g_Config.iReverbVolume = VOLUME_FULL; + g_Config.iReverbVolume = VOLUMEHI_FULL; g_Config.internalDataDirectory.clear(); g_Config.bUseExperimentalAtrac = newAtrac; From fcaf3daea96f14de49a29de072a8fe292be18aa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 12 Feb 2025 10:28:35 -0600 Subject: [PATCH 5/5] Minor fixes, make the achievement volume independent again --- UI/EmuScreen.cpp | 2 +- UI/GameSettingsScreen.cpp | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index befe5a13a2..5b9163ed95 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -630,7 +630,7 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) { } } else if (message == UIMessage::REQUEST_PLAY_SOUND) { if (g_Config.bAchievementsSoundEffects && g_Config.bEnableSound) { - float achievementVolume = Volume100ToMultiplier(g_Config.iAchievementVolume) * Volume100ToMultiplier(g_Config.iGameVolume); + float achievementVolume = Volume100ToMultiplier(g_Config.iAchievementVolume); // TODO: Handle this some nicer way. if (!strcmp(value, "achievement_unlocked")) { g_BackgroundAudio.SFX().Play(UI::UISound::ACHIEVEMENT_UNLOCKED, achievementVolume); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 7c8c02a6b9..8c276f141c 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -58,6 +58,7 @@ #include "UI/RetroAchievementScreens.h" #include "UI/OnScreenDisplay.h" #include "UI/DiscordIntegration.h" +#include "UI/BackgroundAudio.h" #include "Common/File/FileUtil.h" #include "Common/File/AndroidContentURI.h" @@ -657,6 +658,7 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) { CheckBox *enableSound = audioSettings->Add(new CheckBox(&g_Config.bEnableSound, a->T("Enable Sound"))); PopupSliderChoice *volume = audioSettings->Add(new PopupSliderChoice(&g_Config.iGameVolume, VOLUME_OFF, VOLUMEHI_FULL, VOLUMEHI_FULL, a->T("Game volume"), screenManager())); + volume->SetFormat("%d%%"); volume->SetEnabledPtr(&g_Config.bEnableSound); volume->SetZeroLabel(a->T("Mute")); @@ -674,6 +676,13 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) { achievementVolume->SetFormat("%d%%"); achievementVolume->SetEnabledPtr(&g_Config.bEnableSound); achievementVolume->SetZeroLabel(a->T("Mute")); + achievementVolume->SetLiveUpdate(true); + achievementVolume->OnChange.Add([](UI::EventParams &e) { + // Audio preview + float achievementVolume = Volume100ToMultiplier(g_Config.iAchievementVolume); + g_BackgroundAudio.SFX().Play(UI::UISound::ACHIEVEMENT_UNLOCKED, achievementVolume); + return UI::EVENT_DONE; + }); audioSettings->Add(new ItemHeader(a->T("UI sound"))); @@ -693,8 +702,7 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) { #if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP) if (IsVistaOrHigher()) { static const char *backend[] = { "Auto", "DSound (compatible)", "WASAPI (fast)" }; - PopupMultiChoice *audioBackend = audioSettings->Add(new PopupMultiChoice(&g_Config.iAudioBackend, a->T("Audio backend", "Audio backend (restart req.)"), backend, 0, ARRAY_SIZE(backend), I18NCat::AUDIO, screenManager())); - audioBackend->SetEnabledPtr(&g_Config.bEnableSound); + audioSettings->Add(new PopupMultiChoice(&g_Config.iAudioBackend, a->T("Audio backend", "Audio backend (restart req.)"), backend, 0, ARRAY_SIZE(backend), I18NCat::AUDIO, screenManager())); } #endif @@ -714,7 +722,6 @@ void GameSettingsScreen::CreateAudioSettings(UI::ViewGroup *audioSettings) { #if PPSSPP_PLATFORM(ANDROID) CheckBox *extraAudio = audioSettings->Add(new CheckBox(&g_Config.bExtraAudioBuffering, a->T("AudioBufferingForBluetooth", "Bluetooth-friendly buffer (slower)"))); - extraAudio->SetEnabledPtr(&g_Config.bEnableSound); // Show OpenSL debug info const std::string audioErrorStr = AndroidAudio_GetErrorString(g_audioState);