From 3a4115e8f6fb8c0ad3ffd51e94000cca82609f0e Mon Sep 17 00:00:00 2001 From: MeltyPlayer Date: Sun, 6 Nov 2022 20:22:00 -0600 Subject: [PATCH] Pushed the final changes that got audio working! --- src/decomp/audio/external.c | 30 +++- src/decomp/audio/external.h | 10 +- src/decomp/audio/heap.c | 23 +-- src/decomp/audio/load.c | 115 ++++++------ src/decomp/audio/seqplayer.c | 52 ++++-- src/decomp/audio/synthesis.c | 269 +++++++---------------------- src/decomp/include/PR/abi.h | 8 +- src/decomp/include/PR/libaudio.h | 42 +---- src/decomp/include/platform_info.h | 2 +- src/decomp/pc/alBnkfNew.c | 7 + src/decomp/pc/mixer.c | 3 + src/decomp/tools/convUtils.c | 12 ++ src/libsm64.c | 24 ++- src/libsm64.h | 3 +- src/load_audio_data.c | 30 ++-- src/load_audio_data.h | 7 +- src/play_sound.c | 8 + 17 files changed, 274 insertions(+), 371 deletions(-) diff --git a/src/decomp/audio/external.c b/src/decomp/audio/external.c index fabb36f..a2222d7 100644 --- a/src/decomp/audio/external.c +++ b/src/decomp/audio/external.c @@ -35,11 +35,6 @@ #define SAMPLES_TO_OVERPRODUCE 0x10 #define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x40 -struct Sound { - s32 soundBits; - f32 *position; -}; // size = 0x8 - struct ChannelVolumeScaleFade { f32 velocity; u8 target; @@ -413,7 +408,7 @@ extern void func_802ad74c(u32 bits, u32 arg); extern void func_802ad770(u32 bits, s8 arg); static void update_background_music_after_sound(u8 bank, u8 soundIndex); -static void update_game_sound(void); +void update_game_sound(void); static void fade_channel_volume_scale(u8 player, u8 channelId, u8 targetScale, u16 fadeTimer); void process_level_music_dynamics(void); static u8 begin_background_music_fade(u16 fadeDuration); @@ -663,7 +658,11 @@ extern void func_sh_802F64C8(void); * Called from threads: thread5_game_loop */ void maybe_tick_game_sound(void) { + DEBUG_PRINT("maybe_tick_game_sound()"); + + DEBUG_PRINT("- if game loop ticked is false..."); if (sGameLoopTicked != 0) { + DEBUG_PRINT("- updating game sound"); update_game_sound(); sGameLoopTicked = 0; } @@ -794,14 +793,17 @@ struct SPTask *create_next_audio_frame_task(void) { return NULL; } void create_next_audio_buffer(s16 *samples, u32 num_samples) { + DEBUG_PRINT("create_next_audio_buffer()"); gAudioFrameCount++; if (sGameLoopTicked != 0) { update_game_sound(); sGameLoopTicked = 0; } s32 writtenCmds; + DEBUG_PRINT("- synthesis execute"); synthesis_execute(gAudioCmdBuffers[0], &writtenCmds, samples, num_samples); gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount); + DEBUG_PRINT("- decrease sample dma ttls"); decrease_sample_dma_ttls(); } #endif @@ -811,7 +813,7 @@ void create_next_audio_buffer(s16 *samples, u32 num_samples) { * Called from threads: thread4_sound, thread5_game_loop (EU only) */ static void process_sound_request(u32 bits, f32 *pos) { - //DEBUG_PRINT("process_sound_request %d\n", bits); + DEBUG_PRINT("# process_sound_request %d\n", bits); u8 bank; u8 soundIndex; u8 counter = 0; @@ -874,7 +876,7 @@ static void process_sound_request(u32 bits, f32 *pos) { // If free list has more than one element remaining if (sSoundBanks[bank][sSoundBankFreeListFront[bank]].next != 0xff && soundIndex != 0) { - //DEBUG_PRINT("process_sound_request2: soundIndex %d\n", soundIndex); + DEBUG_PRINT("process_sound_request2: soundIndex %d\n", soundIndex); // Allocate from free list soundIndex = sSoundBankFreeListFront[bank]; @@ -1333,7 +1335,7 @@ void audio_signal_game_loop_tick(void) { /** * Called from threads: thread4_sound, thread5_game_loop (EU and SH only) */ -static void update_game_sound(void) { +void update_game_sound(void) { u8 soundStatus; u8 i; u8 soundId; @@ -2628,6 +2630,7 @@ void play_toads_jingle(void) { * Called from threads: thread5_game_loop */ void sound_reset(u8 presetId) { + DEBUG_PRINT("sound_reset()"); #ifndef VERSION_JP if (presetId >= 8) { presetId = 0; @@ -2635,26 +2638,35 @@ void sound_reset(u8 presetId) { } #endif sGameLoopTicked = 0; + DEBUG_PRINT("- disable all sequence players"); disable_all_sequence_players(); + DEBUG_PRINT("- sound init"); sound_init(); #ifdef VERSION_SH func_802ad74c(0xF2000000, 0); #endif #if defined(VERSION_JP) || defined(VERSION_US) + DEBUG_PRINT("- audio reset session"); audio_reset_session(&gAudioSessionPresets[presetId]); #else audio_reset_session_eu(presetId); #endif + DEBUG_PRINT("- os write back dcache all"); osWritebackDCacheAll(); if (presetId != 7) { + DEBUG_PRINT("- preloading solve puzzle sequence"); preload_sequence(SEQ_EVENT_SOLVE_PUZZLE, PRELOAD_BANKS | PRELOAD_SEQUENCE); + DEBUG_PRINT("- preloading peach message"); preload_sequence(SEQ_EVENT_PEACH_MESSAGE, PRELOAD_BANKS | PRELOAD_SEQUENCE); + DEBUG_PRINT("- preloading star spawn"); preload_sequence(SEQ_EVENT_CUTSCENE_STAR_SPAWN, PRELOAD_BANKS | PRELOAD_SEQUENCE); } + DEBUG_PRINT("- playing sfx sequence"); seq_player_play_sequence(SEQ_PLAYER_SFX, SEQ_SOUND_PLAYER, 0); D_80332108 = (D_80332108 & 0xf0) + presetId; gSoundMode = D_80332108 >> 4; sHasStartedFadeOut = FALSE; + DEBUG_PRINT("- done resetting sound"); } /** diff --git a/src/decomp/audio/external.h b/src/decomp/audio/external.h index 53f97d2..00c6d39 100644 --- a/src/decomp/audio/external.h +++ b/src/decomp/audio/external.h @@ -24,11 +24,20 @@ extern u32 gAudioRandom; extern f32 gAudioVolume; extern u8 gAudioReverb; +struct Sound { + s32 soundBits; + f32 *position; +}; // size = 0x8 + +extern struct Sound sSoundRequests[0x100]; +extern u8 sSoundRequestCount; + extern u8 gAudioSPTaskYieldBuffer[]; // ucode yield data ptr; only used in JP struct SPTask *create_next_audio_frame_task(void); void create_next_audio_buffer(s16 *samples, u32 num_samples); void audio_signal_game_loop_tick(void); +void update_game_sound(void); void seq_player_fade_out(u8 player, u16 fadeDuration); void fade_volume_scale(u8 player, u8 targetScale, u16 fadeDuration); void seq_player_lower_volume(u8 player, u16 fadeDuration, u8 percentage); @@ -41,7 +50,6 @@ void stop_sounds_from_source(f32 *pos); void stop_sounds_in_continuous_banks(void); void sound_banks_disable(u8 player, u16 bankMask); void sound_banks_enable(u8 player, u16 bankMask); -void func_80320A4C(u8 bankIndex, u8 arg1); void set_sound_moving_speed(u8 bank, u8 speed); void play_dialog_sound(u8 dialogID); void play_music(u8 player, u16 seqArgs, u16 fadeTimer); diff --git a/src/decomp/audio/heap.c b/src/decomp/audio/heap.c index 27281d8..2ad885b 100644 --- a/src/decomp/audio/heap.c +++ b/src/decomp/audio/heap.c @@ -1,5 +1,6 @@ #include +#include "../../debug_print.h" #include "heap.h" #include "data.h" #include "load.h" @@ -252,26 +253,7 @@ void discard_sequence(s32 seqId) { } void *soundAlloc(struct SoundAllocPool *pool, u32 size) { -#if defined(VERSION_EU) || defined(VERSION_SH) - u8 *start; - u8 *pos; - u32 alignedSize = ALIGN16(size); - - start = pool->cur; - if (start + alignedSize <= pool->start + pool->size) { - pool->cur += alignedSize; - for (pos = start; pos < pool->cur; pos++) { - *pos = 0; - } - } else { - eu_stubbed_printf_1("Heap OverFlow : Not Allocate %d!\n", size); - return NULL; - } -#ifdef VERSION_SH - pool->numAllocatedEntries++; -#endif - return start; -#else + DEBUG_PRINT("soundAlloc()"); u8 *start; s32 last; s32 i; @@ -287,7 +269,6 @@ void *soundAlloc(struct SoundAllocPool *pool, u32 size) { return NULL; } return start; -#endif } #ifdef VERSION_SH diff --git a/src/decomp/audio/load.c b/src/decomp/audio/load.c index 58a2ba3..9dfe84c 100644 --- a/src/decomp/audio/load.c +++ b/src/decomp/audio/load.c @@ -1,6 +1,7 @@ #ifndef VERSION_SH #include +#include "../../debug_print.h" #include "data.h" #include "external.h" #include "heap.h" @@ -110,10 +111,17 @@ ALSeqFile *get_audio_file_header(s32 arg0); * Performs an immediate DMA copy */ void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) { + DEBUG_PRINT("audio_dma_copy_immediate()"); + DEBUG_PRINT("- dev addr: %x", devAddr); + DEBUG_PRINT("- vAddr: %x", vAddr); + DEBUG_PRINT("- # bytes: %d", nbytes); eu_stubbed_printf_3("Romcopy %x -> %x ,size %x\n", devAddr, vAddr, nbytes); + DEBUG_PRINT("- invalidate d cache"); osInvalDCache(vAddr, nbytes); + DEBUG_PRINT("- start dma"); osPiStartDma(&gAudioDmaIoMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, vAddr, nbytes, &gAudioDmaMesgQueue); + DEBUG_PRINT("- recv message"); osRecvMesg(&gAudioDmaMesgQueue, NULL, OS_MESG_BLOCK); eu_stubbed_printf_0("Romcopyend\n"); } @@ -580,6 +588,8 @@ l2: } struct AudioBank *bank_load_immediate(s32 bankId, s32 arg1) { + DEBUG_PRINT("bank_load_immediate()"); + UNUSED u32 pad1[4]; u32 buf[4]; u32 numInstruments, numDrums; @@ -589,24 +599,35 @@ struct AudioBank *bank_load_immediate(s32 bankId, s32 arg1) { // (This is broken if the length is 1 (mod 16), but that never happens -- // it's always divisible by 4.) + DEBUG_PRINT("- getting alloc"); alloc = gAlCtlHeader->seqArray[bankId].len + 0xf; + DEBUG_PRINT("- aligning"); alloc = ALIGN16(alloc); alloc -= 0x10; + DEBUG_PRINT("- getting ctl data for bank %d", bankId); ctlData = gAlCtlHeader->seqArray[bankId].offset; + DEBUG_PRINT("- alloc bank or seq"); ret = alloc_bank_or_seq(&gBankLoadedPool, 1, alloc, arg1, bankId); if (ret == NULL) { return NULL; } + DEBUG_PRINT("- copying dma immediate 1"); + DEBUG_PRINT("- ctlData: %x", ctlData); audio_dma_copy_immediate((uintptr_t) ctlData, buf, 0x10); + DEBUG_PRINT("- getting nums"); numInstruments = buf[0]; numDrums = buf[1]; + DEBUG_PRINT("- copying dma immediate 2"); audio_dma_copy_immediate((uintptr_t)(ctlData + 0x10), ret, alloc); + DEBUG_PRINT("- patching bank"); patch_audio_bank(ret, gAlTbl->seqArray[bankId].offset, numInstruments, numDrums); + DEBUG_PRINT("- setting ctl entries"); gCtlEntries[bankId].numInstruments = (u8) numInstruments; gCtlEntries[bankId].numDrums = (u8) numDrums; gCtlEntries[bankId].instruments = ret->instruments; gCtlEntries[bankId].drums = ret->drums; + DEBUG_PRINT("- setting load status"); gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_COMPLETE; return ret; } @@ -763,26 +784,32 @@ u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) { } struct AudioBank *load_banks_immediate(s32 seqId, u8 *outDefaultBank) { + DEBUG_PRINT("load_banks_immediate()"); void *ret; u32 bankId; u16 offset; u8 i; + DEBUG_PRINT("- getting offset"); offset = ((u16 *) gAlBankSets)[seqId]; #ifdef VERSION_EU for (i = gAlBankSets[offset++]; i != 0; i--) { bankId = gAlBankSets[offset++]; #else offset++; + DEBUG_PRINT("- looping through bank sets"); for (i = gAlBankSets[offset - 1]; i != 0; i--) { offset++; + DEBUG_PRINT("- getting bank id"); bankId = gAlBankSets[offset - 1]; #endif + DEBUG_PRINT("- checking if bank load is complete"); if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) { #ifdef VERSION_EU ret = get_bank_or_seq(&gBankLoadedPool, 2, bankId); #else + DEBUG_PRINT("- getting bank or seq"); ret = get_bank_or_seq(&gBankLoadedPool, 2, gAlBankSets[offset - 1]); #endif } else { @@ -790,6 +817,7 @@ struct AudioBank *load_banks_immediate(s32 seqId, u8 *outDefaultBank) { } if (ret == NULL) { + DEBUG_PRINT("- bank load immediate"); ret = bank_load_immediate(bankId, 2); } } @@ -798,6 +826,7 @@ struct AudioBank *load_banks_immediate(s32 seqId, u8 *outDefaultBank) { } void preload_sequence(u32 seqId, u8 preloadMask) { + DEBUG_PRINT("preload_sequence()"); void *sequenceData; u8 temp; @@ -807,17 +836,21 @@ void preload_sequence(u32 seqId, u8 preloadMask) { gAudioLoadLock = AUDIO_LOCK_LOADING; if (preloadMask & PRELOAD_BANKS) { + DEBUG_PRINT("- load banks immediate"); load_banks_immediate(seqId, &temp); } if (preloadMask & PRELOAD_SEQUENCE) { // @bug should be IS_SEQ_LOAD_COMPLETE + DEBUG_PRINT("- checking if bank load immediate"); if (IS_BANK_LOAD_COMPLETE(seqId) == TRUE) { eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId); + DEBUG_PRINT("- getting bank or seq"); sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId); } else { sequenceData = NULL; } + DEBUG_PRINT("- checking dma immediate"); if (sequenceData == NULL && sequence_dma_immediate(seqId, 2) == NULL) { gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; return; @@ -905,22 +938,12 @@ void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) { // (void) must be omitted from parameters to fix stack with -framepointer void audio_init() { -#if defined(VERSION_EU) - UNUSED s8 pad[16]; -#else + DEBUG_PRINT("audio_init()"); UNUSED s8 pad[32]; -#endif -#if defined(VERSION_JP) || defined(VERSION_US) u8 buf[0x10]; -#endif s32 i, j, UNUSED k; UNUSED s32 lim1; // lim1 unused in EU -#if defined(VERSION_EU) - UNUSED u8 buf[0x10]; - s32 UNUSED lim2, lim3; -#else s32 lim2, UNUSED lim3; -#endif UNUSED u32 size; UNUSED u64 *ptr64; void *data; @@ -928,57 +951,19 @@ void audio_init() { gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED; -#if defined(VERSION_JP) || defined(VERSION_US) + DEBUG_PRINT("- setting values in unused"); lim1 = gUnusedCount80333EE8; for (i = 0; i < lim1; i++) { gUnused80226E58[i] = 0; gUnused80226E98[i] = 0; } + DEBUG_PRINT("- clearing audio heap"); lim2 = gAudioHeapSize; for (i = 0; i <= lim2 / 8 - 1; i++) { ((u64 *) gAudioHeap)[i] = 0; } -#ifdef TARGET_N64 - // It seems boot.s doesn't clear the .bss area for audio, so do it here. - i = 0; - lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8; - ptr64 = &gAudioGlobalsStartMarker - 1; - for (k = lim3; k >= 0; k--) { - i++; - ptr64[i] = 0; - } -#endif - -#else - for (i = 0; i < gAudioHeapSize / 8; i++) { - ((u64 *) gAudioHeap)[i] = 0; - } - -#ifdef TARGET_N64 - // It seems boot.s doesn't clear the .bss area for audio, so do it here. - lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8; - ptr64 = &gAudioGlobalsStartMarker; - for (k = lim3; k >= 0; k--) { - *ptr64++ = 0; - } -#endif - - D_EU_802298D0 = 20.03042f; - gRefreshRate = 50; - port_eu_init(); - if (k) { - } -#endif - -#ifdef TARGET_N64 - eu_stubbed_printf_3("Clear Workarea %x -%x size %x \n", - (uintptr_t) &gAudioGlobalsStartMarker, - (uintptr_t) &gAudioGlobalsEndMarker, - (uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker - ); -#endif eu_stubbed_printf_1("AudioHeap is %x\n", gAudioHeapSize); @@ -1009,13 +994,7 @@ void audio_init() { } } -#if defined(VERSION_EU) - gAudioResetPresetIdToLoad = 0; - gAudioResetStatus = 1; - audio_shut_down_and_reset_step(); -#else audio_reset_session(&gAudioSessionPresets[0]); -#endif // Not sure about these prints eu_stubbed_printf_1("Heap reset.Synth Change %x \n", 0); @@ -1027,33 +1006,45 @@ void audio_init() { data = gMusicData; audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, 0x10); gSequenceCount = gSeqFileHeader->seqCount; -#if defined(VERSION_EU) - size = gSequenceCount * sizeof(ALSeqData) + 4; - size = ALIGN16(size); -#else size = ALIGN16(gSequenceCount * sizeof(ALSeqData) + 4); -#endif gSeqFileHeader = soundAlloc(&gAudioInitPool, size); audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, size); alSeqFileNew(gSeqFileHeader, data); // Load header for CTL (instrument metadata) + DEBUG_PRINT("- loading ctl header"); gAlCtlHeader = (ALSeqFile *) buf; data = gSoundDataADSR; + DEBUG_PRINT("- copying dma immediate"); audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, 0x10); size = gAlCtlHeader->seqCount * sizeof(ALSeqData) + 4; + DEBUG_PRINT("- seq count: %d", gAlCtlHeader->seqCount); + DEBUG_PRINT("- size after read: %d", size); size = ALIGN16(size); + DEBUG_PRINT("- size after align: %d", size); gCtlEntries = soundAlloc(&gAudioInitPool, gAlCtlHeader->seqCount * sizeof(struct CtlEntry)); gAlCtlHeader = soundAlloc(&gAudioInitPool, size); + DEBUG_PRINT("@ copying data from sound data adsr to ctl header"); + DEBUG_PRINT("- data: %x", data); + DEBUG_PRINT("- ctl header: %x", gAlCtlHeader); + DEBUG_PRINT("- size: %d", size); audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, size); + DEBUG_PRINT("- creating new seq file for ctl"); alSeqFileNew(gAlCtlHeader, data); // Load header for TBL (raw sound data) + DEBUG_PRINT("- loading tbl"); gAlTbl = (ALSeqFile *) buf; + DEBUG_PRINT("- copying dma"); audio_dma_copy_immediate((uintptr_t) data, gAlTbl, 0x10); + DEBUG_PRINT("- tbl seq count: %d", gAlTbl->seqCount); size = gAlTbl->seqCount * sizeof(ALSeqData) + 4; + DEBUG_PRINT("- size: %d", size); size = ALIGN16(size); + DEBUG_PRINT("- size after align: %d", size); gAlTbl = soundAlloc(&gAudioInitPool, size); + DEBUG_PRINT("- tbl alloc at %x", gAlTbl); + DEBUG_PRINT("- gSoundDataRaw at %x", gSoundDataRaw); audio_dma_copy_immediate((uintptr_t) gSoundDataRaw, gAlTbl, size); alSeqFileNew(gAlTbl, gSoundDataRaw); diff --git a/src/decomp/audio/seqplayer.c b/src/decomp/audio/seqplayer.c index 9055160..c9e95b6 100644 --- a/src/decomp/audio/seqplayer.c +++ b/src/decomp/audio/seqplayer.c @@ -6,6 +6,7 @@ #include "heap.h" #include "load.h" #include "seqplayer.h" +#include "../../debug_print.h" #define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80) #define PORTAMENTO_MODE(x) ((x).mode & ~0x80) @@ -398,12 +399,11 @@ void init_layer_freelist(void) { } u8 m64_read_u8(struct M64ScriptState *state) { -#if defined(VERSION_EU) || defined(VERSION_SH) - return *(state->pc++); -#else + DEBUG_PRINT("m64_read_u8()"); + DEBUG_PRINT("- state at %x", state); u8 *midiArg = state->pc++; + DEBUG_PRINT("- read u8 (%d) at (%x)", *midiArg, midiArg); return *midiArg; -#endif } s16 m64_read_s16(struct M64ScriptState *state) { @@ -1109,7 +1109,11 @@ s32 seq_channel_layer_process_script_part2(struct SequenceChannelLayer *layer) { break; case 0xc6: // layer_setinstr + DEBUG_PRINT(" - cmd 0xc6, setinstr"); + cmd = m64_read_u8(state); + DEBUG_PRINT(" - read %d from state", cmd); + if (cmd >= 0x7f) { if (cmd == 0x7f) { layer->instOrWave = 0; @@ -1401,6 +1405,9 @@ s32 seq_channel_layer_process_script_part3(struct SequenceChannelLayer *layer, s #endif u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrument **instOut, struct AdsrSettings *adsr) { + DEBUG_PRINT("@ get_instrument()"); + DEBUG_PRINT("- instrument id: %d", instId); + struct Instrument *inst; #if defined(VERSION_EU) || defined(VERSION_SH) inst = get_instrument_inner(seqChannel->bankId, instId); @@ -1458,6 +1465,10 @@ u8 get_instrument(struct SequenceChannel *seqChannel, u8 instId, struct Instrume } void set_instrument(struct SequenceChannel *seqChannel, u8 instId) { + DEBUG_PRINT("@ set_instrument()"); + DEBUG_PRINT("- bank id: %d", seqChannel->bankId); + DEBUG_PRINT("- instrument id: %d", instId); + if (instId >= 0x80) { seqChannel->instOrWave = instId; seqChannel->instrument = NULL; @@ -1486,6 +1497,8 @@ void sequence_channel_set_volume(struct SequenceChannel *seqChannel, u8 volume) } void sequence_channel_process_script(struct SequenceChannel *seqChannel) { + DEBUG_PRINT("sequence_channel_process_script()"); + struct M64ScriptState *state; struct SequencePlayer *seqPlayer; u8 cmd; @@ -1523,6 +1536,8 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { if (seqChannel->delay == 0) { for (;;) { cmd = m64_read_u8(state); + DEBUG_PRINT("- handling command: %x", cmd); + #if !defined(VERSION_EU) && !defined(VERSION_SH) if (cmd == 0xff) // chan_end { @@ -1703,7 +1718,12 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { #endif case 0xc1: // chan_setinstr ("set program"?) - set_instrument(seqChannel, m64_read_u8(state)); + DEBUG_PRINT(" - cmd 0xc1, setinstr"); + + u8 instrId = m64_read_u8(state); + DEBUG_PRINT(" - read %d from state", instrId); + + set_instrument(seqChannel, instrId); break; case 0xc3: // chan_largenotesoff @@ -1832,25 +1852,21 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { break; case 0xc6: // chan_setbank; switch bank within set + DEBUG_PRINT(" - case 0xc6 - switch bank"); + + DEBUG_PRINT(" - seq id %d", seqPlayer->seqId); + cmd = m64_read_u8(state); + DEBUG_PRINT(" - backwards bank id %d", cmd); + // Switch to the temp's (0-indexed) bank in this sequence's // bank set. Note that in the binary format (not in the JSON!) // the banks are listed backwards, so we counts from the back. // (gAlBankSets[offset] is number of banks) -#if defined(VERSION_EU) || defined(VERSION_SH) - sp38 = ((u16 *) gAlBankSets)[seqPlayer->seqId]; - loBits = *(sp38 + gAlBankSets); - cmd = gAlBankSets[(s32)sp38 + loBits - cmd]; -#else sp5A = ((u16 *) gAlBankSets)[seqPlayer->seqId]; loBits = *(sp5A + gAlBankSets); cmd = gAlBankSets[sp5A + loBits - cmd]; -#endif -#ifdef VERSION_SH - if (get_bank_or_seq(1, 2, cmd) != NULL) -#else if (get_bank_or_seq(&gBankLoadedPool, 2, cmd) != NULL) -#endif { seqChannel->bankId = cmd; } else { @@ -2138,6 +2154,8 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { #else case 0x80: // chan_ioreadval; read data from audio lib #endif + DEBUG_PRINT("- cmd 0x80, read data from audio lib"); + DEBUG_PRINT(" - reading index: %d", loBits); value = seqChannel->soundScriptIO[loBits]; if (loBits < 4) { seqChannel->soundScriptIO[loBits] = -1; @@ -2229,7 +2247,9 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { } void sequence_player_process_sequence(struct SequencePlayer *seqPlayer) { - u8 cmd; + DEBUG_PRINT("sequence_player_process_sequence()"); + + u8 cmd; #ifdef VERSION_SH UNUSED u32 pad; #endif diff --git a/src/decomp/audio/synthesis.c b/src/decomp/audio/synthesis.c index 727f195..d673171 100644 --- a/src/decomp/audio/synthesis.c +++ b/src/decomp/audio/synthesis.c @@ -1,6 +1,7 @@ #ifndef VERSION_SH #include +#include "../../debug_print.h" #include "synthesis.h" #include "heap.h" #include "data.h" @@ -27,9 +28,13 @@ #define DMEM_ADDR_WET_RIGHT_CH 0x880 #define aSetLoadBufferPair(pkt, c, off) \ + DEBUG_PRINT("- (in set load buffer pair, set buffer 1) "); \ aSetBuffer(pkt, 0, c + DMEM_ADDR_WET_LEFT_CH, 0, DEFAULT_LEN_1CH - c); \ + DEBUG_PRINT("- (in set load buffer pair, load buffer 1) "); \ aLoadBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.left + (off))); \ + DEBUG_PRINT("- (in set load buffer pair, set buffer 2) "); \ aSetBuffer(pkt, 0, c + DMEM_ADDR_WET_RIGHT_CH, 0, DEFAULT_LEN_1CH - c); \ + DEBUG_PRINT("- (in set load buffer pair, load buffer 2) "); \ aLoadBuffer(pkt, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.ringBuffer.right + (off))) #define aSetSaveBufferPair(pkt, c, d, off) \ @@ -324,6 +329,7 @@ u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { #else // bufLen will be divisible by 16 u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { + DEBUG_PRINT("synthesis_execute()"); s32 chunkLen; s32 i; u32 *aiBufPtr = (u32 *) aiBuf; @@ -506,6 +512,8 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateI } #else u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateIndex) { + DEBUG_PRINT("synthesis_do_one_audio_update()"); + UNUSED s32 pad1[1]; s16 ra; s16 t4; @@ -514,35 +522,52 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateI UNUSED s32 pad2[1]; s16 temp; + DEBUG_PRINT("- curFrame: %d", gSynthesisReverb.curFrame); + DEBUG_PRINT("- updateIndex: %d", updateIndex); + v1 = &gSynthesisReverb.items[gSynthesisReverb.curFrame][updateIndex]; + DEBUG_PRINT("- v1: %x", v1); if (gSynthesisReverb.useReverb == 0) { + DEBUG_PRINT("- w/o reverb"); aClearBuffer(cmd++, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); cmd = synthesis_process_notes(aiBuf, bufLen, cmd); } else { + DEBUG_PRINT("- w/ reverb"); if (gReverbDownsampleRate == 1) { + DEBUG_PRINT("- w/ reverb downsample"); + // Put the oldest samples in the ring buffer into the wet channels + DEBUG_PRINT("- set load buffer pair 1"); + DEBUG_PRINT("- startPos: %d", v1->startPos); aSetLoadBufferPair(cmd++, 0, v1->startPos); if (v1->lengthB != 0) { // Ring buffer wrapped + DEBUG_PRINT("- set load buffer pair 2"); aSetLoadBufferPair(cmd++, v1->lengthA, 0); temp = 0; } // Use the reverb sound as initial sound for this audio update + DEBUG_PRINT("- dmem move"); aDMEMMove(cmd++, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, DEFAULT_LEN_2CH); // (Hopefully) lower the volume of the wet channels. New reverb will later be mixed into // these channels. + DEBUG_PRINT("- set buffer"); aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH); // 0x8000 here is -100% + DEBUG_PRINT("- mix"); aMix(cmd++, 0, /*gain*/ 0x8000 + gSynthesisReverb.reverbGain, /*in*/ DMEM_ADDR_WET_LEFT_CH, /*out*/ DMEM_ADDR_WET_LEFT_CH); } else { + DEBUG_PRINT("- w/o reverb downsample"); + // Same as above but upsample the previously downsampled samples used for reverb first temp = 0; //! jesus christ t4 = (v1->startPos & 7) * 2; ra = ALIGN(v1->lengthA + t4, 4); + DEBUG_PRINT("- set load buffer pair"); aSetLoadBufferPair(cmd++, 0, v1->startPos - t4 / 2); if (v1->lengthB != 0) { // Ring buffer wrapped @@ -553,12 +578,19 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, s32 updateI //! useless assignment. ra = ra + temp; } + DEBUG_PRINT("- set buffer 1"); aSetBuffer(cmd++, 0, t4 + DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH, bufLen << 1); + DEBUG_PRINT("- resample 1"); aResample(cmd++, gSynthesisReverb.resampleFlags, (u16) gSynthesisReverb.resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.resampleStateLeft)); + DEBUG_PRINT("- set buffer 2"); aSetBuffer(cmd++, 0, t4 + DMEM_ADDR_WET_RIGHT_CH, DMEM_ADDR_RIGHT_CH, bufLen << 1); + DEBUG_PRINT("- resample 2"); aResample(cmd++, gSynthesisReverb.resampleFlags, (u16) gSynthesisReverb.resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverb.resampleStateRight)); + DEBUG_PRINT("- set buffer 3"); aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH); + DEBUG_PRINT("- mix"); aMix(cmd++, 0, /*gain*/ 0x8000 + gSynthesisReverb.reverbGain, /*in*/ DMEM_ADDR_LEFT_CH, /*out*/ DMEM_ADDR_LEFT_CH); + DEBUG_PRINT("- dmem move"); aDMEMMove(cmd++, DMEM_ADDR_LEFT_CH, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); } cmd = synthesis_process_notes(aiBuf, bufLen, cmd); @@ -586,6 +618,8 @@ u64 *synthesis_process_note(struct Note *note, struct NoteSubEu *noteSubEu, stru UNUSED s32 pad0[3]; #else u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { + DEBUG_PRINT("synthesis_process_notes()"); + s32 noteIndex; // sp174 struct Note *note; // s7 UNUSED u8 pad0[0x08]; @@ -669,49 +703,35 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { u16 noteSamplesDmemAddrBeforeResampling; // spD6, spAA -#ifndef VERSION_EU for (noteIndex = 0; noteIndex < gMaxSimultaneousNotes; noteIndex++) { + DEBUG_PRINT("- for note index %d/%d", noteIndex, gMaxSimultaneousNotes); + + DEBUG_PRINT("- getting note"); note = &gNotes[noteIndex]; -#ifdef VERSION_US + //! This function requires note->enabled to be volatile, but it breaks other functions like note_enable. //! Casting to a struct with just the volatile bitfield works, but there may be a better way to match. + DEBUG_PRINT("- if note is enabled but not loaded"); if (((struct vNote *)note)->enabled && IS_BANK_LOAD_COMPLETE(note->bankId) == FALSE) { -#else - if (IS_BANK_LOAD_COMPLETE(note->bankId) == FALSE) { -#endif + DEBUG_PRINT("- note is enabled but not loaded"); gAudioErrorFlags = (note->bankId << 8) + noteIndex + 0x1000000; - } else if (((struct vNote *)note)->enabled) { -#else - if (note->noteSubEu.enabled == FALSE) { - return cmd; - } else { -#endif - flags = 0; -#ifdef VERSION_EU - tempBufLen = bufLen; -#endif + continue; + } -#ifdef VERSION_EU - if (noteSubEu->needsInit == TRUE) { -#else + DEBUG_PRINT("- if note is enabled"); + if (((struct vNote *)note)->enabled) { + DEBUG_PRINT("$ note is enabled!"); + + flags = 0; + + DEBUG_PRINT("- if note needs to be init"); if (note->needsInit == TRUE) { -#endif flags = A_INIT; -#ifndef VERSION_EU note->samplePosInt = 0; note->samplePosFrac = 0; -#else - synthesisState->restart = FALSE; - synthesisState->samplePosInt = 0; - synthesisState->samplePosFrac = 0; - synthesisState->curVolLeft = 1; - synthesisState->curVolRight = 1; - synthesisState->prevHeadsetPanRight = 0; - synthesisState->prevHeadsetPanLeft = 0; -#endif } -#ifndef VERSION_EU + DEBUG_PRINT("- if note frequency is less than 2"); if (note->frequency < US_FLOAT(2.0)) { nParts = 1; if (note->frequency > US_FLOAT(1.99996)) { @@ -730,43 +750,29 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { resamplingRateFixedPoint = (u16)(s32)(resamplingRate * 32768.0f); samplesLenFixedPoint = note->samplePosFrac + (resamplingRateFixedPoint * bufLen) * 2; note->samplePosFrac = samplesLenFixedPoint & 0xFFFF; // 16-bit store, can't reuse -#else - resamplingRateFixedPoint = noteSubEu->resamplingRateFixedPoint; - nParts = noteSubEu->hasTwoAdpcmParts + 1; - samplesLenFixedPoint = (resamplingRateFixedPoint * tempBufLen * 2) + synthesisState->samplePosFrac; - synthesisState->samplePosFrac = samplesLenFixedPoint & 0xFFFF; -#endif -#ifdef VERSION_EU - if (noteSubEu->isSyntheticWave) { - cmd = load_wave_samples(cmd, noteSubEu, synthesisState, samplesLenFixedPoint >> 0x10); - noteSamplesDmemAddrBeforeResampling = (synthesisState->samplePosInt * 2) + DMEM_ADDR_UNCOMPRESSED_NOTE; - synthesisState->samplePosInt += samplesLenFixedPoint >> 0x10; - } -#else + DEBUG_PRINT("- if note sound is null"); if (note->sound == NULL) { // A wave synthesis note (not ADPCM) + DEBUG_PRINT("- note is null, do wave synthesis"); cmd = load_wave_samples(cmd, note, samplesLenFixedPoint >> 0x10); noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_UNCOMPRESSED_NOTE + note->samplePosInt * 2; note->samplePosInt += (samplesLenFixedPoint >> 0x10); flags = 0; } -#endif else { // ADPCM note + DEBUG_PRINT("- @ handle adpcm note"); -#ifdef VERSION_EU - audioBookSample = noteSubEu->sound.audioBankSound->sample; -#else audioBookSample = note->sound->sample; -#endif loopInfo = audioBookSample->loop; endPos = loopInfo->end; sampleAddr = audioBookSample->sampleAddr; resampledTempLen = 0; for (curPart = 0; curPart < nParts; curPart++) { + DEBUG_PRINT("- for part %d", curPart); nAdpcmSamplesProcessed = 0; // s8 s5 = 0; // s4 @@ -782,21 +788,11 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { if (curLoadedBook != audioBookSample->book->book) { u32 nEntries; // v1 curLoadedBook = audioBookSample->book->book; -#ifdef VERSION_EU - nEntries = 16 * audioBookSample->book->order * audioBookSample->book->npredictors; - aLoadADPCM(cmd++, nEntries, VIRTUAL_TO_PHYSICAL2(curLoadedBook + noteSubEu->bookOffset)); -#else nEntries = audioBookSample->book->order * audioBookSample->book->npredictors; + DEBUG_PRINT("- loading adpcm"); aLoadADPCM(cmd++, nEntries * 16, VIRTUAL_TO_PHYSICAL2(curLoadedBook)); -#endif } -#ifdef VERSION_EU - if (noteSubEu->bookOffset) { - curLoadedBook = euUnknownData_80301950; // what's this? never read - } -#endif - while (nAdpcmSamplesProcessed != samplesLenAdjusted) { s32 samplesRemaining; // v1 s32 s0; @@ -804,23 +800,12 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { noteFinished = FALSE; restart = FALSE; nSamplesToProcess = samplesLenAdjusted - nAdpcmSamplesProcessed; -#ifdef VERSION_EU - s2 = synthesisState->samplePosInt & 0xf; - samplesRemaining = endPos - synthesisState->samplePosInt; -#else s2 = note->samplePosInt & 0xf; samplesRemaining = endPos - note->samplePosInt; -#endif -#ifdef VERSION_EU - if (s2 == 0 && synthesisState->restart == FALSE) { - s2 = 16; - } -#else if (s2 == 0 && note->restart == FALSE) { s2 = 16; } -#endif s6 = 16 - s2; // a1 if (nSamplesToProcess < samplesRemaining) { @@ -828,11 +813,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { s0 = t0 * 16; s3 = s6 + s0 - nSamplesToProcess; } else { -#ifndef VERSION_EU s0 = samplesRemaining + s2 - 0x10; -#else - s0 = samplesRemaining - s6; -#endif s3 = 0; if (s0 <= 0) { s0 = 0; @@ -848,21 +829,10 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { } if (t0 != 0) { -#ifdef VERSION_EU - temp = (synthesisState->samplePosInt - s2 + 0x10) / 16; - if (audioBookSample->loaded == 0x81) { - v0_2 = sampleAddr + temp * 9; - } else { - v0_2 = dma_sample_data( - (uintptr_t) (sampleAddr + temp * 9), - t0 * 9, flags, &synthesisState->sampleDmaIndex); - } -#else temp = (note->samplePosInt - s2 + 0x10) / 16; v0_2 = dma_sample_data( (uintptr_t) (sampleAddr + temp * 9), t0 * 9, flags, ¬e->sampleDmaIndex); -#endif a3 = (u32)((uintptr_t) v0_2 & 0xf); aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA, 0, t0 * 9 + a3); aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(v0_2 - a3)); @@ -871,38 +841,14 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { a3 = 0; } -#ifdef VERSION_EU - if (synthesisState->restart != FALSE) { - aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state)); - flags = A_LOOP; // = 2 - synthesisState->restart = FALSE; - } -#else + DEBUG_PRINT("- if not note restart"); if (note->restart != FALSE) { aSetLoop(cmd++, VIRTUAL_TO_PHYSICAL2(audioBookSample->loop->state)); flags = A_LOOP; // = 2 note->restart = FALSE; } -#endif nSamplesInThisIteration = s0 + s6 - s3; -#ifdef VERSION_EU - if (nAdpcmSamplesProcessed == 0) { - aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, - DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2); - aADPCMdec(cmd++, flags, - VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); - sp130 = s2 * 2; - } else { - s5Aligned = ALIGN(s5, 5); - aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, - DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned, s0 * 2); - aADPCMdec(cmd++, flags, - VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->adpcmdecState)); - aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5Aligned + (s2 * 2), - DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (nSamplesInThisIteration) * 2); - } -#else if (nAdpcmSamplesProcessed == 0) { aSetBuffer(cmd++, 0, DMEM_ADDR_COMPRESSED_ADPCM_DATA + a3, DMEM_ADDR_UNCOMPRESSED_NOTE, s0 * 2); aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->adpcmdecState)); @@ -912,7 +858,6 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { aADPCMdec(cmd++, flags, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->adpcmdecState)); aDMEMMove(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + ALIGN(s5, 5) + (s2 * 2), DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (nSamplesInThisIteration) * 2); } -#endif nAdpcmSamplesProcessed += nSamplesInThisIteration; @@ -936,35 +881,23 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { } flags = 0; + DEBUG_PRINT("- if note finished"); if (noteFinished) { aClearBuffer(cmd++, DMEM_ADDR_UNCOMPRESSED_NOTE + s5, (samplesLenAdjusted - nAdpcmSamplesProcessed) * 2); -#ifdef VERSION_EU - noteSubEu->finished = 1; - note->noteSubEu.finished = 1; - note->noteSubEu.enabled = 0; -#else note->samplePosInt = 0; note->finished = 1; ((struct vNote *)note)->enabled = 0; -#endif break; } -#ifdef VERSION_EU - if (restart) { - synthesisState->restart = TRUE; - synthesisState->samplePosInt = loopInfo->start; - } else { - synthesisState->samplePosInt += nSamplesToProcess; - } -#else + + DEBUG_PRINT("- if restart"); if (restart) { note->restart = TRUE; note->samplePosInt = loopInfo->start; } else { note->samplePosInt += nSamplesToProcess; } -#endif } switch (nParts) { @@ -976,18 +909,10 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { switch (curPart) { case 0: aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED, samplesLenAdjusted + 4); -#ifdef VERSION_EU - aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->dummyResampleState)); -#else aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->dummyResampleState)); -#endif resampledTempLen = samplesLenAdjusted + 4; noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_RESAMPLED + 4; -#ifdef VERSION_EU - if (noteSubEu->finished != FALSE) { -#else if (note->finished != FALSE) { -#endif aClearBuffer(cmd++, DMEM_ADDR_RESAMPLED + resampledTempLen, samplesLenAdjusted + 0x10); } break; @@ -996,15 +921,9 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED2, samplesLenAdjusted + 8); -#ifdef VERSION_EU - aResample(cmd++, A_INIT, 0xff60, - VIRTUAL_TO_PHYSICAL2( - synthesisState->synthesisBuffers->dummyResampleState)); -#else aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2( note->synthesisBuffers->dummyResampleState)); -#endif aDMEMMove(cmd++, DMEM_ADDR_RESAMPLED2 + 4, DMEM_ADDR_RESAMPLED + resampledTempLen, samplesLenAdjusted + 4); @@ -1012,11 +931,7 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { } } -#ifdef VERSION_EU - if (noteSubEu->finished != FALSE) { -#else if (note->finished != FALSE) { -#endif break; } } @@ -1024,15 +939,6 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { flags = 0; -#ifdef VERSION_EU - if (noteSubEu->needsInit == TRUE) { - flags = A_INIT; - noteSubEu->needsInit = FALSE; - } - - cmd = final_resample(cmd, synthesisState, bufLen * 2, resamplingRateFixedPoint, - noteSamplesDmemAddrBeforeResampling, flags); -#else if (note->needsInit == TRUE) { flags = A_INIT; note->needsInit = FALSE; @@ -1040,75 +946,41 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { cmd = final_resample(cmd, note, bufLen * 2, resamplingRateFixedPoint, noteSamplesDmemAddrBeforeResampling, flags); -#endif -#ifdef VERSION_EU - if (noteSubEu->headsetPanRight != 0 || synthesisState->prevHeadsetPanRight != 0) { - leftRight = 1; - } else if (noteSubEu->headsetPanLeft != 0 || synthesisState->prevHeadsetPanLeft != 0) { - leftRight = 2; -#else if (note->headsetPanRight != 0 || note->prevHeadsetPanRight != 0) { leftRight = 1; } else if (note->headsetPanLeft != 0 || note->prevHeadsetPanLeft != 0) { leftRight = 2; -#endif } else { leftRight = 0; } -#ifdef VERSION_EU - cmd = process_envelope(cmd, noteSubEu, synthesisState, bufLen, 0, leftRight, flags); -#else cmd = process_envelope(cmd, note, bufLen, 0, leftRight, flags); -#endif -#ifdef VERSION_EU - if (noteSubEu->usesHeadsetPanEffects) { - cmd = note_apply_headset_pan_effects(cmd, noteSubEu, synthesisState, bufLen * 2, flags, leftRight); - } -#else if (note->usesHeadsetPanEffects) { cmd = note_apply_headset_pan_effects(cmd, note, bufLen * 2, flags, leftRight); } -#endif } -#ifndef VERSION_EU } + DEBUG_PRINT("- done handling notes"); + + DEBUG_PRINT("- setting buffer 1"); t9 = bufLen * 2; aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, t9); + DEBUG_PRINT("- interleaving"); aInterleave(cmd++, DMEM_ADDR_LEFT_CH, DMEM_ADDR_RIGHT_CH); t9 *= 2; + DEBUG_PRINT("- setting buffer 2"); aSetBuffer(cmd++, 0, 0, DMEM_ADDR_TEMP, t9); + DEBUG_PRINT("- saving buffer"); aSaveBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(aiBuf)); -#endif + DEBUG_PRINT("- returning from process notes"); return cmd; } -#ifdef VERSION_EU -u64 *load_wave_samples(u64 *cmd, struct NoteSubEu *noteSubEu, struct NoteSynthesisState *synthesisState, s32 nSamplesToLoad) { - s32 a3; - s32 repeats; - s32 i; - aSetBuffer(cmd++, /*flags*/ 0, /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, /*dmemout*/ 0, /*count*/ 128); - aLoadBuffer(cmd++, VIRTUAL_TO_PHYSICAL2(noteSubEu->sound.samples)); - synthesisState->samplePosInt &= 0x3f; - a3 = 64 - synthesisState->samplePosInt; - if (a3 < nSamplesToLoad) { - repeats = (nSamplesToLoad - a3 + 63) / 64; - for (i = 0; i < repeats; i++) { - aDMEMMove(cmd++, - /*dmemin*/ DMEM_ADDR_UNCOMPRESSED_NOTE, - /*dmemout*/ DMEM_ADDR_UNCOMPRESSED_NOTE + (1 + i) * 128, - /*count*/ 128); - } - } - return cmd; -} -#else u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad) { s32 a3; s32 i; @@ -1124,21 +996,12 @@ u64 *load_wave_samples(u64 *cmd, struct Note *note, s32 nSamplesToLoad) { } return cmd; } -#endif -#ifdef VERSION_EU -u64 *final_resample(u64 *cmd, struct NoteSynthesisState *synthesisState, s32 count, u16 pitch, u16 dmemIn, u32 flags) { - aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ DMEM_ADDR_TEMP, count); - aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->finalResampleState)); - return cmd; -} -#else u64 *final_resample(u64 *cmd, struct Note *note, s32 count, u16 pitch, u16 dmemIn, u32 flags) { aSetBuffer(cmd++, /*flags*/ 0, dmemIn, /*dmemout*/ DMEM_ADDR_TEMP, count); aResample(cmd++, flags, pitch, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->finalResampleState)); return cmd; } -#endif #ifndef VERSION_EU u64 *process_envelope(u64 *cmd, struct Note *note, s32 nSamples, u16 inBuf, s32 headsetPanSettings, diff --git a/src/decomp/include/PR/abi.h b/src/decomp/include/PR/abi.h index b73cb72..b4b2f84 100644 --- a/src/decomp/include/PR/abi.h +++ b/src/decomp/include/PR/abi.h @@ -439,10 +439,14 @@ typedef short ENVMIX_STATE[40]; * s parameter to this command is the source in DRAM. */ #define aLoadBuffer(pkt, s) \ -{ \ +{ \ + DEBUG_PRINT("aLoadBuffer()"); \ + DEBUG_PRINT("- getting pkt"); \ Acmd *_a = (Acmd *)pkt; \ \ + DEBUG_PRINT("- setting first word"); \ _a->words.w0 = _SHIFTL(A_LOADBUFF, 24, 8); \ + DEBUG_PRINT("- setting second word"); \ _a->words.w1 = (uintptr_t)(s); \ } @@ -558,6 +562,8 @@ typedef short ENVMIX_STATE[40]; */ #define aSetBuffer(pkt, f, i, o, c) \ { \ + DEBUG_PRINT("aSetBuffer()"); \ + DEBUG_PRINT("- getting pkt"); \ Acmd *_a = (Acmd *)pkt; \ \ _a->words.w0 = (_SHIFTL(A_SETBUFF, 24, 8) | _SHIFTL(f, 16, 8) | \ diff --git a/src/decomp/include/PR/libaudio.h b/src/decomp/include/PR/libaudio.h index cb7a5b1..81d1c18 100644 --- a/src/decomp/include/PR/libaudio.h +++ b/src/decomp/include/PR/libaudio.h @@ -2,49 +2,21 @@ #define _ULTRA64_LIBAUDIO_H_ #include "abi.h" +#include typedef struct { - u8 *offset; - s32 len; -#ifdef VERSION_SH - s8 medium; - s8 magic; // tbl: 0x04, otherwise: 0x03 - - // for ctl (else zeros): - union { - // unused, just for clarification (big endian) - struct { - u8 bank; - u8 ff; - u8 numInstruments; - u8 numDrums; - } as_u8; - - // used - struct { - s16 bankAndFf; - s16 numInstrumentsAndDrums; - } as_s16; - } ctl; -#endif + u8 *offset __attribute__((aligned (8))); + s32 len __attribute__((aligned (8))); } ALSeqData; typedef struct { -#ifndef VERSION_SH - s16 revision; -#endif - s16 seqCount; -#ifdef VERSION_SH - s16 unk2; - u8 *data; -#if !IS_64_BIT - s32 pad[2]; -#endif -#endif + unsigned short revision; + unsigned short seqCount; + unsigned int pad; ALSeqData seqArray[1]; -} ALSeqFile; +} __attribute__((aligned (16))) ALSeqFile; void alSeqFileNew(ALSeqFile *f, u8 *base); diff --git a/src/decomp/include/platform_info.h b/src/decomp/include/platform_info.h index 310aa4d..f8ccbe2 100644 --- a/src/decomp/include/platform_info.h +++ b/src/decomp/include/platform_info.h @@ -10,6 +10,6 @@ #define IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) #endif -#define DOUBLE_SIZE_ON_64_BIT(size) ((size) * (sizeof(void *) / 4)) +#define DOUBLE_SIZE_ON_64_BIT(size) ((size) * 2) #endif // PLATFORM_INFO_H diff --git a/src/decomp/pc/alBnkfNew.c b/src/decomp/pc/alBnkfNew.c index bb04df3..fa003b1 100644 --- a/src/decomp/pc/alBnkfNew.c +++ b/src/decomp/pc/alBnkfNew.c @@ -1,12 +1,19 @@ #include "libultra_internal.h" #include "libaudio_internal.h" +#include "../../debug_print.h" + #define PATCH(SRC, BASE, TYPE) //SRC = (TYPE)((uintptr_t) SRC + (uintptr_t) BASE) void alSeqFileNew(ALSeqFile *f, u8 *base) { + DEBUG_PRINT("alSeqFileNew()"); int i; + DEBUG_PRINT("- patching %d entries", f->seqCount); for (i = 0; i < f->seqCount; i++) { + DEBUG_PRINT("- handling entry %d", i); + DEBUG_PRINT("- patching offset (%x) with base (%x)", f->seqArray[i].offset, base); PATCH(f->seqArray[i].offset, base, u8 *); + DEBUG_PRINT("- result is (%x)", f->seqArray[i].offset); } } diff --git a/src/decomp/pc/mixer.c b/src/decomp/pc/mixer.c index 62d2cbb..8c53ad4 100644 --- a/src/decomp/pc/mixer.c +++ b/src/decomp/pc/mixer.c @@ -4,6 +4,7 @@ #include #include "mixer.h" +#include "../../debug_print.h" #ifdef __SSE4_1__ #include @@ -147,6 +148,8 @@ void aSaveBufferImpl(uint16_t source_addr, int16_t *dest_addr, uint16_t nbytes) } #else void aLoadBufferImpl(const void *source_addr) { + DEBUG_PRINT("aLoadBufferImpl()"); + DEBUG_PRINT("- source_addr: %x", source_addr); memcpy(BUF_U8(rspa.in), source_addr, ROUND_UP_8(rspa.nbytes)); } diff --git a/src/decomp/tools/convUtils.c b/src/decomp/tools/convUtils.c index 5ee21f4..d9b3794 100644 --- a/src/decomp/tools/convUtils.c +++ b/src/decomp/tools/convUtils.c @@ -1,6 +1,7 @@ #pragma once #include "convUtils.h" +#include "../../debug_print.h" #include "utils.h" #include #include @@ -21,6 +22,8 @@ unsigned char* gCtlSeqs; struct seqFile* parse_seqfile(unsigned char* seq){ /* Read SeqFile data */ + DEBUG_PRINT("parse_seqfile()"); + short revision = read_u16_be(seq); short bankCount = read_u16_be(seq + 2); @@ -34,14 +37,20 @@ struct seqFile* parse_seqfile(unsigned char* seq){ /* Read SeqFile data */ seqFile->seqArray[i].len = read_u32_be((seq + 4 + i * 8 + 4)); } + DEBUG_PRINT("- revision: %d", revision); if (revision == TYPE_CTL){ + DEBUG_PRINT("- ctl!"); // CTL file, contains instrument and drum data, this is really the only one that needs to be parsed, the rest only needs a header change gCtlSeqs = (unsigned char*)calloc(0x20B40, 1); // We only really need 0x20AD0 bytes but still uintptr_t pos = (uintptr_t)gCtlSeqs; + DEBUG_PRINT("- bank count: %d", bankCount); for (int i = 0; i < bankCount; i++){ + DEBUG_PRINT("- ctl bank index: %d", i); uintptr_t start = pos; struct CTL* ptr = parse_ctl_data(seq+(seqFile->seqArray[i].offset), &pos); + DEBUG_PRINT("- read ptr: %x", ptr); seqFile->seqArray[i].offset = ptr; + DEBUG_PRINT("- stored offset: %x", seqFile->seqArray[i].offset); seqFile->seqArray[i].len = (unsigned int)(pos - start); } }else if (revision == TYPE_TBL){ @@ -247,6 +256,9 @@ struct SEQ* parse_seq_data(unsigned char* seq){ } struct CTL* parse_ctl_data(unsigned char* ctlData, uintptr_t* pos){ + DEBUG_PRINT("parse_ctl_data()"); + DEBUG_PRINT("- ctlData: %x", ctlData); + DEBUG_PRINT("- pos: %x", pos); int instruments=read_u32_be(ctlData); unsigned int size = sizeof(struct CTL) + sizeof(struct CInstrument*) * (instruments-1); struct CTL* ctl = (struct CTL*)(*pos); diff --git a/src/libsm64.c b/src/libsm64.c index dd8c15d..5157113 100644 --- a/src/libsm64.c +++ b/src/libsm64.c @@ -10,6 +10,7 @@ #include #include +#include "decomp/audio/external.h" #include "decomp/include/PR/os_cont.h" #include "decomp/engine/math_util.h" #include "decomp/include/sm64.h" @@ -135,8 +136,27 @@ SM64_LIB_FN void sm64_global_terminate( void ) memory_terminate(); } -SM64_LIB_FN struct AudioBanks sm64_asset_load_audio_banks( uint8_t *rom ) { - return load_audio_banks( rom ); +SM64_LIB_FN void sm64_audio_init( uint8_t *rom ) { + load_audio_banks( rom ); +} + +#define SAMPLES_HIGH 544 +#define SAMPLES_LOW 528 + +extern SM64_LIB_FN uint32_t sm64_audio_tick( uint32_t numQueuedSamples, uint32_t numDesiredSamples, int16_t *audio_buffer ) { + DEBUG_PRINT("sm64_tick_audio()"); + + DEBUG_PRINT("- update game sound"); + update_game_sound(); + + DEBUG_PRINT("- create next audio buffer"); + u32 num_audio_samples = numQueuedSamples < numDesiredSamples ? SAMPLES_HIGH : SAMPLES_LOW; + for (int i = 0; i < 2; i++) + { + create_next_audio_buffer(audio_buffer + i * (2 * num_audio_samples), num_audio_samples); + } + + return num_audio_samples; } SM64_LIB_FN void sm64_static_surfaces_load( const struct SM64Surface *surfaceArray, uint32_t numSurfaces ) diff --git a/src/libsm64.h b/src/libsm64.h index 53ac004..0a7d902 100644 --- a/src/libsm64.h +++ b/src/libsm64.h @@ -80,7 +80,8 @@ extern SM64_LIB_FN void sm64_register_play_sound_function( SM64PlaySoundFunction extern SM64_LIB_FN void sm64_global_init( uint8_t *rom, uint8_t *outTexture ); extern SM64_LIB_FN void sm64_global_terminate( void ); -extern SM64_LIB_FN struct AudioBanks sm64_asset_load_audio_banks( uint8_t *rom ); +extern SM64_LIB_FN void sm64_audio_init( uint8_t *rom ); +extern SM64_LIB_FN uint32_t sm64_audio_tick( uint32_t numQueuedSamples, uint32_t numDesiredSamples, int16_t *audio_buffer ); extern SM64_LIB_FN void sm64_static_surfaces_load( const struct SM64Surface *surfaceArray, uint32_t numSurfaces ); diff --git a/src/load_audio_data.c b/src/load_audio_data.c index efa500c..b8c1363 100644 --- a/src/load_audio_data.c +++ b/src/load_audio_data.c @@ -1,32 +1,36 @@ #include "load_audio_data.h" +#include "debug_print.h" #include "decomp/tools/convUtils.h" #include "decomp/audio/load.h" #include "decomp/audio/load_dat.h" -extern struct AudioBanks load_audio_banks( uint8_t *rom ) { +extern void load_audio_banks( uint8_t *rom ) { + DEBUG_PRINT("load_audio_banks()"); + DEBUG_PRINT("- malloc"); uint8_t *rom2 = malloc(0x800000); + DEBUG_PRINT("- memcpy"); memcpy(rom2, rom, 0x800000); rom = rom2; + DEBUG_PRINT("- parse ctl"); gSoundDataADSR = parse_seqfile(rom+0x57B720); //ctl + DEBUG_PRINT("- parse tbl"); gSoundDataRaw = parse_seqfile(rom+0x593560); //tbl + DEBUG_PRINT("- parse music"); gMusicData = parse_seqfile(rom+0x7B0860); gBankSetsData = rom+0x7CC621; + DEBUG_PRINT("- memmove"); memmove(gBankSetsData+0x45,gBankSetsData+0x45-1,0x5B); gBankSetsData[0x45]=0x00; + DEBUG_PRINT("- ptrs to offsets"); ptrs_to_offsets(gSoundDataADSR); - audio_init(); - - int numBanks = 10; - for (int i = 0; i < 10; ++i) { - bank_load_immediate(i, 2); - } - - struct AudioBanks audioBanks; - audioBanks.numCtlEntries = numBanks; - audioBanks.ctlEntries = gCtlEntries; - - return audioBanks; + DEBUG_PRINT("- audio init"); + audio_init(); + DEBUG_PRINT("- sound init"); + sound_init(); + DEBUG_PRINT("- sound reset"); + sound_reset(0); + DEBUG_PRINT("- done with audio init!"); } \ No newline at end of file diff --git a/src/load_audio_data.h b/src/load_audio_data.h index 90b99c8..6d9c537 100644 --- a/src/load_audio_data.h +++ b/src/load_audio_data.h @@ -2,9 +2,4 @@ #include -struct AudioBanks { - int numCtlEntries; - struct CtlEntry * ctlEntries; -}; - -extern struct AudioBanks load_audio_banks( uint8_t *rom ); \ No newline at end of file +extern void load_audio_banks( uint8_t *rom ); \ No newline at end of file diff --git a/src/play_sound.c b/src/play_sound.c index 0560ba3..10efbd1 100644 --- a/src/play_sound.c +++ b/src/play_sound.c @@ -1,8 +1,16 @@ #include "play_sound.h" +#include "decomp/audio/external.h" +#include "debug_print.h" + SM64PlaySoundFunctionPtr g_play_sound_func = NULL; extern void play_sound( uint32_t soundBits, f32 *pos ) { + DEBUG_PRINT("$ play_sound(%d) request %d; pos %f %f %f\n", soundBits,sSoundRequestCount,pos[0],pos[1],pos[2]); + sSoundRequests[sSoundRequestCount].soundBits = soundBits; + sSoundRequests[sSoundRequestCount].position = pos; + sSoundRequestCount++; + if ( g_play_sound_func ) { g_play_sound_func(soundBits, pos); }