diff --git a/README.md b/README.md
index 3d1bf736..562473ea 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# banjo (89.9076%)
+# banjo (90.0795%)
diff --git a/include/file_and_line.h b/include/file_and_line.h
index ecb5f3b2..a67656c6 100644
--- a/include/file_and_line.h
+++ b/include/file_and_line.h
@@ -1,6 +1,6 @@
#ifndef _FILE_AND_LINE_H_
#define _FILE_AND_LINE_H_
-
+#include
extern void func_8033F000(const char *, const char *, int);
diff --git a/progress/progress_core1.svg b/progress/progress_core1.svg
index 4b1ca596..ac72062c 100644
--- a/progress/progress_core1.svg
+++ b/progress/progress_core1.svg
@@ -9,7 +9,7 @@
-
+
@@ -17,7 +17,7 @@
core1
- 76.3559%
- 76.3559%
+ 77.5401%
+ 77.5401%
\ No newline at end of file
diff --git a/progress/progress_total.svg b/progress/progress_total.svg
index f0b50deb..5fd45b2d 100644
--- a/progress/progress_total.svg
+++ b/progress/progress_total.svg
@@ -9,7 +9,7 @@
-
+
@@ -17,7 +17,7 @@
Banjo-Kazooie (us.v10)
- 89.9076%
- 89.9076%
+ 90.0795%
+ 90.0795%
\ No newline at end of file
diff --git a/src/core1/done/audio/n_reverb.c b/src/core1/done/audio/n_reverb.c
new file mode 100644
index 00000000..f6677a10
--- /dev/null
+++ b/src/core1/done/audio/n_reverb.c
@@ -0,0 +1,375 @@
+#include
+#include "n_libaudio.h"
+#include "n_synth.h"
+
+
+#define RANGE 2.0
+extern ALGlobals *alGlobals;
+
+#ifdef AUD_PROFILE
+extern u32 cnt_index, reverb_num, reverb_cnt, reverb_max, reverb_min, lastCnt[];
+extern u32 load_num, load_cnt, load_max, load_min, save_num, save_cnt, save_max, save_min;
+#endif
+
+/*
+ * macros
+ */
+#define SWAP(in, out) \
+{ \
+ s16 t = out; \
+ out = in; \
+ in = t; \
+}
+
+#define N_REVERB_OUTCOUNT 0xb8
+
+Acmd *_n_loadOutputBuffer(ALFx *r, ALDelay *d, s32 buff, Acmd *p); //_loadOutputBuffer
+Acmd *_n_loadBuffer(ALFx *r, s16 *curr_ptr, s32 buff, s32 count, Acmd *p); //_loadBuffer
+Acmd *__n_saveBuffer(ALFx *r, s16 *curr_ptr, s32 buff, Acmd *p); //__saveBuffer
+Acmd *__n_filterBuffer(ALLowPass *lp, s32 buff, Acmd *p); //__filterBuffer
+f32 _doModFunc(ALDelay *d, s32 count);
+
+// static s32 L_INC[] = { L0_INC, L1_INC, L2_INC };
+
+/***********************************************************************
+ * Reverb filter public interfaces
+ ***********************************************************************/
+Acmd *n_alFxPull(void)
+{
+ ALFx *r = (ALFx *)n_syn->auxBus->fx;
+ ALFilter *source = r->filter.source;
+ s16 i, buff1, buff2, input, output;
+ s16 *in_ptr, *out_ptr, gain, *prev_out_ptr = 0;
+ ALDelay *d, *pd;
+ Acmd *ptr;
+
+
+
+#ifdef AUD_PROFILE
+ lastCnt[++cnt_index] = osGetCount();
+#endif
+
+ // assert(source);
+ ptr = n_alAuxBusPull();
+ /*
+ * pull channels going into this effect first
+ */
+ // ptr = (*source->handler)(source, outp, outCount, sampleOffset, p);
+
+ input = N_AL_AUX_L_OUT;
+ output = N_AL_AUX_R_OUT;
+ buff1 = N_AL_TEMP_0;
+ buff2 = N_AL_TEMP_1;
+
+ // aSetBuffer(ptr++, 0, 0, 0, outCount<<1); /* set the buffer size */
+ aMix(ptr++, 0, 0xda83, N_AL_AUX_L_OUT, input); /* .707L = L - .293L */
+ aMix(ptr++, 0, 0x5a82, N_AL_AUX_R_OUT, input); /* mix the AuxL and AuxR into the AuxL */
+ /* and write the mixed value to the delay line at r->input */
+ ptr = __n_saveBuffer(r, r->input, input, ptr);
+
+ aClearBuffer(ptr++, output, N_REVERB_OUTCOUNT << 1); /* clear the AL_AUX_R_OUT */
+
+
+ for (i = 0; i < r->section_count; i++) {
+ d = &r->delay[i]; /* get the ALDelay structure */
+ in_ptr = &r->input[-d->input];
+ out_ptr = &r->input[-d->output];
+
+ if (in_ptr == prev_out_ptr) {
+ SWAP(buff1, buff2);
+ } else { /* load data at in_ptr into buff1 */
+ ptr = _n_loadBuffer(r, in_ptr, buff1, N_REVERB_OUTCOUNT, ptr);
+ }
+ ptr = _n_loadOutputBuffer(r, d, buff2, ptr);
+
+ if (d->ffcoef) {
+ aMix(ptr++, 0, (u16)d->ffcoef, buff1, buff2);
+ if (!d->rs && !d->lp) {
+ ptr = __n_saveBuffer(r, out_ptr, buff2, ptr);
+ }
+ }
+
+ if (d->fbcoef) {
+ aMix(ptr++, 0, (u16)d->fbcoef, buff2, buff1);
+ ptr = __n_saveBuffer(r, in_ptr, buff1, ptr);
+ }
+
+ if (d->lp)
+ ptr = __n_filterBuffer(d->lp, buff2, ptr);
+
+ if (!d->rs)
+ ptr = __n_saveBuffer(r, out_ptr, buff2, ptr);
+
+ if (d->gain)
+ aMix(ptr++, 0, (u16)d->gain, buff2, output);
+
+ prev_out_ptr = &r->input[d->output];
+ }
+
+ /*
+ * bump the master delay line input pointer
+ * modulo the length
+ */
+ r->input += N_REVERB_OUTCOUNT;
+ if (r->input > &r->base[r->length])
+ r->input -= r->length;
+
+ /*
+ * output already in AL_AUX_R_OUT
+ * just copy to AL_AUX_L_OUT
+ */
+ aDMEMMove(ptr++, output, N_AL_AUX_L_OUT, N_REVERB_OUTCOUNT<<1);
+
+#ifdef AUD_PROFILE
+ PROFILE_AUD(reverb_num, reverb_cnt, reverb_max, reverb_min);
+#endif
+ return ptr;
+}
+
+
+/*
+ * This routine gets called by alSynSetFXParam. No checking takes place to
+ * verify the validity of the paramID or the param value. input and output
+ * values must be 8 byte aligned, so round down any param passed.
+ */
+s32 n_alFxParamHdl(void *filter, s32 paramID, void *param)
+{
+ ALFx *f = (ALFx *) filter;
+ s32 p = (paramID - 2) % 8;
+ s32 s = (paramID - 2) / 8;
+ s32 val = *(s32*)param;
+
+#define INPUT_PARAM 0
+#define OUTPUT_PARAM 1
+#define FBCOEF_PARAM 2
+#define FFCOEF_PARAM 3
+#define GAIN_PARAM 4
+#define CHORUSRATE_PARAM 5
+#define CHORUSDEPTH_PARAM 6
+#define LPFILT_PARAM 7
+
+ switch(p)
+ {
+ case INPUT_PARAM:
+ f->delay[s].input = (u32)val & 0xFFFFFFF8;
+ break;
+ case OUTPUT_PARAM:
+ f->delay[s].output = (u32)val & 0xFFFFFFF8;
+ break;
+ case FFCOEF_PARAM:
+ f->delay[s].ffcoef = (s16)val;
+ break;
+ case FBCOEF_PARAM:
+ f->delay[s].fbcoef = (s16)val;
+ break;
+ case GAIN_PARAM:
+ f->delay[s].gain = (s16)val;
+ break;
+ case CHORUSRATE_PARAM:
+ /* f->delay[s].rsinc = ((f32)val)/0xffffff; */
+ f->delay[s].rsinc = ((((f32)val)/1000) * RANGE)/n_syn->outputRate;
+ break;
+
+/*
+ * the following constant is derived from:
+ *
+ * ratio = 2^(cents/1200)
+ *
+ * and therefore for hundredths of a cent
+ * x
+ * ln(ratio) = ---------------
+ * (120,000)/ln(2)
+ * where
+ * 120,000/ln(2) = 173123.40...
+ */
+#define CONVERT 173123.404906676
+#define LENGTH (f->delay[s].output - f->delay[s].input)
+
+ case CHORUSDEPTH_PARAM:
+ /*f->delay[s].rsgain = (((f32)val) / CONVERT) * LENGTH; */
+ f->delay[s].rsgain = (((f32)val) / CONVERT) * LENGTH;
+ break;
+ case LPFILT_PARAM:
+ if(f->delay[s].lp)
+ {
+ f->delay[s].lp->fc = (s16)val;
+ _init_lpfilter(f->delay[s].lp);
+ }
+ break;
+ }
+ return 0;
+}
+
+Acmd *_n_loadOutputBuffer(ALFx *r, ALDelay *d, s32 buff, Acmd *p)
+{
+ Acmd *ptr = p;
+ s32 ratio, count, rbuff = N_AL_TEMP_2;
+ s16 *out_ptr;
+ f32 fincount, fratio, delta;
+ s32 ramalign = 0, length;
+ s32 inCount = 0xb8;
+ s8 tmp;
+ static f32 val=0.0, lastval=-10.0;
+ static f32 blob=0;
+/*
+ * The following section implements the chorus resampling. Modulate where you pull
+ * the samples from, since you need varying amounts of samples.
+ */
+ if (d->rs) {
+ length = d->output - d->input;
+ delta = _doModFunc(d, inCount); /* get the number of samples to modulate by */
+ /*
+ * find ratio of delta to delay length and quantize
+ * to same resolution as resampler
+ */
+ delta /= length; /* convert delta from number of samples to a pitch ratio */
+ delta = (s32)(delta * UNITY_PITCH); /* quantize to value microcode will use */
+ delta = delta / UNITY_PITCH;
+ fratio = 1.0 - delta; /* pitch ratio needs to be centered around 1, not zero */
+
+ /* d->rs->delta is the difference between the fractional and integer value
+ * of the samples needed. fratio * incount + rs->delta gives the number of samples
+ * needed for this frame.
+ */
+ fincount = d->rs->delta + (fratio * (f32)inCount);
+ count = (s32) fincount; /* quantize to s32 */
+ d->rs->delta = fincount - (f32)count; /* calculate the round off and store */
+
+ /*
+ * d->rsdelta is amount the out_ptr has deviated from its starting position.
+ * You calc the out_ptr by taking d->output - d->rsdelta, and then using the
+ * negative of that as an index into the delay buffer. loadBuffer that uses this
+ * value then bumps it up if it is below the delay buffer.
+ */
+ out_ptr = &r->input[-(d->output - d->rsdelta)];
+ ramalign = (((s32)out_ptr & 0x7) >> 1); /* calculate the number of samples needed
+ to align the buffer*/
+#ifdef _DEBUG
+#if 0
+ if(length > 0) {
+ if (length - d->rsdelta > (s32)r->length) {
+ __osError(ERR_ALMODDELAYOVERFLOW, 1, length - d->rsdelta - r->length);
+ }
+ }
+ else if(length < 0) {
+ if ((-length) - d->rsdelta > (s32)r->length) {
+ __osError(ERR_ALMODDELAYOVERFLOW, 1, (-length) - d->rsdelta - r->length);
+ }
+ }
+#endif
+#endif
+ /* load the rbuff with samples, note that there will be ramalign worth of
+ * samples at the begining which you don't care about. */
+ ptr = _n_loadBuffer(r, out_ptr - ramalign, rbuff, count + ramalign, ptr);
+
+ /* convert fratio to 16 bit fraction for microcode use */
+ ratio = (s32)(fratio * UNITY_PITCH);
+ /* set the buffers, and do the resample */
+ // aSetBuffer(ptr++, 0, rbuff + (ramalign<<1), buff, inCount<<1);
+ tmp = (buff>>8);
+ n_aResample(ptr++, osVirtualToPhysical(d->rs->state), d->rs->first, ratio, rbuff + (ramalign<<1), tmp);
+
+ d->rs->first = 0; /* turn off first time flag */
+ d->rsdelta += count - inCount; /* add the number of samples to d->rsdelta */
+ } else {
+ out_ptr = &r->input[-d->output];
+ ptr = _n_loadBuffer(r, out_ptr, buff, inCount, ptr);
+ }
+
+ return ptr;
+}
+/*
+ * This routine is for loading data from the delay line buff. If the
+ * address of curr_ptr < r->base, it will force it to be within r->base
+ * space, If the load goes past the end of r->base it will wrap around.
+ * Cause count bytes of data at curr_ptr (within the delay line) to be
+ * loaded into buff. (Buff is a dmem buffer)
+ */
+Acmd *_n_loadBuffer(ALFx *r, s16 *curr_ptr, s32 buff, s32 count, Acmd *p)
+{
+ Acmd *ptr = p;
+ s32 after_end, before_end;
+ s16 *updated_ptr, *delay_end;
+
+#ifdef AUD_PROFILE
+ lastCnt[++cnt_index] = osGetCount();
+#endif
+
+ delay_end = &r->base[r->length];
+
+#ifdef _DEBUG
+ if(curr_ptr > delay_end)
+ __osError(ERR_ALMODDELAYOVERFLOW, 1, delay_end - curr_ptr);
+#endif
+
+ if (curr_ptr < r->base)
+ curr_ptr += r->length;
+ updated_ptr = curr_ptr + count;
+
+ if (updated_ptr > delay_end) {
+ after_end = updated_ptr - delay_end;
+ before_end = delay_end - curr_ptr;
+
+ n_aLoadBuffer(ptr++, before_end << 1, buff, osVirtualToPhysical(curr_ptr));
+ n_aLoadBuffer(ptr++, after_end<<1, buff + (before_end<<1), osVirtualToPhysical(r->base));
+ } else {
+ n_aLoadBuffer(ptr++, count<<1, buff, osVirtualToPhysical(curr_ptr));
+ }
+
+#ifdef AUD_PROFILE
+ PROFILE_AUD(load_num, load_cnt, load_max, load_min);
+#endif
+ return ptr;
+
+}
+
+/*
+ * This routine is for writing data to the delay line buff. If the
+ * address of curr_ptr < r->base, it will force it to be within r->base
+ * space. If the write goes past the end of r->base, it will wrap around
+ * Cause count bytes of data at buff to be written to delay line, curr_ptr.
+ */
+Acmd *__n_saveBuffer(ALFx *r, s16 *curr_ptr, s32 buff, Acmd *p)
+{
+ Acmd *ptr = p;
+ s32 after_end, before_end;
+ s16 *updated_ptr, *delay_end;
+
+#ifdef AUD_PROFILE
+ lastCnt[++cnt_index] = osGetCount();
+#endif
+
+ delay_end = &r->base[r->length];
+ if (curr_ptr < r->base) /* probably just security */
+ curr_ptr += r->length; /* shouldn't occur */
+ updated_ptr = curr_ptr + 0xb8;
+
+ if (updated_ptr > delay_end) { /* if the data wraps past end of r->base */
+ after_end = updated_ptr - delay_end;
+ before_end = delay_end - curr_ptr;
+
+ n_aSaveBuffer(ptr++, before_end<<1, buff, osVirtualToPhysical(curr_ptr));
+ n_aSaveBuffer(ptr++, after_end<<1, buff+(before_end<<1), osVirtualToPhysical(r->base));
+ } else {
+ n_aSaveBuffer(ptr++, 0xb8 << 1, buff, osVirtualToPhysical(curr_ptr));
+ }
+
+#ifdef AUD_PROFILE
+ PROFILE_AUD(save_num, save_cnt, save_max, save_min);
+#endif
+ return ptr;
+
+}
+
+Acmd *__n_filterBuffer(ALLowPass *lp, s32 buff, Acmd *p)
+{
+ Acmd* ptr = p;
+ s8 t8;
+
+ n_aLoadADPCM(ptr++, 32, osVirtualToPhysical(lp->fcvec.fccoef));
+ t8 = buff>>8;
+ n_aPoleFilter(ptr++, lp->first, lp->fgain, t8, osVirtualToPhysical(lp->fstate));
+ lp->first = 0;
+
+ return ptr;
+}
\ No newline at end of file
diff --git a/src/core1/done/audio/n_seqplayer.c b/src/core1/done/audio/n_seqplayer.c
index 282008fa..69b4da09 100644
--- a/src/core1/done/audio/n_seqplayer.c
+++ b/src/core1/done/audio/n_seqplayer.c
@@ -865,7 +865,6 @@ ALSound *__n_lookupSoundQuick(N_ALSeqPlayer *seqp, u8 key, u8 vel, u8 chan)
s16 __n_vsVol(N_ALVoiceState *vs, N_ALSeqPlayer *seqp)
{
u32 t1, t2;
- ALChanState *temp_a2;
t1 = (vs->tremelo*vs->velocity*vs->envGain*seqp->chanState[vs->channel].unkA) >> 13;
t2 = (vs->sound->sampleVolume*seqp->vol*seqp->chanState[vs->channel].vol) >> 14;
diff --git a/src/core1/n_reverb.c b/src/core1/n_reverb.c
deleted file mode 100644
index 7a263343..00000000
--- a/src/core1/n_reverb.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include
-#include "functions.h"
-#include "variables.h"
-
-
-#pragma GLOBAL_ASM("asm/nonmatchings/core1/n_reverb/func_8025F6D0.s")
-
-#pragma GLOBAL_ASM("asm/nonmatchings/core1/n_reverb/func_8025F784.s")
-
-#pragma GLOBAL_ASM("asm/nonmatchings/core1/n_reverb/func_8025F8B0.s")
-
-#pragma GLOBAL_ASM("asm/nonmatchings/core1/n_reverb/func_8025F9F4.s")
-
-#pragma GLOBAL_ASM("asm/nonmatchings/core1/n_reverb/func_8025FC10.s")
-
-#pragma GLOBAL_ASM("asm/nonmatchings/core1/n_reverb/func_8025FE6C.s")
diff --git a/subyaml/core1.us.v10.yaml b/subyaml/core1.us.v10.yaml
index 9fec730e..7629ed38 100644
--- a/subyaml/core1.us.v10.yaml
+++ b/subyaml/core1.us.v10.yaml
@@ -94,7 +94,7 @@ segments:
- [0x21AF0, c, done/audio/code_21AF0] #DONE
- [0x21B50, c, done/audio/code_21B50] #DONE
- [0x21C50, c, done/audio/n_synallocfx] #DONE
- - [0x21CB0, c, n_reverb]
+ - [0x21CB0, c, done/audio/n_reverb]
- [0x22740, c, done/audio/n_auxbus] #DONE
- [0x227F0, c, done/audio/n_drvrNew] #DONE
- [0x22D50, c, done/audio/n_save] #DONE
@@ -285,7 +285,7 @@ segments:
- [0x3A950, .rodata, code_1D5D0]
- [0x3A9B0, .rodata, done/audio/n_synthesizer]
- [0x3A9C0, bin, data_3A9C0] # .rodata, done/audio/n_csplayer]
- - [0x3AD30, bin, data_3AD30]
+ - [0x3AD30, .rodata, done/audio/n_reverb]
- [0x3AD60, .rodata, done/audio/n_drvrNew]
- [0x3AD80, bin, data_3AD80]
- [0x3ADD0, .rodata, done/audio/n_seqplayer]