Mixer: Convert volatile variables to atomics.

This commit is contained in:
Lioncash 2015-05-09 23:50:45 -04:00
parent 4920dbed13
commit 7b376abd3b
2 changed files with 18 additions and 20 deletions

View File

@ -4,7 +4,6 @@
#include "AudioCommon/AudioCommon.h" #include "AudioCommon/AudioCommon.h"
#include "AudioCommon/Mixer.h" #include "AudioCommon/Mixer.h"
#include "Common/Atomic.h"
#include "Common/CPUDetect.h" #include "Common/CPUDetect.h"
#include "Common/MathUtil.h" #include "Common/MathUtil.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
@ -31,8 +30,8 @@ unsigned int CMixer::MixerFifo::Mix(short* samples, unsigned int numSamples, boo
// so we will just ignore new written data while interpolating. // so we will just ignore new written data while interpolating.
// Without this cache, the compiler wouldn't be allowed to optimize the // Without this cache, the compiler wouldn't be allowed to optimize the
// interpolation loop. // interpolation loop.
u32 indexR = Common::AtomicLoad(m_indexR); u32 indexR = m_indexR.load();
u32 indexW = Common::AtomicLoad(m_indexW); u32 indexW = m_indexW.load();
float numLeft = (float)(((indexW - indexR) & INDEX_MASK) / 2); float numLeft = (float)(((indexW - indexR) & INDEX_MASK) / 2);
m_numLeftI = (numLeft + m_numLeftI*(CONTROL_AVG-1)) / CONTROL_AVG; m_numLeftI = (numLeft + m_numLeftI*(CONTROL_AVG-1)) / CONTROL_AVG;
@ -53,8 +52,8 @@ unsigned int CMixer::MixerFifo::Mix(short* samples, unsigned int numSamples, boo
const u32 ratio = (u32)(65536.0f * aid_sample_rate / (float)m_mixer->m_sampleRate); const u32 ratio = (u32)(65536.0f * aid_sample_rate / (float)m_mixer->m_sampleRate);
s32 lvolume = m_LVolume; s32 lvolume = m_LVolume.load();
s32 rvolume = m_RVolume; s32 rvolume = m_RVolume.load();
// TODO: consider a higher-quality resampling algorithm. // TODO: consider a higher-quality resampling algorithm.
for (; currentSample < numSamples * 2 && ((indexW-indexR) & INDEX_MASK) > 2; currentSample += 2) for (; currentSample < numSamples * 2 && ((indexW-indexR) & INDEX_MASK) > 2; currentSample += 2)
@ -99,7 +98,7 @@ unsigned int CMixer::MixerFifo::Mix(short* samples, unsigned int numSamples, boo
} }
// Flush cached variable // Flush cached variable
Common::AtomicStore(m_indexR, indexR); m_indexR.store(indexR);
return numSamples; return numSamples;
} }
@ -130,11 +129,11 @@ void CMixer::MixerFifo::PushSamples(const short *samples, unsigned int num_sampl
// Cache access in non-volatile variable // Cache access in non-volatile variable
// indexR isn't allowed to cache in the audio throttling loop as it // indexR isn't allowed to cache in the audio throttling loop as it
// needs to get updates to not deadlock. // needs to get updates to not deadlock.
u32 indexW = Common::AtomicLoad(m_indexW); u32 indexW = m_indexW.load();
// Check if we have enough free space // Check if we have enough free space
// indexW == m_indexR results in empty buffer, so indexR must always be smaller than indexW // indexW == m_indexR results in empty buffer, so indexR must always be smaller than indexW
if (num_samples * 2 + ((indexW - Common::AtomicLoad(m_indexR)) & INDEX_MASK) >= MAX_SAMPLES * 2) if (num_samples * 2 + ((indexW - m_indexR.load()) & INDEX_MASK) >= MAX_SAMPLES * 2)
return; return;
// AyuanX: Actual re-sampling work has been moved to sound thread // AyuanX: Actual re-sampling work has been moved to sound thread
@ -151,9 +150,7 @@ void CMixer::MixerFifo::PushSamples(const short *samples, unsigned int num_sampl
memcpy(&m_buffer[indexW & INDEX_MASK], samples, num_samples * 4); memcpy(&m_buffer[indexW & INDEX_MASK], samples, num_samples * 4);
} }
Common::AtomicAdd(m_indexW, num_samples * 2); m_indexW.fetch_add(num_samples * 2);
return;
} }
void CMixer::PushSamples(const short *samples, unsigned int num_samples) void CMixer::PushSamples(const short *samples, unsigned int num_samples)
@ -215,6 +212,6 @@ void CMixer::MixerFifo::SetInputSampleRate(unsigned int rate)
void CMixer::MixerFifo::SetVolume(unsigned int lvolume, unsigned int rvolume) void CMixer::MixerFifo::SetVolume(unsigned int lvolume, unsigned int rvolume)
{ {
m_LVolume = lvolume + (lvolume >> 7); m_LVolume.store(lvolume + (lvolume >> 7));
m_RVolume = rvolume + (rvolume >> 7); m_RVolume.store(rvolume + (rvolume >> 7));
} }

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <atomic>
#include <mutex> #include <mutex>
#include <string> #include <string>
@ -109,8 +110,8 @@ public:
std::mutex& MixerCritical() { return m_csMixing; } std::mutex& MixerCritical() { return m_csMixing; }
float GetCurrentSpeed() const { return m_speed; } float GetCurrentSpeed() const { return m_speed.load(); }
void UpdateSpeed(volatile float val) { m_speed = val; } void UpdateSpeed(float val) { m_speed.store(val); }
protected: protected:
class MixerFifo { class MixerFifo {
@ -135,11 +136,11 @@ protected:
CMixer *m_mixer; CMixer *m_mixer;
unsigned m_input_sample_rate; unsigned m_input_sample_rate;
short m_buffer[MAX_SAMPLES * 2]; short m_buffer[MAX_SAMPLES * 2];
volatile u32 m_indexW; std::atomic<u32> m_indexW;
volatile u32 m_indexR; std::atomic<u32> m_indexR;
// Volume ranges from 0-256 // Volume ranges from 0-256
volatile s32 m_LVolume; std::atomic<s32> m_LVolume;
volatile s32 m_RVolume; std::atomic<s32> m_RVolume;
float m_numLeftI; float m_numLeftI;
u32 m_frac; u32 m_frac;
}; };
@ -156,5 +157,5 @@ protected:
std::mutex m_csMixing; std::mutex m_csMixing;
volatile float m_speed; // Current rate of the emulation (1.0 = 100% speed) std::atomic<float> m_speed; // Current rate of the emulation (1.0 = 100% speed)
}; };