Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Volume control UI changes, part 1 #19969

Merged
merged 5 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Common/System/System.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ void System_AudioClear();
// These samples really have 16 bits of value, but can be a little out of range.
// This is for pushing rate-controlled 44khz audio from emulation.
// If you push a little too fast, we'll pitch up to a limit, for example.
// Volume is a 12-bit multiplier.
void System_AudioPushSamples(const int32_t *audio, int numSamples, int volume);
// Volume is a unit-range multiplier.
void System_AudioPushSamples(const int32_t *audio, int numSamples, float volume);

inline void System_AudioResetStatCounters() {
return System_AudioGetDebugStats(nullptr, 0);
Expand Down
9 changes: 8 additions & 1 deletion Common/UI/PopupScreens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ void PopupSliderChoiceFloat::SetFormat(std::string_view fmt) {
EventReturn PopupSliderChoice::HandleClick(EventParams &e) {
restoreFocus_ = HasFocus();

SliderPopupScreen *popupScreen = new SliderPopupScreen(value_, minValue_, maxValue_, defaultValue_, ChopTitle(text_), step_, units_);
SliderPopupScreen *popupScreen = new SliderPopupScreen(value_, minValue_, maxValue_, defaultValue_, ChopTitle(text_), step_, units_, liveUpdate_);
if (!negativeLabel_.empty())
popupScreen->SetNegativeDisable(negativeLabel_);
popupScreen->OnChange.Handle(this, &PopupSliderChoice::HandleChange);
Expand Down Expand Up @@ -346,6 +346,13 @@ void SliderPopupScreen::UpdateTextBox() {
char temp[128];
snprintf(temp, sizeof(temp), "%d", sliderValue_);
edit_->SetText(temp);
if (liveUpdate_ && *value_ != sliderValue_) {
*value_ = sliderValue_;
EventParams e{};
e.v = nullptr;
e.a = *value_;
OnChange.Trigger(e);
}
}

void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
Expand Down
9 changes: 7 additions & 2 deletions Common/UI/PopupScreens.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ class MessagePopupScreen : public PopupScreen {

class SliderPopupScreen : public PopupScreen {
public:
SliderPopupScreen(int *value, int minValue, int maxValue, int defaultValue, std::string_view title, int step = 1, std::string_view units = "")
: PopupScreen(title, "OK", "Cancel"), units_(units), value_(value), minValue_(minValue), maxValue_(maxValue), defaultValue_(defaultValue), step_(step) {}
SliderPopupScreen(int *value, int minValue, int maxValue, int defaultValue, std::string_view title, int step, std::string_view units, bool liveUpdate)
: PopupScreen(title, "OK", "Cancel"), units_(units), value_(value), minValue_(minValue), maxValue_(maxValue), defaultValue_(defaultValue), step_(step), liveUpdate_(liveUpdate) {}
void CreatePopupContents(ViewGroup *parent) override;

void SetNegativeDisable(const std::string &str) {
Expand Down Expand Up @@ -110,6 +110,7 @@ class SliderPopupScreen : public PopupScreen {
int maxValue_;
int defaultValue_;
int step_;
bool liveUpdate_;
bool changing_ = false;
bool disabled_ = false;
};
Expand Down Expand Up @@ -303,6 +304,9 @@ class PopupSliderChoice : public AbstractChoiceWithValueDisplay {
void SetZeroLabel(std::string_view str) {
zeroLabel_ = str;
}
void SetLiveUpdate(bool update) {
liveUpdate_ = update;
}
void SetNegativeDisable(std::string_view str) {
negativeLabel_ = str;
}
Expand All @@ -327,6 +331,7 @@ class PopupSliderChoice : public AbstractChoiceWithValueDisplay {
std::string units_;
ScreenManager *screenManager_;
bool restoreFocus_ = false;
bool liveUpdate_ = false;
};

class PopupSliderChoiceFloat : public AbstractChoiceWithValueDisplay {
Expand Down
15 changes: 5 additions & 10 deletions Common/UI/Root.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ static View *focusedView;
static bool focusMovementEnabled;
bool focusForced;

static std::function<void(UISound, float)> soundCallback;
static bool soundEnabled = true;
static std::function<void(UISound)> soundCallback;

struct DispatchQueueItem {
Event *e;
Expand Down Expand Up @@ -126,17 +125,13 @@ static void MoveFocus(ViewGroup *root, FocusDirection direction) {
}
}

void SetSoundEnabled(bool enabled) {
soundEnabled = enabled;
}

void SetSoundCallback(std::function<void(UISound, float)> func) {
void SetSoundCallback(std::function<void(UISound)> func) {
soundCallback = func;
}

void PlayUISound(UISound sound, float volume) {
if (soundEnabled && soundCallback) {
soundCallback(sound, volume);
void PlayUISound(UISound sound) {
if (soundCallback) {
soundCallback(sound);
}
}

Expand Down
5 changes: 2 additions & 3 deletions Common/UI/Root.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,10 @@ enum class UISound {
COUNT,
};

void SetSoundEnabled(bool enabled);
void SetSoundCallback(std::function<void(UISound, float)> func);
void SetSoundCallback(std::function<void(UISound)> func);

// This is only meant for actual UI navigation sound, not achievements.
// Call directly into the player for other UI effects.
void PlayUISound(UISound sound, float volume = 0.25f);
void PlayUISound(UISound sound);

} // namespace UI
23 changes: 14 additions & 9 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -749,10 +749,13 @@ 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.iGlobalVolume, VOLUME_FULL, CfgFlag::PER_GAME),

ConfigSetting("GlobalVolume", &g_Config.iGameVolume, VOLUME_FULL, CfgFlag::PER_GAME),
ConfigSetting("ReverbVolume", &g_Config.iReverbVolume, VOLUME_FULL, CfgFlag::PER_GAME),
ConfigSetting("AltSpeedVolume", &g_Config.iAltSpeedVolume, -1, 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("AudioDevice", &g_Config.sAudioDevice, "", CfgFlag::DEFAULT),
ConfigSetting("AutoAudioDevice", &g_Config.bAutoAudioDevice, true, CfgFlag::DEFAULT),
ConfigSetting("AudioMixWithOthers", &g_Config.bAudioMixWithOthers, true, CfgFlag::DEFAULT),
Expand Down Expand Up @@ -1293,12 +1296,14 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
vPostShaderNames.push_back(it.second);
}

// Check for an old dpad setting
Section *control = iniFile.GetOrCreateSection("Control");
float f;
control->Get("DPadRadius", &f, 0.0f);
if (f > 0.0f) {
ResetControlLayout();
// Check for an old dpad setting (very obsolete)
Section *control = iniFile.GetSection("Control");
if (control) {
float f;
control->Get("DPadRadius", &f, 0.0f);
if (f > 0.0f) {
ResetControlLayout();
}
}

// Force JIT setting to a valid value for the current system configuration.
Expand Down Expand Up @@ -1485,7 +1490,7 @@ void Config::PostLoadCleanup(bool gameSpecific) {

// Automatically silence secondary instances. Could be an option I guess, but meh.
if (PPSSPP_ID > 1) {
g_Config.iGlobalVolume = 0;
g_Config.iGameVolume = 0;
}

// Automatically switch away from deprecated setting value.
Expand Down
8 changes: 7 additions & 1 deletion Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,16 @@ struct Config {
// Sound
bool bEnableSound;
int iAudioBackend;
int iGlobalVolume;

// Volume settings, 0-10
int iGameVolume;
int iReverbVolume;
int iAltSpeedVolume;
int iAchievementSoundVolume;

// Newer volume settings, 0-100
int iUIVolume;

bool bExtraAudioBuffering; // For bluetooth
std::string sAudioDevice;
bool bAutoAudioDevice;
Expand Down
17 changes: 17 additions & 0 deletions Core/ConfigValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#pragma once

#include <cstdint>
#include <cmath>
#include <string>
#ifndef _MSC_VER
#include <strings.h>
Expand All @@ -30,6 +31,22 @@ constexpr int PSP_MODEL_SLIM = 1;
constexpr int PSP_DEFAULT_FIRMWARE = 660;
constexpr int VOLUME_OFF = 0;
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));
}

// 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);
}

struct ConfigTouchPos {
float x;
Expand Down
16 changes: 4 additions & 12 deletions Core/HLE/__sceAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,23 +414,15 @@ void __AudioUpdate(bool resetRecording) {
}

if (g_Config.bEnableSound) {
int vol = g_Config.iGlobalVolume;
float multiplier = Volume10ToMultiplier(std::clamp(g_Config.iGameVolume, 0, VOLUME_FULL));
if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL || PSP_CoreParameter().fastForward) {
if (g_Config.iAltSpeedVolume != -1) {
vol = g_Config.iAltSpeedVolume;
// Multiply in the alt speed volume instead of replacing like before.
multiplier *= Volume100ToMultiplier(g_Config.iAltSpeedVolume);
}
}

vol = std::clamp(vol, 0, VOLUME_FULL);

// 12-bit volume. So far this isn't any better than the shift, but stay tuned.
int volume;
if (vol != 0) {
volume = 4096 >> (VOLUME_FULL - vol);
} else {
volume = 0;
}
System_AudioPushSamples(mixBuffer, hwBlockSize, volume);
System_AudioPushSamples(mixBuffer, hwBlockSize, multiplier);

#ifndef MOBILE_DEVICE
if (g_Config.bSaveLoadResetsAVdumping && resetRecording) {
Expand Down
5 changes: 4 additions & 1 deletion Core/HW/StereoResampler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ unsigned int StereoResampler::Mix(short* samples, unsigned int numSamples, bool
}

// Executes on the emulator thread, pushing sound into the buffer.
void StereoResampler::PushSamples(const s32 *samples, unsigned int numSamples, int volume) {
void StereoResampler::PushSamples(const s32 *samples, unsigned int numSamples, float multiplier) {
inputSampleCount_ += numSamples;

UpdateBufferSize();
Expand All @@ -274,6 +274,9 @@ void StereoResampler::PushSamples(const s32 *samples, unsigned int numSamples, i
return;
}

// 12-bit volume.
int volume = (int)(multiplier * 4096.0f);

// Check if we need to roll over to the start of the buffer during the copy.
unsigned int indexW_left_samples = m_maxBufsize * 2 - (indexW & INDEX_MASK);
if (numSamples * 2 > indexW_left_samples) {
Expand Down
4 changes: 2 additions & 2 deletions Core/HW/StereoResampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ class StereoResampler {

// Called from main thread
// This clamps the samples to 16-bit before starting to work on them.
// Volume is a 12-bit fixed point multiplier.
void PushSamples(const s32* samples, unsigned int num_samples, int volume);
// Volume is a multiplier from 0.0f to 1.0f.
void PushSamples(const s32* samples, unsigned int num_samples, float volume);

void Clear();

Expand Down
20 changes: 10 additions & 10 deletions Tools/langtool/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions UI/AudioCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ StereoResampler g_resampler;

// numFrames is number of stereo frames.
// This is called from *outside* the emulator thread.
int __AudioMix(int16_t *outStereo, int numFrames, int sampleRateHz) {
int NativeMix(int16_t *outStereo, int numFrames, int sampleRateHz) {
int validFrames = g_resampler.Mix(outStereo, numFrames, false, sampleRateHz);

// Mix sound effects on top.
Expand All @@ -28,7 +28,7 @@ void System_AudioClear() {
g_resampler.Clear();
}

void System_AudioPushSamples(const int32_t *audio, int numSamples, int volume) {
void System_AudioPushSamples(const int32_t *audio, int numSamples, float volume) {
if (audio) {
g_resampler.PushSamples(audio, numSamples, volume);
} else {
Expand Down
2 changes: 0 additions & 2 deletions UI/AudioCommon.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#pragma once

#include <cstdint>

int __AudioMix(int16_t *outstereo, int numFrames, int sampleRate);
Loading
Loading