Reset audio buffer when you finish fast-forwarding
Fixes excessive audio being buffered and audio going sharp after fast-forwarding.
This commit is contained in:
parent
0472960f1a
commit
dde6a616ca
|
@ -14,6 +14,7 @@
|
|||
#include "Common/Swap.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "VideoCommon/PerformanceMetrics.h"
|
||||
|
||||
static u32 DPL2QualityToFrameBlockSize(AudioCommon::DPL2Quality quality)
|
||||
|
@ -60,10 +61,8 @@ void Mixer::DoState(PointerWrap& p)
|
|||
// Executed from sound stream thread
|
||||
unsigned int Mixer::MixerFifo::Mix(short* samples, unsigned int numSamples,
|
||||
bool consider_framelimit, float emulationspeed,
|
||||
int timing_variance)
|
||||
bool should_resync, int timing_variance)
|
||||
{
|
||||
unsigned int currentSample = 0;
|
||||
|
||||
// Cache access in non-volatile variable
|
||||
// This is the only function changing the read value, so it's safe to
|
||||
// cache it locally although it's written here.
|
||||
|
@ -88,6 +87,15 @@ unsigned int Mixer::MixerFifo::Mix(short* samples, unsigned int numSamples,
|
|||
(static_cast<u64>(m_input_sample_rate_divisor) * 1000);
|
||||
low_watermark = std::min(low_watermark, MAX_SAMPLES / 2);
|
||||
|
||||
// When the writer exits fast-forward, throw away extra audio beyond low_watermark.
|
||||
if (should_resync && numLeft > low_watermark)
|
||||
{
|
||||
numLeft = m_numLeftI = low_watermark;
|
||||
indexR = (indexW - 2 * low_watermark) & INDEX_MASK;
|
||||
// Verify that numLeft is correct (using its initial formula).
|
||||
ASSERT(numLeft == static_cast<float>(((indexW - indexR) & INDEX_MASK) / 2));
|
||||
}
|
||||
|
||||
m_numLeftI = (numLeft + m_numLeftI * (CONTROL_AVG - 1)) / CONTROL_AVG;
|
||||
float offset = (m_numLeftI - low_watermark) * CONTROL_FACTOR;
|
||||
if (offset > MAX_FREQ_SHIFT)
|
||||
|
@ -107,6 +115,7 @@ unsigned int Mixer::MixerFifo::Mix(short* samples, unsigned int numSamples,
|
|||
return m_little_endian ? m_buffer[index] : Common::swap16(m_buffer[index]);
|
||||
};
|
||||
|
||||
unsigned int currentSample = 0;
|
||||
// TODO: consider a higher-quality resampling algorithm.
|
||||
for (; currentSample < numSamples * 2 && ((indexW - indexR) & INDEX_MASK) > 2; currentSample += 2)
|
||||
{
|
||||
|
@ -178,17 +187,17 @@ unsigned int Mixer::Mix(short* samples, unsigned int num_samples)
|
|||
|
||||
m_scratch_buffer.fill(0);
|
||||
|
||||
m_dma_mixer.Mix(m_scratch_buffer.data(), available_samples, false, emulation_speed,
|
||||
m_dma_mixer.Mix(m_scratch_buffer.data(), available_samples, false, emulation_speed, false,
|
||||
timing_variance);
|
||||
m_streaming_mixer.Mix(m_scratch_buffer.data(), available_samples, false, emulation_speed,
|
||||
m_streaming_mixer.Mix(m_scratch_buffer.data(), available_samples, false, emulation_speed, false,
|
||||
timing_variance);
|
||||
m_wiimote_speaker_mixer.Mix(m_scratch_buffer.data(), available_samples, false, emulation_speed,
|
||||
timing_variance);
|
||||
false, timing_variance);
|
||||
m_skylander_portal_mixer.Mix(m_scratch_buffer.data(), available_samples, false, emulation_speed,
|
||||
timing_variance);
|
||||
false, timing_variance);
|
||||
for (auto& mixer : m_gba_mixers)
|
||||
{
|
||||
mixer.Mix(m_scratch_buffer.data(), available_samples, false, emulation_speed,
|
||||
mixer.Mix(m_scratch_buffer.data(), available_samples, false, emulation_speed, false,
|
||||
timing_variance);
|
||||
}
|
||||
|
||||
|
@ -202,12 +211,24 @@ unsigned int Mixer::Mix(short* samples, unsigned int num_samples)
|
|||
}
|
||||
else
|
||||
{
|
||||
m_dma_mixer.Mix(samples, num_samples, true, emulation_speed, timing_variance);
|
||||
m_streaming_mixer.Mix(samples, num_samples, true, emulation_speed, timing_variance);
|
||||
m_wiimote_speaker_mixer.Mix(samples, num_samples, true, emulation_speed, timing_variance);
|
||||
m_skylander_portal_mixer.Mix(samples, num_samples, true, emulation_speed, timing_variance);
|
||||
const bool is_fast_forwarding = Core::GetIsThrottlerTempDisabled();
|
||||
const bool should_resync = m_was_fast_forwarding && !is_fast_forwarding;
|
||||
m_was_fast_forwarding = is_fast_forwarding;
|
||||
|
||||
if (should_resync)
|
||||
{
|
||||
INFO_LOG_FMT(AUDIO, "Resyncing after fast forward");
|
||||
}
|
||||
|
||||
m_dma_mixer.Mix(samples, num_samples, true, emulation_speed, should_resync, timing_variance);
|
||||
m_streaming_mixer.Mix(samples, num_samples, true, emulation_speed, should_resync,
|
||||
timing_variance);
|
||||
m_wiimote_speaker_mixer.Mix(samples, num_samples, true, emulation_speed, should_resync,
|
||||
timing_variance);
|
||||
m_skylander_portal_mixer.Mix(samples, num_samples, true, emulation_speed, should_resync,
|
||||
timing_variance);
|
||||
for (auto& mixer : m_gba_mixers)
|
||||
mixer.Mix(samples, num_samples, true, emulation_speed, timing_variance);
|
||||
mixer.Mix(samples, num_samples, true, emulation_speed, should_resync, timing_variance);
|
||||
m_is_stretching = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ private:
|
|||
void DoState(PointerWrap& p);
|
||||
void PushSamples(const short* samples, unsigned int num_samples);
|
||||
unsigned int Mix(short* samples, unsigned int numSamples, bool consider_framelimit,
|
||||
float emulationspeed, int timing_variance);
|
||||
float emulationspeed, bool should_resync, int timing_variance);
|
||||
void SetInputSampleRateDivisor(unsigned int rate_divisor);
|
||||
unsigned int GetInputSampleRateDivisor() const;
|
||||
void SetVolume(unsigned int lvolume, unsigned int rvolume);
|
||||
|
@ -119,6 +119,7 @@ private:
|
|||
float m_config_emulation_speed;
|
||||
int m_config_timing_variance;
|
||||
bool m_config_audio_stretch;
|
||||
bool m_was_fast_forwarding = false;
|
||||
|
||||
size_t m_config_changed_callback_id;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue