@@ -76,17 +76,33 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* settings_dialog, QWidge
7676 m_ui.standardVolume ->setValue (dialog ()->getEffectiveIntValue (" SPU2/Output" , " StandardVolume" , 100 ));
7777 m_ui.fastForwardVolume ->setValue (dialog ()->getEffectiveIntValue (" SPU2/Output" , " FastForwardVolume" , 100 ));
7878 m_ui.muted ->setChecked (dialog ()->getEffectiveBoolValue (" SPU2/Output" , " OutputMuted" , false ));
79+ m_ui.syncVolume ->setChecked (dialog ()->getEffectiveBoolValue (" SPU2/Output" , " SyncVolume" , true ));
7980 connect (m_ui.standardVolume , &QSlider::valueChanged, this , &AudioSettingsWidget::onStandardVolumeChanged);
8081 connect (m_ui.fastForwardVolume , &QSlider::valueChanged, this , &AudioSettingsWidget::onFastForwardVolumeChanged);
8182 connect (m_ui.muted , &QCheckBox::checkStateChanged, this , &AudioSettingsWidget::onOutputMutedChanged);
83+ connect (m_ui.syncVolume , &QCheckBox::checkStateChanged, this , &AudioSettingsWidget::onVolumeSyncChanged);
8284 updateVolumeLabel ();
8385 }
8486 else
8587 {
8688 SettingWidgetBinder::BindWidgetAndLabelToIntSetting (sif, m_ui.standardVolume , m_ui.standardVolumeLabel , tr (" %" ), " SPU2/Output" , " StandardVolume" , 100 );
8789 SettingWidgetBinder::BindWidgetAndLabelToIntSetting (sif, m_ui.fastForwardVolume , m_ui.fastForwardVolumeLabel , tr (" %" ), " SPU2/Output" , " FastForwardVolume" , 100 );
8890 SettingWidgetBinder::BindWidgetToBoolSetting (sif, m_ui.muted , " SPU2/Output" , " OutputMuted" , false );
91+ SettingWidgetBinder::BindWidgetToBoolSetting (sif, m_ui.syncVolume , " SPU2/Output" , " SyncVolume" , true );
92+ connect (m_ui.standardVolume , &QSlider::valueChanged, this , [this ](const int new_value) {
93+ // only synchronize the standard and fast-forward volume is the sync volume checkboxed is ticked
94+ if (dialog ()->getEffectiveBoolValue (" SPU2/Output" , " SyncVolume" , true ))
95+ m_ui.fastForwardVolume ->setValue (new_value);
96+ });
97+ connect (m_ui.syncVolume , &QCheckBox::checkStateChanged, this , [this ]() {
98+ // re-sync the fast-forward volume when volume sync is enabled
99+ if (dialog ()->getEffectiveBoolValue (" SPU2/Output" , " SyncVolume" , true ))
100+ m_ui.fastForwardVolume ->setValue (m_ui.standardVolume ->value ());
101+
102+ updateVolumeSyncState ();
103+ });
89104 }
105+ updateVolumeSyncState ();
90106 connect (m_ui.resetStandardVolume , &QToolButton::clicked, this , [this ]() { resetVolume (false ); });
91107 connect (m_ui.resetFastForwardVolume , &QToolButton::clicked, this , [this ]() { resetVolume (true ); });
92108
@@ -109,6 +125,8 @@ AudioSettingsWidget::AudioSettingsWidget(SettingsWindow* settings_dialog, QWidge
109125 tr (" Controls the volume of the audio played on the host when fast forwarding." ));
110126 dialog ()->registerWidgetHelp (m_ui.muted , tr (" Mute All Sound" ), tr (" Unchecked" ),
111127 tr (" Prevents the emulator from producing any audible sound." ));
128+ dialog ()->registerWidgetHelp (m_ui.syncVolume , tr (" Sync Volume" ), tr (" Checked" ),
129+ tr (" Synchronizes the fast-forward volume of the audio to the standard volume." ));
112130 dialog ()->registerWidgetHelp (m_ui.expansionMode , tr (" Expansion Mode" ), tr (" Disabled (Stereo)" ),
113131 tr (" Determines how audio is expanded from stereo to surround for supported games. This "
114132 " includes games that support Dolby Pro Logic/Pro Logic II." ));
@@ -308,6 +326,15 @@ void AudioSettingsWidget::onStandardVolumeChanged(const int new_value)
308326 // only called for base settings
309327 pxAssert (!dialog ()->isPerGameSettings ());
310328 Host::SetBaseIntSettingValue (" SPU2/Output" , " StandardVolume" , new_value);
329+
330+ // only synchronize the standard and fast-forward volume is the sync volume checkboxed is ticked
331+ const bool syncVolume = dialog ()->getEffectiveBoolValue (" SPU2/Output" , " SyncVolume" , true );
332+ if (syncVolume) {
333+ QSignalBlocker sb (m_ui.fastForwardVolume );
334+ m_ui.fastForwardVolume ->setValue (new_value);
335+ Host::SetBaseIntSettingValue (" SPU2/Output" , " FastForwardVolume" , new_value);
336+ }
337+
311338 Host::CommitBaseSettingChanges ();
312339 g_emu_thread->applySettings ();
313340
@@ -336,6 +363,38 @@ void AudioSettingsWidget::onOutputMutedChanged(const int new_state)
336363 g_emu_thread->applySettings ();
337364}
338365
366+ void AudioSettingsWidget::onVolumeSyncChanged (const int new_state)
367+ {
368+ // only called for base settings
369+ pxAssert (!dialog ()->isPerGameSettings ());
370+
371+ const bool syncVolume = (new_state != 0 );
372+ Host::SetBaseBoolSettingValue (" SPU2/Output" , " SyncVolume" , syncVolume);
373+
374+ // re-sync the fast-forward volume when volume sync is enabled
375+ if (syncVolume)
376+ {
377+ const int standard_volume = m_ui.standardVolume ->value ();
378+ QSignalBlocker sb (m_ui.fastForwardVolume );
379+ m_ui.fastForwardVolume ->setValue (standard_volume);
380+ Host::SetBaseIntSettingValue (" SPU2/Output" , " FastForwardVolume" , standard_volume);
381+ updateVolumeLabel ();
382+ }
383+
384+ Host::CommitBaseSettingChanges ();
385+ updateVolumeSyncState ();
386+ g_emu_thread->applySettings ();
387+ }
388+
389+ void AudioSettingsWidget::updateVolumeSyncState ()
390+ {
391+ // disables the fast forward volume slider and reset button if volume synchronization is enabled
392+ // re-enables it when the synchronization is deactivated
393+ const bool syncVolume = dialog ()->getEffectiveBoolValue (" SPU2/Output" , " SyncVolume" , true );
394+ m_ui.fastForwardVolume ->setEnabled (!syncVolume);
395+ m_ui.resetFastForwardVolume ->setEnabled (!syncVolume);
396+ }
397+
339398void AudioSettingsWidget::onExpansionSettingsClicked ()
340399{
341400 QDialog dlg (QtUtils::GetRootWidget (this ));
@@ -484,7 +543,18 @@ void AudioSettingsWidget::resetVolume(const bool fast_forward)
484543 QSlider* const slider = fast_forward ? m_ui.fastForwardVolume : m_ui.standardVolume ;
485544 QLabel* const label = fast_forward ? m_ui.fastForwardVolumeLabel : m_ui.standardVolumeLabel ;
486545
487- if (dialog ()->isPerGameSettings ())
546+ const bool syncVolume = dialog ()->getEffectiveBoolValue (" SPU2/Output" , " SyncVolume" , true );
547+ const bool perGame = dialog ()->isPerGameSettings ();
548+
549+ resetVolumeAction (perGame, key, slider, label);
550+
551+ if (syncVolume && !fast_forward) {
552+ resetVolumeAction (perGame, " FastForwardVolume" , m_ui.fastForwardVolume , m_ui.fastForwardVolumeLabel );
553+ }
554+ }
555+
556+ void AudioSettingsWidget::resetVolumeAction (bool per_game, const char * key, QSlider* slider, QLabel* label) {
557+ if (per_game)
488558 {
489559 dialog ()->removeSettingValue (" SPU2/Output" , key);
490560
0 commit comments