mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-01-31 01:15:17 +01:00
Merge pull request #14307 from Sam-Belliveau/granular-audio-stretching
Add an option to preserve audio pitch when emulation speed changes
This commit is contained in:
@@ -31,6 +31,7 @@ enum class BooleanSetting(
|
||||
false
|
||||
),
|
||||
MAIN_AUDIO_FILL_GAPS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AudioFillGaps", true),
|
||||
MAIN_AUDIO_PRESERVE_PITCH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AudioPreservePitch", false),
|
||||
MAIN_BBA_XLINK_CHAT_OSD(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
|
||||
@@ -556,6 +556,14 @@ class SettingsFragmentPresenter(
|
||||
R.string.audio_fill_gaps_description
|
||||
)
|
||||
)
|
||||
sl.add(
|
||||
SwitchSetting(
|
||||
context,
|
||||
BooleanSetting.MAIN_AUDIO_PRESERVE_PITCH,
|
||||
R.string.audio_preserve_pitch,
|
||||
R.string.audio_preserve_pitch_description
|
||||
)
|
||||
)
|
||||
sl.add(
|
||||
IntSliderSetting(
|
||||
context,
|
||||
|
||||
@@ -188,6 +188,8 @@
|
||||
<string name="audio_buffer_size_description">Controls the number of audio samples buffered. Lower values reduce latency but may cause more crackling or stuttering. If unsure, set this to 80 ms.</string>
|
||||
<string name="audio_fill_gaps">Fill Audio Gaps</string>
|
||||
<string name="audio_fill_gaps_description">Repeat existing audio during lag spikes to prevent stuttering. If unsure, leave this checked.</string>
|
||||
<string name="audio_preserve_pitch">Preserve Audio Pitch</string>
|
||||
<string name="audio_preserve_pitch_description">Keeps audio at normal pitch when changing emulation speed. Without this, audio pitch changes proportionally with speed. If unsure, leave this unchecked.</string>
|
||||
<string name="audio_volume">Audio Volume</string>
|
||||
|
||||
<!-- Path Settings -->
|
||||
|
||||
@@ -71,7 +71,7 @@ void Mixer::MixerFifo::Mix(s16* samples, std::size_t num_samples)
|
||||
static_cast<double>(FIXED_SAMPLE_RATE_DIVIDEND) / m_input_sample_rate_divisor;
|
||||
|
||||
const double emulation_speed = m_mixer->m_config_emulation_speed;
|
||||
if (0 < emulation_speed && emulation_speed != 1.0)
|
||||
if (!m_mixer->m_config_audio_preserve_pitch && 0 < emulation_speed && emulation_speed != 1.0)
|
||||
in_sample_rate *= emulation_speed;
|
||||
|
||||
const double base = static_cast<double>(1 << GRANULE_FRAC_BITS);
|
||||
@@ -430,6 +430,7 @@ void Mixer::StopLogDSPAudio()
|
||||
void Mixer::RefreshConfig()
|
||||
{
|
||||
m_config_emulation_speed = Config::Get(Config::MAIN_EMULATION_SPEED);
|
||||
m_config_audio_preserve_pitch = Config::Get(Config::MAIN_AUDIO_PRESERVE_PITCH);
|
||||
m_config_fill_audio_gaps = Config::Get(Config::MAIN_AUDIO_FILL_GAPS);
|
||||
m_config_audio_buffer_ms = Config::Get(Config::MAIN_AUDIO_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
@@ -163,6 +163,7 @@ private:
|
||||
bool m_log_dsp_audio = false;
|
||||
|
||||
float m_config_emulation_speed;
|
||||
bool m_config_audio_preserve_pitch;
|
||||
bool m_config_fill_audio_gaps;
|
||||
int m_config_audio_buffer_ms;
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ const Info<AudioCommon::DPL2Quality> MAIN_DPL2_QUALITY{{System::Main, "Core", "D
|
||||
const Info<int> MAIN_AUDIO_LATENCY{{System::Main, "Core", "AudioLatency"}, 20};
|
||||
const Info<int> MAIN_AUDIO_BUFFER_SIZE{{System::Main, "Core", "AudioBufferSize"}, 80};
|
||||
const Info<bool> MAIN_AUDIO_FILL_GAPS{{System::Main, "Core", "AudioFillGaps"}, true};
|
||||
const Info<bool> MAIN_AUDIO_PRESERVE_PITCH{{System::Main, "Core", "AudioPreservePitch"}, false};
|
||||
const Info<std::string> MAIN_MEMCARD_A_PATH{{System::Main, "Core", "MemcardAPath"}, ""};
|
||||
const Info<std::string> MAIN_MEMCARD_B_PATH{{System::Main, "Core", "MemcardBPath"}, ""};
|
||||
const Info<std::string>& GetInfoForMemcardPath(ExpansionInterface::Slot slot)
|
||||
|
||||
@@ -79,6 +79,7 @@ extern const Info<AudioCommon::DPL2Quality> MAIN_DPL2_QUALITY;
|
||||
extern const Info<int> MAIN_AUDIO_LATENCY;
|
||||
extern const Info<int> MAIN_AUDIO_BUFFER_SIZE;
|
||||
extern const Info<bool> MAIN_AUDIO_FILL_GAPS;
|
||||
extern const Info<bool> MAIN_AUDIO_PRESERVE_PITCH;
|
||||
extern const Info<std::string> MAIN_MEMCARD_A_PATH;
|
||||
extern const Info<std::string> MAIN_MEMCARD_B_PATH;
|
||||
const Info<std::string>& GetInfoForMemcardPath(ExpansionInterface::Slot slot);
|
||||
|
||||
@@ -181,6 +181,9 @@ void AudioPane::CreateWidgets()
|
||||
|
||||
m_audio_fill_gaps = new ConfigBool(tr("Fill Audio Gaps"), Config::MAIN_AUDIO_FILL_GAPS);
|
||||
|
||||
m_audio_preserve_pitch =
|
||||
new ConfigBool(tr("Preserve Audio Pitch"), Config::MAIN_AUDIO_PRESERVE_PITCH);
|
||||
|
||||
m_speed_up_mute_enable = new ConfigBool(tr("Mute When Disabling Speed Limit"),
|
||||
Config::MAIN_AUDIO_MUTE_ON_DISABLED_SPEED_LIMIT);
|
||||
|
||||
@@ -192,8 +195,9 @@ void AudioPane::CreateWidgets()
|
||||
|
||||
playback_layout->addLayout(buffer_layout, 0, 0);
|
||||
playback_layout->addWidget(m_audio_fill_gaps, 1, 0);
|
||||
playback_layout->addWidget(m_speed_up_mute_enable, 2, 0);
|
||||
playback_layout->setRowStretch(3, 1);
|
||||
playback_layout->addWidget(m_audio_preserve_pitch, 2, 0);
|
||||
playback_layout->addWidget(m_speed_up_mute_enable, 3, 0);
|
||||
playback_layout->setRowStretch(4, 1);
|
||||
playback_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
|
||||
auto* const main_vbox_layout = new QVBoxLayout;
|
||||
@@ -317,6 +321,10 @@ void AudioPane::AddDescriptions()
|
||||
static const char TR_FILL_AUDIO_GAPS_DESCRIPTION[] = QT_TR_NOOP(
|
||||
"Repeat existing audio during lag spikes to prevent stuttering.<br><br><dolphin_emphasis>If "
|
||||
"unsure, leave this checked.</dolphin_emphasis>");
|
||||
static const char TR_PRESERVE_AUDIO_PITCH_DESCRIPTION[] = QT_TR_NOOP(
|
||||
"Keeps audio at normal pitch when changing emulation speed. Without this, audio pitch "
|
||||
"changes proportionally with speed.<br><br><dolphin_emphasis>If unsure, leave this "
|
||||
"unchecked.</dolphin_emphasis>");
|
||||
static const char TR_SPEED_UP_MUTE_DESCRIPTION[] =
|
||||
QT_TR_NOOP("Mutes the audio when overriding the emulation speed limit (default hotkey: Tab). "
|
||||
"<br><br><dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");
|
||||
@@ -357,4 +365,7 @@ void AudioPane::AddDescriptions()
|
||||
|
||||
m_audio_fill_gaps->SetTitle(tr("Fill Audio Gaps"));
|
||||
m_audio_fill_gaps->SetDescription(tr(TR_FILL_AUDIO_GAPS_DESCRIPTION));
|
||||
|
||||
m_audio_preserve_pitch->SetTitle(tr("Preserve Audio Pitch"));
|
||||
m_audio_preserve_pitch->SetDescription(tr(TR_PRESERVE_AUDIO_PITCH_DESCRIPTION));
|
||||
}
|
||||
|
||||
@@ -66,5 +66,6 @@ private:
|
||||
|
||||
// Misc Settings
|
||||
ConfigBool* m_audio_fill_gaps;
|
||||
ConfigBool* m_audio_preserve_pitch;
|
||||
ConfigBool* m_speed_up_mute_enable;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user