Audio Processor now uses atomics rather than mutex

This commit is contained in:
Siddharth 2013-10-02 01:54:55 +05:30
parent 11f8203cc4
commit a6ec70fe90
2 changed files with 50 additions and 5 deletions

View file

@ -29,8 +29,9 @@
#include "FixedSizeQueue.h"
#include "Common/Thread.h"
// Should be used to lock anything related to the outAudioQueue.
recursive_mutex section;
std::atomic<bool> audioQueueLock;
int eventAudioUpdate = -1;
int eventHostAudioUpdate = -1;
@ -55,6 +56,10 @@ static int chanQueueMinSizeFactor;
// is bad mojo.
FixedSizeQueue<s16, 512 * 16> outAudioQueue;
bool __gainAudioQueueLock();
static inline s16 clamp_s16(int i) {
if (i > 32767)
return 32767;
@ -108,6 +113,8 @@ void __AudioInit() {
mixBuffer = new s32[hwBlockSize * 2];
memset(mixBuffer, 0, hwBlockSize * 2 * sizeof(s32));
audioQueueLock.store(false);
}
void __AudioDoState(PointerWrap &p) {
@ -123,8 +130,15 @@ void __AudioDoState(PointerWrap &p) {
p.Do(mixFrequency);
{
lock_guard guard(section);
if(!__gainAudioQueueLock()){
return;
}
outAudioQueue.DoState(p);
//release the atomic lock
audioQueueLock.store(false);
}
int chanCount = ARRAY_SIZE(chans);
@ -322,11 +336,18 @@ void __AudioUpdate() {
}
if (g_Config.bEnableSound) {
lock_guard guard(section);
//looks like the heavy lifting is done here.
//we have to optimize this some more.
if(!__gainAudioQueueLock()){
return;
}
if (outAudioQueue.room() >= hwBlockSize * 2) {
s16 *buf1 = 0, *buf2 = 0;
size_t sz1, sz2;
outAudioQueue.pushPointers(hwBlockSize * 2, &buf1, &sz1, &buf2, &sz2);
for (size_t s = 0; s < sz1; s++)
buf1[s] = clamp_s16(mixBuffer[s]);
if (buf2) {
@ -337,6 +358,9 @@ void __AudioUpdate() {
// This happens quite a lot. There's still something slightly off
// about the amount of audio we produce.
}
//release the atomic lock
audioQueueLock.store(false);
}
}
@ -352,12 +376,21 @@ int __AudioMix(short *outstereo, int numFrames)
const s16 *buf1 = 0, *buf2 = 0;
size_t sz1, sz2;
{
lock_guard guard(section);
if(!__gainAudioQueueLock()){
return numFrames;
}
outAudioQueue.popPointers(numFrames * 2, &buf1, &sz1, &buf2, &sz2);
memcpy(outstereo, buf1, sz1 * sizeof(s16));
if (buf2) {
memcpy(outstereo + sz1, buf2, sz2 * sizeof(s16));
}
//release the atomic lock
audioQueueLock.store(false);
}
int remains = (int)(numFrames * 2 - sz1 - sz2);
@ -370,3 +403,13 @@ int __AudioMix(short *outstereo, int numFrames)
}
return underrun >= 0 ? underrun : numFrames;
}
bool __gainAudioQueueLock(){
if(audioQueueLock.load(std::memory_order::memory_order_relaxed) == true){
return false;
}
audioQueueLock.store(true, std::memory_order::memory_order_relaxed );
return true;
};

View file

@ -16,8 +16,10 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once
#include "sceAudio.h"
#include <atomic>
// Easy interface for sceAudio to write to, to keep the complexity in check.