From 5ed3bb86d35e0bf8ce8c6ec39a91396e07d5e797 Mon Sep 17 00:00:00 2001 From: Sonic Dreamcaster Date: Tue, 12 Nov 2024 13:21:26 -0300 Subject: [PATCH] audiospec fix --- include/sf64audio_external.h | 4 +- src/audio/audio_heap.c | 16 +++ src/audio/audio_load.c | 230 ++++++++++++++++++----------------- src/audio/audio_synthesis.c | 24 ++-- src/audio/audio_thread.c | 20 +-- src/audio/mixer.c | 9 +- src/buffers.c | 2 +- src/engine/fox_game.c | 45 +++++-- src/port/Engine.cpp | 9 +- src/port/Engine.h | 5 +- 10 files changed, 213 insertions(+), 151 deletions(-) diff --git a/include/sf64audio_external.h b/include/sf64audio_external.h index 034c6006..eea7762b 100644 --- a/include/sf64audio_external.h +++ b/include/sf64audio_external.h @@ -18,8 +18,8 @@ void Audio_SetVolume(u8 audioType, u8 volume); void Audio_FadeOutAll(u8 fadeoutTime); void Audio_SetAudioSpec(u8 unused, u16 specParam); -#define AUDIO_SET_SPEC(sfxLayout, spec) // Audio_SetAudioSpec(0, ((sfxLayout) << 8) | (spec)) -#define AUDIO_SET_SPEC_ALT(sfxLayout, spec) // Audio_SetAudioSpec((sfxLayout), ((sfxLayout) << 8) | (spec)) +#define AUDIO_SET_SPEC(sfxLayout, spec) Audio_SetAudioSpec(0, ((sfxLayout) << 8) | (spec)) +#define AUDIO_SET_SPEC_ALT(sfxLayout, spec) Audio_SetAudioSpec((sfxLayout), ((sfxLayout) << 8) | (spec)) // used by sys or related void AudioLoad_Init(void); diff --git a/src/audio/audio_heap.c b/src/audio/audio_heap.c index ddabe098..b9911a35 100644 --- a/src/audio/audio_heap.c +++ b/src/audio/audio_heap.c @@ -664,17 +664,21 @@ void AudioHeap_Init(void) { gAudioBufferParams.resampleRate = 32000.0f / (s32) gAudioBufferParams.samplingFrequency; gAudioBufferParams.ticksPerUpdateInvScaled = (3.0f / 2560.0f) / gAudioBufferParams.ticksPerUpdate; gAudioBufferParams.ticksPerUpdateInv = 1.0f / gAudioBufferParams.ticksPerUpdate; + gNumNotes = spec->numNotes; D_8014C1B0 = spec->unk_14; gMaxTempo = (u16) ((gAudioBufferParams.ticksPerUpdate * 2880000.0f / gSeqTicksPerBeat) / gMaxTempoTvTypeFactors); + gAudioBufferParams.count = spec->numBuffers; gAudioBufferParams.samplesPerFrameTarget *= gAudioBufferParams.count; gAudioBufferParams.maxAiBufferLength *= gAudioBufferParams.count; gAudioBufferParams.minAiBufferLength *= gAudioBufferParams.count; gAudioBufferParams.ticksPerUpdate *= gAudioBufferParams.count; + if (gAudioBufferParams.count >= 2) { gAudioBufferParams.maxAiBufferLength -= 0x10; } + gMaxAudioCmds = (gNumNotes * 20 * gAudioBufferParams.ticksPerUpdate) + (spec->numReverbs * 32) + 480; persistentSize = spec->persistentSeqCacheSize + spec->persistentFontCacheSize + spec->persistentSampleBankCacheSize + spec->persistentSampleCacheSize + 0x10; @@ -684,30 +688,42 @@ void AudioHeap_Init(void) { miscPoolSize = gSessionPool.size - cachePoolSize - 0x100; gSessionPoolSplit.miscPoolSize = miscPoolSize; gSessionPoolSplit.cachePoolSize = cachePoolSize; + AudioHeap_InitSessionPools(&gSessionPoolSplit); + gCachePoolSplit.persistentCommonPoolSize = persistentSize; gCachePoolSplit.temporaryCommonPoolSize = temporarySize; + AudioHeap_InitCachePools(&gCachePoolSplit); + gPersistentCommonPoolSplit.seqCacheSize = spec->persistentSeqCacheSize; gPersistentCommonPoolSplit.fontCacheSize = spec->persistentFontCacheSize; gPersistentCommonPoolSplit.sampleBankCacheSize = spec->persistentSampleBankCacheSize; + AudioHeap_InitPersistentPoolsAndCaches(&gPersistentCommonPoolSplit); + gTemporaryCommonPoolSplit.seqCacheSize = spec->temporarySeqCacheSize; gTemporaryCommonPoolSplit.fontCacheSize = spec->temporaryFontCacheSize; gTemporaryCommonPoolSplit.sampleBankCacheSize = spec->temporarySampleBankCacheSize; + AudioHeap_InitTemporaryPoolsAndCaches(&gTemporaryCommonPoolSplit); AudioHeap_InitSampleCaches(spec->persistentSampleCacheSize, spec->temporarySampleCacheSize); AudioHeap_ResetLoadStatus(); + gNotes = AudioHeap_AllocZeroed(&gMiscPool, gNumNotes * sizeof(Note)); + func_800132E8(); func_800128B4(); + gNoteSubsEu = AudioHeap_AllocZeroed(&gMiscPool, gAudioBufferParams.ticksPerUpdate * gNumNotes * sizeof(NoteSubEu)); + for (i = 0; i != 2; i++) { gAbiCmdBuffs[i] = AudioHeap_AllocZeroed(&gMiscPool, gMaxAudioCmds * 8); } for (i = 0; i < ARRAY_COUNT(gSynthReverbs); i++) { gSynthReverbs[i].useReverb = 0; } + gNumSynthReverbs = spec->numReverbs; for (i = 0; i < gNumSynthReverbs; i++) { settings = &spec->reverbSettings[i]; diff --git a/src/audio/audio_load.c b/src/audio/audio_load.c index 2ab63256..25461d79 100644 --- a/src/audio/audio_load.c +++ b/src/audio/audio_load.c @@ -38,7 +38,8 @@ void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus); void AudioLoad_AsyncDma(AudioAsyncLoad* asyncLoad, u32 size); void AudioLoad_AsyncDmaUnkMedium(uintptr_t devAddr, u8* ramAddr, u32 size, s32 unkMediumParam); void AudioLoad_RelocateSample(TunedSample* tSample, u32 fontDataAddr, SampleBankRelocInfo* relocInfo); -s32 AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, uintptr_t fontDataAddr, SampleBankRelocInfo* relocData, s32 isAsync); +s32 AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, uintptr_t fontDataAddr, SampleBankRelocInfo* relocData, + s32 isAsync); s32 AudioLoad_ProcessSamplePreloads(s32 resetStatus); void AudioLoad_DecreaseSampleDmaTtls(void) { @@ -269,7 +270,8 @@ s32 AudioLoad_SyncLoadSample(Sample* sample, s32 fontId) { u8* sampleAddr; if ((sample->isRelocated == true) && (sample->medium != MEDIUM_RAM)) { - sampleAddr = AudioHeap_AllocPersistentSampleCache(sample->size, fontId, (uintptr_t) sample->sampleAddr, sample->medium); + sampleAddr = + AudioHeap_AllocPersistentSampleCache(sample->size, fontId, (uintptr_t) sample->sampleAddr, sample->medium); if (sampleAddr == NULL) { return -1; } @@ -311,7 +313,8 @@ s32 AudioLoad_SyncLoadInstrument(s32 fontId, s32 instId, s32 drumId) { } void AudioLoad_AsyncLoadSampleBank(s32 sampleBankId, s32 nChunks, s32 retData, OSMesgQueue* retQueue) { - AudioLoad_AsyncLoadInner(SAMPLE_TABLE, AudioLoad_GetLoadTableIndex(SAMPLE_TABLE, sampleBankId), nChunks, retData, retQueue); + AudioLoad_AsyncLoadInner(SAMPLE_TABLE, AudioLoad_GetLoadTableIndex(SAMPLE_TABLE, sampleBankId), nChunks, retData, + retQueue); osSendMesg(retQueue, OS_MESG_PTR(NULL), OS_MESG_NOBLOCK); } @@ -577,34 +580,34 @@ AudioTable* AudioLoad_GetLoadTable(s32 tableType) { } void AudioLoad_RelocateFont(s32 fontId, uintptr_t fontBaseAddr, SampleBankRelocInfo* relocData) { -// uint32_t* fontDataPtrs = fontBaseAddr; -// uint32_t** drumDataPtrs = fontBaseAddr; -// s32 numDrums; -// u32 offset; -// s32 i; -// s32 numInstruments; -// -// numDrums = gSoundFontList[fontId].numDrums; -// numInstruments = gSoundFontList[fontId].numInstruments; -// -// Drum** relocatedDrums = memalloc(numDrums * sizeof(Drum*)); -// Instrument** relocatedInstruments = memalloc((numInstruments + 1) * sizeof(Instrument*)); -// -// if ((fontDataPtrs[0] != 0) && (numDrums != 0)) { -// for (i = 0; i < numDrums; i++) { -// offset = *(*drumDataPtrs + i); -// if (offset != 0) { -// relocatedDrums[i] = Audio_LoadDrum(BSWAP32(offset), 0, relocData->sampleBankId1); -// } -// } -// } -// -// for (i = 1; i <= numInstruments; i++) { -// if (fontDataPtrs[i] != 0) { -// // TODO: fix this -// relocatedInstruments[i] = Audio_LoadInstrument(BSWAP32(fontDataPtrs[i]), relocData->sampleBankId1); -// } -// } + // uint32_t* fontDataPtrs = fontBaseAddr; + // uint32_t** drumDataPtrs = fontBaseAddr; + // s32 numDrums; + // u32 offset; + // s32 i; + // s32 numInstruments; + // + // numDrums = gSoundFontList[fontId].numDrums; + // numInstruments = gSoundFontList[fontId].numInstruments; + // + // Drum** relocatedDrums = memalloc(numDrums * sizeof(Drum*)); + // Instrument** relocatedInstruments = memalloc((numInstruments + 1) * sizeof(Instrument*)); + // + // if ((fontDataPtrs[0] != 0) && (numDrums != 0)) { + // for (i = 0; i < numDrums; i++) { + // offset = *(*drumDataPtrs + i); + // if (offset != 0) { + // relocatedDrums[i] = Audio_LoadDrum(BSWAP32(offset), 0, relocData->sampleBankId1); + // } + // } + // } + // + // for (i = 1; i <= numInstruments; i++) { + // if (fontDataPtrs[i] != 0) { + // // TODO: fix this + // relocatedInstruments[i] = Audio_LoadInstrument(BSWAP32(fontDataPtrs[i]), relocData->sampleBankId1); + // } + // } AudioTable* table = AudioLoad_GetLoadTable(FONT_TABLE); printf("fontId: %d\n", fontId); SoundFont* font = Audio_LoadFont(table->entries[fontId]); @@ -716,7 +719,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, 0); return NULL; } @@ -733,40 +736,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) { @@ -821,9 +823,9 @@ void AudioLoad_Init(void) { gAudioResetTimer = 0; - // for (i = 0; i < gAudioHeapSize / 8; i++) { - // *((u64*) gAudioHeap + i) = 0; - // } + for (i = 0; i < gAudioHeapSize / 8; i++) { + *((u64*) gAudioHeap + i) = 0; + } clearContext = gAudioContextStart; dwordsLeft = ((uintptr_t) gAudioContextEnd - (uintptr_t) gAudioContextStart) / 8; @@ -874,9 +876,9 @@ void AudioLoad_Init(void) { gSeqFontTable = gSeqFontTableInit; gNumSequences = gSequenceTable->base.numEntries; -// AudioLoad_InitTable(gSequenceTable, LOAD_ASSET(gAudioSeq), gSequenceMedium); -// AudioLoad_InitTable(gSoundFontTable, LOAD_ASSET(gAudioBank), gSoundFontMedium); -// AudioLoad_InitTable(gSampleBankTable, LOAD_ASSET(gAudioTable), gSampleBankMedium); + // AudioLoad_InitTable(gSequenceTable, LOAD_ASSET(gAudioSeq), gSequenceMedium); + // AudioLoad_InitTable(gSoundFontTable, LOAD_ASSET(gAudioBank), gSoundFontMedium); + // AudioLoad_InitTable(gSampleBankTable, LOAD_ASSET(gAudioTable), gSampleBankMedium); numFonts = gSoundFontTable->base.numEntries; @@ -1213,41 +1215,43 @@ static const char devstr50[] = "Error: Already wavetable is touched %x.\n"; static const char devstr51[] = "Touch Warning: Length zero %x\n"; void AudioLoad_RelocateSample(TunedSample* tSample, u32 fontDataAddr, SampleBankRelocInfo* relocInfo) { -// Sample32Bit* baseSample = fontDataAddr + BSWAP32(tSample->sample); -// -// // "Touch Warning: Length zero %x\n"; -// if ((baseSample->size != 0) && (baseSample->isRelocated != 1)) { -// Sample* output = memalloc(sizeof(Sample)); -// -// output->loop = Audio_LoadLoop(fontDataAddr + BSWAP32(baseSample->loop)); -// output->book = Audio_LoadBook(fontDataAddr + BSWAP32(baseSample->book)); -// output->codec = baseSample->codec; -// output->medium = baseSample->medium; -// output->unk_bit26 = baseSample->unk_bit26; -// output->isRelocated = baseSample->isRelocated; -// output->size = baseSample->size; -// -// output->isRelocated = 1; -// switch (baseSample->medium) { -// case MEDIUM_RAM: -//// baseSample->sampleAddr = Audio_LoadCopy(relocInfo->baseAddr1 + BSWAP32(baseSample->sampleAddr), BSWAP32(baseSample->size)); -// baseSample->medium = relocInfo->medium1; -// break; -// case MEDIUM_UNK: -//// baseSample->sampleAddr = Audio_LoadCopy(relocInfo->baseAddr2 + BSWAP32(baseSample->sampleAddr), BSWAP32(baseSample->size)); -// baseSample->medium = relocInfo->medium2; -// break; -// case MEDIUM_CART: -// case MEDIUM_DISK_DRIVE: -// output->sampleAddr = fontDataAddr + BSWAP32(baseSample->sampleAddr); -// break; -// } -// -// baseSample->isRelocated = true; -// if (baseSample->unk_bit26 && (baseSample->medium != 0)) { -// gUsedSamples[gNumUsedSamples++] = output; -// } -// } + // Sample32Bit* baseSample = fontDataAddr + BSWAP32(tSample->sample); + // + // // "Touch Warning: Length zero %x\n"; + // if ((baseSample->size != 0) && (baseSample->isRelocated != 1)) { + // Sample* output = memalloc(sizeof(Sample)); + // + // output->loop = Audio_LoadLoop(fontDataAddr + BSWAP32(baseSample->loop)); + // output->book = Audio_LoadBook(fontDataAddr + BSWAP32(baseSample->book)); + // output->codec = baseSample->codec; + // output->medium = baseSample->medium; + // output->unk_bit26 = baseSample->unk_bit26; + // output->isRelocated = baseSample->isRelocated; + // output->size = baseSample->size; + // + // output->isRelocated = 1; + // switch (baseSample->medium) { + // case MEDIUM_RAM: + //// baseSample->sampleAddr = Audio_LoadCopy(relocInfo->baseAddr1 + BSWAP32(baseSample->sampleAddr), + ///BSWAP32(baseSample->size)); + // baseSample->medium = relocInfo->medium1; + // break; + // case MEDIUM_UNK: + //// baseSample->sampleAddr = Audio_LoadCopy(relocInfo->baseAddr2 + BSWAP32(baseSample->sampleAddr), + ///BSWAP32(baseSample->size)); + // baseSample->medium = relocInfo->medium2; + // break; + // case MEDIUM_CART: + // case MEDIUM_DISK_DRIVE: + // output->sampleAddr = fontDataAddr + BSWAP32(baseSample->sampleAddr); + // break; + // } + // + // baseSample->isRelocated = true; + // if (baseSample->unk_bit26 && (baseSample->medium != 0)) { + // gUsedSamples[gNumUsedSamples++] = output; + // } + // } } static const char devstr52[] = "It's busy now!!!!! %d\n"; @@ -1256,7 +1260,8 @@ static const char devstr54[] = "Warning: Length zero %x\n"; static const char devstr55[] = "Wave Load %d \n"; static const char devstr56[] = "Total Bg Wave Load %d \n"; -s32 AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, uintptr_t fontDataAddr, SampleBankRelocInfo* relocData, s32 isAsync) { +s32 AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, uintptr_t fontDataAddr, SampleBankRelocInfo* relocData, + s32 isAsync) { s32 i; Sample* sample; u8* sampleRamAddr; @@ -1279,9 +1284,9 @@ s32 AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, uintptr_t fontDataAddr, size = 0; - for (i = 0; i < gNumUsedSamples; i++) { - size += ALIGN16(gUsedSamples[i]->size); - } + for (i = 0; i < gNumUsedSamples; i++) { + size += ALIGN16(gUsedSamples[i]->size); + } for (i = 0; i < gNumUsedSamples; i++) { if (gPreloadSampleStackTop == 120) { @@ -1322,7 +1327,8 @@ s32 AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, uintptr_t fontDataAddr, switch (isAsync) { case AUDIOLOAD_SYNC: if (sample->medium == MEDIUM_UNK) { - AudioLoad_SyncDmaUnkMedium(sample->sampleAddr, sampleRamAddr, sample->size, gSampleBankTable->base.unkMediumParam); + AudioLoad_SyncDmaUnkMedium(sample->sampleAddr, sampleRamAddr, sample->size, + gSampleBankTable->base.unkMediumParam); sample->sampleAddr = sampleRamAddr; sample->medium = MEDIUM_RAM; } else { diff --git a/src/audio/audio_synthesis.c b/src/audio/audio_synthesis.c index 85b82639..b867cd2a 100644 --- a/src/audio/audio_synthesis.c +++ b/src/audio/audio_synthesis.c @@ -655,31 +655,39 @@ void AudioSynth_SyncSampleStates(s32 updateIndex) { } } } - +extern GameState gGameState; Acmd* AudioSynth_Update(Acmd* aList, s32* cmdCount, s16* aiBufStart, s32 aiBufLen) { Acmd* aCmdPtr; - s32* aiBufPtr; + s16* aiBufPtr; s32 chunkLen; + volatile s32 chunkLentemp = aiBufLen; s32 i; s32 j; + //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); } - aiBufPtr = (s32*) aiBufStart; + aiBufPtr = aiBufStart; // @port: i = gAudioBufferParams.ticksPerUpdate - 1 // this change is necessary to avoid a crash, sounds like a // problem - for (i = gAudioBufferParams.ticksPerUpdate - 1; i > 0; i--) { + s32 temp = gGameState == GSTATE_MENU ? gAudioBufferParams.ticksPerUpdate-1 : gAudioBufferParams.ticksPerUpdate-1; + + for (i = temp; i > 0; i--) { if (i == 1) { + printf("func_80009B64 i == 1\n"); chunkLen = aiBufLen; } else if ((aiBufLen / i) >= gAudioBufferParams.samplesPerTickMax) { + 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"); chunkLen = gAudioBufferParams.samplesPerTickMin; } else { + printf("func_80009B64 else\n"); chunkLen = gAudioBufferParams.samplesPerTick; } @@ -688,11 +696,12 @@ 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); aCmdPtr = AudioSynth_DoOneAudioUpdate((s16*) aiBufPtr, chunkLen, aCmdPtr, gAudioBufferParams.ticksPerUpdate - i); aiBufLen -= chunkLen; - aiBufPtr += chunkLen; + aiBufPtr += chunkLen*2; } for (j = 0; j < gNumSynthReverbs; j++) { @@ -840,8 +849,6 @@ Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* aList, s32 upd return aList; } -// https://decomp.me/scratch/RgX4r -#ifdef NON_MATCHING Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisState* synthState, s16* aiBuf, s32 aiBufLen, Acmd* aList, s32 updateIndex) { s32 pad11C; @@ -1213,9 +1220,6 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisSta } return aList; } -#else -#pragma GLOBAL_ASM("asm/us/rev1/nonmatchings/audio/audio_synthesis/AudioSynth_ProcessNote.s") -#endif Acmd* AudioSynth_LoadWaveSamples(Acmd* aList, NoteSubEu* noteSub, NoteSynthesisState* synthState, s32 numSamplesToLoad) { diff --git a/src/audio/audio_thread.c b/src/audio/audio_thread.c index ec7a79b9..41d25f18 100644 --- a/src/audio/audio_thread.c +++ b/src/audio/audio_thread.c @@ -43,23 +43,26 @@ void AudioThread_CreateNextAudioBuffer(s16* samples, u32 num_samples) { static s32 gMaxAbiCmdCnt = 128; static SPTask* gWaitingAudioTask = NULL; s32 abiCmdCount; - u32 specId; + OSMesg specId; OSMesg msg; + gCurAiBuffIndex++; + gCurAiBuffIndex %= 3; + gCurAudioFrameDmaCount = 0; AudioLoad_DecreaseSampleDmaTtls(); AudioLoad_ProcessLoads(gAudioResetStep); - if (MQ_GET_MESG(gAudioSpecQueue, &specId)) { + if (osRecvMesg(gAudioSpecQueue, &specId, 0) != -1) { if (gAudioResetStep == 0) { gAudioResetStep = 5; } - gAudioSpecId = specId; + gAudioSpecId = specId.data8; } if ((gAudioResetStep != 0) && (AudioHeap_ResetStep() == 0)) { if (gAudioResetStep == 0) { - osSendMesg(gAudioResetQueue, OS_MESG_32((s32) gAudioSpecId), OS_MESG_NOBLOCK); + osSendMesg8(gAudioResetQueue, gAudioSpecId, OS_MESG_NOBLOCK); } gWaitingAudioTask = NULL; return NULL; @@ -82,6 +85,7 @@ void AudioThread_CreateNextAudioBuffer(s16* samples, u32 num_samples) { AudioSynth_Update(gCurAbiCmdBuffer, &abiCmdCount, samples, num_samples); memcpy(gAiBuffers[gCurAiBuffIndex], samples, num_samples); gAudioRandom = osGetCount() * (gAudioRandom + gAudioTaskCountQ); + gAudioCurTask->msg = OS_MESG_PTR(NULL); @@ -457,22 +461,24 @@ u8* AudioThread_GetFontsForSequence(s32 seqId, u32* outNumFonts) { bool AudioThread_ResetComplete(void) { s32 pad; - s32 sp18; + OSMesg sp18; if (!MQ_GET_MESG(gAudioResetQueue, &sp18)) { return false; } - if (sp18 != gAudioSpecId) { + if (sp18.data8 != gAudioSpecId) { return false; } return true; } void AudioThread_ResetAudioHeap(s32 specId) { + OSMesg msg; + msg.data8 = specId & 0xFF; MQ_CLEAR_QUEUE(gAudioResetQueue); AudioThread_ResetCmdQueue(); - osSendMesg(gAudioSpecQueue, OS_MESG_32(specId), OS_MESG_NOBLOCK); + osSendMesg8(gAudioSpecQueue, msg.data8, OS_MESG_NOBLOCK); } void AudioThread_PreNMIReset(void) { diff --git a/src/audio/mixer.c b/src/audio/mixer.c index 1c8225b7..0a0b83be 100644 --- a/src/audio/mixer.c +++ b/src/audio/mixer.c @@ -16,9 +16,10 @@ #define ROUND_DOWN_16(v) ((v) & ~0xf) //#define DMEM_BUF_SIZE (0x1000 - 0x0330 - 0x10 - 0x40) -#define DMEM_BUF_SIZE 0xC80 -#define BUF_U8(a) (rspa.buf.as_u8 + ((a)-0x0330)) -#define BUF_S16(a) (rspa.buf.as_s16 + ((a)-0x0330) / sizeof(int16_t)) +#define DMEM_BUF_SIZE (0x1000 - 0x450 - 0x40) +// #define DMEM_BUF_SIZE 0xC90 +#define BUF_U8(a) (rspa.buf.as_u8 + ((a)-0x450)) +#define BUF_S16(a) (rspa.buf.as_s16 + ((a)-0x450) / sizeof(int16_t)) static struct { uint16_t in; @@ -112,6 +113,8 @@ void aLoadBufferImpl(const void *source_addr, uint16_t dest_addr, uint16_t nbyte } void aSaveBufferImpl(uint16_t source_addr, int16_t *dest_addr, uint16_t nbytes) { + //printf("source_addr: %x\n dest_addr; %x\n nbytes: %d\n", source_addr, dest_addr, nbytes); + //if (nbytes > 704) {nbytes = 704;} memcpy(dest_addr, BUF_S16(source_addr), ROUND_DOWN_16(nbytes)); } diff --git a/src/buffers.c b/src/buffers.c index 2c55c737..596ccb34 100644 --- a/src/buffers.c +++ b/src/buffers.c @@ -3,7 +3,7 @@ u8 gOSYieldData[OS_YIELD_DATA_SIZE]; FrameBuffer gZBuffer; // z buffer u8 gTaskOutputBuffer[0x30000]; -u8 gAudioHeap[0xB0000]; +u8 gAudioHeap[0x15FC00]; u16 gTextureRenderBuffer[0x3C40]; u16 gFillBuffer[3 * SCREEN_WIDTH]; FrameBuffer gFrameBuffers[3]; diff --git a/src/engine/fox_game.c b/src/engine/fox_game.c index f6f131d7..2352b25c 100644 --- a/src/engine/fox_game.c +++ b/src/engine/fox_game.c @@ -4,7 +4,21 @@ #include "assets/ast_logo.h" #include "mods.h" #include "port/interpolation/FrameInterpolation.h" - +typedef struct { + /* 0x00 */ s16 count; + /* 0x02 */ u16 samplingFrequency; // Target sampling rate in Hz + /* 0x04 */ u16 aiSamplingFrequency; // True sampling rate of the audio interface (AI), see `osAiSetFrequency` + /* 0x06 */ s16 samplesPerFrameTarget; + /* 0x08 */ s16 maxAiBufferLength; + /* 0x0A */ s16 minAiBufferLength; + /* 0x0C */ s16 ticksPerUpdate; // for each audio thread update, number of ticks to process audio + /* 0x0E */ s16 samplesPerTick; + /* 0x10 */ s16 samplesPerTickMax; + /* 0x12 */ s16 samplesPerTickMin; + /* 0x14 */ f32 resampleRate; + /* 0x18 */ f32 ticksPerUpdateInv; // inverse (reciprocal) of ticksPerUpdate + /* 0x1C */ f32 ticksPerUpdateInvScaled; // ticksPerUpdateInv scaled down by a factor of 256 +} AudioBufferParameters; // size = 0x20 f32 gNextVsViewScale; f32 gVsViewScale; s32 gPlayerInactive[4]; @@ -165,8 +179,7 @@ void Game_InitMasterDL(Gfx** dList) { gDPSetDepthImage((*dList)++, &gZBuffer); gDPSetColorImage((*dList)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, RIGHT_MARGIN, &gZBuffer); gDPSetFillColor((*dList)++, FILL_COLOR(GPACK_ZDZ(G_MAXFBZ, 0))); - gDPFillWideRectangle((*dList)++, LEFT_MARGIN, SCREEN_MARGIN, RIGHT_MARGIN, - SCREEN_HEIGHT - SCREEN_MARGIN); + gDPFillWideRectangle((*dList)++, LEFT_MARGIN, SCREEN_MARGIN, RIGHT_MARGIN, SCREEN_HEIGHT - SCREEN_MARGIN); gDPSetColorImage((*dList)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, RIGHT_MARGIN, gFrameBuffer); if (gBlurAlpha < 255) { @@ -179,8 +192,7 @@ void Game_InitMasterDL(Gfx** dList) { } else { gDPSetFillColor((*dList)++, FILL_COLOR(gBgColor | 1)); } - gDPFillWideRectangle((*dList)++, LEFT_MARGIN, SCREEN_MARGIN, RIGHT_MARGIN, - SCREEN_HEIGHT - SCREEN_MARGIN); + gDPFillWideRectangle((*dList)++, LEFT_MARGIN, SCREEN_MARGIN, RIGHT_MARGIN, SCREEN_HEIGHT - SCREEN_MARGIN); gDPPipeSync((*dList)++); gDPSetColorDither((*dList)++, G_CD_MAGICSQ); } @@ -190,7 +202,8 @@ void Game_InitStandbyDL(Gfx** dList) { gDPSetScissor((*dList)++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT * 3); gDPSetFillColor((*dList)++, FILL_COLOR(0x0001)); gDPSetColorImage((*dList)++, G_IM_FMT_RGBA, G_IM_SIZ_16b, RIGHT_MARGIN, gFrameBuffers[0].data); - gDPFillWideRectangle((*dList)++, OTRGetDimensionFromLeftEdge(0), 0, OTRGetRectDimensionFromRightEdge(0), SCREEN_HEIGHT * 3 - 1); + gDPFillWideRectangle((*dList)++, OTRGetDimensionFromLeftEdge(0), 0, OTRGetRectDimensionFromRightEdge(0), + SCREEN_HEIGHT * 3 - 1); gDPPipeSync((*dList)++); gDPSetColorDither((*dList)++, G_CD_MAGICSQ); } @@ -341,7 +354,8 @@ void Game_SetScene(void) { break; } } - +extern u8 gAudioSpecId; +extern AudioBufferParameters gAudioBufferParams; void Game_Update(void) { s32 i; u8 partialFill; @@ -554,8 +568,10 @@ void Game_Update(void) { partialFill = false; if (gCamCount == 1) { - Graphics_FillRectangle(&gMasterDisp, OTRGetRectDimensionFromLeftEdge(0), 0, OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH - 1), SCREEN_HEIGHT - 1, gPlayerGlareReds[0], - gPlayerGlareGreens[0], gPlayerGlareBlues[0], gPlayerGlareAlphas[0]); + Graphics_FillRectangle(&gMasterDisp, OTRGetRectDimensionFromLeftEdge(0), 0, + OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH - 1), SCREEN_HEIGHT - 1, + gPlayerGlareReds[0], gPlayerGlareGreens[0], gPlayerGlareBlues[0], + gPlayerGlareAlphas[0]); if ((gDrawMode == DRAW_PLAY) || (gDrawMode == DRAW_ENDING)) { Radio_Draw(); if (gShowHud) { @@ -591,8 +607,9 @@ void Game_Update(void) { Wipe_Draw(WIPE_CIRCULAR, gCircleWipeFrame); if (!partialFill) { - Graphics_FillRectangle(&gMasterDisp, OTRGetRectDimensionFromLeftEdge(0), 0, OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH - 1), SCREEN_HEIGHT - 1, gFillScreenRed, - gFillScreenGreen, gFillScreenBlue, gFillScreenAlpha); + Graphics_FillRectangle(&gMasterDisp, OTRGetRectDimensionFromLeftEdge(0), 0, + OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH - 1), SCREEN_HEIGHT - 1, + gFillScreenRed, gFillScreenGreen, gFillScreenBlue, gFillScreenAlpha); } Audio_dummy_80016A50(); #if MODS_RAM_MOD == 1 @@ -605,6 +622,12 @@ void Game_Update(void) { Spawner(); #endif } + RCP_SetupDL(&gMasterDisp, SETUPDL_83); + gDPSetPrimColor(gMasterDisp++, 0, 0, 255, 255, 0, 255); + Graphics_DisplaySmallText(10, 210, 1.0f, 1.0f, "AUDIOSPEC:"); + Graphics_DisplaySmallNumber(90, 210, gAudioSpecId); + Graphics_DisplaySmallText(10, 220, 1.0f, 1.0f, "TICKS:"); + Graphics_DisplaySmallNumber(90, 220, gAudioBufferParams.ticksPerUpdate); } #if MODS_FPS_COUNTER == 1 diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 79a9761e..6c8f504d 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -123,6 +123,11 @@ void GameEngine::StartFrame() const{ this->context->GetWindow()->StartFrame(); } +#define SAMPLES_HIGH 752 +#define SAMPLES_LOW 720 +#define NUM_AUDIO_CHANNELS 2 +#define SAMPLES_PER_FRAME (SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3) + void GameEngine::HandleAudioThread(){ while (audio.running) { { @@ -140,10 +145,12 @@ void GameEngine::HandleAudioThread(){ std::unique_lock Lock(audio.mutex); int samples_left = AudioPlayerBuffered(); u32 num_audio_samples = samples_left < AudioPlayerGetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW; - s16 audio_buffer[SAMPLES_PER_FRAME]; + s16 audio_buffer[SAMPLES_PER_FRAME] = {0}; + for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) { AudioThread_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples); } + AudioPlayerPlayFrame((u8 *) audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE)); audio.processing = false; audio.cv_from_thread.notify_one(); diff --git a/src/port/Engine.h b/src/port/Engine.h index 74b63f2e..20391528 100644 --- a/src/port/Engine.h +++ b/src/port/Engine.h @@ -15,10 +15,7 @@ struct GamePool { #include #include "libultraship/src/Context.h" -#define SAMPLES_HIGH 752 -#define SAMPLES_LOW 720 -#define NUM_AUDIO_CHANNELS 2 -#define SAMPLES_PER_FRAME (SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3) + class GameEngine { public: