summaryrefslogtreecommitdiff
path: root/Source/Core/AudioCommon/Mixer.cpp
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2014-02-06 06:55:45 +0100
committerdegasus <wickmarkus@web.de>2014-02-11 07:25:58 +0100
commitd20dbbc92fe78bd5e5005bb6512c688beb3df681 (patch)
treedc27e7b649be5910d8ff5bf5e19c4933908053b1 /Source/Core/AudioCommon/Mixer.cpp
parent2956ffa5be8c564274b3ba3eeb5ed765f2ee3ede (diff)
audiocommon: sync mixer by fifo instead of estimate values
Diffstat (limited to 'Source/Core/AudioCommon/Mixer.cpp')
-rw-r--r--Source/Core/AudioCommon/Mixer.cpp115
1 files changed, 34 insertions, 81 deletions
diff --git a/Source/Core/AudioCommon/Mixer.cpp b/Source/Core/AudioCommon/Mixer.cpp
index a015f25f7f..dd1e7ed386 100644
--- a/Source/Core/AudioCommon/Mixer.cpp
+++ b/Source/Core/AudioCommon/Mixer.cpp
@@ -32,16 +32,7 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples)
return numSamples;
}
- unsigned int numLeft = GetNumSamples();
- if (m_AIplaying) {
- if (numLeft < numSamples)//cannot do much about this
- m_AIplaying = false;
- if (numLeft < MAX_SAMPLES/4)//low watermark
- m_AIplaying = false;
- } else {
- if (numLeft > MAX_SAMPLES/2)//high watermark
- m_AIplaying = true;
- }
+ unsigned int currentSample = 0;
// Cache access in non-volatile variable
// This is the only function changing the read value, so it's safe to
@@ -53,72 +44,55 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples)
u32 indexR = Common::AtomicLoad(m_indexR);
u32 indexW = Common::AtomicLoad(m_indexW);
- if (m_AIplaying) {
- numLeft = (numLeft > numSamples) ? numSamples : numLeft;
-
- //render numleft sample pairs to samples[]
- //advance indexR with sample position
- //remember fractional offset
+ //render numleft sample pairs to samples[]
+ //advance indexR with sample position
+ //remember fractional offset
- static u32 frac = 0;
- const u32 ratio = (u32)( 65536.0f * (float)AudioInterface::GetAIDSampleRate() / (float)m_sampleRate );
+ static u32 frac = 0;
+ const u32 ratio = (u32)( 65536.0f * (float)AudioInterface::GetAIDSampleRate() / (float)m_sampleRate );
- for (u32 i = 0; i < numLeft * 2; i+=2) {
- u32 indexR2 = indexR + 2; //next sample
- if ((indexR2 & INDEX_MASK) == (indexW & INDEX_MASK)) //..if it exists
- indexR2 = indexR;
+ if(ratio > 0x10000)
+ ERROR_LOG(AUDIO, "ratio out of range");
- 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;
- samples[i+1] = sampleL;
+ for (; currentSample < numSamples*2 && ((indexW-indexR) & INDEX_MASK) > 2; currentSample+=2) {
+ u32 indexR2 = indexR + 2; //next sample
- 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;
- samples[i] = sampleR;
+ 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;
+ samples[currentSample+1] = sampleL;
- frac += ratio;
- indexR += 2 * (u16)(frac >> 16);
- frac &= 0xffff;
- }
+ 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;
+ samples[currentSample] = sampleR;
- } else {
- numLeft = 0;
+ frac += ratio;
+ indexR += 2 * (u16)(frac >> 16);
+ frac &= 0xffff;
}
// Padding
- if (numSamples > numLeft)
+ unsigned 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)
{
- unsigned short s[2];
- s[0] = Common::swap16(m_buffer[(indexR - 1) & INDEX_MASK]);
- s[1] = Common::swap16(m_buffer[(indexR - 2) & INDEX_MASK]);
- for (unsigned int i = numLeft*2; i < numSamples*2; i+=2)
- *(u32*)(samples+i) = *(u32*)(s);
-// memset(&samples[numLeft * 2], 0, (numSamples - numLeft) * 4);
+ samples[currentSample] = s[0];
+ samples[currentSample+1] = s[1];
}
// Flush cached variable
Common::AtomicStore(m_indexR, indexR);
- //when logging, also throttle HLE audio
- if (m_logAudio) {
- if (m_AIplaying) {
- Premix(samples, numLeft);
-
- AudioInterface::Callback_GetStreaming(samples, numLeft, m_sampleRate);
-
- g_wave_writer.AddStereoSamples(samples, numLeft);
- }
- }
- else { //or mix as usual
- // Add the DSPHLE sound, re-sampling is done inside
- Premix(samples, numSamples);
+ // Add the DSPHLE sound, re-sampling is done inside
+ Premix(samples, numSamples);
- // Add the DTK Music
- // Re-sampling is done inside
- AudioInterface::Callback_GetStreaming(samples, numSamples, m_sampleRate);
- }
+ // 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;
}
@@ -170,24 +144,3 @@ void CMixer::PushSamples(const short *samples, unsigned int num_samples)
return;
}
-unsigned int CMixer::GetNumSamples()
-{
- // Guess how many samples would be available after interpolation.
- // As interpolation needs at least on sample from the future to
- // linear interpolate between them, one sample less is available.
- // We also can't say the current interpolation state (specially
- // the frac), so to be sure, subtract one again to be sure not
- // to underflow the fifo.
-
- u32 numSamples = ((Common::AtomicLoad(m_indexW) - Common::AtomicLoad(m_indexR)) & INDEX_MASK) / 2;
-
- if (AudioInterface::GetAIDSampleRate() == m_sampleRate)
- ; //numSamples = numSamples; // 1:1
- else if (m_sampleRate == 48000 && AudioInterface::GetAIDSampleRate() == 32000)
- numSamples = numSamples * 3 / 2 - 2; // most common case
- else
- numSamples = numSamples * m_sampleRate / AudioInterface::GetAIDSampleRate() - 2;
-
- return numSamples;
-}
-