Skip to content

Commit

Permalink
Changes to Queue audio for media engine **Not clean **
Browse files Browse the repository at this point in the history
  • Loading branch information
z2442 committed Oct 14, 2024
1 parent 8573b52 commit 23249c5
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 34 deletions.
89 changes: 63 additions & 26 deletions Source/HLEAudio/HLEMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,33 +113,70 @@ inline void Audio_Ucode_Detect(OSTask *pTask) {
//*****************************************************************************
//
//*****************************************************************************
#include <queue>
#include <atomic>
#include <cstdint>

// Atomic flag to signal which queue is active
std::atomic<bool> activeQueueIndex{0}; // 0 or 1 to switch between the two queues

// Two separate task queues for each CPU
std::queue<OSTask*> queue1;
std::queue<OSTask*> queue2;

// Function to enqueue tasks into one of the two queues
void EnqueueTask() {

OSTask *pTask = (OSTask *)(g_pu8SpMemBase + 0x0FC0);
// Determine which queue to enqueue the task into based on the active queue
if (activeQueueIndex.load() == 0) {
queue1.push(pTask);
} else {
queue2.push(pTask);
}
}

void Audio_Ucode() {
#ifdef DAEDALUS_PROFILE
DAEDALUS_PROFILE("HLEMain::Audio_Ucode");
DAEDALUS_PROFILE("HLEMain::Audio_Ucode");
#endif
OSTask *pTask = (OSTask *)(g_pu8SpMemBase + 0x0FC0);

// Only detect ABI once per game
if (!bAudioChanged) {
bAudioChanged = true;
Audio_Ucode_Detect(pTask);
}

gAudioHLEState.LoopVal = 0;
memset( gAudioHLEState.Segments, 0, sizeof( gAudioHLEState.Segments ) );

u32 *p_alist = (u32 *)(g_pu8RamBase + (uintptr_t)pTask->t.data_ptr);
u32 ucode_size = (pTask->t.data_size >> 3); // ABI5 can return 0 here!!!

while (ucode_size) {
AudioHLECommand command;
command.cmd0 = *p_alist++;
command.cmd1 = *p_alist++;

ABI[command.cmd](command);

--ucode_size;

// printf("%08X %08X\n",command.cmd0,command.cmd1);
}
}
// Process tasks from the current active queue
std::queue<OSTask*>& processingQueue = (activeQueueIndex.load() == 0) ? queue1 : queue2;

while (!processingQueue.empty()) {
OSTask* pTask = processingQueue.front();
processingQueue.pop();

// Only detect ABI once per game
if (!bAudioChanged) {
bAudioChanged = true;
Audio_Ucode_Detect(pTask);
}

gAudioHLEState.LoopVal = 0;

u32* p_alist = (u32*)(g_pu8RamBase + (uintptr_t)pTask->t.data_ptr);
u32 ucode_size = (pTask->t.data_size >> 3); // ABI5 can return 0 here!

// Process the commands in the task
while (ucode_size) {
AudioHLECommand command;
command.cmd0 = *p_alist++;
command.cmd1 = *p_alist++;

// Execute the command using the ABI
ABI[command.cmd](command);

--ucode_size;
}
for(int i = 0; i < 8192; i += 64)
{
__builtin_allegrex_cache(0x14, i);
__builtin_allegrex_cache(0x14, i);
}
}

// Swap the active queue after processing
activeQueueIndex.store(!activeQueueIndex.load());
}
69 changes: 61 additions & 8 deletions Source/HLEAudio/Plugin/PSP/AudioPluginPSP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,67 @@ class AudioPluginPSP : public CAudioPlugin

static AudioPluginPSP * ac;

#include <queue>
#include <atomic>
#include <cstdint>

// Atomic flag to signal which queue is active
std::atomic<bool> activeQueueIndexplayback{0}; // 0 or 1 to switch between the two queues

// Two separate task queues for each CPU
std::queue<Sample*> Samplequeue1;
std::queue<Sample*> Samplequeue2;
std::queue<u32> num_Samplequeue1;
std::queue<u32> num_Samplequeue2;

// Function to enqueue tasks into one of the two queues
void EnqueueTaskplayback(Sample * buffer, u32 num_samples) {

// Determine which queue to enqueue the task into based on the active queue
if (activeQueueIndexplayback.load() == 0) {
Samplequeue1.push(buffer);
num_Samplequeue1.push(num_samples);
} else {
Samplequeue2.push(buffer);
num_Samplequeue2.push(num_samples);
}
}

void processthequeues(CAudioBuffer * bubble){

std::queue<Sample*>& processingQueue1 = (activeQueueIndexplayback.load() == 0) ? Samplequeue1 : Samplequeue2;
std::queue<u32>& processingQueue2 = (activeQueueIndexplayback.load() == 0) ? num_Samplequeue1 : num_Samplequeue2;

while (!processingQueue1.empty()) {

Sample* buffer = processingQueue1.front();
processingQueue1.pop();
u32 numberofsamples = processingQueue2.front();
processingQueue2.pop();


bubble->Drain( buffer, numberofsamples );

for(int i = 0; i < 8192; i += 64)
{
__builtin_allegrex_cache(0x14, i);
__builtin_allegrex_cache(0x14, i);
}

}
}




void AudioPluginPSP::FillBuffer(Sample * buffer, u32 num_samples)
{
sceKernelWaitSema( mSemaphore, 1, nullptr );

mAudioBufferUncached->Drain( buffer, num_samples );
EnqueueTaskplayback(buffer, num_samples);
sceKernelDcacheWritebackInvalidateAll();
BeginME( mei, (int)&processthequeues, (int)mAudioBuffer, -1, NULL, -1, NULL);


sceKernelSignalSema( mSemaphore, 1 );
}
Expand Down Expand Up @@ -228,6 +284,7 @@ void AudioPluginPSP::LenChanged()
}
}

extern void EnqueueTask();

EProcessResult AudioPluginPSP::ProcessAList()
{
Expand All @@ -242,23 +299,19 @@ EProcessResult AudioPluginPSP::ProcessAList()
break;
case APM_ENABLED_ASYNC:
{
#ifdef DAEDALUS_PSP_USE_ME
EnqueueTask();
sceKernelDcacheWritebackInvalidateAll();
if(BeginME( mei, (int)&Audio_Ucode, (int)NULL, -1, NULL, -1, NULL) < 0){
Audio_Ucode();
result = PR_COMPLETED;
break;
}
#else
DAEDALUS_ERROR("Async audio is unimplemented");
Audio_Ucode();
result = PR_COMPLETED;
break;
#endif
}
result = PR_COMPLETED;
break;
case APM_ENABLED_SYNC:
EnqueueTask();
Audio_Ucode();
result = PR_COMPLETED;
break;
Expand All @@ -267,7 +320,6 @@ EProcessResult AudioPluginPSP::ProcessAList()
return result;
}


void audioCallback( void * buf, unsigned int length, void * userdata )
{
AudioPluginPSP * ac( reinterpret_cast< AudioPluginPSP * >( userdata ) );
Expand All @@ -276,6 +328,7 @@ void audioCallback( void * buf, unsigned int length, void * userdata )
}



void AudioPluginPSP::StartAudio()
{
if (mKeepRunning)
Expand Down

0 comments on commit 23249c5

Please sign in to comment.