Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
33450.c
Go to the documentation of this file.
1#include "common.h"
2#include "audio.h"
3
4#define LFSAMPLES 4
5#define AUEQPOWER_LENGTH 128
6
7// values for cosine from 0 to pi/2 multiplied by 32767
8// called n_eqpower in libultra
10 32767, 32764, 32757, 32744, 32727, 32704, 32677, 32644,
11 32607, 32564, 32517, 32464, 32407, 32344, 32277, 32205,
12 32127, 32045, 31958, 31866, 31770, 31668, 31561, 31450,
13 31334, 31213, 31087, 30957, 30822, 30682, 30537, 30388,
14 30234, 30075, 29912, 29744, 29572, 29395, 29214, 29028,
15 28838, 28643, 28444, 28241, 28033, 27821, 27605, 27385,
16 27160, 26931, 26698, 26461, 26220, 25975, 25726, 25473,
17 25216, 24956, 24691, 24423, 24151, 23875, 23596, 23313,
18 23026, 22736, 22442, 22145, 21845, 21541, 21234, 20924,
19 20610, 20294, 19974, 19651, 19325, 18997, 18665, 18331,
20 17993, 17653, 17310, 16965, 16617, 16266, 15913, 15558,
21 15200, 14840, 14477, 14113, 13746, 13377, 13006, 12633,
22 12258, 11881, 11503, 11122, 10740, 10357, 9971, 9584,
23 9196, 8806, 8415, 8023, 7630, 7235, 6839, 6442,
24 6044, 5646, 5246, 4845, 4444, 4042, 3640, 3237,
25 2833, 2429, 2025, 1620, 1216, 810, 405, 0
26};
27
28static Acmd* _decodeChunk(Acmd* cmdBufPos, AuLoadFilter* arg1, s32 count, s32 size, s16 arg4, s16 arg5, s32 flags);
29static s16 _getRate(f64 arg0, f64 arg1, s32 arg4, u16* arg5);
30
31// decode, resample and mix
32Acmd* au_pull_voice(AuPVoice* pvoice, Acmd* cmdBufPos) {
33 Acmd* ptr = cmdBufPos;
34 AuLoadFilter* decoder;
35 AuResampler* resampler;
36 AuEnvMixer* envMixer;
37 s16 inp;
38 f32 finCount;
39 s16 outp;
40 s32 startZero;
41 s32 outCount;
42 s32 incr;
43
44 envMixer = &pvoice->envMixer;
45 resampler = &pvoice->resampler;
46 decoder = &pvoice->decoder;
47
48 if (envMixer->motion != AL_PLAYING) {
49 return ptr;
50 }
51 outp = N_AL_DECODER_OUT;
52 if (resampler->ratio > MAX_RATIO) {
53 resampler->ratio = MAX_RATIO;
54 }
55
56 resampler->ratio = (s32)(resampler->ratio * UNITY_PITCH);
57 resampler->ratio = resampler->ratio / UNITY_PITCH;
58 finCount = resampler->delta + resampler->ratio * (f32)184;
59 outCount = (s32) finCount;
60 resampler->delta = finCount - (f32) outCount;
61 if (outCount != 0) {
62 if (decoder->instrument->type == AL_ADPCM_WAVE) {
63 s32 nSam;
64 s32 nbytes;
65 s32 nframes;
66 s32 op;
67 s32 tsam;
68 s32 nLeft;
69 s32 bEnd;
70 s32 nOver;
71 s32 overFlow;
72 s32 decoded = FALSE;
73 s32 looped = FALSE;
74 inp = N_AL_DECODER_IN;
75
76 aLoadADPCM(ptr++, decoder->bookSize, K0_TO_PHYS(decoder->instrument->predictor));
77
78 looped = (decoder->loop.end < outCount + decoder->sample) && (decoder->loop.count != 0);
79
80 if (looped) {
81 nSam = decoder->loop.end - decoder->sample;
82 } else {
83 nSam = outCount;
84 }
85 if (decoder->lastsam != 0) {
86 nLeft = ADPCMFSIZE - decoder->lastsam;
87 } else {
88 nLeft = 0;
89 }
90 tsam = nSam - nLeft;
91 if (tsam < 0) {
92 tsam = 0;
93 }
94 nframes = (tsam + ADPCMFSIZE - 1) >> LFSAMPLES;
95 nbytes = nframes * ADPCMFBYTES;
96 if (looped) {
97 ptr = _decodeChunk(ptr, decoder, tsam, nbytes, outp, inp, decoder->first);
98 if (decoder->lastsam != 0) {
99 outp += (decoder->lastsam << 1);
100 } else {
101 outp += (ADPCMFSIZE << 1);
102 }
103
104 decoder->lastsam = decoder->loop.start & 0xF;
105 decoder->memin = (s32)decoder->instrument->base + ADPCMFBYTES * ((s32)(decoder->loop.start >> LFSAMPLES) + 1);
106 decoder->sample = decoder->loop.start;
107 bEnd = outp;
108 while (outCount > nSam) {
109 outCount -= nSam;
110 op = (bEnd + ((nframes + 1) << (LFSAMPLES + 1)) + 16) & ~0x1f;
111 bEnd += nSam << 1;
112 if (decoder->loop.count != -1 && decoder->loop.count != 0) {
113 decoder->loop.count--;
114 }
115 nSam = MIN(outCount, decoder->loop.end - decoder->loop.start);
116 tsam = nSam - ADPCMFSIZE + decoder->lastsam;
117 if (tsam < 0) {
118 tsam = 0;
119 }
120 nframes = (tsam + ADPCMFSIZE - 1) >> LFSAMPLES;
121 nbytes = nframes * ADPCMFBYTES;
122 ptr = _decodeChunk(ptr, decoder, tsam, nbytes, op, inp, decoder->first | A_LOOP);
123 aDMEMMove(ptr++, op + (decoder->lastsam << 1), bEnd, nSam << 1);
124 }
125 decoder->lastsam = (outCount + decoder->lastsam) & 0xF;
126 decoder->sample += outCount;
127 decoder->memin += ADPCMFBYTES * nframes;
128 } else {
129 nSam = nframes << LFSAMPLES;
130 overFlow = decoder->memin + nbytes - ((s32)decoder->instrument->base + decoder->instrument->wavDataLength);
131
132 if (overFlow <= 0) {
133 overFlow = 0;
134 } else {
135 envMixer->motion = AL_STOPPED;
136 }
137 nOver = (overFlow / ADPCMFBYTES) << LFSAMPLES;
138 if (nOver > nSam + nLeft) {
139 nOver = nSam + nLeft;
140 }
141 nbytes -= overFlow;
142 if (nOver - (nOver & 0xF) < outCount) {
143 decoded = TRUE;
144 ptr = _decodeChunk(ptr, decoder, nSam - nOver, nbytes, outp, inp, decoder->first);
145 if (decoder->lastsam != 0) {
146 outp += decoder->lastsam << 1;
147 } else {
148 outp += ADPCMFSIZE << 1;
149 }
150 decoder->lastsam = (outCount + decoder->lastsam) & 0xF;
151 decoder->sample += outCount;
152 decoder->memin += ADPCMFBYTES * nframes;
153 } else {
154 decoder->lastsam = 0;
155 decoder->memin += ADPCMFBYTES * nframes;
156 }
157
158 if (nOver != 0) {
159 decoder->lastsam = 0;
160 if (decoded) {
161 startZero = (nLeft + nSam - nOver) << 1;
162 } else {
163 startZero = 0;
164 }
165 aClearBuffer(ptr++, startZero + outp, nOver << 1);
166 }
167 }
168 } else {
169 s32 nSam;
170 s32 nbytes;
171 s32 op;
172 s32 dramAlign;
173 s32 dramLoc;
174 s32 dmemAlign;
175 s32 overFlow;
176 if (decoder->loop.end < outCount + decoder->sample && decoder->loop.count != 0) {
177 nSam = decoder->loop.end - decoder->sample;
178 nbytes = nSam << 1;
179 if (nSam > 0) {
180 dramLoc = decoder->dmaFunc(decoder->memin, nbytes, decoder->dmaState, decoder->instrument->unk_25);
181 dramAlign = dramLoc & 7;
182 nbytes += dramAlign;
183 n_aLoadBuffer(ptr++, nbytes + 8 - (nbytes & 7), outp, dramLoc - dramAlign);
184 } else {
185 dramAlign = 0;
186 }
187 outp += dramAlign;
188 decoder->memin = (s32)decoder->instrument->base + (decoder->loop.start << 1);
189 decoder->sample = decoder->loop.start;
190 op = outp;
191 while (outCount > nSam){
192 op += nSam << 1;
193 outCount -= nSam;
194 if (decoder->loop.count != -1 && decoder->loop.count != 0) {
195 decoder->loop.count--;
196 }
197 nSam = MIN(outCount, decoder->loop.end - decoder->loop.start);
198 nbytes = nSam << 1;
199 dramLoc = decoder->dmaFunc(decoder->memin, nbytes, decoder->dmaState, decoder->instrument->unk_25);
200 dramAlign = dramLoc & 7;
201 nbytes += dramAlign;
202 if ((op & 7) != 0) {
203 dmemAlign = 8 - (op & 7);
204 } else {
205 dmemAlign = 0;
206 }
207 n_aLoadBuffer(ptr++, nbytes + 8 - (nbytes & 7), op + dmemAlign, dramLoc - dramAlign);
208
209 if (dramAlign != 0 || dmemAlign != 0) {
210 aDMEMMove(ptr++, op + dramAlign + dmemAlign, op, nSam * 2);
211 }
212 }
213 decoder->sample += outCount;
214 decoder->memin += outCount << 1;
215 } else {
216 nbytes = outCount << 1;
217 overFlow = decoder->memin + nbytes - ((s32)decoder->instrument->base + decoder->instrument->wavDataLength);
218 if (overFlow <= 0) {
219 overFlow = 0;
220 } else {
221 envMixer->motion = AL_STOPPED;
222 }
223 if (nbytes < overFlow) {
224 overFlow = nbytes;
225 }
226 if (overFlow < nbytes) {
227 if (outCount > 0) {
228 nbytes -= overFlow;
229 dramLoc = decoder->dmaFunc(decoder->memin, nbytes, decoder->dmaState, decoder->instrument->unk_25);
230 dramAlign = dramLoc & 7;
231 nbytes += dramAlign;
232 n_aLoadBuffer(ptr++, nbytes + 8 - (nbytes & 7), outp, dramLoc - dramAlign);
233 } else {
234 dramAlign = 0;
235 }
236 outp += dramAlign;
237 decoder->sample += outCount;
238 decoder->memin += outCount << 1;
239 } else {
240 decoder->memin += outCount << 1;
241 }
242
243 if (overFlow != 0) {
244 startZero = (outCount << 1) - overFlow;
245 if (startZero < 0) {
246 startZero = 0;
247 }
248 aClearBuffer(ptr++, startZero + outp, overFlow);
249 }
250 }
251 }
252 }
253 incr = (s32)(resampler->ratio * UNITY_PITCH);
254 n_aResample(ptr++, osVirtualToPhysical(resampler->state), resampler->first, incr, outp, 0);
255 resampler->first = 0;
256
257 if (envMixer->first != 0) {
258 envMixer->first = 0;
259 if (!AuSynUseStereo) {
260 envMixer->ltgt = (envMixer->volume * AuEqPower[AUEQPOWER_LENGTH / 2]) >> 15;
261 envMixer->rtgt = (envMixer->volume * AuEqPower[AUEQPOWER_LENGTH / 2]) >> 15;
262 } else {
263 envMixer->ltgt = (envMixer->volume * AuEqPower[envMixer->pan]) >> 15;
264 envMixer->rtgt = (envMixer->volume * AuEqPower[AUEQPOWER_LENGTH - envMixer->pan - 1]) >> 15;
265 }
266 envMixer->lratm = _getRate(envMixer->cvolL, envMixer->ltgt, envMixer->segEnd, &envMixer->lratl);
267 envMixer->rratm = _getRate(envMixer->cvolR, envMixer->rtgt, envMixer->segEnd, &envMixer->rratl);
268 n_aSetVolume(ptr++, A_RATE, envMixer->ltgt, envMixer->lratm, envMixer->lratl);
269 n_aSetVolume(ptr++, A_LEFT | A_VOL, envMixer->cvolL, envMixer->dryamt, envMixer->wetamt);
270 n_aSetVolume(ptr++, A_RIGHT | A_VOL, envMixer->rtgt, envMixer->rratm, envMixer->rratl);
271 n_aEnvMixer(ptr++, A_INIT, envMixer->cvolR, osVirtualToPhysical(envMixer->state));
272 } else {
273 n_aEnvMixer(ptr++, A_CONTINUE, 0, osVirtualToPhysical(envMixer->state));
274 }
275
276 envMixer->delta += AUDIO_SAMPLES;
277 if (envMixer->segEnd < envMixer->delta) {
278 envMixer->delta = envMixer->segEnd;
279 }
280 if (envMixer->motion == AL_STOPPED) {
281 envMixer->first = 1;
282 envMixer->volume = 1;
283 resampler->delta = 0.0f;
284 resampler->first = 1;
285 decoder->lastsam = 0;
286 decoder->first = 1;
287 decoder->sample = 0;
288 decoder->memin = (s32) decoder->instrument->base;
289 decoder->loop.count = decoder->instrument->loopCount;
290 func_80052E30(pvoice->index);
291 }
292 return ptr;
293}
294
295static Acmd* _decodeChunk(Acmd* cmdBufPos, AuLoadFilter* filter, s32 tsam, s32 nbytes, s16 output, s16 input, s32 flags) {
296 s32 endAddr;
297 s32 endAlign;
298 s32 paddedSize;
299
300 if (nbytes > 0) {
301 endAddr = filter->dmaFunc((s32) filter->memin, nbytes, filter->dmaState, filter->instrument->unk_25);
302 endAlign = endAddr & 7;
303 nbytes += endAlign;
304 paddedSize = nbytes + 8 - (nbytes & 7);
305 n_aLoadBuffer(cmdBufPos++, paddedSize, input, endAddr - endAlign);
306 } else {
307 endAlign = 0;
308 }
309
310 if (flags & A_LOOP) {
311 aSetLoop(cmdBufPos++, K0_TO_PHYS(filter->lstate));
312 }
313
314 n_aADPCMdec(cmdBufPos++, filter->state, flags, tsam << 1, endAlign, output);
315
316 filter->first = 0;
317 return cmdBufPos;
318}
319
320static s16 _getRate(f64 vol, f64 tgt, s32 count, u16* ratel) {
321 f64 inv;
322 f64 a;
323 f64 b;
324 s16 c_int;
325 s16 a_int;
326 s16 b_int;
327
328 if (count == 0) {
329 if (tgt >= vol) {
330 *ratel = 0xFFFF;
331 return 0x7FFF;
332 } else {
333 *ratel = 0;
334 return 0;
335 }
336 }
337 inv = (1.0 / count);
338
339 if (tgt < 1.0) {
340 tgt = 1.0;
341 }
342 if (vol <= 0.0) {
343 vol = 1.0;
344 }
345
346 a = (tgt - vol) * inv * 8.0;
347 a_int = a;
348 c_int = (a_int - 1);
349
350 b = (a - a_int) + 1.0;
351 b_int = b;
352 c_int += b_int;
353
354 *ratel = (b - b_int) * 0xFFFF;
355 return c_int;
356}
void func_80052E30(u8 index)
#define LFSAMPLES
Definition 33450.c:4
Acmd * au_pull_voice(AuPVoice *pvoice, Acmd *cmdBufPos)
Definition 33450.c:32
#define AUEQPOWER_LENGTH
Definition 33450.c:5
s16 AuEqPower[128]
Definition 33450.c:9
u16 * predictor
Definition audio.h:556
f32 delta
Definition audio.h:470
s16 dryamt
Definition audio.h:481
volatile u8 AuSynUseStereo
f32 ratio
Definition audio.h:469
#define N_AL_DECODER_OUT
Definition audio.h:31
s16 wetamt
Definition audio.h:482
s32 segEnd
Definition audio.h:490
s16 rtgt
Definition audio.h:488
s16 cvolR
Definition audio.h:480
s16 lratm
Definition audio.h:484
s32 bookSize
Definition audio.h:457
AuLoadFilter decoder
Definition audio.h:498
ADPCM_STATE * state
Definition audio.h:453
#define AUDIO_SAMPLES
Definition audio.h:44
s32 first
Definition audio.h:471
u32 wavDataLength
Definition audio.h:551
s32 loopCount
Definition audio.h:555
s16 rratm
Definition audio.h:487
s16 volume
Definition audio.h:478
s16 pan
Definition audio.h:477
s32 delta
Definition audio.h:489
u8 * base
Definition audio.h:550
ENVMIX_STATE * state
Definition audio.h:476
s32 lastsam
Definition audio.h:461
struct Instrument * instrument
Definition audio.h:456
AuResampler resampler
Definition audio.h:499
#define ADPCMFBYTES
Definition audio.h:47
s16 cvolL
Definition audio.h:479
s16 rratl
Definition audio.h:486
s16 lratl
Definition audio.h:483
u8 index
Definition audio.h:504
ALDMAproc2 dmaFunc
Definition audio.h:458
s32 first
Definition audio.h:491
ALRawLoop loop
Definition audio.h:455
s32 motion
Definition audio.h:492
ADPCM_STATE * lstate
Definition audio.h:454
NUDMAState * dmaState
Definition audio.h:459
#define N_AL_DECODER_IN
Definition audio.h:28
u8 unk_25
Definition audio.h:564
AuEnvMixer envMixer
Definition audio.h:500
s32 memin
Definition audio.h:463
RESAMPLE_STATE * state
Definition audio.h:468
s16 ltgt
Definition audio.h:485
u8 type
Definition audio.h:563
s32 first
Definition audio.h:462
s32 sample
Definition audio.h:460
s8 flags
Definition demo_api.c:15