mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
SPU2: Fix interface for output muting
This commit is contained in:
parent
b02318e2b6
commit
38cfa9912d
@ -879,38 +879,6 @@ void EmuThread::endCapture()
|
||||
MTGS::RunOnGSThread(&GSEndCapture);
|
||||
}
|
||||
|
||||
void EmuThread::setAudioOutputVolume(int volume, int fast_forward_volume)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "setAudioOutputVolume", Qt::QueuedConnection, Q_ARG(int, volume),
|
||||
Q_ARG(int, fast_forward_volume));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
EmuConfig.SPU2.OutputVolume = static_cast<u32>(volume);
|
||||
EmuConfig.SPU2.FastForwardVolume = static_cast<u32>(fast_forward_volume);
|
||||
SPU2::SetOutputVolume(SPU2::GetResetVolume());
|
||||
}
|
||||
|
||||
void EmuThread::setAudioOutputMuted(bool muted)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "setAudioOutputMuted", Qt::QueuedConnection, Q_ARG(bool, muted));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
EmuConfig.SPU2.OutputMuted = muted;
|
||||
SPU2::SetOutputVolume(SPU2::GetResetVolume());
|
||||
}
|
||||
|
||||
std::optional<WindowInfo> EmuThread::acquireRenderWindow(bool recreate_window)
|
||||
{
|
||||
// Check if we're wanting to get exclusive fullscreen. This should be safe to read, since we're going to be calling from the GS thread.
|
||||
|
||||
@ -112,8 +112,6 @@ public Q_SLOTS:
|
||||
void queueSnapshot(quint32 gsdump_frames);
|
||||
void beginCapture(const QString& path);
|
||||
void endCapture();
|
||||
void setAudioOutputVolume(int volume, int fast_forward_volume);
|
||||
void setAudioOutputMuted(bool muted);
|
||||
|
||||
Q_SIGNALS:
|
||||
bool messageConfirmed(const QString& title, const QString& message);
|
||||
|
||||
@ -40,28 +40,58 @@ static void HotkeyAdjustTargetSpeed(double delta)
|
||||
Host::OSD_QUICK_DURATION);
|
||||
}
|
||||
|
||||
static void HotkeyAdjustVolume(s32 fixed, s32 delta)
|
||||
static void HotkeyAdjustVolume(const s32 delta)
|
||||
{
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
const s32 current_vol = static_cast<s32>(SPU2::GetOutputVolume());
|
||||
const s32 new_volume =
|
||||
std::clamp((fixed >= 0) ? fixed : (current_vol + delta), 0, static_cast<s32>(Pcsx2Config::SPU2Options::MAX_VOLUME));
|
||||
if (current_vol != new_volume)
|
||||
// Volume-adjusting hotkeys override mute toggle hotkey. EmuConfig.SPU2.OutputMuted overrides hotkeys.
|
||||
if (!SPU2::SetOutputMuted(false))
|
||||
{
|
||||
Host::AddIconOSDMessage("VolumeChanged", ICON_FA_VOLUME_XMARK, TRANSLATE_STR("Hotkeys", "Volume: Muted in Settings"));
|
||||
return;
|
||||
}
|
||||
|
||||
const s32 current_volume = static_cast<s32>(SPU2::GetOutputVolume());
|
||||
const s32 maximum_volume = static_cast<s32>(Pcsx2Config::SPU2Options::MAX_VOLUME);
|
||||
const s32 new_volume = std::clamp(current_volume + delta, 0, maximum_volume);
|
||||
|
||||
if (current_volume != new_volume)
|
||||
SPU2::SetOutputVolume(static_cast<u32>(new_volume));
|
||||
|
||||
if (new_volume == 0)
|
||||
if (new_volume > 0 && new_volume < maximum_volume)
|
||||
{
|
||||
Host::AddIconOSDMessage("VolumeChanged", ICON_FA_VOLUME_XMARK, TRANSLATE_STR("Hotkeys", "Volume: Muted"));
|
||||
Host::AddIconOSDMessage("VolumeChanged", new_volume < 100 ? ICON_FA_VOLUME_LOW : ICON_FA_VOLUME_HIGH,
|
||||
fmt::format(TRANSLATE_FS("Hotkeys", "Volume: {} to {}%"), delta < 0 ? TRANSLATE_STR("Hotkeys", "Decreased") : TRANSLATE_STR("Hotkeys", "Increased"), new_volume));
|
||||
}
|
||||
else
|
||||
{
|
||||
Host::AddIconOSDMessage("VolumeChanged", (current_vol < new_volume) ? ICON_FA_VOLUME_HIGH : ICON_FA_VOLUME_LOW,
|
||||
fmt::format(TRANSLATE_FS("Hotkeys", "Volume: {}%"), new_volume));
|
||||
Host::AddIconOSDMessage("VolumeChanged", delta < 0 ? ICON_FA_VOLUME_OFF : ICON_FA_VOLUME_HIGH,
|
||||
fmt::format(TRANSLATE_FS("Hotkeys", "Volume: {} {}% Reached"), delta < 0 ? TRANSLATE_STR("Hotkeys", "Minimum") : TRANSLATE_STR("Hotkeys", "Maximum"), new_volume));
|
||||
}
|
||||
}
|
||||
|
||||
static void HotkeyToggleMute()
|
||||
{
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
// Attempt to toggle output muting. EmuConfig.SPU2.OutputMuted overrides hotkeys.
|
||||
if (SPU2::SetOutputMuted(!SPU2::IsOutputMuted()))
|
||||
{
|
||||
if (SPU2::IsOutputMuted())
|
||||
Host::AddIconOSDMessage("VolumeChanged", ICON_FA_VOLUME_XMARK, TRANSLATE_STR("Hotkeys", "Volume: Muted"));
|
||||
else
|
||||
{
|
||||
const u32 current_volume = SPU2::GetOutputVolume();
|
||||
Host::AddIconOSDMessage("VolumeChanged", current_volume < 100 ? (current_volume == 0 ? ICON_FA_VOLUME_OFF : ICON_FA_VOLUME_LOW) : ICON_FA_VOLUME_HIGH,
|
||||
fmt::format(TRANSLATE_FS("Hotkeys", "Volume: Unmuted to {}%"), current_volume));
|
||||
}
|
||||
}
|
||||
else
|
||||
Host::AddIconOSDMessage("VolumeChanged", ICON_FA_VOLUME_XMARK, TRANSLATE_STR("Hotkeys", "Volume: Muted in Settings"));
|
||||
}
|
||||
|
||||
static void HotkeyLoadStateSlot(s32 slot)
|
||||
{
|
||||
// Can reapply settings and thus binds, therefore must be deferred.
|
||||
@ -293,16 +323,16 @@ DEFINE_HOTKEY_LOADSTATE_X(10, TRANSLATE_NOOP("Hotkeys", "Load State From Slot 10
|
||||
#undef DEFINE_HOTKEY_LOADSTATE_X
|
||||
DEFINE_HOTKEY("Mute", TRANSLATE_NOOP("Hotkeys", "Audio"), TRANSLATE_NOOP("Hotkeys", "Toggle Mute"), [](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
HotkeyAdjustVolume((SPU2::GetOutputVolume() == 0) ? SPU2::GetResetVolume() : 0, 0);
|
||||
HotkeyToggleMute();
|
||||
})
|
||||
DEFINE_HOTKEY("IncreaseVolume", TRANSLATE_NOOP("Hotkeys", "Audio"), TRANSLATE_NOOP("Hotkeys", "Increase Volume"),
|
||||
[](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
HotkeyAdjustVolume(-1, 5);
|
||||
HotkeyAdjustVolume(5);
|
||||
})
|
||||
DEFINE_HOTKEY("DecreaseVolume", TRANSLATE_NOOP("Hotkeys", "Audio"), TRANSLATE_NOOP("Hotkeys", "Decrease Volume"),
|
||||
[](s32 pressed) {
|
||||
if (!pressed && VMManager::HasValidVM())
|
||||
HotkeyAdjustVolume(-1, -5);
|
||||
HotkeyAdjustVolume(-5);
|
||||
})
|
||||
END_HOTKEY_LIST()
|
||||
|
||||
@ -28,10 +28,13 @@ u32 lClocks = 0;
|
||||
|
||||
static bool s_audio_capture_active = false;
|
||||
static bool s_psxmode = false;
|
||||
static bool s_output_muted = false;
|
||||
|
||||
static std::unique_ptr<AudioStream> s_output_stream;
|
||||
static std::array<s16, AudioStream::CHUNK_SIZE * 2> s_current_chunk;
|
||||
static u32 s_current_chunk_pos;
|
||||
static u32 s_standard_volume = 0;
|
||||
static u32 s_fast_forward_volume = 0;
|
||||
|
||||
u32 SPU2::GetConsoleSampleRate()
|
||||
{
|
||||
@ -97,8 +100,17 @@ void SPU2writeDMA7Mem(u16* pMem, u32 size)
|
||||
|
||||
void SPU2::CreateOutputStream()
|
||||
{
|
||||
// Persist volume through stream recreates.
|
||||
const u32 volume = s_output_stream ? s_output_stream->GetOutputVolume() : GetResetVolume();
|
||||
// Initialize volume and mute settings on new session.
|
||||
if (!s_output_stream)
|
||||
{
|
||||
s_standard_volume = EmuConfig.SPU2.OutputVolume;
|
||||
s_fast_forward_volume = EmuConfig.SPU2.FastForwardVolume;
|
||||
s_output_muted = EmuConfig.SPU2.OutputMuted;
|
||||
}
|
||||
// Else persist volume through stream recreates.
|
||||
else if (!s_output_muted)
|
||||
SPU2::SaveOutputVolume();
|
||||
|
||||
const u32 sample_rate = GetConsoleSampleRate();
|
||||
s_output_stream.reset();
|
||||
|
||||
@ -114,7 +126,7 @@ void SPU2::CreateOutputStream()
|
||||
s_output_stream = AudioStream::CreateNullStream(sample_rate, EmuConfig.SPU2.StreamParameters.buffer_ms);
|
||||
}
|
||||
|
||||
s_output_stream->SetOutputVolume(volume);
|
||||
SPU2::UpdateOutputVolume();
|
||||
s_output_stream->SetNominalRate(GetNominalRate());
|
||||
s_output_stream->SetPaused(VMManager::GetState() == VMState::Paused);
|
||||
}
|
||||
@ -144,20 +156,52 @@ void SPU2::SetOutputVolume(u32 volume)
|
||||
s_output_stream->SetOutputVolume(volume);
|
||||
}
|
||||
|
||||
u32 SPU2::GetResetVolume()
|
||||
{
|
||||
return EmuConfig.SPU2.OutputMuted ? 0 :
|
||||
((VMManager::GetTargetSpeed() != 1.0f) ?
|
||||
EmuConfig.SPU2.FastForwardVolume :
|
||||
EmuConfig.SPU2.OutputVolume);
|
||||
}
|
||||
|
||||
float SPU2::GetNominalRate()
|
||||
{
|
||||
// Adjust nominal rate when syncing to host.
|
||||
return VMManager::IsTargetSpeedAdjustedToHost() ? VMManager::GetTargetSpeed() : 1.0f;
|
||||
}
|
||||
|
||||
bool SPU2::SetOutputMuted(const bool muted)
|
||||
{
|
||||
// User setting takes precedence. Unmute not guaranteed by design.
|
||||
if (!s_output_stream || (!muted && EmuConfig.SPU2.OutputMuted))
|
||||
return false;
|
||||
|
||||
if (muted == s_output_muted)
|
||||
return true;
|
||||
|
||||
if (muted)
|
||||
SPU2::SaveOutputVolume();
|
||||
|
||||
s_output_muted = muted;
|
||||
SPU2::UpdateOutputVolume();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SPU2::IsOutputMuted()
|
||||
{
|
||||
return s_output_muted;
|
||||
}
|
||||
|
||||
void SPU2::UpdateOutputVolume()
|
||||
{
|
||||
s_output_stream->SetOutputVolume(s_output_muted ?
|
||||
0 : (VMManager::GetTargetSpeed() == 1.0f ?
|
||||
s_standard_volume : s_fast_forward_volume));
|
||||
}
|
||||
|
||||
void SPU2::SaveOutputVolume()
|
||||
{
|
||||
if (!s_output_muted)
|
||||
{
|
||||
if (VMManager::GetTargetSpeed() == 1.0f)
|
||||
s_standard_volume = s_output_stream->GetOutputVolume();
|
||||
else
|
||||
s_fast_forward_volume = s_output_stream->GetOutputVolume();
|
||||
}
|
||||
}
|
||||
|
||||
void SPU2::SetOutputPaused(bool paused)
|
||||
{
|
||||
s_output_stream->SetPaused(paused);
|
||||
@ -210,8 +254,20 @@ void SPU2::OnTargetSpeedChanged()
|
||||
|
||||
s_output_stream->SetNominalRate(GetNominalRate());
|
||||
|
||||
if (EmuConfig.SPU2.OutputVolume != EmuConfig.SPU2.FastForwardVolume && !EmuConfig.SPU2.OutputMuted)
|
||||
s_output_stream->SetOutputVolume(GetResetVolume());
|
||||
// Flipped save as speed has already changed.
|
||||
if (!s_output_muted)
|
||||
{
|
||||
if (VMManager::GetTargetSpeed() == 1.0f)
|
||||
{
|
||||
s_fast_forward_volume = s_output_stream->GetOutputVolume();
|
||||
s_output_stream->SetOutputVolume(s_standard_volume);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_standard_volume = s_output_stream->GetOutputVolume();
|
||||
s_output_stream->SetOutputVolume(s_fast_forward_volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SPU2::Open()
|
||||
@ -265,13 +321,25 @@ void SPU2::CheckForConfigChanges(const Pcsx2Config& old_config)
|
||||
const Pcsx2Config::SPU2Options& oldopts = old_config.SPU2;
|
||||
|
||||
// No need to reinit for volume change.
|
||||
if ((opts.OutputVolume != oldopts.OutputVolume && VMManager::GetTargetSpeed() == 1.0f) ||
|
||||
(opts.FastForwardVolume != oldopts.FastForwardVolume && VMManager::GetTargetSpeed() != 1.0f) ||
|
||||
opts.OutputMuted != oldopts.OutputMuted)
|
||||
if (opts.OutputMuted != oldopts.OutputMuted)
|
||||
SPU2::SetOutputMuted(opts.OutputMuted);
|
||||
|
||||
bool volume_settings_changed = false;
|
||||
if (opts.OutputVolume != oldopts.OutputVolume)
|
||||
{
|
||||
SetOutputVolume(GetResetVolume());
|
||||
s_standard_volume = opts.OutputVolume;
|
||||
volume_settings_changed = true;
|
||||
}
|
||||
|
||||
if (opts.FastForwardVolume != oldopts.FastForwardVolume)
|
||||
{
|
||||
s_fast_forward_volume = opts.FastForwardVolume;
|
||||
volume_settings_changed = true;
|
||||
}
|
||||
|
||||
if (volume_settings_changed)
|
||||
SPU2::UpdateOutputVolume();
|
||||
|
||||
// Things which require re-initialzing the output.
|
||||
if (opts.Backend != oldopts.Backend ||
|
||||
opts.StreamParameters != oldopts.StreamParameters ||
|
||||
|
||||
@ -36,8 +36,17 @@ u32 GetOutputVolume();
|
||||
/// Directly updates the output volume without going through the configuration.
|
||||
void SetOutputVolume(u32 volume);
|
||||
|
||||
/// Returns the volume that we would reset the output to on startup.
|
||||
u32 GetResetVolume();
|
||||
/// Sets up muting and unmuting and reports success or failure.
|
||||
bool SetOutputMuted(const bool muted);
|
||||
|
||||
/// Returns true if the output is muted (distinct from 0%).
|
||||
bool IsOutputMuted();
|
||||
|
||||
/// Updates the current volume based on running state.
|
||||
void UpdateOutputVolume();
|
||||
|
||||
/// Saves the current volume based on running state.
|
||||
void SaveOutputVolume();
|
||||
|
||||
/// Pauses/resumes the output stream.
|
||||
void SetOutputPaused(bool paused);
|
||||
@ -74,4 +83,3 @@ extern u32 lClocks;
|
||||
extern void TimeUpdate(u32 cClocks);
|
||||
extern void SPU2_FastWrite(u32 rmem, u16 value);
|
||||
|
||||
//#define PCM24_S1_INTERLEAVE
|
||||
|
||||
Loading…
Reference in New Issue
Block a user