Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
reverb.c File Reference

Go to the source code of this file.

Macros

#define SWAP16(in, out)
 
#define CONVERT   173123.404906676
 
#define SCALE   16384
 
#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
 

Functions

void au_fx_create (AuFX *fx, u8 effectType, ALHeap *heap)
 
void au_filter_create (AuFilter *filter, ALHeap *heap)
 
void au_filter_init (AuFilter *filter, s16 arg1, s16 arg2, s16 cutoff)
 
void au_fx_load_preset (AuFX *fx, u8 effectType)
 
Acmdau_pull_fx (AuFX *fx, Acmd *ptr, s16 wetDmem, s16 tempDmem)
 Applies a chain of delay-line based effects to audio and mixes into output.
 
s32 au_fx_param_hdl (AuFX *fx, s16 index, s16 paramID, s32 value)
 

Variables

s32 SMALL_ROOM_PARAMS []
 
s32 BIG_ROOM_PARAMS []
 
s32 D_8007F0C0 []
 
s32 ECHO_PARAMS []
 
s32 CHORUS_PARAMS []
 
s32 FLANGE_PARAMS []
 
s32 NULL_PARAMS []
 
s32AU_FX_CUSTOM_PARAMS []
 

Macro Definition Documentation

◆ SWAP16

#define SWAP16 ( in,
out )
Value:
{ \
s16 t = out; \
out = in; \
in = t; \
}
BSS s32 PopupMenu_SelectedIndex

Definition at line 5 of file reverb.c.

5#define SWAP16(in, out) \
6{ \
7 s16 t = out; \
8 out = in; \
9 in = t; \
10}

Referenced by au_pull_fx().

◆ CONVERT

#define CONVERT   173123.404906676

Definition at line 27 of file reverb.c.

Referenced by au_fx_load_preset(), and au_fx_param_hdl().

◆ SCALE

#define SCALE   16384

Definition at line 29 of file reverb.c.

◆ INPUT_PARAM

#define INPUT_PARAM   0

Definition at line 31 of file reverb.c.

Referenced by au_fx_param_hdl().

◆ OUTPUT_PARAM

#define OUTPUT_PARAM   1

Definition at line 32 of file reverb.c.

Referenced by au_fx_param_hdl().

◆ FBCOEF_PARAM

#define FBCOEF_PARAM   2

Definition at line 33 of file reverb.c.

Referenced by au_fx_param_hdl().

◆ FFCOEF_PARAM

#define FFCOEF_PARAM   3

Definition at line 34 of file reverb.c.

Referenced by au_fx_param_hdl().

◆ GAIN_PARAM

#define GAIN_PARAM   4

Definition at line 35 of file reverb.c.

Referenced by au_fx_param_hdl().

◆ CHORUSRATE_PARAM

#define CHORUSRATE_PARAM   5

Definition at line 36 of file reverb.c.

Referenced by au_fx_param_hdl().

◆ CHORUSDEPTH_PARAM

#define CHORUSDEPTH_PARAM   6

Definition at line 37 of file reverb.c.

Referenced by au_fx_param_hdl().

◆ LPFILT_PARAM

#define LPFILT_PARAM   7

Definition at line 38 of file reverb.c.

Referenced by au_fx_param_hdl().

Function Documentation

◆ au_fx_create()

void au_fx_create ( AuFX * fx,
u8 effectType,
ALHeap * heap )
Parameters
effectTypefrom enum AuEffectType

Definition at line 138 of file reverb.c.

138 {
139 AuDelay* delay;
140 u16 i;
141
142 // allocate space for 4 AuDelay
143 fx->delays = alHeapAlloc(heap, AU_FX_MAX_TAPS, sizeof(AuDelay));
144 fx->base = alHeapAlloc(heap, AU_FX_LENGTH, sizeof(s16));
145
146 for (i = 0; i < AU_FX_MAX_TAPS; i++) {
147 delay = &fx->delays[i];
148 delay->resamplerTemplate = alHeapAlloc(heap, 1, sizeof(AuResampler));
149 delay->resamplerTemplate->state = alHeapAlloc(heap, 1, sizeof(RESAMPLE_STATE));
150 delay->lowpassTemplate = alHeapAlloc(heap, 1, sizeof(AuLowPass));
151 delay->lowpassTemplate->fstate = alHeapAlloc(heap, 1, sizeof(POLEF_STATE));
152 }
153
154 au_fx_load_preset(fx, effectType);
155}
#define AU_FX_LENGTH
Definition audio.h:19
struct AuResampler * resamplerTemplate
Definition audio.h:530
POLEF_STATE * fstate
Definition audio.h:546
struct AuLowPass * lowpassTemplate
Definition audio.h:528
RESAMPLE_STATE * state
Definition audio.h:593
#define AU_FX_MAX_TAPS
Definition audio.h:18
void * alHeapAlloc(ALHeap *heap, s32 count, s32 size)
Definition syn_driver.c:765
void au_fx_load_preset(AuFX *fx, u8 effectType)
Definition reverb.c:181

Referenced by au_driver_init().

◆ au_filter_create()

void au_filter_create ( AuFilter * filter,
ALHeap * heap )

Definition at line 158 of file reverb.c.

158 {
159 filter->base = alHeapAlloc(heap, AU_FILTER_LENGTH, sizeof(s16));
160 filter->lowpassTemplate = alHeapAlloc(heap, 1, sizeof(AuLowPass));
161 filter->lowpassTemplate->fstate = alHeapAlloc(heap, 1, sizeof(POLEF_STATE));
162 au_filter_init(filter, 0, 0, 0x5000);
163}
#define AU_FILTER_LENGTH
Definition audio.h:21
void au_filter_init(AuFilter *filter, s16 arg1, s16 arg2, s16 cutoff)
Definition reverb.c:166

◆ au_filter_init()

void au_filter_init ( AuFilter * filter,
s16 arg1,
s16 arg2,
s16 cutoff )

Definition at line 166 of file reverb.c.

166 {
167 filter->unused_06 = arg1;
168 filter->unused_08 = arg2;
169
170 if (cutoff != 0) {
171 filter->activeLowpass = filter->lowpassTemplate;
172 filter->activeLowpass->fc = cutoff;
173 _init_lpfilter(filter->activeLowpass);
174 return;
175 }
176
177 filter->activeLowpass = NULL;
178}

Referenced by au_filter_create().

◆ au_fx_load_preset()

void au_fx_load_preset ( AuFX * fx,
u8 effectType )

Definition at line 181 of file reverb.c.

181 {
182 s32* params;
183 s32* clr;
184 s32 i, j;
185 clr = (s32*)fx->base;
186
187 switch (effectType) {
188 case AU_FX_SMALLROOM:
189 params = SMALL_ROOM_PARAMS;
190 break;
191 case AU_FX_BIGROOM:
192 params = BIG_ROOM_PARAMS;
193 break;
194 case AU_FX_ECHO:
195 params = ECHO_PARAMS;
196 break;
197 case AU_FX_CHORUS:
198 params = CHORUS_PARAMS;
199 break;
200 case AU_FX_FLANGE:
201 params = FLANGE_PARAMS;
202 break;
203 case AU_FX_CUSTOM_0:
204 params = AU_FX_CUSTOM_PARAMS[0];
205 break;
206 case AU_FX_CUSTOM_1:
207 params = AU_FX_CUSTOM_PARAMS[1];
208 break;
209 case AU_FX_CUSTOM_2:
210 params = AU_FX_CUSTOM_PARAMS[2];
211 break;
212 case AU_FX_CUSTOM_3:
213 params = AU_FX_CUSTOM_PARAMS[3];
214 break;
216 params = BIG_ROOM_PARAMS;
217 break;
218 default:
219 params = NULL_PARAMS;
220 break;
221 }
222
223 j = 0;
224 fx->delayCount = params[j++];
225 fx->length = params[j++] * AUDIO_SAMPLES;
226 fx->input = fx->base;
227
228 for (i = 0; i < AU_FX_LENGTH/2; i++) {
229 *clr++ = 0;
230 }
231
232 for (i = 0; i < fx->delayCount; i++) {
233 AuDelay* delay = &fx->delays[i];
234 delay->input = params[j++] * AUDIO_SAMPLES;
235 delay->output = params[j++] * AUDIO_SAMPLES;
236 delay->fbcoef = (u16) params[j++];
237 delay->ffcoef = (u16) params[j++];
238 delay->gain = (u16) params[j++];
239
240 if (params[j]) {
241 delay->rsinc = (2.0 * (params[j++] / 1000.0f)) / gActiveSynDriverPtr->outputRate;
242 delay->rsgain = ((f32)params[j++] / CONVERT) * (delay->output - delay->input);
243 delay->rsval = 1.0f;
244 delay->rsdelta = 0.0f;
245 delay->activeResampler = delay->resamplerTemplate;
246 delay->resamplerTemplate->delta = 0.0;
247 delay->activeResampler->first = TRUE;
248 } else {
249 delay->activeResampler = NULL;
250 j++;
251 j++;
252 }
253
254 if (params[j]) {
255 delay->activeLowpass = delay->lowpassTemplate;
256 delay->activeLowpass->fc = params[j++];
257 _init_lpfilter(delay->activeLowpass);
258 } else {
259 delay->activeLowpass = NULL;
260 j++;
261 }
262 }
263}
f32 delta
Definition audio.h:595
f32 rsval
Definition audio.h:524
s32 rsdelta
Definition audio.h:525
@ AU_FX_CUSTOM_3
Definition audio.h:164
@ AU_FX_FLANGE
Definition audio.h:159
@ AU_FX_CUSTOM_2
Definition audio.h:163
@ AU_FX_CUSTOM_1
Definition audio.h:162
@ AU_FX_ECHO
Definition audio.h:160
@ AU_FX_CHORUS
Definition audio.h:158
@ AU_FX_SMALLROOM
Definition audio.h:156
@ AU_FX_OTHER_BIGROOM
Definition audio.h:165
@ AU_FX_BIGROOM
Definition audio.h:157
@ AU_FX_CUSTOM_0
Definition audio.h:161
AuSynDriver * gActiveSynDriverPtr
Definition syn_driver.c:14
s16 fc
Definition audio.h:542
s32 outputRate
Definition audio.h:637
u32 output
Definition audio.h:518
s16 fbcoef
Definition audio.h:520
s16 ffcoef
Definition audio.h:519
#define AUDIO_SAMPLES
Definition audio.h:16
b32 first
Definition audio.h:596
f32 rsgain
Definition audio.h:526
struct AuResampler * activeResampler
Definition audio.h:529
f32 rsinc
Definition audio.h:523
u32 input
Definition audio.h:517
s16 gain
Definition audio.h:521
struct AuLowPass * activeLowpass
Definition audio.h:527
#define CONVERT
Definition reverb.c:27
s32 ECHO_PARAMS[]
Definition reverb.c:73
s32 CHORUS_PARAMS[]
Definition reverb.c:81
s32 * AU_FX_CUSTOM_PARAMS[]
Definition reverb.c:106
s32 BIG_ROOM_PARAMS[]
Definition reverb.c:50
s32 FLANGE_PARAMS[]
Definition reverb.c:89
s32 NULL_PARAMS[]
Definition reverb.c:97
s32 SMALL_ROOM_PARAMS[]
Definition reverb.c:40

Referenced by au_bus_set_effect(), and au_fx_create().

◆ au_pull_fx()

Acmd * au_pull_fx ( AuFX * fx,
Acmd * ptr,
s16 wetDmem,
s16 tempDmem )

Applies a chain of delay-line based effects to audio and mixes into output.

For each delay tap in the FX chain:

  • Loads delay input/output from circular buffer.
  • Applies optional modulation and resampling.
  • Applies feedforward/feedback mixing.
  • Applies optional lowpass filtering.
  • Mixes result into wet output buffer.
Parameters
fxPointer to FX state (delay taps, buffers, etc.)
ptrPointer to the current audio command list position.
wetDmemDMEM offset to mix wet output into.
tempDmemBase DMEM offset for temporary working buffers.
Returns
Updated command list pointer.

Definition at line 281 of file reverb.c.

281 {
282 Acmd* cmdBufPos = ptr;
284
285 s16* inPtr;
286 s16* outPtr;
287
288 // DMEM temp buffer layout:
292
293 s16* prevOutPtr = 0;
295
296 // save wet input from voice mixing into circular delay buffer
298
299 // clear the wet output buffer for this frame
301
302 for (delayIdx = 0; delayIdx < fx->delayCount; delayIdx++) {
303 AuDelay* delay = &fx->delays[delayIdx];
305
306 // calculate read positions for input and output taps, wrapping the circular buffer if necessary
307 inPtr = &fx->input[-delay->input];
308 if (inPtr < fx->base) {
309 inPtr += fx->length;
310 }
311 outPtr = &fx->input[-delay->output];
312 if (outPtr < fx->base) {
313 outPtr += fx->length;
314 }
315
316 // if output is same as previous tap, reuse loaded data by swapping buffers
317 if (inPtr == prevOutPtr) {
319 } else {
320 // load from input tap into buffer
322 }
323
324 if (delay->activeResampler) {
325 // triangle wave modulation for chorus/flange
326 s32 ratio;
327 s32 length, count;
328 f32 delta, fratio, fincount;
330 s16 tmp;
331 s16* rsOutPtr;
332
333 // modulate delay time (triangle wave)
334 length = delay->output - delay->input;
335 delta = updateTriangleModulation(delay, AUDIO_SAMPLES);
336 delta /= length;
337 delta = (s32)(delta * fUnityPitch);
338 delta = delta / UNITY_PITCH;
339
340 fratio = 1.0 - delta;
341
342 // calculate fractional resampling count
344 count = (s32) fincount;
345 delay->activeResampler->delta = fincount - count;
346
347 // prepare delay line for resampling (wrap if needed)
348 rsOutPtr = &fx->input[-(delay->output - delay->rsdelta)];
349 ramAlign = ((s32) rsOutPtr & 7) >> 1;
351 if (rsOutPtr < fx->base) {
352 rsOutPtr += fx->length;
353 }
354
355 // load from delay line
356 cmdBufPos = _loadDelayLineBuffer(fx, rsOutPtr, resampleBuffer, count + ramAlign, cmdBufPos);
357
358 // process resampler
359 ratio = fratio * fUnityPitch;
360 tmp = outputTapBuffer >> 8;
362 delay->activeResampler->first, ratio, resampleBuffer + (ramAlign<<1), tmp);
363 delay->activeResampler->first = FALSE;
364 delay->rsdelta += count - AUDIO_SAMPLES;
365 } else {
366 // no resampling -- just load from output pointer
368 }
369
370 // feedforward: input -> output
371 if (delay->ffcoef) {
373
374 // save output if no additional processing needed
375 if (delay->activeResampler == NULL && delay->activeLowpass == NULL) {
377 }
378 }
379
380 // feedback: output -> input
381 if (delay->fbcoef) {
384 }
385
386 // Save processed output back into delay line (if not resampled)
387 if (delay->activeLowpass != NULL) {
388 // modified _n_filterBuffer
392 delay->activeLowpass->first = 0;
393 }
394
395 // save output (if not already saved earlier)
396 if (!delay->activeResampler) {
398 }
399
400 // mix input from this delay into wet output buffer
401 if (delay->gain) {
402 aMix(cmdBufPos++, 0, (u16)delay->gain, outputTapBuffer, outDmem);
403 }
404 prevOutPtr = &fx->input[delay->output];
405 }
406
407 // advance position in ring buffer
408 fx->input += AUDIO_SAMPLES;
409 if (fx->input >= &fx->base[fx->length]) {
410 fx->input = fx->base;
411 }
412
413 return cmdBufPos;
414}
s16 fccoef[16]
Definition audio.h:545
s32 first
Definition audio.h:547
s16 fgain
Definition audio.h:543
#define SWAP16(in, out)
Definition reverb.c:5

Referenced by alAudioFrame().

◆ au_fx_param_hdl()

s32 au_fx_param_hdl ( AuFX * fx,
s16 index,
s16 paramID,
s32 value )

Definition at line 416 of file reverb.c.

416 {
417 switch (paramID) {
418 case INPUT_PARAM:
419 fx->delays[index].input = value & 0xFFFFFFF8;
420 break;
421 case OUTPUT_PARAM:
422 fx->delays[index].output = value & 0xFFFFFFF8;
423 break;
424 case FFCOEF_PARAM:
425 fx->delays[index].ffcoef = value;
426 break;
427 case FBCOEF_PARAM:
428 fx->delays[index].fbcoef = value;
429 break;
430 case GAIN_PARAM:
431 fx->delays[index].gain = value;
432 break;
433 case CHORUSRATE_PARAM:
434 fx->delays[index].rsinc = (2.0 * (value / 1000.0f)) / gActiveSynDriverPtr->outputRate;
435 break;
437 fx->delays[index].rsgain = ((f32)value / CONVERT) * (fx->delays[index].output - fx->delays[index].input);
438 break;
439 case LPFILT_PARAM:
440 if (fx->delays[index].activeLowpass) {
441 fx->delays[index].activeLowpass->fc = value;
442 _init_lpfilter(fx->delays[index].activeLowpass);
443 }
444 break;
445 }
446 return 0;
447}
#define FBCOEF_PARAM
Definition reverb.c:33
#define INPUT_PARAM
Definition reverb.c:31
#define CHORUSRATE_PARAM
Definition reverb.c:36
#define OUTPUT_PARAM
Definition reverb.c:32
#define CHORUSDEPTH_PARAM
Definition reverb.c:37
#define GAIN_PARAM
Definition reverb.c:35
#define FFCOEF_PARAM
Definition reverb.c:34
#define LPFILT_PARAM
Definition reverb.c:38

Referenced by au_bus_set_fx_params().

Variable Documentation

◆ SMALL_ROOM_PARAMS

s32 SMALL_ROOM_PARAMS[]
Initial value:
= {
3, 11,
0, 9, 9830, -9830, 0, 0, 0, 0,
3, 7, 3276, -3276, 0x3FFF, 0, 0, 0,
0, 10, 5000, 0, 0, 0, 0, 0x5000
}

Definition at line 40 of file reverb.c.

40 {
41 /* sections length */
42 3, 11,
43 /* chorus chorus filter
44 input output fbcoef ffcoef gain rate depth coef */
45 0, 9, 9830, -9830, 0, 0, 0, 0,
46 3, 7, 3276, -3276, 0x3FFF, 0, 0, 0,
47 0, 10, 5000, 0, 0, 0, 0, 0x5000
48};

Referenced by au_fx_load_preset().

◆ BIG_ROOM_PARAMS

s32 BIG_ROOM_PARAMS[]
Initial value:
= {
4, 14,
0, 9, 9830, -9830, 0, 0, 0, 0,
2, 6, 3276, -3276, 0x3FFF, 0, 0, 0,
9, 12, 3276, -3276, 0x3FFF, 0, 0, 0,
0, 13, 6000, 0, 0, 0, 0, 0x5000
}

Definition at line 50 of file reverb.c.

50 {
51 /* sections length */
52 4, 14,
53 /* chorus chorus filter
54 input output fbcoef ffcoef gain rate depth coef */
55 0, 9, 9830, -9830, 0, 0, 0, 0,
56 2, 6, 3276, -3276, 0x3FFF, 0, 0, 0,
57 9, 12, 3276, -3276, 0x3FFF, 0, 0, 0,
58 0, 13, 6000, 0, 0, 0, 0, 0x5000
59};

Referenced by au_fx_load_preset().

◆ D_8007F0C0

s32 D_8007F0C0[]
Initial value:
= {
4, 17,
0, 11, 9830, -9830, 0, 0, 0, 0,
4, 9, 3276, -3276, 0x3FFF, 0, 0, 0,
11, 15, 3276, -3276, 0x3FFF, 0, 0, 0,
0, 16, 8000, 0, 0, 0, 0, 0x5000
}

Definition at line 62 of file reverb.c.

62 {
63 /* sections length */
64 4, 17,
65 /* chorus chorus filter
66 input output fbcoef ffcoef gain rate depth coef */
67 0, 11, 9830, -9830, 0, 0, 0, 0,
68 4, 9, 3276, -3276, 0x3FFF, 0, 0, 0,
69 11, 15, 3276, -3276, 0x3FFF, 0, 0, 0,
70 0, 16, 8000, 0, 0, 0, 0, 0x5000
71};

◆ ECHO_PARAMS

s32 ECHO_PARAMS[]
Initial value:
= {
1, 14,
0, 13, 20000, 0, 0x7FFF, 0, 0, 0x7FFF
}

Definition at line 73 of file reverb.c.

73 {
74 /* sections length */
75 1, 14,
76 /* chorus chorus filter
77 input output fbcoef ffcoef gain rate depth coef */
78 0, 13, 20000, 0, 0x7FFF, 0, 0, 0x7FFF
79};

Referenced by au_fx_load_preset().

◆ CHORUS_PARAMS

s32 CHORUS_PARAMS[]
Initial value:
= {
1, 3,
0, 1, 16384, 0, 0x7FFF, 7600, 700, 0
}

Definition at line 81 of file reverb.c.

81 {
82 /* sections length */
83 1, 3,
84 /* chorus chorus filter
85 input output fbcoef ffcoef gain rate depth coef */
86 0, 1, 16384, 0, 0x7FFF, 7600, 700, 0
87};

Referenced by au_fx_load_preset().

◆ FLANGE_PARAMS

s32 FLANGE_PARAMS[]
Initial value:
= {
1, 3,
0, 1, 0, 0x5FFF, 0x7FFF, 380, 500, 0
}

Definition at line 89 of file reverb.c.

89 {
90 /* sections length */
91 1, 3,
92 /* chorus chorus filter
93 input output fbcoef ffcoef gain rate depth coef */
94 0, 1, 0, 0x5FFF, 0x7FFF, 380, 500, 0
95};

Referenced by au_fx_load_preset().

◆ NULL_PARAMS

s32 NULL_PARAMS[]
Initial value:
= {
0, 0,
0, 0, 0, 0, 0, 0, 0, 0
}

Definition at line 97 of file reverb.c.

97 {
98 /* sections length */
99 0, 0,
100 /* chorus chorus filter
101 input output fbcoef ffcoef gain rate depth coef */
102 0, 0, 0, 0, 0, 0, 0, 0
103};

Referenced by au_fx_load_preset().

◆ AU_FX_CUSTOM_PARAMS

s32* AU_FX_CUSTOM_PARAMS[]
Initial value:

Definition at line 106 of file reverb.c.

Referenced by au_fx_load_preset(), and au_sfx_set_reverb_type().