Add audio stretching as a configuration option
This commit is contained in:
parent
b8c867dd7a
commit
26514358f4
|
@ -122,18 +122,26 @@ unsigned int CMixer::MixerFifo::Mix(short* samples, unsigned int numSamples,
|
||||||
return actual_sample_count;
|
return actual_sample_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CMixer::Mix(short* samples, unsigned int num_samples, bool consider_framelimit)
|
unsigned int CMixer::Mix(short* samples, unsigned int num_samples)
|
||||||
{
|
{
|
||||||
if (!samples)
|
if (!samples)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memset(samples, 0, num_samples * 2 * sizeof(short));
|
memset(samples, 0, num_samples * 2 * sizeof(short));
|
||||||
|
|
||||||
unsigned int actual_samples = m_dma_mixer.Mix(samples, num_samples, false);
|
const bool stretch = SConfig::GetInstance().m_audio_stretch;
|
||||||
m_streaming_mixer.Mix(samples, num_samples, false);
|
|
||||||
m_wiimote_speaker_mixer.Mix(samples, num_samples, false);
|
|
||||||
|
|
||||||
|
unsigned int actual_samples = m_dma_mixer.Mix(samples, num_samples, !stretch);
|
||||||
|
m_streaming_mixer.Mix(samples, num_samples, !stretch);
|
||||||
|
m_wiimote_speaker_mixer.Mix(samples, num_samples, !stretch);
|
||||||
|
|
||||||
|
if (stretch)
|
||||||
|
{
|
||||||
|
if (m_is_stretching != stretch)
|
||||||
|
m_sound_touch.clear();
|
||||||
StretchAudio(samples, actual_samples, num_samples);
|
StretchAudio(samples, actual_samples, num_samples);
|
||||||
|
}
|
||||||
|
m_is_stretching = stretch;
|
||||||
|
|
||||||
return num_samples;
|
return num_samples;
|
||||||
}
|
}
|
||||||
|
@ -145,9 +153,9 @@ void CMixer::StretchAudio(short* samples, unsigned int actual_samples, unsigned
|
||||||
// We were given actual_samples number of samples, and num_samples were requested from us.
|
// We were given actual_samples number of samples, and num_samples were requested from us.
|
||||||
double current_ratio = static_cast<double>(actual_samples) / static_cast<double>(num_samples);
|
double current_ratio = static_cast<double>(actual_samples) / static_cast<double>(num_samples);
|
||||||
|
|
||||||
constexpr double MAXIMUM_LATENCY = 0.080; // seconds
|
const double max_latency = SConfig::GetInstance().m_audio_stretch_max_latency;
|
||||||
const double max_backlog = m_sampleRate * MAXIMUM_LATENCY;
|
const double max_backlog = m_sampleRate * max_latency / 1000.0;
|
||||||
double backlog_fullness = m_sound_touch.numSamples() / max_backlog;
|
const double backlog_fullness = m_sound_touch.numSamples() / max_backlog;
|
||||||
if (backlog_fullness > 1.0)
|
if (backlog_fullness > 1.0)
|
||||||
{
|
{
|
||||||
// Exceeded latency budget: Do not add more samples into FIFO.
|
// Exceeded latency budget: Do not add more samples into FIFO.
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
~CMixer();
|
~CMixer();
|
||||||
|
|
||||||
// Called from audio threads
|
// Called from audio threads
|
||||||
unsigned int Mix(short* samples, unsigned int numSamples, bool consider_framelimit = true);
|
unsigned int Mix(short* samples, unsigned int numSamples);
|
||||||
|
|
||||||
// Called from main thread
|
// Called from main thread
|
||||||
void PushSamples(const short* samples, unsigned int num_samples);
|
void PushSamples(const short* samples, unsigned int num_samples);
|
||||||
|
|
|
@ -249,6 +249,8 @@ void SConfig::SaveCoreSettings(IniFile& ini)
|
||||||
core->Set("OverrideGCLang", bOverrideGCLanguage);
|
core->Set("OverrideGCLang", bOverrideGCLanguage);
|
||||||
core->Set("DPL2Decoder", bDPL2Decoder);
|
core->Set("DPL2Decoder", bDPL2Decoder);
|
||||||
core->Set("Latency", iLatency);
|
core->Set("Latency", iLatency);
|
||||||
|
core->Set("AudioStretch", m_audio_stretch);
|
||||||
|
core->Set("AudioStretchMaxLatency", m_audio_stretch_max_latency);
|
||||||
core->Set("MemcardAPath", m_strMemoryCardA);
|
core->Set("MemcardAPath", m_strMemoryCardA);
|
||||||
core->Set("MemcardBPath", m_strMemoryCardB);
|
core->Set("MemcardBPath", m_strMemoryCardB);
|
||||||
core->Set("AgpCartAPath", m_strGbaCartA);
|
core->Set("AgpCartAPath", m_strGbaCartA);
|
||||||
|
@ -567,6 +569,8 @@ void SConfig::LoadCoreSettings(IniFile& ini)
|
||||||
core->Get("OverrideGCLang", &bOverrideGCLanguage, false);
|
core->Get("OverrideGCLang", &bOverrideGCLanguage, false);
|
||||||
core->Get("DPL2Decoder", &bDPL2Decoder, false);
|
core->Get("DPL2Decoder", &bDPL2Decoder, false);
|
||||||
core->Get("Latency", &iLatency, 2);
|
core->Get("Latency", &iLatency, 2);
|
||||||
|
core->Get("AudioStretch", &m_audio_stretch, false);
|
||||||
|
core->Get("AudioStretchMaxLatency", &m_audio_stretch_max_latency, 80);
|
||||||
core->Get("MemcardAPath", &m_strMemoryCardA);
|
core->Get("MemcardAPath", &m_strMemoryCardA);
|
||||||
core->Get("MemcardBPath", &m_strMemoryCardB);
|
core->Get("MemcardBPath", &m_strMemoryCardB);
|
||||||
core->Get("AgpCartAPath", &m_strGbaCartA);
|
core->Get("AgpCartAPath", &m_strGbaCartA);
|
||||||
|
@ -827,6 +831,8 @@ void SConfig::LoadDefaults()
|
||||||
bWii = false;
|
bWii = false;
|
||||||
bDPL2Decoder = false;
|
bDPL2Decoder = false;
|
||||||
iLatency = 14;
|
iLatency = 14;
|
||||||
|
m_audio_stretch = false;
|
||||||
|
m_audio_stretch_max_latency = 80;
|
||||||
|
|
||||||
iPosX = INT_MIN;
|
iPosX = INT_MIN;
|
||||||
iPosY = INT_MIN;
|
iPosY = INT_MIN;
|
||||||
|
|
|
@ -110,6 +110,8 @@ struct SConfig : NonCopyable
|
||||||
|
|
||||||
bool bDPL2Decoder = false;
|
bool bDPL2Decoder = false;
|
||||||
int iLatency = 14;
|
int iLatency = 14;
|
||||||
|
bool m_audio_stretch = false;
|
||||||
|
int m_audio_stretch_max_latency = 80;
|
||||||
|
|
||||||
bool bRunCompareServer = false;
|
bool bRunCompareServer = false;
|
||||||
bool bRunCompareClient = false;
|
bool bRunCompareClient = false;
|
||||||
|
|
Loading…
Reference in New Issue