mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Audio: Avoid exposing fixed size queue in header.
This commit is contained in:
parent
2da977bed2
commit
4c46867230
4 changed files with 38 additions and 32 deletions
|
@ -52,6 +52,10 @@ StereoResampler resampler;
|
|||
// atomic locks are used on the lock. TODO: make this lock-free
|
||||
std::atomic_flag atomicLock_;
|
||||
|
||||
// We copy samples as they are written into this simple ring buffer.
|
||||
// Might try something more efficient later.
|
||||
FixedSizeQueue<s16, 32768 * 8> chanSampleQueues[PSP_AUDIO_CHANNEL_MAX + 1];
|
||||
|
||||
int eventAudioUpdate = -1;
|
||||
int eventHostAudioUpdate = -1;
|
||||
int mixFrequency = 44100;
|
||||
|
@ -115,8 +119,10 @@ void __AudioInit() {
|
|||
|
||||
CoreTiming::ScheduleEvent(audioIntervalCycles, eventAudioUpdate, 0);
|
||||
CoreTiming::ScheduleEvent(audioHostIntervalCycles, eventHostAudioUpdate, 0);
|
||||
for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)
|
||||
for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++) {
|
||||
chans[i].index = i;
|
||||
chans[i].clear();
|
||||
}
|
||||
|
||||
mixBuffer = new s32[hwBlockSize * 2];
|
||||
clampedMixBuffer = new s16[hwBlockSize * 2];
|
||||
|
@ -164,8 +170,10 @@ void __AudioDoState(PointerWrap &p) {
|
|||
p.SetError(p.ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < chanCount; ++i)
|
||||
for (int i = 0; i < chanCount; ++i) {
|
||||
chans[i].index = i;
|
||||
chans[i].DoState(p);
|
||||
}
|
||||
|
||||
__AudioCPUMHzChange();
|
||||
}
|
||||
|
@ -175,8 +183,10 @@ void __AudioShutdown() {
|
|||
delete [] clampedMixBuffer;
|
||||
|
||||
mixBuffer = 0;
|
||||
for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)
|
||||
for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++) {
|
||||
chans[i].index = i;
|
||||
chans[i].clear();
|
||||
}
|
||||
|
||||
#ifndef MOBILE_DEVICE
|
||||
if (g_Config.bDumpAudio) {
|
||||
|
@ -196,11 +206,11 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) {
|
|||
}
|
||||
|
||||
// If there's anything on the queue at all, it should be busy, but we try to be a bit lax.
|
||||
//if (chan.sampleQueue.size() > chan.sampleCount * 2 * chanQueueMaxSizeFactor || chan.sampleAddress == 0) {
|
||||
if (chan.sampleQueue.size() > 0) {
|
||||
//if (chanSampleQueues[chanNum].size() > chan.sampleCount * 2 * chanQueueMaxSizeFactor || chan.sampleAddress == 0) {
|
||||
if (chanSampleQueues[chanNum].size() > 0) {
|
||||
if (blocking) {
|
||||
// TODO: Regular multichannel audio seems to block for 64 samples less? Or enqueue the first 64 sync?
|
||||
int blockSamples = (int)chan.sampleQueue.size() / 2 / chanQueueMinSizeFactor;
|
||||
int blockSamples = (int)chanSampleQueues[chanNum].size() / 2 / chanQueueMinSizeFactor;
|
||||
|
||||
if (__KernelIsDispatchEnabled()) {
|
||||
AudioChannelWaitInfo waitInfo = {__KernelGetCurThread(), blockSamples};
|
||||
|
@ -235,7 +245,7 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) {
|
|||
const u32 totalSamples = chan.sampleCount * (chan.format == PSP_AUDIO_FORMAT_STEREO ? 2 : 1);
|
||||
s16 *buf1 = 0, *buf2 = 0;
|
||||
size_t sz1, sz2;
|
||||
chan.sampleQueue.pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2);
|
||||
chanSampleQueues[chanNum].pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2);
|
||||
|
||||
if (Memory::IsValidAddress(chan.sampleAddress + (totalSamples - 1) * sizeof(s16_le))) {
|
||||
Memory::Memcpy(buf1, chan.sampleAddress, (u32)sz1 * sizeof(s16));
|
||||
|
@ -257,7 +267,7 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) {
|
|||
if (Memory::IsValidAddress(chan.sampleAddress + (totalSamples - 1) * sizeof(s16_le))) {
|
||||
s16 *buf1 = 0, *buf2 = 0;
|
||||
size_t sz1, sz2;
|
||||
chan.sampleQueue.pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2);
|
||||
chanSampleQueues[chanNum].pushPointers(totalSamples, &buf1, &sz1, &buf2, &sz2);
|
||||
AdjustVolumeBlock(buf1, sampleData, sz1, leftVol, rightVol);
|
||||
if (buf2) {
|
||||
AdjustVolumeBlock(buf2, sampleData + sz1, sz2, leftVol, rightVol);
|
||||
|
@ -267,8 +277,8 @@ u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) {
|
|||
// Rare, so unoptimized. Expands to stereo.
|
||||
for (u32 i = 0; i < chan.sampleCount; i++) {
|
||||
s16 sample = (s16)Memory::Read_U16(chan.sampleAddress + 2 * i);
|
||||
chan.sampleQueue.push(ApplySampleVolume(sample, leftVol));
|
||||
chan.sampleQueue.push(ApplySampleVolume(sample, rightVol));
|
||||
chanSampleQueues[chanNum].push(ApplySampleVolume(sample, leftVol));
|
||||
chanSampleQueues[chanNum].push(ApplySampleVolume(sample, rightVol));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -335,20 +345,20 @@ void __AudioUpdate(bool resetRecording) {
|
|||
|
||||
__AudioWakeThreads(chans[i], 0, hwBlockSize);
|
||||
|
||||
if (!chans[i].sampleQueue.size()) {
|
||||
if (!chanSampleQueues[i].size()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool needsResample = i == PSP_AUDIO_CHANNEL_SRC && srcFrequency != 0 && srcFrequency != mixFrequency;
|
||||
size_t sz = needsResample ? (hwBlockSize * 2 * srcFrequency) / mixFrequency : hwBlockSize * 2;
|
||||
if (sz > chans[i].sampleQueue.size()) {
|
||||
ERROR_LOG(SCEAUDIO, "Channel %i buffer underrun at %i of %i", i, (int)chans[i].sampleQueue.size() / 2, (int)sz / 2);
|
||||
if (sz > chanSampleQueues[i].size()) {
|
||||
ERROR_LOG(SCEAUDIO, "Channel %i buffer underrun at %i of %i", i, (int)chanSampleQueues[i].size() / 2, (int)sz / 2);
|
||||
}
|
||||
|
||||
const s16 *buf1 = 0, *buf2 = 0;
|
||||
size_t sz1, sz2;
|
||||
|
||||
chans[i].sampleQueue.popPointers(sz, &buf1, &sz1, &buf2, &sz2);
|
||||
chanSampleQueues[i].popPointers(sz, &buf1, &sz1, &buf2, &sz2);
|
||||
|
||||
if (needsResample) {
|
||||
auto read = [&](size_t i) {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/ChunkFileDo.h"
|
||||
#include "Common/FixedSizeQueue.h"
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
|
@ -35,6 +36,8 @@ const int AUDIO_ROUTING_SPEAKER_ON = 1;
|
|||
int defaultRoutingMode = AUDIO_ROUTING_SPEAKER_ON;
|
||||
int defaultRoutingVolMode = AUDIO_ROUTING_SPEAKER_ON;
|
||||
|
||||
extern FixedSizeQueue<s16, 32768 * 8> chanSampleQueues[PSP_AUDIO_CHANNEL_MAX + 1];
|
||||
|
||||
void AudioChannel::DoState(PointerWrap &p)
|
||||
{
|
||||
auto s = p.Section("AudioChannel", 1, 2);
|
||||
|
@ -52,7 +55,7 @@ void AudioChannel::DoState(PointerWrap &p)
|
|||
Do(p, defaultRoutingMode);
|
||||
Do(p, defaultRoutingVolMode);
|
||||
}
|
||||
sampleQueue.DoState(p);
|
||||
chanSampleQueues[index].DoState(p);
|
||||
}
|
||||
|
||||
void AudioChannel::reset()
|
||||
|
@ -69,7 +72,7 @@ void AudioChannel::clear()
|
|||
format = 0;
|
||||
sampleAddress = 0;
|
||||
sampleCount = 0;
|
||||
sampleQueue.clear();
|
||||
chanSampleQueues[index].clear();
|
||||
waitingThreads.clear();
|
||||
}
|
||||
|
||||
|
@ -183,7 +186,7 @@ static int sceAudioGetChannelRestLen(u32 chan) {
|
|||
ERROR_LOG(SCEAUDIO, "sceAudioGetChannelRestLen(%08x) - bad channel", chan);
|
||||
return SCE_ERROR_AUDIO_INVALID_CHANNEL;
|
||||
}
|
||||
int remainingSamples = (int)chans[chan].sampleQueue.size() / 2;
|
||||
int remainingSamples = (int)chanSampleQueues[chan].size() / 2;
|
||||
VERBOSE_LOG(SCEAUDIO, "%d=sceAudioGetChannelRestLen(%08x)", remainingSamples, chan);
|
||||
return remainingSamples;
|
||||
}
|
||||
|
@ -193,7 +196,7 @@ static int sceAudioGetChannelRestLength(u32 chan) {
|
|||
ERROR_LOG(SCEAUDIO, "sceAudioGetChannelRestLength(%08x) - bad channel", chan);
|
||||
return SCE_ERROR_AUDIO_INVALID_CHANNEL;
|
||||
}
|
||||
int remainingSamples = (int)chans[chan].sampleQueue.size() / 2;
|
||||
int remainingSamples = (int)chanSampleQueues[chan].size() / 2;
|
||||
VERBOSE_LOG(SCEAUDIO, "%d=sceAudioGetChannelRestLength(%08x)", remainingSamples, chan);
|
||||
return remainingSamples;
|
||||
}
|
||||
|
@ -371,7 +374,7 @@ static u32 sceAudioOutput2GetRestSample() {
|
|||
if (!chan.reserved) {
|
||||
return hleLogError(SCEAUDIO, SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED, "channel not reserved");
|
||||
}
|
||||
u32 size = (u32)chan.sampleQueue.size() / 2;
|
||||
u32 size = (u32)chanSampleQueues[PSP_AUDIO_CHANNEL_OUTPUT2].size() / 2;
|
||||
if (size > chan.sampleCount) {
|
||||
// If ChangeLength reduces the size, it still gets output but this return is clamped.
|
||||
size = chan.sampleCount;
|
||||
|
@ -383,7 +386,7 @@ static u32 sceAudioOutput2Release() {
|
|||
auto &chan = chans[PSP_AUDIO_CHANNEL_OUTPUT2];
|
||||
if (!chan.reserved)
|
||||
return hleLogError(SCEAUDIO, SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED, "channel not reserved");
|
||||
if (!chan.sampleQueue.empty())
|
||||
if (!chanSampleQueues[PSP_AUDIO_CHANNEL_OUTPUT2].empty())
|
||||
return hleLogError(SCEAUDIO, SCE_ERROR_AUDIO_CHANNEL_ALREADY_RESERVED, "output busy");
|
||||
|
||||
chan.reset();
|
||||
|
@ -444,7 +447,7 @@ static u32 sceAudioSRCChRelease() {
|
|||
auto &chan = chans[PSP_AUDIO_CHANNEL_SRC];
|
||||
if (!chan.reserved)
|
||||
return hleLogError(SCEAUDIO, SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED, "channel not reserved");
|
||||
if (!chan.sampleQueue.empty())
|
||||
if (!chanSampleQueues[PSP_AUDIO_CHANNEL_SRC].empty())
|
||||
return hleLogError(SCEAUDIO, SCE_ERROR_AUDIO_CHANNEL_ALREADY_RESERVED, "output busy");
|
||||
|
||||
chan.reset();
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include "CommonTypes.h"
|
||||
#include "sceKernel.h"
|
||||
#include "FixedSizeQueue.h"
|
||||
|
||||
class PointerWrap;
|
||||
|
||||
|
@ -60,9 +59,8 @@ struct AudioChannel
|
|||
clear();
|
||||
}
|
||||
|
||||
// PSP side
|
||||
|
||||
bool reserved;
|
||||
int index = 0;
|
||||
bool reserved = false;
|
||||
|
||||
// last sample address
|
||||
u32 sampleAddress;
|
||||
|
@ -73,12 +71,6 @@ struct AudioChannel
|
|||
|
||||
std::vector<AudioChannelWaitInfo> waitingThreads;
|
||||
|
||||
// PC side - should probably split out
|
||||
|
||||
// We copy samples as they are written into this simple ring buffer.
|
||||
// Might try something more efficient later.
|
||||
FixedSizeQueue<s16, 32768 * 8> sampleQueue;
|
||||
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
void reset();
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
#include "file/vfs.h"
|
||||
#include "ui/root.h"
|
||||
|
||||
#include "Common/ChunkFileDo.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FixedSizeQueue.h"
|
||||
#include "Core/HW/SimpleAudioDec.h"
|
||||
#include "Core/HLE/__sceAudio.h"
|
||||
#include "Common/FixedSizeQueue.h"
|
||||
#include "GameInfoCache.h"
|
||||
#include "Core/Config.h"
|
||||
#include "UI/BackgroundAudio.h"
|
||||
|
|
Loading…
Add table
Reference in a new issue