From 85c13b7cc8d2e6edc83939fd3591c8ec6a414431 Mon Sep 17 00:00:00 2001 From: Banjo Kazooie Date: Fri, 28 Oct 2022 19:21:47 -0500 Subject: [PATCH] core1/audio/n_adpcm.c done --- README.md | 2 +- include/n_synth.h | 2 +- progress/progress_core1.svg | 6 +- progress/progress_total.svg | 4 +- src/core1/audio/n_adpcm.c | 7 -- src/core1/done/audio/n_adpcm.c | 213 +++++++++++++++++++++++++++++++++ subyaml/core1.us.v10.yaml | 2 +- 7 files changed, 221 insertions(+), 15 deletions(-) delete mode 100644 src/core1/audio/n_adpcm.c create mode 100644 src/core1/done/audio/n_adpcm.c diff --git a/README.md b/README.md index 216eb244..98dd5ada 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# banjo (92.1173%) +# banjo (92.2108%) diff --git a/include/n_synth.h b/include/n_synth.h index 7846e1bb..f8a33679 100644 --- a/include/n_synth.h +++ b/include/n_synth.h @@ -23,7 +23,7 @@ #define N_AL_DIVIDED 368 typedef struct N_ALLoadFilter_s{ - //ALFilter filter; + u8 pad0[0xC]; ADPCM_STATE *state; //0xC ADPCM_STATE *lstate; //0x10 ALRawLoop loop; //0x14 diff --git a/progress/progress_core1.svg b/progress/progress_core1.svg index 01b58079..576a72db 100644 --- a/progress/progress_core1.svg +++ b/progress/progress_core1.svg @@ -9,7 +9,7 @@ - + @@ -17,7 +17,7 @@ core1 - 84.3371% - 84.3371% + 84.9818% + 84.9818% \ No newline at end of file diff --git a/progress/progress_total.svg b/progress/progress_total.svg index 2a246656..76ccec42 100644 --- a/progress/progress_total.svg +++ b/progress/progress_total.svg @@ -17,7 +17,7 @@ Banjo-Kazooie (us.v10) - 92.1173% - 92.1173% + 92.2108% + 92.2108% \ No newline at end of file diff --git a/src/core1/audio/n_adpcm.c b/src/core1/audio/n_adpcm.c deleted file mode 100644 index c6686ea3..00000000 --- a/src/core1/audio/n_adpcm.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "n_synth.h" -//see libultre src/audio/load.c - -#pragma GLOBAL_ASM("asm/nonmatchings/core1/audio/n_adpcm/_n_decodeChunk.s") - -#pragma GLOBAL_ASM("asm/nonmatchings/core1/audio/n_adpcm/n_alAdpcmPull.s") diff --git a/src/core1/done/audio/n_adpcm.c b/src/core1/done/audio/n_adpcm.c new file mode 100644 index 00000000..557a9e39 --- /dev/null +++ b/src/core1/done/audio/n_adpcm.c @@ -0,0 +1,213 @@ +#include +#include "n_synth.h" + +#ifndef MIN +# define MIN(a,b) (((a)<(b))?(a):(b)) +#endif + +#ifdef AUD_PROFILE +extern u32 cnt_index, adpcm_num, adpcm_cnt, adpcm_max, adpcm_min, lastCnt[]; +#endif + +#define ADPCMFBYTES 9 +#define LFSAMPLES 4 + +static +Acmd *_n_decodeChunk(Acmd *ptr, N_ALLoadFilter *f, s32 tsam, s32 nbytes, s16 outp, s16 inp, u32 flags); + +Acmd *n_alAdpcmPull(void *filter, s16 *outp, s32 outCount, Acmd *p) +{ + Acmd *ptr = p; + s16 inp; + s32 tsam; + s32 nframes; + s32 nbytes; + s32 overFlow; + s32 startZero; + s32 nOver; + s32 nSam; + s32 op; + s32 nLeft; + s32 bEnd; + s32 decoded = 0; + s32 looped = 0; + + N_ALLoadFilter *f = (N_ALLoadFilter *)filter; + +#ifdef AUD_PROFILE + lastCnt[++cnt_index] = osGetCount(); +#endif + + if (outCount == 0) + return ptr; + + inp = AL_DECODER_IN; + aLoadADPCM(ptr++, f->bookSize, + K0_TO_PHYS(f->table->waveInfo.adpcmWave.book->book)); + + looped = (outCount + f->sample > f->loop.end) && (f->loop.count != 0); + if (looped) + nSam = f->loop.end - f->sample; + else + nSam = outCount; + + if (f->lastsam) + nLeft = ADPCMFSIZE - f->lastsam; + else + nLeft = 0; + tsam = nSam - nLeft; + if (tsam<0) tsam = 0; + + nframes = (tsam+ADPCMFSIZE-1)>>LFSAMPLES; + nbytes = nframes*ADPCMFBYTES; + + if (looped){ + + ptr = _n_decodeChunk(ptr, f, tsam, nbytes, *outp, inp, f->first); + + /* + * Fix up output pointer, which will be used as the input pointer + * by the following module. + */ + if (f->lastsam) + *outp += (f->lastsam<<1); + else + *outp += (ADPCMFSIZE<<1); + + /* + * Now fix up state info to reflect the loop start point + */ + f->lastsam = f->loop.start &0xf; + f->memin = (s32) f->table->base + ADPCMFBYTES * + ((s32) (f->loop.start>>LFSAMPLES) + 1); + f->sample = f->loop.start; + + bEnd = *outp; + while (outCount > nSam){ + + outCount -= nSam; + + /* + * Put next one after the end of the last lot - on the + * frame boundary (32 byte) after the end. + */ + op = (bEnd + ((nframes+1)<<(LFSAMPLES+1)) + 0x10) & ~0x1f; + + /* + * The actual end of data + */ + bEnd += (nSam<<1); + + /* + * -1 is loop forever - the loop count is not exact now + * for small loops! + */ + if ((f->loop.count != -1) && (f->loop.count != 0)) + f->loop.count--; + + /* + * What's left to compute. + */ + nSam = MIN(outCount, f->loop.end - f->loop.start); + tsam = nSam - ADPCMFSIZE + f->lastsam; + if (tsam<0) tsam = 0; + nframes = (tsam+ADPCMFSIZE-1)>>LFSAMPLES; + nbytes = nframes*ADPCMFBYTES; + ptr = _n_decodeChunk(ptr, f, tsam, nbytes, op, inp, f->first | A_LOOP); + /* + * Merge the two sections in DMEM. + */ + aDMEMMove(ptr++, op+(f->lastsam<<1), bEnd, nSam<<1); + + } + + f->lastsam = (outCount + f->lastsam) & 0xf; + f->sample += outCount; + f->memin += ADPCMFBYTES*nframes; +#ifdef AUD_PROFILE + PROFILE_AUD(adpcm_num, adpcm_cnt, adpcm_max, adpcm_min); +#endif + return ptr; + } + + /* + * The unlooped case, which is executed most of the time + */ + + nSam = nframes<memin + nbytes - ((s32) f->table->base + f->table->len); + if (overFlow < 0) + overFlow = 0; + nOver = (overFlow/ADPCMFBYTES)< nSam + nLeft) + nOver = nSam + nLeft; + + nbytes -= overFlow; + + if ((nOver - (nOver & 0xf))< outCount){ + decoded = 1; + ptr = _n_decodeChunk(ptr, f, nSam - nOver, nbytes, *outp, inp, f->first); + + if (f->lastsam) + *outp += (f->lastsam<<1); + else + *outp += (ADPCMFSIZE<<1); + + f->lastsam = (outCount + f->lastsam) & 0xf; + f->sample += outCount; + f->memin += ADPCMFBYTES*nframes; + } else { + f->lastsam = 0; + f->memin += ADPCMFBYTES*nframes; + } + + /* + * Put zeros in if necessary + */ + if (nOver){ + f->lastsam = 0; + if (decoded) + startZero = (nLeft + nSam - nOver)<<1; + else + startZero = 0; + aClearBuffer(ptr++, startZero + *outp, nOver<<1); + } +#ifdef AUD_PROFILE + PROFILE_AUD(adpcm_num, adpcm_cnt, adpcm_max, adpcm_min); +#endif + + return ptr; +} + +Acmd *_n_decodeChunk(Acmd *ptr, N_ALLoadFilter *f, s32 tsam, s32 nbytes, s16 outp, s16 inp, u32 flags) +{ + s32 + dramAlign, + dramLoc; + + if (nbytes > 0){ + dramLoc = (f->dma)(f->memin, nbytes, f->dmaState); + /* + * Make sure enough is loaded into DMEM to take care + * of 8 byte alignment + */ + dramAlign = dramLoc & 0x7; + nbytes += dramAlign; + n_aLoadBuffer(ptr++, nbytes + 8 - (nbytes & 0x7), inp, dramLoc - dramAlign); + } else + dramAlign = 0; + + if (flags & A_LOOP){ + aSetLoop(ptr++, K0_TO_PHYS(f->lstate)); + } + + n_aADPCMdec(ptr++, K0_TO_PHYS(f->state), flags, tsam<<1, dramAlign, outp); + f->first = 0; + + return ptr; +} diff --git a/subyaml/core1.us.v10.yaml b/subyaml/core1.us.v10.yaml index e273c0f3..e5bb57f9 100644 --- a/subyaml/core1.us.v10.yaml +++ b/subyaml/core1.us.v10.yaml @@ -108,7 +108,7 @@ segments: - [0x25360, c, done/audio/n_synstartvoiceparam] #DONE - [0x25440, c, done/audio/n_mainbus] #DONE - [0x254C0, c, done/audio/n_load] #DONE - - [0x25680, c, audio/n_adpcm] + - [0x25680, c, done/audio/n_adpcm] - [0x25C40, c, done/audio/n_resample] #DONE - [0x25E20, c, done/audio/n_seq] #DONE - [0x26110, c, done/audio/n_synsetpriority] #DONE