diff options
Diffstat (limited to 'Source/Core/AudioCommon/Mixer.cpp')
| -rw-r--r-- | Source/Core/AudioCommon/Mixer.cpp | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/Source/Core/AudioCommon/Mixer.cpp b/Source/Core/AudioCommon/Mixer.cpp index c1ff49dd03..3e75777f9a 100644 --- a/Source/Core/AudioCommon/Mixer.cpp +++ b/Source/Core/AudioCommon/Mixer.cpp @@ -6,6 +6,7 @@ #include "AudioCommon/Mixer.h" #include "Common/Atomic.h" #include "Common/CPUDetect.h" +#include "Common/MathUtil.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/HW/AudioInterface.h" @@ -19,20 +20,8 @@ #endif // Executed from sound stream thread -unsigned int CMixer::Mix(short* samples, unsigned int numSamples, bool consider_framelimit) +unsigned int CMixer::MixerFifo::Mix(short* samples, unsigned int numSamples, bool consider_framelimit) { - if (!samples) - return 0; - - std::lock_guard<std::mutex> lk(m_csMixing); - - if (PowerPC::GetState() != PowerPC::CPU_RUNNING) - { - // Silence - memset(samples, 0, numSamples * 4); - return numSamples; - } - unsigned int currentSample = 0; // Cache access in non-volatile variable @@ -56,14 +45,14 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples, bool consider_ //remember fractional offset u32 framelimit = SConfig::GetInstance().m_Framelimit; - float aid_sample_rate = AudioInterface::GetAIDSampleRate() + offset; + float aid_sample_rate = m_input_sample_rate + offset; if (consider_framelimit && framelimit > 2) { aid_sample_rate = aid_sample_rate * (framelimit - 1) * 5 / VideoInterface::TargetRefreshRate; } static u32 frac = 0; - const u32 ratio = (u32)( 65536.0f * aid_sample_rate / (float)m_sampleRate ); + const u32 ratio = (u32)( 65536.0f * aid_sample_rate / (float)m_mixer->m_sampleRate ); if (ratio > 0x10000) ERROR_LOG(AUDIO, "ratio out of range"); @@ -74,11 +63,15 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples, bool consider_ s16 l1 = Common::swap16(m_buffer[indexR & INDEX_MASK]); //current s16 l2 = Common::swap16(m_buffer[indexR2 & INDEX_MASK]); //next int sampleL = ((l1 << 16) + (l2 - l1) * (u16)frac) >> 16; + sampleL += samples[currentSample + 1]; + MathUtil::Clamp(&sampleL, -32767, 32767); samples[currentSample+1] = sampleL; s16 r1 = Common::swap16(m_buffer[(indexR + 1) & INDEX_MASK]); //current s16 r2 = Common::swap16(m_buffer[(indexR2 + 1) & INDEX_MASK]); //next int sampleR = ((r1 << 16) + (r2 - r1) * (u16)frac) >> 16; + sampleR += samples[currentSample]; + MathUtil::Clamp(&sampleR, -32767, 32767); samples[currentSample] = sampleR; frac += ratio; @@ -87,36 +80,55 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples, bool consider_ } // Padding - unsigned short s[2]; + short s[2]; s[0] = Common::swap16(m_buffer[(indexR - 1) & INDEX_MASK]); s[1] = Common::swap16(m_buffer[(indexR - 2) & INDEX_MASK]); for (; currentSample < numSamples*2; currentSample+=2) { - samples[currentSample] = s[0]; - samples[currentSample+1] = s[1]; + int sampleR = s[0] + samples[currentSample]; + MathUtil::Clamp(&sampleR, -32767, 32767); + samples[currentSample] = sampleR; + int sampleL = s[1] + samples[currentSample + 1]; + MathUtil::Clamp(&sampleL, -32767, 32767); + samples[currentSample + 1] = sampleL; } // Flush cached variable Common::AtomicStore(m_indexR, indexR); - // Add the DTK Music - // Re-sampling is done inside - AudioInterface::Callback_GetStreaming(samples, numSamples, m_sampleRate); - if (m_logAudio) - g_wave_writer.AddStereoSamples(samples, numSamples); - return numSamples; } +unsigned int CMixer::Mix(short* samples, unsigned int num_samples, bool consider_framelimit) +{ + if (!samples) + return 0; -void CMixer::PushSamples(const short *samples, unsigned int num_samples) + std::lock_guard<std::mutex> lk(m_csMixing); + + memset(samples, 0, num_samples * 2 * sizeof(short)); + + if (PowerPC::GetState() != PowerPC::CPU_RUNNING) + { + // Silence + return num_samples; + } + + m_dma_mixer.Mix(samples, num_samples, consider_framelimit); + m_streaming_mixer.Mix(samples, num_samples, consider_framelimit); + if (m_logAudio) + g_wave_writer.AddStereoSamples(samples, num_samples); + return num_samples; +} + +void CMixer::MixerFifo::PushSamples(const short *samples, unsigned int num_samples) { // Cache access in non-volatile variable // indexR isn't allowed to cache in the audio throttling loop as it // needs to get updates to not deadlock. u32 indexW = Common::AtomicLoad(m_indexW); - if (m_throttle) + if (m_mixer->m_throttle) { // The auto throttle function. This loop will put a ceiling on the CPU MHz. while (num_samples * 2 + ((indexW - Common::AtomicLoad(m_indexR)) & INDEX_MASK) >= MAX_SAMPLES * 2) @@ -155,3 +167,12 @@ void CMixer::PushSamples(const short *samples, unsigned int num_samples) return; } +void CMixer::PushSamples(const short *samples, unsigned int num_samples) +{ + m_dma_mixer.PushSamples(samples, num_samples); +} + +void CMixer::PushStreamingSamples(const short *samples, unsigned int num_samples) +{ + m_streaming_mixer.PushSamples(samples, num_samples); +} |
