Use a separate channel for SRC/Output2.

Tests on the PSP show that all 8 channels can be reserved/used at the
same time as *either* Output2 or SRC (but SRC and Output2 cannot be used
at the same time.)
This commit is contained in:
Unknown W. Brackets 2013-05-15 23:18:57 -07:00
parent 8b3b666612
commit 0ab30ecb07
3 changed files with 35 additions and 31 deletions

View file

@ -83,7 +83,7 @@ void __AudioInit()
CoreTiming::ScheduleEvent(usToCycles(audioIntervalUs), eventAudioUpdate, 0);
CoreTiming::ScheduleEvent(usToCycles(audioHostIntervalUs), eventHostAudioUpdate, 0);
for (int i = 0; i < 8; i++)
for (int i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)
chans[i].clear();
}
@ -116,7 +116,7 @@ void __AudioDoState(PointerWrap &p)
void __AudioShutdown()
{
for (int i = 0; i < 8; i++)
for (int i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)
chans[i].clear();
}
@ -200,7 +200,7 @@ void __AudioUpdate()
s32 mixBuffer[hwBlockSize * 2];
memset(mixBuffer, 0, sizeof(mixBuffer));
for (int i = 0; i < PSP_AUDIO_CHANNEL_MAX; i++)
for (int i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)
{
if (!chans[i].reserved)
continue;

View file

@ -40,10 +40,10 @@ void AudioChannel::DoState(PointerWrap &p)
}
// There's a second Audio api called Audio2 that only has one channel, I guess the 8 channel api was overkill.
// We simply map it to the first of the 8 channels.
// We simply map it to an extra channel after the 8 channels, since they can be used concurrently.
AudioChannel chans[8];
int src; //not initialized and default 0
// The extra channel is for SRC/Output2.
AudioChannel chans[PSP_AUDIO_CHANNEL_MAX + 1];
// Enqueues the buffer pointer on the channel. If channel buffer queue is full (2 items?) will block until it isn't.
// For solid audio output we'll need a queue length of 2 buffers at least, we'll try that first.
@ -273,8 +273,8 @@ u32 sceAudioEnd(){
u32 sceAudioOutput2Reserve(u32 sampleCount){
DEBUG_LOG(HLE,"sceAudioOutput2Reserve(%08x)", sampleCount);
chans[0].sampleCount = sampleCount;
chans[0].reserved = true;
chans[PSP_AUDIO_CHANNEL_OUTPUT2].sampleCount = sampleCount;
chans[PSP_AUDIO_CHANNEL_OUTPUT2].reserved = true;
return 0;
}
@ -285,35 +285,35 @@ u32 sceAudioOutput2OutputBlocking(u32 vol, u32 dataPtr){
return SCE_ERROR_AUDIO_INVALID_VOLUME;
}
DEBUG_LOG(HLE,"sceAudioOutput2OutputBlocking(%08x, %08x)", vol, dataPtr);
chans[0].leftVolume = vol;
chans[0].rightVolume = vol;
chans[0].sampleAddress = dataPtr;
return __AudioEnqueue(chans[0], 0, true);
chans[PSP_AUDIO_CHANNEL_OUTPUT2].leftVolume = vol;
chans[PSP_AUDIO_CHANNEL_OUTPUT2].rightVolume = vol;
chans[PSP_AUDIO_CHANNEL_OUTPUT2].sampleAddress = dataPtr;
return __AudioEnqueue(chans[PSP_AUDIO_CHANNEL_OUTPUT2], PSP_AUDIO_CHANNEL_OUTPUT2, true);
}
u32 sceAudioOutput2ChangeLength(u32 sampleCount){
DEBUG_LOG(HLE,"sceAudioOutput2ChangeLength(%08x)", sampleCount);
if (!chans[0].reserved) {
if (!chans[PSP_AUDIO_CHANNEL_OUTPUT2].reserved) {
DEBUG_LOG(HLE,"sceAudioOutput2ChangeLength(%08x) - channel not reserved ", sampleCount);
return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED;
}
chans[0].sampleCount = sampleCount;
chans[PSP_AUDIO_CHANNEL_OUTPUT2].sampleCount = sampleCount;
return 0;
}
u32 sceAudioOutput2GetRestSample(){
DEBUG_LOG(HLE,"sceAudioOutput2GetRestSample()");
if (!chans[0].reserved) {
if (!chans[PSP_AUDIO_CHANNEL_OUTPUT2].reserved) {
DEBUG_LOG(HLE,"sceAudioOutput2GetRestSample() - channel not reserved ");
return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED;
}
return (u32) chans[0].sampleQueue.size() * 2;
return (u32) chans[PSP_AUDIO_CHANNEL_OUTPUT2].sampleQueue.size() * 2;
}
u32 sceAudioOutput2Release(){
DEBUG_LOG(HLE,"sceAudioOutput2Release()");
chans[0].clear();
chans[0].reserved = false;
chans[PSP_AUDIO_CHANNEL_OUTPUT2].clear();
chans[PSP_AUDIO_CHANNEL_OUTPUT2].reserved = false;
return 0;
}
@ -334,14 +334,14 @@ u32 sceAudioSetVolumeOffset() {
}
u32 sceAudioSRCChReserve(u32 sampleCount, u32 freq, u32 format) {
if (chans[src].reserved) {
if (chans[PSP_AUDIO_CHANNEL_SRC].reserved) {
DEBUG_LOG(HLE, "sceAudioSRCChReserve(%08x, %08x, %08x) - channel already reserved ", sampleCount, freq, format);
return SCE_ERROR_AUDIO_CHANNEL_ALREADY_RESERVED;
} else {
DEBUG_LOG(HLE, "sceAudioSRCChReserve(%08x, %08x, %08x)", sampleCount, freq, format);
chans[src].reserved = true;
chans[src].sampleCount = sampleCount;
chans[src].format = format;
chans[PSP_AUDIO_CHANNEL_SRC].reserved = true;
chans[PSP_AUDIO_CHANNEL_SRC].sampleCount = sampleCount;
chans[PSP_AUDIO_CHANNEL_SRC].format = format;
__AudioSetOutputFrequency(freq);
}
return 0;
@ -349,12 +349,12 @@ u32 sceAudioSRCChReserve(u32 sampleCount, u32 freq, u32 format) {
u32 sceAudioSRCChRelease() {
DEBUG_LOG(HLE, "sceAudioSRCChRelease()");
if (!chans[src].reserved) {
if (!chans[PSP_AUDIO_CHANNEL_SRC].reserved) {
DEBUG_LOG(HLE, "sceAudioSRCChRelease() - channel already reserved ");
return SCE_ERROR_AUDIO_CHANNEL_NOT_RESERVED;
}
chans[src].clear();
chans[src].reserved = false;
chans[PSP_AUDIO_CHANNEL_SRC].clear();
chans[PSP_AUDIO_CHANNEL_SRC].reserved = false;
return 0;
}
@ -364,10 +364,10 @@ u32 sceAudioSRCOutputBlocking(u32 vol, u32 buf) {
return SCE_ERROR_AUDIO_INVALID_VOLUME;
}
DEBUG_LOG(HLE, "sceAudioSRCOutputBlocking(%08x, %08x)", vol, buf);
chans[src].leftVolume = vol;
chans[src].rightVolume = vol;
chans[src].sampleAddress = buf;
return __AudioEnqueue(chans[src], src, true);
chans[PSP_AUDIO_CHANNEL_SRC].leftVolume = vol;
chans[PSP_AUDIO_CHANNEL_SRC].rightVolume = vol;
chans[PSP_AUDIO_CHANNEL_SRC].sampleAddress = buf;
return __AudioEnqueue(chans[PSP_AUDIO_CHANNEL_SRC], PSP_AUDIO_CHANNEL_SRC, true);
}
const HLEFunction sceAudio[] =

View file

@ -42,7 +42,10 @@ enum PspAudioFrequencies { PSP_AUDIO_FREQ_44K = 44100, PSP_AUDIO_FREQ_48K = 48
#define SCE_ERROR_AUDIO_CHANNEL_ALREADY_RESERVED 0x80268002
#define PSP_AUDIO_CHANNEL_MAX 8
const int PSP_AUDIO_CHANNEL_MAX = 8;
const int PSP_AUDIO_CHANNEL_SRC = 8;
const int PSP_AUDIO_CHANNEL_OUTPUT2 = 8;
struct AudioChannel
{
@ -83,6 +86,7 @@ struct AudioChannel
}
};
extern AudioChannel chans[8];
// The extra channel is for SRC/Output2.
extern AudioChannel chans[PSP_AUDIO_CHANNEL_MAX + 1];
void Register_sceAudio();