mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Audio Processor now uses atomics rather than mutex
This commit is contained in:
parent
11f8203cc4
commit
a6ec70fe90
2 changed files with 50 additions and 5 deletions
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue