From f07a9b6c8171aaedb6df7950d36c218339954c9c Mon Sep 17 00:00:00 2001 From: Nicholas Estelami Date: Thu, 14 Nov 2024 23:53:56 -0500 Subject: [PATCH] Audio and Message Fixes --- include/sfx.h | 2 +- src/audio/audio_general.c | 22 +++++-- src/audio/audio_heap.c | 12 +++- src/audio/audio_load.c | 73 ++++++++++++----------- src/audio/audio_playback.c | 5 +- src/audio/audio_seqplayer.c | 24 +++++--- src/audio/audio_synthesis.c | 17 +++--- src/engine/fox_load.c | 7 ++- src/engine/fox_message.c | 2 +- src/port/Engine.cpp | 13 +++- src/port/resource/loaders/AudioLoader.cpp | 2 +- src/sys/sys_main.c | 2 - 12 files changed, 109 insertions(+), 72 deletions(-) diff --git a/include/sfx.h b/include/sfx.h index 522f3ca5..37394ccc 100644 --- a/include/sfx.h +++ b/include/sfx.h @@ -34,7 +34,7 @@ void Audio_PlayPauseSfx(u8 active); void Audio_PlayMapMenuSfx(u8 active); void Audio_KillAllSfx(void); -#define AUDIO_PLAY_SFX(sfxId, srcPos, token) //(Audio_PlaySfx((sfxId),(srcPos),(token),&gDefaultMod,&gDefaultMod,&gDefaultReverb)) +#define AUDIO_PLAY_SFX(sfxId, srcPos, token) (Audio_PlaySfx((sfxId),(srcPos),(token),&gDefaultMod,&gDefaultMod,&gDefaultReverb)) #define SFX_FLAG_18 (1 << 18) // makes distance ignore z position? probably more #define SFX_FLAG_19 (1 << 19) diff --git a/src/audio/audio_general.c b/src/audio/audio_general.c index 43bd0958..bb37dbcd 100644 --- a/src/audio/audio_general.c +++ b/src/audio/audio_general.c @@ -692,7 +692,12 @@ void Audio_ProcessSeqCmd(u32 seqCmd) { seqNumber = seqCmd & 0xFF; seqArgs = (seqCmd & 0xFF00) >> 8; fadeTimer = (seqCmd & 0xFF0000) >> 13; - if (!sActiveSequences[seqPlayId].isWaitingForFonts) { + + seqArgs = 0; + + //if (!sActiveSequences[seqPlayId].isWaitingForFonts) + if (true) + { if (seqArgs < 0x80) { Audio_StartSequence(seqPlayId, seqNumber, seqArgs, fadeTimer); } else { @@ -888,12 +893,14 @@ void Audio_ProcessSeqCmd(u32 seqCmd) { oldSpecId = sAudioSpecId; sAudioSpecId = specId; - if (oldSpecId != specId) { + if (oldSpecId != specId) + { AudioThread_ResetAudioHeap(specId); Audio_StartReset(oldSpecId); AUDIOCMD_GLOBAL_STOP_AUDIOCMDS(); - - } else { + } + else + { Audio_StopSequence(SEQ_PLAYER_BGM, 1); Audio_StopSequence(SEQ_PLAYER_FANFARE, 1); } @@ -991,7 +998,8 @@ void Audio_UpdateActiveSequences(void) { for (seqPlayId = 0; seqPlayId < SEQ_PLAYER_MAX; seqPlayId++) { if (sActiveSequences[seqPlayId].isWaitingForFonts) { - switch ((s32) AudioThread_GetAsyncLoadStatus(&out)) { + switch ((s32) AudioThread_GetAsyncLoadStatus(&out)) + { case SEQ_PLAYER_BGM + 1: case SEQ_PLAYER_FANFARE + 1: case SEQ_PLAYER_SFX + 1: @@ -1322,7 +1330,7 @@ void Audio_ProcessSfxRequest(void) { SfxRequest* request = &sSfxRequests[sSfxRequestReadIndex]; u8 next; s32 bankId; - u8 evict; + u8 evict = 0; u32 sfxId; u8 count; SfxBankEntry* entry; @@ -1850,6 +1858,7 @@ void Audio_UpdateVoice(void) { voiceId = sNextVoiceId % 1000; voiceIdHi = voiceId / 256; voiceIdLo = voiceId % 256; + AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_VOICE, 15, 0, 1); AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_VOICE, 15, 4, voiceBank); AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_VOICE, 15, 5, voiceIdHi); @@ -2570,6 +2579,7 @@ void Audio_SetBgmParam(s8 bgmParam) { } void Audio_PlaySequence(u8 seqPlayId, u16 seqId, u8 fadeinTime, u8 bgmParam) { + //seqId &= 0xFF; SEQCMD_SET_SEQPLAYER_IO(seqPlayId, 0, bgmParam); SEQCMD_PLAY_SEQUENCE(seqPlayId, fadeinTime, 0, seqId); } diff --git a/src/audio/audio_heap.c b/src/audio/audio_heap.c index bb3b2a82..e85f195f 100644 --- a/src/audio/audio_heap.c +++ b/src/audio/audio_heap.c @@ -451,7 +451,7 @@ uintptr_t AudioHeap_SearchCaches(s32 tableType, s32 cache, s32 id) { return (uintptr_t) ramAddr; } if (cache == CACHE_PERMANENT) { - return (uintptr_t) NULL; + //return (uintptr_t) NULL; } return (uintptr_t) AudioHeap_SearchRegularCaches(tableType, cache, id); } @@ -667,9 +667,17 @@ void AudioHeap_Init(void) { gNumNotes = spec->numNotes; D_8014C1B0 = spec->unk_14; - gMaxTempo = (u16) ((gAudioBufferParams.ticksPerUpdate * 2880000.0f / gSeqTicksPerBeat) / gMaxTempoTvTypeFactors); + + // STARTODO: The game was originally designed to use either 1 or 2 buffers depending on the scenario + // Using 1 buffer has caused issues, so we hardcoded it to 2. + // To prevent sequences from going too fast, we added a * 2 here. + // This is not an optimal fix but it works. We may wish to find something better in the future. + gMaxTempo = (u16) ((gAudioBufferParams.ticksPerUpdate * 2 * 2880000.0f / gSeqTicksPerBeat) / gMaxTempoTvTypeFactors); + //gMaxTempo = (u16) ((gAudioBufferParams.ticksPerUpdate * 2880000.0f / gSeqTicksPerBeat) / gMaxTempoTvTypeFactors); gAudioBufferParams.numBuffers = spec->numBuffers; + gAudioBufferParams.numBuffers = 2; + gAudioBufferParams.samplesPerFrameTarget *= gAudioBufferParams.numBuffers; gAudioBufferParams.maxAiBufferLength *= gAudioBufferParams.numBuffers; gAudioBufferParams.minAiBufferLength *= gAudioBufferParams.numBuffers; diff --git a/src/audio/audio_load.c b/src/audio/audio_load.c index b0f2b823..e08f62f3 100644 --- a/src/audio/audio_load.c +++ b/src/audio/audio_load.c @@ -522,9 +522,12 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) { switch (tableType) { case SEQUENCE_TABLE: gSeqLoadStatus[id] = LOAD_STATUS_COMPLETE; + + //ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, id); return Audio_LoadBlob(gAudioSeq, table->entries[id].romAddr); case FONT_TABLE: gFontLoadStatus[id] = LOAD_STATUS_COMPLETE; + //ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, id); return Audio_LoadFont(table->entries[id]); case SAMPLE_TABLE: loadStatus = 0; @@ -708,7 +711,7 @@ void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, switch (tableType) { case SEQUENCE_TABLE: - gFontLoadStatus[id] = LOAD_STATUS_COMPLETE; + gSeqLoadStatus[id] = LOAD_STATUS_COMPLETE; osSendMesg(retQueue, OS_MESG_32(retData << 0x18), OS_MESG_NOBLOCK); return Audio_LoadBlob(gAudioSeq, table->entries[id].romAddr); case FONT_TABLE: @@ -719,7 +722,7 @@ void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, case SAMPLE_TABLE: gSampleFontLoadStatus[id] = LOAD_STATUS_COMPLETE; // LTODO: Validate this - // return Audio_LoadSample(table->entries[id].romAddr, 0); + return Audio_LoadSample(table->entries[id].romAddr, table->entries[id], id); return NULL; } @@ -736,39 +739,39 @@ void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, romAddr = table->entries[id].romAddr; loadStatus = LOAD_STATUS_COMPLETE; - // switch (cachePolicy) { - // case CACHEPOLICY_0: - // ramAddr = AudioHeap_AllocPermanent(tableType, id, size); - // if (ramAddr == NULL) { - // return ramAddr; - // } - // loadStatus = LOAD_STATUS_PERMANENTLY_LOADED; - // break; - // - // case CACHEPOLICY_1: - // ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, id); - // if (ramAddr == NULL) { - // return ramAddr; - // } - // break; - // - // case CACHEPOLICY_2: - // ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_TEMPORARY, id); - // if (ramAddr == NULL) { - // return ramAddr; - // } - // break; - // - // case CACHEPOLICY_3: - // case CACHEPOLICY_4: - // ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_EITHER, id); - // if (ramAddr == NULL) { - // return ramAddr; - // } - // break; - // } - // AudioLoad_StartAsyncLoad(romAddr, ramAddr, size, medium, nChunks, retQueue, - // (retData << 0x18) | (tableType << 0x10) | (id << 8) | loadStatus); + switch (cachePolicy) { + case CACHEPOLICY_0: + ramAddr = AudioHeap_AllocPermanent(tableType, id, size); + if (ramAddr == NULL) { + return ramAddr; + } + loadStatus = LOAD_STATUS_PERMANENTLY_LOADED; + break; + + case CACHEPOLICY_1: + ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, id); + if (ramAddr == NULL) { + return ramAddr; + } + break; + + case CACHEPOLICY_2: + ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_TEMPORARY, id); + if (ramAddr == NULL) { + return ramAddr; + } + break; + + case CACHEPOLICY_3: + case CACHEPOLICY_4: + ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_EITHER, id); + if (ramAddr == NULL) { + return ramAddr; + } + break; + } + AudioLoad_StartAsyncLoad(romAddr, ramAddr, size, medium, nChunks, retQueue, + (retData << 0x18) | (tableType << 0x10) | (id << 8) | loadStatus); } switch (tableType) { diff --git a/src/audio/audio_playback.c b/src/audio/audio_playback.c index 50242bf4..b83a60bc 100644 --- a/src/audio/audio_playback.c +++ b/src/audio/audio_playback.c @@ -169,9 +169,10 @@ TunedSample* Audio_GetInstrumentTunedSample(Instrument* instrument, s32 arg1) { Instrument* Audio_GetInstrument(s32 fontId, s32 instId) { Instrument* instrument; - // LTODO: Remove this + //fontId = 7; + if(gSoundFontList[fontId].instruments == NULL){ - gSoundFontList[fontId] = *Audio_LoadFont(gSoundFontTable->entries[fontId]); + gSoundFontList[fontId] = *Audio_LoadFont(gSoundFontTable->entries[fontId]); } if ((gFontLoadStatus[fontId] < 2) != 0) { diff --git a/src/audio/audio_seqplayer.c b/src/audio/audio_seqplayer.c index 0ea7cb6f..a1bad11f 100644 --- a/src/audio/audio_seqplayer.c +++ b/src/audio/audio_seqplayer.c @@ -143,13 +143,16 @@ void AudioSeq_SeqLayerDisable(SequenceLayer* layer) { } } -void AudioSeq_SeqLayerFree(SequenceChannel* channel, s32 layerIndex) { - SequenceLayer* layer = channel->layers[layerIndex]; +void AudioSeq_SeqLayerFree(SequenceChannel* channel, s32 layerIndex) +{ + if (layerIndex < 4) { + SequenceLayer* layer = channel->layers[layerIndex]; - if (layer != NULL) { - AudioSeq_AudioListPushBack(&gLayerFreeList, &layer->listItem); - AudioSeq_SeqLayerDisable(layer); - channel->layers[layerIndex] = NULL; + if (layer != NULL) { + AudioSeq_AudioListPushBack(&gLayerFreeList, &layer->listItem); + AudioSeq_SeqLayerDisable(layer); + channel->layers[layerIndex] = NULL; + } } } @@ -907,7 +910,8 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { sp52 = ((u16*) gSeqFontTable)[seqPlayer->seqId]; loBits = gSeqFontTable[sp52]; cmd = gSeqFontTable[sp52 + loBits - cmd]; - if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, cmd) != NULL) { + //if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, cmd) != NULL) + { channel->fontId = cmd; } /* fallthrough */ @@ -1013,7 +1017,11 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { sp52 = ((u16*) gSeqFontTable)[seqPlayer->seqId]; loBits = gSeqFontTable[sp52]; cmd = gSeqFontTable[sp52 + loBits - cmd]; - if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, cmd) != NULL) { + + printf("seqID: %02X\n", seqPlayer->seqId); + + //if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, cmd) != NULL) + { channel->fontId = cmd; } break; diff --git a/src/audio/audio_synthesis.c b/src/audio/audio_synthesis.c index 9bc8444f..0500e01f 100644 --- a/src/audio/audio_synthesis.c +++ b/src/audio/audio_synthesis.c @@ -667,8 +667,9 @@ Acmd* AudioSynth_Update(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLe //if (gAudioBufferParams.ticksPerUpdate > 3 && gGameState != GSTATE_PLAY) return; aCmdPtr = aList; for (i = gAudioBufferParams.ticksPerUpdate; i > 0; i--) { - AudioSeq_ProcessSequences(i - 1); - AudioSynth_SyncSampleStates(gAudioBufferParams.ticksPerUpdate - i); + + AudioSeq_ProcessSequences(i - 1); + AudioSynth_SyncSampleStates(gAudioBufferParams.ticksPerUpdate - i); } aiBufPtr = aiBufStart; @@ -676,16 +677,16 @@ Acmd* AudioSynth_Update(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLe // problem for (i = gAudioBufferParams.ticksPerUpdate; i > 0; i--) { if (i == 1) { - printf("func_80009B64 i == 1\n"); + //printf("func_80009B64 i == 1\n"); chunkLen = aiBufLen; } else if ((aiBufLen / i) >= gAudioBufferParams.samplesPerTickMax) { - printf("func_80009B64 (aiBufLen / i) >= gAudioBufferParams.samplesPerTickMax\n"); + //printf("func_80009B64 (aiBufLen / i) >= gAudioBufferParams.samplesPerTickMax\n"); chunkLen = gAudioBufferParams.samplesPerTickMax; } else if (gAudioBufferParams.samplesPerTickMin >= (aiBufLen / i)) { - printf("func_80009B64 gAudioBufferParams.samplesPerTickMin >= (aiBufLen / i)\n"); + //printf("func_80009B64 gAudioBufferParams.samplesPerTickMin >= (aiBufLen / i)\n"); chunkLen = gAudioBufferParams.samplesPerTickMin; } else { - printf("func_80009B64 else\n"); + //printf("func_80009B64 else\n"); chunkLen = gAudioBufferParams.samplesPerTick; } @@ -694,7 +695,7 @@ Acmd* AudioSynth_Update(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLe AudioSynth_InitNextRingBuf(chunkLen, gAudioBufferParams.ticksPerUpdate - i, j); } } - printf("chunkLen: %d, aiBufLen: %d \n", chunkLen, aiBufLen); + //printf("chunkLen: %d, aiBufLen: %d \n", chunkLen, aiBufLen); aCmdPtr = AudioSynth_DoOneAudioUpdate((s16*) aiBufPtr, chunkLen, aCmdPtr, gAudioBufferParams.ticksPerUpdate - i); @@ -866,7 +867,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisSta s32 padE8; s32 padE4; s32 padE0; - s32 skipBytes; + s32 skipBytes = 0; s32 padD8; s32 padD4; s32 padD0; diff --git a/src/engine/fox_load.c b/src/engine/fox_load.c index 63f36c6b..f740a0e2 100644 --- a/src/engine/fox_load.c +++ b/src/engine/fox_load.c @@ -34,8 +34,9 @@ void Load_RomFile(void* vRomAddress, void* dest, ptrdiff_t size) { u8 Load_SceneFiles(Scene* scene) { #if 1 + bool hasSceneChanged = memcmp(&sCurrentScene, scene, sizeof(Scene)) != 0; sCurrentScene = *scene; - return true; + return hasSceneChanged; #else u8* ramPtr = SEGMENT_VRAM_START(ovl_i1); u8 segment; @@ -167,13 +168,13 @@ u8 Load_SceneSetup(u8 sceneId, u8 sceneSetup) { case SCENE_VERSUS: changeScene = Load_SceneFiles(&sOvli2_Versus[sceneSetup]); if (changeScene == true) { - // AUDIO_SET_SPEC_ALT(SFXCHAN_3, AUDIOSPEC_16); + AUDIO_SET_SPEC_ALT(SFXCHAN_3, AUDIOSPEC_16); } break; case SCENE_LOGO: changeScene = Load_SceneFiles(&sNoOvl_Logo[sceneSetup]); // Logo does not load an overlay file if (changeScene == true) { - // AUDIO_SET_SPEC(SFXCHAN_0, AUDIOSPEC_MA); + AUDIO_SET_SPEC(SFXCHAN_0, AUDIOSPEC_MA); } break; case SCENE_CREDITS: diff --git a/src/engine/fox_message.c b/src/engine/fox_message.c index 750e10ef..5b7a9d06 100644 --- a/src/engine/fox_message.c +++ b/src/engine/fox_message.c @@ -7,7 +7,7 @@ u16* Message_PtrFromId(u16 msgId) { while (lookup->msgId != -1) { if (lookup->msgId == msgId) { - return lookup->path; + return ResourceGetDataByName(lookup->path); } lookup++; } diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 95c8b3b6..de722428 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -25,11 +25,14 @@ #include #include #include "audio/GameAudio.h" +//#include "sf64audio_provisional.h" #include #include #include +//extern "C" AudioBufferParameters gAudioBufferParams; + #include extern "C" { @@ -151,7 +154,7 @@ void GameEngine::StartFrame() const { #define NUM_AUDIO_CHANNELS 2 #define SAMPLES_PER_FRAME (SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3) -s16 audio_buffer[SAMPLES_PER_FRAME * 2] = { 0 }; +s16 audio_buffer[SAMPLES_PER_FRAME * 2 * 2] = { 0 }; extern "C" s32 audBuffer = 0; #include @@ -171,7 +174,11 @@ void GameEngine::HandleAudioThread() { } } -#define AUDIO_FRAMES_PER_UPDATE (gVIsPerFrame > 0 ? gVIsPerFrame : 1) + //gVIsPerFrame = 2; + +//#define AUDIO_FRAMES_PER_UPDATE (gVIsPerFrame > 0 ? gVIsPerFrame : 1) +#define AUDIO_FRAMES_PER_UPDATE 2 + std::unique_lock Lock(audio.mutex); int samples_left = AudioPlayerBuffered(); @@ -183,7 +190,7 @@ void GameEngine::HandleAudioThread() { countermin++; } - for (int i = 0; i < 2; i++) { + for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) { AudioThread_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples); } diff --git a/src/port/resource/loaders/AudioLoader.cpp b/src/port/resource/loaders/AudioLoader.cpp index 8a74db65..db1345dc 100644 --- a/src/port/resource/loaders/AudioLoader.cpp +++ b/src/port/resource/loaders/AudioLoader.cpp @@ -90,7 +90,7 @@ extern "C" SoundFont* Audio_LoadFont(AudioTableEntry entry) { } } - gSampleFontLoadStatus[font->sampleBankId1] = 2; + gSampleFontLoadStatus[font->sampleBankId1] = LOAD_STATUS_COMPLETE; gAudioCache[entry.romAddr] = font; return font; diff --git a/src/sys/sys_main.c b/src/sys/sys_main.c index dbe173a4..0d50b0e9 100644 --- a/src/sys/sys_main.c +++ b/src/sys/sys_main.c @@ -277,7 +277,6 @@ void Graphics_ThreadUpdate() { // osRecvMesg(&gGfxVImsgQueue, NULL, OS_MESG_BLOCK); // } - // LTODO: There is no audio for now :P osSendMesg(&gTaskMesgQueue, OS_MESG_PTR(NULL), OS_MESG_NOBLOCK); Audio_Update(); } @@ -363,7 +362,6 @@ void Main_ThreadEntry(void* arg0) { OSMesg ogMsg; u32 mesg; - // LTODO: Implement audio Audio_ThreadEntry(NULL); Graphics_ThreadEntry(NULL); Controller_Init();