Skip to content

Commit

Permalink
Remove the Audio Resampling setting (now always on). Having it off is…
Browse files Browse the repository at this point in the history
… not useful because it'll never sync up perfectly over time.
  • Loading branch information
hrydgard committed May 17, 2020
1 parent 0692b6d commit 90fd2d9
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 70 deletions.
1 change: 0 additions & 1 deletion Core/Config.cpp
Expand Up @@ -786,7 +786,6 @@ static ConfigSetting soundSettings[] = {
ConfigSetting("Enable", &g_Config.bEnableSound, true, true, true),
ConfigSetting("AudioBackend", &g_Config.iAudioBackend, 0, true, true),
ConfigSetting("ExtraAudioBuffering", &g_Config.bExtraAudioBuffering, false, true, false),
ConfigSetting("AudioResampler", &g_Config.bAudioResampler, true, true, true),
ConfigSetting("GlobalVolume", &g_Config.iGlobalVolume, VOLUME_MAX, true, true),
ConfigSetting("AltSpeedVolume", &g_Config.iAltSpeedVolume, -1, true, true),
ConfigSetting("AudioDevice", &g_Config.sAudioDevice, "", true, false),
Expand Down
1 change: 0 additions & 1 deletion Core/Config.h
Expand Up @@ -261,7 +261,6 @@ struct Config {
bool bShowDebugStats;
bool bShowAudioDebug;
bool bShowGpuProfile;
bool bAudioResampler;

//Analog stick tilting
//the base x and y tilt. this inclination is treated as (0,0) and the tilt input
Expand Down
110 changes: 46 additions & 64 deletions Core/HW/StereoResampler.cpp
Expand Up @@ -181,72 +181,54 @@ unsigned int StereoResampler::Mix(short* samples, unsigned int numSamples, bool
const int INDEX_MASK = (m_maxBufsize * 2 - 1);
lastBufSize_ = (indexR - m_indexW) & INDEX_MASK;

// We force on the audio resampler if the output sample rate doesn't match the input.
if (!g_Config.bAudioResampler && sample_rate == (int)m_input_sample_rate) {
for (currentSample = 0; currentSample < numSamples * 2; currentSample += 2) {
s16 l1 = m_buffer[indexR & INDEX_MASK]; //current
s16 r1 = m_buffer[(indexR + 1) & INDEX_MASK]; //current
samples[currentSample] = l1;
samples[currentSample + 1] = r1;
if (((indexW - indexR) & INDEX_MASK) <= 2) {
// Ran out!
underrunCount_++;
break;
}
indexR += 2;
// Drift prevention mechanism.
float numLeft = (float)(((indexW - indexR) & INDEX_MASK) / 2);
// If we had to discard samples the last frame due to underrun,
// apply an adjustment here. Otherwise we'll overestimate how many
// samples we need.
numLeft -= droppedSamples_;
droppedSamples_ = 0;

// m_numLeftI here becomes a lowpass filtered version of numLeft.
m_numLeftI = (numLeft + m_numLeftI * (CONTROL_AVG - 1.0f)) / CONTROL_AVG;

// Here we try to keep the buffer size around m_lowwatermark (which is
// really now more like desired_buffer_size) by adjusting the speed.
// Note that the speed of adjustment here does not take the buffer size into
// account. Since this is called once per "output frame", the frame size
// will affect how fast this algorithm reacts, which can't be a good thing.
float offset = (m_numLeftI - (float)m_targetBufsize) * CONTROL_FACTOR;
if (offset > MAX_FREQ_SHIFT) offset = MAX_FREQ_SHIFT;
if (offset < -MAX_FREQ_SHIFT) offset = -MAX_FREQ_SHIFT;

output_sample_rate_ = (float)(m_input_sample_rate + offset);
const u32 ratio = (u32)(65536.0 * output_sample_rate_ / (double)sample_rate);
ratio_ = ratio;
// TODO: consider a higher-quality resampling algorithm.
// TODO: Add a fast path for 1:1.
u32 frac = m_frac;
for (currentSample = 0; currentSample < numSamples * 2; currentSample += 2) {
if (((indexW - indexR) & INDEX_MASK) <= 2) {
// Ran out!
// int missing = numSamples * 2 - currentSample;
// ILOG("Resampler underrun: %d (numSamples: %d, currentSample: %d)", missing, numSamples, currentSample / 2);
underrunCount_++;
break;
}
output_sample_rate_ = (float)sample_rate;
droppedSamples_ = 0;
} else {
// Drift prevention mechanism.
float numLeft = (float)(((indexW - indexR) & INDEX_MASK) / 2);
// If we had to discard samples the last frame due to underrun,
// apply an adjustment here. Otherwise we'll overestimate how many
// samples we need.
numLeft -= droppedSamples_;
droppedSamples_ = 0;

// m_numLeftI here becomes a lowpass filtered version of numLeft.
m_numLeftI = (numLeft + m_numLeftI * (CONTROL_AVG - 1.0f)) / CONTROL_AVG;

// Here we try to keep the buffer size around m_lowwatermark (which is
// really now more like desired_buffer_size) by adjusting the speed.
// Note that the speed of adjustment here does not take the buffer size into
// account. Since this is called once per "output frame", the frame size
// will affect how fast this algorithm reacts, which can't be a good thing.
float offset = (m_numLeftI - (float)m_targetBufsize) * CONTROL_FACTOR;
if (offset > MAX_FREQ_SHIFT) offset = MAX_FREQ_SHIFT;
if (offset < -MAX_FREQ_SHIFT) offset = -MAX_FREQ_SHIFT;

output_sample_rate_ = (float)(m_input_sample_rate + offset);
const u32 ratio = (u32)(65536.0 * output_sample_rate_ / (double)sample_rate);
ratio_ = ratio;
// TODO: consider a higher-quality resampling algorithm.
// TODO: Add a fast path for 1:1.
u32 frac = m_frac;
for (currentSample = 0; currentSample < numSamples * 2; currentSample += 2) {
if (((indexW - indexR) & INDEX_MASK) <= 2) {
// Ran out!
// int missing = numSamples * 2 - currentSample;
// ILOG("Resampler underrun: %d (numSamples: %d, currentSample: %d)", missing, numSamples, currentSample / 2);
underrunCount_++;
break;
}
u32 indexR2 = indexR + 2; //next sample
s16 l1 = m_buffer[indexR & INDEX_MASK]; //current
s16 r1 = m_buffer[(indexR + 1) & INDEX_MASK]; //current
s16 l2 = m_buffer[indexR2 & INDEX_MASK]; //next
s16 r2 = m_buffer[(indexR2 + 1) & INDEX_MASK]; //next
int sampleL = ((l1 << 16) + (l2 - l1) * (u16)frac) >> 16;
int sampleR = ((r1 << 16) + (r2 - r1) * (u16)frac) >> 16;
samples[currentSample] = sampleL;
samples[currentSample + 1] = sampleR;
frac += ratio;
indexR += 2 * (frac >> 16);
frac &= 0xffff;
}
m_frac = frac;
u32 indexR2 = indexR + 2; //next sample
s16 l1 = m_buffer[indexR & INDEX_MASK]; //current
s16 r1 = m_buffer[(indexR + 1) & INDEX_MASK]; //current
s16 l2 = m_buffer[indexR2 & INDEX_MASK]; //next
s16 r2 = m_buffer[(indexR2 + 1) & INDEX_MASK]; //next
int sampleL = ((l1 << 16) + (l2 - l1) * (u16)frac) >> 16;
int sampleR = ((r1 << 16) + (r2 - r1) * (u16)frac) >> 16;
samples[currentSample] = sampleL;
samples[currentSample + 1] = sampleR;
frac += ratio;
indexR += 2 * (frac >> 16);
frac &= 0xffff;
}
m_frac = frac;

// Let's not count the underrun padding here.
outputSampleCount_ += currentSample / 2;
Expand Down
4 changes: 0 additions & 4 deletions UI/GameSettingsScreen.cpp
Expand Up @@ -548,10 +548,6 @@ void GameSettingsScreen::CreateViews() {
CheckBox *extraAudio = audioSettings->Add(new CheckBox(&g_Config.bExtraAudioBuffering, a->T("AudioBufferingForBluetooth", "Bluetooth-friendly buffer (slower)")));
extraAudio->SetEnabledPtr(&g_Config.bEnableSound);
#endif
if (System_GetPropertyInt(SYSPROP_AUDIO_SAMPLE_RATE) == 44100) {
CheckBox *resampling = audioSettings->Add(new CheckBox(&g_Config.bAudioResampler, a->T("Audio sync", "Audio sync (resampling)")));
resampling->SetEnabledPtr(&g_Config.bEnableSound);
}

// Control
ViewGroup *controlsSettingsScroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
Expand Down

0 comments on commit 90fd2d9

Please sign in to comment.