Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/src/audio/load.c
7857 views
1
#ifndef VERSION_SH
2
#include <ultra64.h>
3
4
#include "data.h"
5
#include "external.h"
6
#include "heap.h"
7
#include "load.h"
8
#include "seqplayer.h"
9
10
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
11
12
struct SharedDma {
13
/*0x0*/ u8 *buffer; // target, points to pre-allocated buffer
14
/*0x4*/ uintptr_t source; // device address
15
/*0x8*/ u16 sizeUnused; // set to bufSize, never read
16
/*0xA*/ u16 bufSize; // size of buffer
17
/*0xC*/ u8 unused2; // set to 0, never read
18
/*0xD*/ u8 reuseIndex; // position in sSampleDmaReuseQueue1/2, if ttl == 0
19
/*0xE*/ u8 ttl; // duration after which the DMA can be discarded
20
}; // size = 0x10
21
22
// EU only
23
void port_eu_init(void);
24
25
struct Note *gNotes;
26
27
#if defined(VERSION_EU)
28
UNUSED static u8 pad[4];
29
#endif
30
31
struct SequencePlayer gSequencePlayers[SEQUENCE_PLAYERS];
32
struct SequenceChannel gSequenceChannels[SEQUENCE_CHANNELS];
33
struct SequenceChannelLayer gSequenceLayers[SEQUENCE_LAYERS];
34
35
struct SequenceChannel gSequenceChannelNone;
36
struct AudioListItem gLayerFreeList;
37
struct NotePool gNoteFreeLists;
38
39
OSMesgQueue gCurrAudioFrameDmaQueue;
40
OSMesg gCurrAudioFrameDmaMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE];
41
OSIoMesg gCurrAudioFrameDmaIoMesgBufs[AUDIO_FRAME_DMA_QUEUE_SIZE];
42
43
OSMesgQueue gAudioDmaMesgQueue;
44
OSMesg gAudioDmaMesg;
45
OSIoMesg gAudioDmaIoMesg;
46
47
struct SharedDma sSampleDmas[0x60];
48
u32 gSampleDmaNumListItems; // sh: 0x803503D4
49
u32 sSampleDmaListSize1; // sh: 0x803503D8
50
u32 sUnused80226B40; // set to 0, never read, sh: 0x803503DC
51
52
// Circular buffer of DMAs with ttl = 0. tail <= head, wrapping around mod 256.
53
u8 sSampleDmaReuseQueue1[256];
54
u8 sSampleDmaReuseQueue2[256];
55
u8 sSampleDmaReuseQueueTail1;
56
u8 sSampleDmaReuseQueueTail2;
57
u8 sSampleDmaReuseQueueHead1; // sh: 0x803505E2
58
u8 sSampleDmaReuseQueueHead2; // sh: 0x803505E3
59
60
// bss correct up to here
61
62
ALSeqFile *gSeqFileHeader;
63
ALSeqFile *gAlCtlHeader;
64
ALSeqFile *gAlTbl;
65
u8 *gAlBankSets;
66
u16 gSequenceCount;
67
68
struct CtlEntry *gCtlEntries; // sh: 0x803505F8
69
70
#if defined(VERSION_EU)
71
u32 padEuBss1;
72
struct AudioBufferParametersEU gAudioBufferParameters;
73
#elif defined(VERSION_US) || defined(VERSION_JP)
74
s32 gAiFrequency;
75
#endif
76
77
u32 sDmaBufSize;
78
s32 gMaxAudioCmds;
79
s32 gMaxSimultaneousNotes;
80
81
#if defined(VERSION_EU)
82
s16 gTempoInternalToExternal;
83
#else
84
s32 gSamplesPerFrameTarget;
85
s32 gMinAiBufferLength;
86
87
s16 gTempoInternalToExternal;
88
89
s8 gAudioUpdatesPerFrame;
90
#endif
91
92
s8 gSoundMode;
93
94
#if defined(VERSION_EU)
95
s8 gAudioUpdatesPerFrame;
96
#endif
97
98
extern u64 gAudioGlobalsStartMarker;
99
extern u64 gAudioGlobalsEndMarker;
100
101
extern u8 gSoundDataADSR[]; // sound_data.ctl
102
extern u8 gSoundDataRaw[]; // sound_data.tbl
103
extern u8 gMusicData[]; // sequences.s
104
extern u8 gBankSetsData[]; // bank_sets.s
105
106
ALSeqFile *get_audio_file_header(s32 arg0);
107
108
/**
109
* Performs an immediate DMA copy
110
*/
111
void audio_dma_copy_immediate(uintptr_t devAddr, void *vAddr, size_t nbytes) {
112
eu_stubbed_printf_3("Romcopy %x -> %x ,size %x\n", devAddr, vAddr, nbytes);
113
osInvalDCache(vAddr, nbytes);
114
osPiStartDma(&gAudioDmaIoMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, vAddr, nbytes,
115
&gAudioDmaMesgQueue);
116
osRecvMesg(&gAudioDmaMesgQueue, NULL, OS_MESG_BLOCK);
117
eu_stubbed_printf_0("Romcopyend\n");
118
}
119
120
#ifdef VERSION_EU
121
u8 audioString34[] = "CAUTION:WAVE CACHE FULL %d";
122
u8 audioString35[] = "BASE %x %x\n";
123
u8 audioString36[] = "LOAD %x %x %x\n";
124
u8 audioString37[] = "INSTTOP %x\n";
125
u8 audioString38[] = "INSTMAP[0] %x\n";
126
u8 audioString39[] = "already flags %d\n";
127
u8 audioString40[] = "already flags %d\n";
128
u8 audioString41[] = "ERR:SLOW BANK DMA BUSY\n";
129
u8 audioString42[] = "ERR:SLOW DMA BUSY\n";
130
u8 audioString43[] = "Check %d bank %d\n";
131
u8 audioString44[] = "Cache Check\n";
132
u8 audioString45[] = "NO BANK ERROR\n";
133
u8 audioString46[] = "BANK %d LOADING START\n";
134
u8 audioString47[] = "BANK %d LOAD MISS (NO MEMORY)!\n";
135
u8 audioString48[] = "BANK %d ALREADY CACHED\n";
136
u8 audioString49[] = "BANK LOAD MISS! FOR %d\n";
137
#endif
138
139
/**
140
* Performs an asynchronus (normal priority) DMA copy
141
*/
142
void audio_dma_copy_async(uintptr_t devAddr, void *vAddr, size_t nbytes, OSMesgQueue *queue, OSIoMesg *mesg) {
143
osInvalDCache(vAddr, nbytes);
144
osPiStartDma(mesg, OS_MESG_PRI_NORMAL, OS_READ, devAddr, vAddr, nbytes, queue);
145
}
146
147
/**
148
* Performs a partial asynchronous (normal priority) DMA copy. This is limited
149
* to 0x1000 bytes transfer at once.
150
*/
151
void audio_dma_partial_copy_async(uintptr_t *devAddr, u8 **vAddr, ssize_t *remaining, OSMesgQueue *queue, OSIoMesg *mesg) {
152
#if defined(VERSION_EU)
153
ssize_t transfer = (*remaining >= 0x1000 ? 0x1000 : *remaining);
154
#else
155
ssize_t transfer = (*remaining < 0x1000 ? *remaining : 0x1000);
156
#endif
157
*remaining -= transfer;
158
osInvalDCache(*vAddr, transfer);
159
osPiStartDma(mesg, OS_MESG_PRI_NORMAL, OS_READ, *devAddr, *vAddr, transfer, queue);
160
*devAddr += transfer;
161
*vAddr += transfer;
162
}
163
164
void decrease_sample_dma_ttls() {
165
u32 i;
166
167
for (i = 0; i < sSampleDmaListSize1; i++) {
168
#if defined(VERSION_EU)
169
struct SharedDma *temp = &sSampleDmas[i];
170
#else
171
struct SharedDma *temp = sSampleDmas + i;
172
#endif
173
if (temp->ttl != 0) {
174
temp->ttl--;
175
if (temp->ttl == 0) {
176
temp->reuseIndex = sSampleDmaReuseQueueHead1;
177
sSampleDmaReuseQueue1[sSampleDmaReuseQueueHead1++] = (u8) i;
178
}
179
}
180
}
181
182
for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) {
183
#if defined(VERSION_EU)
184
struct SharedDma *temp = &sSampleDmas[i];
185
#else
186
struct SharedDma *temp = sSampleDmas + i;
187
#endif
188
if (temp->ttl != 0) {
189
temp->ttl--;
190
if (temp->ttl == 0) {
191
temp->reuseIndex = sSampleDmaReuseQueueHead2;
192
sSampleDmaReuseQueue2[sSampleDmaReuseQueueHead2++] = (u8) i;
193
}
194
}
195
}
196
197
sUnused80226B40 = 0;
198
}
199
200
void *dma_sample_data(uintptr_t devAddr, u32 size, s32 arg2, u8 *dmaIndexRef) {
201
s32 hasDma = FALSE;
202
struct SharedDma *dma;
203
uintptr_t dmaDevAddr;
204
u32 transfer;
205
u32 i;
206
u32 dmaIndex;
207
ssize_t bufferPos;
208
UNUSED u32 pad;
209
210
if (arg2 != 0 || *dmaIndexRef >= sSampleDmaListSize1) {
211
for (i = sSampleDmaListSize1; i < gSampleDmaNumListItems; i++) {
212
#if defined(VERSION_EU)
213
dma = &sSampleDmas[i];
214
#else
215
dma = sSampleDmas + i;
216
#endif
217
bufferPos = devAddr - dma->source;
218
if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) {
219
// We already have a DMA request for this memory range.
220
if (dma->ttl == 0 && sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2) {
221
// Move the DMA out of the reuse queue, by swapping it with the
222
// tail, and then incrementing the tail.
223
if (dma->reuseIndex != sSampleDmaReuseQueueTail2) {
224
sSampleDmaReuseQueue2[dma->reuseIndex] =
225
sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2];
226
sSampleDmas[sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2]].reuseIndex =
227
dma->reuseIndex;
228
}
229
sSampleDmaReuseQueueTail2++;
230
}
231
dma->ttl = 60;
232
*dmaIndexRef = (u8) i;
233
#if defined(VERSION_EU)
234
return &dma->buffer[(devAddr - dma->source)];
235
#else
236
return (devAddr - dma->source) + dma->buffer;
237
#endif
238
}
239
}
240
241
if (sSampleDmaReuseQueueTail2 != sSampleDmaReuseQueueHead2 && arg2 != 0) {
242
// Allocate a DMA from reuse queue 2. This queue can be empty, since
243
// TTL 60 is pretty large.
244
dmaIndex = sSampleDmaReuseQueue2[sSampleDmaReuseQueueTail2];
245
sSampleDmaReuseQueueTail2++;
246
dma = sSampleDmas + dmaIndex;
247
hasDma = TRUE;
248
}
249
} else {
250
#if defined(VERSION_EU)
251
dma = sSampleDmas;
252
dma += *dmaIndexRef;
253
#else
254
dma = sSampleDmas + *dmaIndexRef;
255
#endif
256
bufferPos = devAddr - dma->source;
257
if (0 <= bufferPos && (size_t) bufferPos <= dma->bufSize - size) {
258
// We already have DMA for this memory range.
259
if (dma->ttl == 0) {
260
// Move the DMA out of the reuse queue, by swapping it with the
261
// tail, and then incrementing the tail.
262
if (dma->reuseIndex != sSampleDmaReuseQueueTail1) {
263
#if defined(VERSION_EU)
264
if (1) {
265
}
266
#endif
267
sSampleDmaReuseQueue1[dma->reuseIndex] =
268
sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1];
269
sSampleDmas[sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1]].reuseIndex =
270
dma->reuseIndex;
271
}
272
sSampleDmaReuseQueueTail1++;
273
}
274
dma->ttl = 2;
275
#if defined(VERSION_EU)
276
return dma->buffer + (devAddr - dma->source);
277
#else
278
return (devAddr - dma->source) + dma->buffer;
279
#endif
280
}
281
}
282
283
if (!hasDma) {
284
// Allocate a DMA from reuse queue 1. This queue will hopefully never
285
// be empty, since TTL 2 is so small.
286
dmaIndex = sSampleDmaReuseQueue1[sSampleDmaReuseQueueTail1++];
287
dma = sSampleDmas + dmaIndex;
288
hasDma = TRUE;
289
}
290
291
transfer = dma->bufSize;
292
dmaDevAddr = devAddr & ~0xF;
293
dma->ttl = 2;
294
dma->source = dmaDevAddr;
295
dma->sizeUnused = transfer;
296
#ifdef VERSION_US
297
osInvalDCache(dma->buffer, transfer);
298
#endif
299
#if defined(VERSION_EU)
300
osPiStartDma(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount++], OS_MESG_PRI_NORMAL,
301
OS_READ, dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue);
302
*dmaIndexRef = dmaIndex;
303
return (devAddr - dmaDevAddr) + dma->buffer;
304
#else
305
gCurrAudioFrameDmaCount++;
306
osPiStartDma(&gCurrAudioFrameDmaIoMesgBufs[gCurrAudioFrameDmaCount - 1], OS_MESG_PRI_NORMAL,
307
OS_READ, dmaDevAddr, dma->buffer, transfer, &gCurrAudioFrameDmaQueue);
308
*dmaIndexRef = dmaIndex;
309
return dma->buffer + (devAddr - dmaDevAddr);
310
#endif
311
}
312
313
314
void init_sample_dma_buffers(UNUSED s32 arg0) {
315
s32 i;
316
#if defined(VERSION_EU)
317
#define j i
318
#else
319
s32 j;
320
#endif
321
322
#if defined(VERSION_EU)
323
sDmaBufSize = 0x400;
324
#else
325
sDmaBufSize = 144 * 9;
326
#endif
327
328
#if defined(VERSION_EU)
329
for (i = 0; i < gMaxSimultaneousNotes * 3 * gAudioBufferParameters.presetUnk4; i++)
330
#else
331
for (i = 0; i < gMaxSimultaneousNotes * 3; i++)
332
#endif
333
{
334
sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, sDmaBufSize);
335
if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) {
336
#if defined(VERSION_EU)
337
break;
338
#else
339
goto out1;
340
#endif
341
}
342
sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize;
343
sSampleDmas[gSampleDmaNumListItems].source = 0;
344
sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0;
345
sSampleDmas[gSampleDmaNumListItems].unused2 = 0;
346
sSampleDmas[gSampleDmaNumListItems].ttl = 0;
347
gSampleDmaNumListItems++;
348
}
349
#if defined(VERSION_JP) || defined(VERSION_US)
350
out1:
351
#endif
352
353
for (i = 0; (u32) i < gSampleDmaNumListItems; i++) {
354
sSampleDmaReuseQueue1[i] = (u8) i;
355
sSampleDmas[i].reuseIndex = (u8) i;
356
}
357
358
for (j = gSampleDmaNumListItems; j < 0x100; j++) {
359
sSampleDmaReuseQueue1[j] = 0;
360
}
361
362
sSampleDmaReuseQueueTail1 = 0;
363
sSampleDmaReuseQueueHead1 = (u8) gSampleDmaNumListItems;
364
sSampleDmaListSize1 = gSampleDmaNumListItems;
365
366
#if defined(VERSION_EU)
367
sDmaBufSize = 0x200;
368
#else
369
sDmaBufSize = 160 * 9;
370
#endif
371
for (i = 0; i < gMaxSimultaneousNotes; i++) {
372
sSampleDmas[gSampleDmaNumListItems].buffer = soundAlloc(&gNotesAndBuffersPool, sDmaBufSize);
373
if (sSampleDmas[gSampleDmaNumListItems].buffer == NULL) {
374
#if defined(VERSION_EU)
375
break;
376
#else
377
goto out2;
378
#endif
379
}
380
sSampleDmas[gSampleDmaNumListItems].bufSize = sDmaBufSize;
381
sSampleDmas[gSampleDmaNumListItems].source = 0;
382
sSampleDmas[gSampleDmaNumListItems].sizeUnused = 0;
383
sSampleDmas[gSampleDmaNumListItems].unused2 = 0;
384
sSampleDmas[gSampleDmaNumListItems].ttl = 0;
385
gSampleDmaNumListItems++;
386
}
387
#if defined(VERSION_JP) || defined(VERSION_US)
388
out2:
389
#endif
390
391
for (i = sSampleDmaListSize1; (u32) i < gSampleDmaNumListItems; i++) {
392
sSampleDmaReuseQueue2[i - sSampleDmaListSize1] = (u8) i;
393
sSampleDmas[i].reuseIndex = (u8)(i - sSampleDmaListSize1);
394
}
395
396
// This probably meant to touch the range size1..size2 as well... but it
397
// doesn't matter, since these values are never read anyway.
398
for (j = gSampleDmaNumListItems; j < 0x100; j++) {
399
sSampleDmaReuseQueue2[j] = sSampleDmaListSize1;
400
}
401
402
sSampleDmaReuseQueueTail2 = 0;
403
sSampleDmaReuseQueueHead2 = gSampleDmaNumListItems - sSampleDmaListSize1;
404
#if defined(VERSION_EU)
405
#undef j
406
#endif
407
}
408
409
#if defined(VERSION_JP) || defined(VERSION_US)
410
// This function gets optimized out on US due to being static and never called
411
UNUSED static
412
#endif
413
void patch_sound(UNUSED struct AudioBankSound *sound, UNUSED u8 *memBase, UNUSED u8 *offsetBase) {
414
struct AudioBankSample *sample;
415
void *patched;
416
UNUSED u8 *mem; // unused on US
417
418
#define PATCH(x, base) (patched = (void *)((uintptr_t) (x) + (uintptr_t) base))
419
420
if (sound->sample != NULL) {
421
sample = sound->sample = PATCH(sound->sample, memBase);
422
if (sample->loaded == 0) {
423
sample->sampleAddr = PATCH(sample->sampleAddr, offsetBase);
424
sample->loop = PATCH(sample->loop, memBase);
425
sample->book = PATCH(sample->book, memBase);
426
sample->loaded = 1;
427
}
428
#if defined(VERSION_EU)
429
else if (sample->loaded == 0x80) {
430
PATCH(sample->sampleAddr, offsetBase);
431
mem = soundAlloc(&gNotesAndBuffersPool, sample->sampleSize);
432
if (mem == NULL) {
433
sample->sampleAddr = patched;
434
sample->loaded = 1;
435
} else {
436
audio_dma_copy_immediate((uintptr_t) patched, mem, sample->sampleSize);
437
sample->loaded = 0x81;
438
sample->sampleAddr = mem;
439
}
440
sample->loop = PATCH(sample->loop, memBase);
441
sample->book = PATCH(sample->book, memBase);
442
}
443
#endif
444
}
445
446
#undef PATCH
447
}
448
449
#ifdef VERSION_EU
450
#define PATCH_SOUND patch_sound
451
#else
452
// copt inline of the above
453
#define PATCH_SOUND(_sound, mem, offset) \
454
{ \
455
struct AudioBankSound *sound = _sound; \
456
struct AudioBankSample *sample; \
457
void *patched; \
458
if ((*sound).sample != (void *) 0) \
459
{ \
460
patched = (void *)(((uintptr_t)(*sound).sample) + ((uintptr_t)((u8 *) mem))); \
461
(*sound).sample = patched; \
462
sample = (*sound).sample; \
463
if ((*sample).loaded == 0) \
464
{ \
465
patched = (void *)(((uintptr_t)(*sample).sampleAddr) + ((uintptr_t) offset)); \
466
(*sample).sampleAddr = patched; \
467
patched = (void *)(((uintptr_t)(*sample).loop) + ((uintptr_t)((u8 *) mem))); \
468
(*sample).loop = patched; \
469
patched = (void *)(((uintptr_t)(*sample).book) + ((uintptr_t)((u8 *) mem))); \
470
(*sample).book = patched; \
471
(*sample).loaded = 1; \
472
} \
473
} \
474
}
475
#endif
476
477
// on US/JP this inlines patch_sound, using some -sopt compiler flag
478
void patch_audio_bank(struct AudioBank *mem, u8 *offset, u32 numInstruments, u32 numDrums) {
479
struct Instrument *instrument;
480
struct Instrument **itInstrs;
481
struct Instrument **end;
482
struct AudioBank *temp;
483
u32 i;
484
void *patched;
485
struct Drum *drum;
486
struct Drum **drums;
487
#if defined(VERSION_EU)
488
u32 numDrums2;
489
#endif
490
491
#define BASE_OFFSET_REAL(x, base) (void *)((uintptr_t) (x) + (uintptr_t) base)
492
#define PATCH(x, base) (patched = BASE_OFFSET_REAL(x, base))
493
#define PATCH_MEM(x) x = PATCH(x, mem)
494
495
#if defined(VERSION_JP) || defined(VERSION_US)
496
#define BASE_OFFSET(x, base) BASE_OFFSET_REAL(x, base)
497
#else
498
#define BASE_OFFSET(x, base) BASE_OFFSET_REAL(base, x)
499
#endif
500
501
drums = mem->drums;
502
#if defined(VERSION_JP) || defined(VERSION_US)
503
if (drums != NULL && numDrums > 0) {
504
mem->drums = (void *)((uintptr_t) drums + (uintptr_t) mem);
505
if (numDrums > 0) //! unneeded when -sopt is enabled
506
for (i = 0; i < numDrums; i++) {
507
#else
508
numDrums2 = numDrums;
509
if (drums != NULL && numDrums2 > 0) {
510
mem->drums = PATCH(drums, mem);
511
for (i = 0; i < numDrums2; i++) {
512
#endif
513
patched = mem->drums[i];
514
if (patched != NULL) {
515
drum = PATCH(patched, mem);
516
mem->drums[i] = drum;
517
if (drum->loaded == 0) {
518
#if defined(VERSION_JP) || defined(VERSION_US)
519
//! copt replaces drum with 'patched' for these two lines
520
PATCH_SOUND(&(*(struct Drum *)patched).sound, mem, offset);
521
patched = (*(struct Drum *)patched).envelope;
522
#else
523
patch_sound(&drum->sound, (u8 *) mem, offset);
524
patched = drum->envelope;
525
#endif
526
drum->envelope = BASE_OFFSET(mem, patched);
527
drum->loaded = 1;
528
}
529
530
}
531
}
532
}
533
534
//! Doesn't affect EU, but required for US/JP
535
temp = &*mem;
536
#if defined(VERSION_JP) || defined(VERSION_US)
537
if (numInstruments >= 1)
538
#endif
539
if (numInstruments > 0) {
540
//! Doesn't affect EU, but required for US/JP
541
struct Instrument **tempInst;
542
itInstrs = temp->instruments;
543
tempInst = temp->instruments;
544
end = numInstruments + tempInst;
545
546
#if defined(VERSION_JP) || defined(VERSION_US)
547
l2:
548
#else
549
do {
550
#endif
551
if (*itInstrs != NULL) {
552
*itInstrs = BASE_OFFSET(*itInstrs, mem);
553
instrument = *itInstrs;
554
555
if (instrument->loaded == 0) {
556
PATCH_SOUND(&instrument->lowNotesSound, (u8 *) mem, offset);
557
PATCH_SOUND(&instrument->normalNotesSound, (u8 *) mem, offset);
558
PATCH_SOUND(&instrument->highNotesSound, (u8 *) mem, offset);
559
patched = instrument->envelope;
560
instrument->envelope = BASE_OFFSET(mem, patched);
561
instrument->loaded = 1;
562
}
563
}
564
itInstrs++;
565
#if defined(VERSION_JP) || defined(VERSION_US)
566
//! goto generated by copt, required to match US/JP
567
if (end != itInstrs) {
568
goto l2;
569
}
570
#else
571
} while (end != itInstrs);
572
#endif
573
}
574
#undef PATCH_MEM
575
#undef PATCH
576
#undef BASE_OFFSET_REAL
577
#undef BASE_OFFSET
578
#undef PATCH_SOUND
579
}
580
581
struct AudioBank *bank_load_immediate(s32 bankId, s32 arg1) {
582
UNUSED u32 pad1[4];
583
u32 buf[4];
584
u32 numInstruments, numDrums;
585
struct AudioBank *ret;
586
u8 *ctlData;
587
s32 alloc;
588
589
// (This is broken if the length is 1 (mod 16), but that never happens --
590
// it's always divisible by 4.)
591
alloc = gAlCtlHeader->seqArray[bankId].len + 0xf;
592
alloc = ALIGN16(alloc);
593
alloc -= 0x10;
594
ctlData = gAlCtlHeader->seqArray[bankId].offset;
595
ret = alloc_bank_or_seq(&gBankLoadedPool, 1, alloc, arg1, bankId);
596
if (ret == NULL) {
597
return NULL;
598
}
599
600
audio_dma_copy_immediate((uintptr_t) ctlData, buf, 0x10);
601
numInstruments = buf[0];
602
numDrums = buf[1];
603
audio_dma_copy_immediate((uintptr_t)(ctlData + 0x10), ret, alloc);
604
patch_audio_bank(ret, gAlTbl->seqArray[bankId].offset, numInstruments, numDrums);
605
gCtlEntries[bankId].numInstruments = (u8) numInstruments;
606
gCtlEntries[bankId].numDrums = (u8) numDrums;
607
gCtlEntries[bankId].instruments = ret->instruments;
608
gCtlEntries[bankId].drums = ret->drums;
609
gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_COMPLETE;
610
return ret;
611
}
612
613
struct AudioBank *bank_load_async(s32 bankId, s32 arg1, struct SequencePlayer *seqPlayer) {
614
u32 numInstruments, numDrums;
615
UNUSED u32 pad1[2];
616
u32 buf[4];
617
UNUSED u32 pad2;
618
size_t alloc;
619
struct AudioBank *ret;
620
u8 *ctlData;
621
OSMesgQueue *mesgQueue;
622
#if defined(VERSION_EU)
623
UNUSED u32 pad3;
624
#endif
625
626
alloc = gAlCtlHeader->seqArray[bankId].len + 0xf;
627
alloc = ALIGN16(alloc);
628
alloc -= 0x10;
629
ctlData = gAlCtlHeader->seqArray[bankId].offset;
630
ret = alloc_bank_or_seq(&gBankLoadedPool, 1, alloc, arg1, bankId);
631
if (ret == NULL) {
632
return NULL;
633
}
634
635
audio_dma_copy_immediate((uintptr_t) ctlData, buf, 0x10);
636
numInstruments = buf[0];
637
numDrums = buf[1];
638
seqPlayer->loadingBankId = (u8) bankId;
639
#if defined(VERSION_EU)
640
gCtlEntries[bankId].numInstruments = numInstruments;
641
gCtlEntries[bankId].numDrums = numDrums;
642
gCtlEntries[bankId].instruments = ret->instruments;
643
gCtlEntries[bankId].drums = 0;
644
seqPlayer->bankDmaCurrMemAddr = (u8 *) ret;
645
seqPlayer->bankDmaCurrDevAddr = (uintptr_t)(ctlData + 0x10);
646
seqPlayer->bankDmaRemaining = alloc;
647
if (1) {
648
}
649
#else
650
seqPlayer->loadingBankNumInstruments = numInstruments;
651
seqPlayer->loadingBankNumDrums = numDrums;
652
seqPlayer->bankDmaCurrMemAddr = (u8 *) ret;
653
seqPlayer->loadingBank = ret;
654
seqPlayer->bankDmaCurrDevAddr = (uintptr_t)(ctlData + 0x10);
655
seqPlayer->bankDmaRemaining = alloc;
656
#endif
657
mesgQueue = &seqPlayer->bankDmaMesgQueue;
658
osCreateMesgQueue(mesgQueue, &seqPlayer->bankDmaMesg, 1);
659
#if defined(VERSION_JP) || defined(VERSION_US)
660
seqPlayer->bankDmaMesg = NULL;
661
#endif
662
seqPlayer->bankDmaInProgress = TRUE;
663
audio_dma_partial_copy_async(&seqPlayer->bankDmaCurrDevAddr, &seqPlayer->bankDmaCurrMemAddr,
664
&seqPlayer->bankDmaRemaining, mesgQueue, &seqPlayer->bankDmaIoMesg);
665
gBankLoadStatus[bankId] = SOUND_LOAD_STATUS_IN_PROGRESS;
666
return ret;
667
}
668
669
void *sequence_dma_immediate(s32 seqId, s32 arg1) {
670
s32 seqLength;
671
void *ptr;
672
u8 *seqData;
673
674
seqLength = gSeqFileHeader->seqArray[seqId].len + 0xf;
675
seqLength = ALIGN16(seqLength);
676
seqData = gSeqFileHeader->seqArray[seqId].offset;
677
ptr = alloc_bank_or_seq(&gSeqLoadedPool, 1, seqLength, arg1, seqId);
678
if (ptr == NULL) {
679
return NULL;
680
}
681
682
audio_dma_copy_immediate((uintptr_t) seqData, ptr, seqLength);
683
gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE;
684
return ptr;
685
}
686
687
void *sequence_dma_async(s32 seqId, s32 arg1, struct SequencePlayer *seqPlayer) {
688
s32 seqLength;
689
void *ptr;
690
u8 *seqData;
691
OSMesgQueue *mesgQueue;
692
693
eu_stubbed_printf_1("Seq %d Loading Start\n", seqId);
694
seqLength = gSeqFileHeader->seqArray[seqId].len + 0xf;
695
seqLength = ALIGN16(seqLength);
696
seqData = gSeqFileHeader->seqArray[seqId].offset;
697
ptr = alloc_bank_or_seq(&gSeqLoadedPool, 1, seqLength, arg1, seqId);
698
if (ptr == NULL) {
699
eu_stubbed_printf_0("Heap Overflow Error\n");
700
return NULL;
701
}
702
703
if (seqLength <= 0x40) {
704
// Immediately load short sequenece
705
audio_dma_copy_immediate((uintptr_t) seqData, ptr, seqLength);
706
if (1) {
707
}
708
gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_COMPLETE;
709
} else {
710
audio_dma_copy_immediate((uintptr_t) seqData, ptr, 0x40);
711
mesgQueue = &seqPlayer->seqDmaMesgQueue;
712
osCreateMesgQueue(mesgQueue, &seqPlayer->seqDmaMesg, 1);
713
#if defined(VERSION_JP) || defined(VERSION_US)
714
seqPlayer->seqDmaMesg = NULL;
715
#endif
716
seqPlayer->seqDmaInProgress = TRUE;
717
audio_dma_copy_async((uintptr_t)(seqData + 0x40), (u8 *) ptr + 0x40, seqLength - 0x40, mesgQueue,
718
&seqPlayer->seqDmaIoMesg);
719
gSeqLoadStatus[seqId] = SOUND_LOAD_STATUS_IN_PROGRESS;
720
}
721
return ptr;
722
}
723
724
u8 get_missing_bank(u32 seqId, s32 *nonNullCount, s32 *nullCount) {
725
void *temp;
726
u32 bankId;
727
u16 offset;
728
u8 i;
729
u8 ret;
730
731
*nullCount = 0;
732
*nonNullCount = 0;
733
#if defined(VERSION_EU)
734
offset = ((u16 *) gAlBankSets)[seqId];
735
for (i = gAlBankSets[offset++], ret = 0; i != 0; i--) {
736
bankId = gAlBankSets[offset++];
737
#else
738
offset = ((u16 *) gAlBankSets)[seqId] + 1;
739
for (i = gAlBankSets[offset - 1], ret = 0; i != 0; i--) {
740
offset++;
741
bankId = gAlBankSets[offset - 1];
742
#endif
743
744
if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) {
745
#if defined(VERSION_EU)
746
temp = get_bank_or_seq(&gBankLoadedPool, 2, bankId);
747
#else
748
temp = get_bank_or_seq(&gBankLoadedPool, 2, gAlBankSets[offset - 1]);
749
#endif
750
} else {
751
temp = NULL;
752
}
753
754
if (temp == NULL) {
755
(*nullCount)++;
756
ret = bankId;
757
} else {
758
(*nonNullCount)++;
759
}
760
}
761
762
return ret;
763
}
764
765
struct AudioBank *load_banks_immediate(s32 seqId, u8 *outDefaultBank) {
766
void *ret;
767
u32 bankId;
768
u16 offset;
769
u8 i;
770
771
offset = ((u16 *) gAlBankSets)[seqId];
772
#ifdef VERSION_EU
773
for (i = gAlBankSets[offset++]; i != 0; i--) {
774
bankId = gAlBankSets[offset++];
775
#else
776
offset++;
777
for (i = gAlBankSets[offset - 1]; i != 0; i--) {
778
offset++;
779
bankId = gAlBankSets[offset - 1];
780
#endif
781
782
if (IS_BANK_LOAD_COMPLETE(bankId) == TRUE) {
783
#ifdef VERSION_EU
784
ret = get_bank_or_seq(&gBankLoadedPool, 2, bankId);
785
#else
786
ret = get_bank_or_seq(&gBankLoadedPool, 2, gAlBankSets[offset - 1]);
787
#endif
788
} else {
789
ret = NULL;
790
}
791
792
if (ret == NULL) {
793
ret = bank_load_immediate(bankId, 2);
794
}
795
}
796
*outDefaultBank = bankId;
797
return ret;
798
}
799
800
void preload_sequence(u32 seqId, u8 preloadMask) {
801
void *sequenceData;
802
u8 temp;
803
804
if (seqId >= gSequenceCount) {
805
return;
806
}
807
808
gAudioLoadLock = AUDIO_LOCK_LOADING;
809
if (preloadMask & PRELOAD_BANKS) {
810
load_banks_immediate(seqId, &temp);
811
}
812
813
if (preloadMask & PRELOAD_SEQUENCE) {
814
// @bug should be IS_SEQ_LOAD_COMPLETE
815
if (IS_BANK_LOAD_COMPLETE(seqId) == TRUE) {
816
eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId);
817
sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId);
818
} else {
819
sequenceData = NULL;
820
}
821
if (sequenceData == NULL && sequence_dma_immediate(seqId, 2) == NULL) {
822
gAudioLoadLock = AUDIO_LOCK_NOT_LOADING;
823
return;
824
}
825
}
826
827
gAudioLoadLock = AUDIO_LOCK_NOT_LOADING;
828
}
829
830
void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync);
831
832
void load_sequence(u32 player, u32 seqId, s32 loadAsync) {
833
if (!loadAsync) {
834
gAudioLoadLock = AUDIO_LOCK_LOADING;
835
}
836
load_sequence_internal(player, seqId, loadAsync);
837
if (!loadAsync) {
838
gAudioLoadLock = AUDIO_LOCK_NOT_LOADING;
839
}
840
}
841
842
void load_sequence_internal(u32 player, u32 seqId, s32 loadAsync) {
843
void *sequenceData;
844
struct SequencePlayer *seqPlayer = &gSequencePlayers[player];
845
UNUSED u32 padding[2];
846
847
if (seqId >= gSequenceCount) {
848
return;
849
}
850
851
sequence_player_disable(seqPlayer);
852
if (loadAsync) {
853
s32 numMissingBanks = 0;
854
s32 dummy = 0;
855
s32 bankId = get_missing_bank(seqId, &dummy, &numMissingBanks);
856
if (numMissingBanks == 1) {
857
eu_stubbed_printf_0("Ok,one bank slow load Start \n");
858
if (bank_load_async(bankId, 2, seqPlayer) == NULL) {
859
return;
860
}
861
// @bug This should set the last bank (i.e. the first in the JSON)
862
// as default, not the missing one. This code path never gets
863
// taken, though -- all sequence loading is synchronous.
864
seqPlayer->defaultBank[0] = bankId;
865
} else {
866
eu_stubbed_printf_1("Sorry,too many %d bank is none.fast load Start \n", numMissingBanks);
867
if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) {
868
return;
869
}
870
}
871
} else if (load_banks_immediate(seqId, &seqPlayer->defaultBank[0]) == NULL) {
872
return;
873
}
874
875
eu_stubbed_printf_2("Seq %d:Default Load Id is %d\n", seqId, seqPlayer->defaultBank[0]);
876
eu_stubbed_printf_0("Seq Loading Start\n");
877
878
seqPlayer->seqId = seqId;
879
sequenceData = get_bank_or_seq(&gSeqLoadedPool, 2, seqId);
880
if (sequenceData == NULL) {
881
if (seqPlayer->seqDmaInProgress) {
882
eu_stubbed_printf_0("Error:Before Sequence-SlowDma remain.\n");
883
eu_stubbed_printf_0(" Cancel Seq Start.\n");
884
return;
885
}
886
if (loadAsync) {
887
sequenceData = sequence_dma_async(seqId, 2, seqPlayer);
888
} else {
889
sequenceData = sequence_dma_immediate(seqId, 2);
890
}
891
892
if (sequenceData == NULL) {
893
return;
894
}
895
}
896
897
eu_stubbed_printf_1("SEQ %d ALREADY CACHED\n", seqId);
898
init_sequence_player(player);
899
seqPlayer->scriptState.depth = 0;
900
seqPlayer->delay = 0;
901
seqPlayer->enabled = TRUE;
902
seqPlayer->seqData = sequenceData;
903
seqPlayer->scriptState.pc = sequenceData;
904
}
905
906
// (void) must be omitted from parameters to fix stack with -framepointer
907
void audio_init() {
908
#if defined(VERSION_EU)
909
UNUSED s8 pad[16];
910
#else
911
UNUSED s8 pad[32];
912
#endif
913
#if defined(VERSION_JP) || defined(VERSION_US)
914
u8 buf[0x10];
915
#endif
916
s32 i, j, UNUSED k;
917
UNUSED s32 lim1; // lim1 unused in EU
918
#if defined(VERSION_EU)
919
UNUSED u8 buf[0x10];
920
s32 UNUSED lim2, lim3;
921
#else
922
s32 lim2, UNUSED lim3;
923
#endif
924
UNUSED u32 size;
925
UNUSED u64 *ptr64;
926
void *data;
927
UNUSED s32 pad2;
928
929
gAudioLoadLock = AUDIO_LOCK_UNINITIALIZED;
930
931
#if defined(VERSION_JP) || defined(VERSION_US)
932
lim1 = gUnusedCount80333EE8;
933
for (i = 0; i < lim1; i++) {
934
gUnused80226E58[i] = 0;
935
gUnused80226E98[i] = 0;
936
}
937
938
lim2 = gAudioHeapSize;
939
for (i = 0; i <= lim2 / 8 - 1; i++) {
940
((u64 *) gAudioHeap)[i] = 0;
941
}
942
943
#ifdef TARGET_N64
944
// It seems boot.s doesn't clear the .bss area for audio, so do it here.
945
i = 0;
946
lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8;
947
ptr64 = &gAudioGlobalsStartMarker - 1;
948
for (k = lim3; k >= 0; k--) {
949
i++;
950
ptr64[i] = 0;
951
}
952
#endif
953
954
#else
955
for (i = 0; i < gAudioHeapSize / 8; i++) {
956
((u64 *) gAudioHeap)[i] = 0;
957
}
958
959
#ifdef TARGET_N64
960
// It seems boot.s doesn't clear the .bss area for audio, so do it here.
961
lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8;
962
ptr64 = &gAudioGlobalsStartMarker;
963
for (k = lim3; k >= 0; k--) {
964
*ptr64++ = 0;
965
}
966
#endif
967
968
D_EU_802298D0 = 20.03042f;
969
gRefreshRate = 50;
970
port_eu_init();
971
if (k) {
972
}
973
#endif
974
975
#ifdef TARGET_N64
976
eu_stubbed_printf_3("Clear Workarea %x -%x size %x \n",
977
(uintptr_t) &gAudioGlobalsStartMarker,
978
(uintptr_t) &gAudioGlobalsEndMarker,
979
(uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker
980
);
981
#endif
982
983
eu_stubbed_printf_1("AudioHeap is %x\n", gAudioHeapSize);
984
985
for (i = 0; i < NUMAIBUFFERS; i++) {
986
gAiBufferLengths[i] = 0xa0;
987
}
988
989
gAudioFrameCount = 0;
990
gAudioTaskIndex = 0;
991
gCurrAiBufferIndex = 0;
992
gSoundMode = 0;
993
gAudioTask = NULL;
994
gAudioTasks[0].task.t.data_size = 0;
995
gAudioTasks[1].task.t.data_size = 0;
996
osCreateMesgQueue(&gAudioDmaMesgQueue, &gAudioDmaMesg, 1);
997
osCreateMesgQueue(&gCurrAudioFrameDmaQueue, gCurrAudioFrameDmaMesgBufs,
998
ARRAY_COUNT(gCurrAudioFrameDmaMesgBufs));
999
gCurrAudioFrameDmaCount = 0;
1000
gSampleDmaNumListItems = 0;
1001
1002
sound_init_main_pools(gAudioInitPoolSize);
1003
1004
for (i = 0; i < NUMAIBUFFERS; i++) {
1005
gAiBuffers[i] = soundAlloc(&gAudioInitPool, AIBUFFER_LEN);
1006
1007
for (j = 0; j < (s32) (AIBUFFER_LEN / sizeof(s16)); j++) {
1008
gAiBuffers[i][j] = 0;
1009
}
1010
}
1011
1012
#if defined(VERSION_EU)
1013
gAudioResetPresetIdToLoad = 0;
1014
gAudioResetStatus = 1;
1015
audio_shut_down_and_reset_step();
1016
#else
1017
audio_reset_session(&gAudioSessionPresets[0]);
1018
#endif
1019
1020
// Not sure about these prints
1021
eu_stubbed_printf_1("Heap reset.Synth Change %x \n", 0);
1022
eu_stubbed_printf_3("Heap %x %x %x\n", 0, 0, 0);
1023
eu_stubbed_printf_0("Main Heap Initialize.\n");
1024
1025
// Load headers for sounds and sequences
1026
gSeqFileHeader = (ALSeqFile *) buf;
1027
data = gMusicData;
1028
audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, 0x10);
1029
gSequenceCount = gSeqFileHeader->seqCount;
1030
#if defined(VERSION_EU)
1031
size = gSequenceCount * sizeof(ALSeqData) + 4;
1032
size = ALIGN16(size);
1033
#else
1034
size = ALIGN16(gSequenceCount * sizeof(ALSeqData) + 4);
1035
#endif
1036
gSeqFileHeader = soundAlloc(&gAudioInitPool, size);
1037
audio_dma_copy_immediate((uintptr_t) data, gSeqFileHeader, size);
1038
alSeqFileNew(gSeqFileHeader, data);
1039
1040
// Load header for CTL (instrument metadata)
1041
gAlCtlHeader = (ALSeqFile *) buf;
1042
data = gSoundDataADSR;
1043
audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, 0x10);
1044
size = gAlCtlHeader->seqCount * sizeof(ALSeqData) + 4;
1045
size = ALIGN16(size);
1046
gCtlEntries = soundAlloc(&gAudioInitPool, gAlCtlHeader->seqCount * sizeof(struct CtlEntry));
1047
gAlCtlHeader = soundAlloc(&gAudioInitPool, size);
1048
audio_dma_copy_immediate((uintptr_t) data, gAlCtlHeader, size);
1049
alSeqFileNew(gAlCtlHeader, data);
1050
1051
// Load header for TBL (raw sound data)
1052
gAlTbl = (ALSeqFile *) buf;
1053
audio_dma_copy_immediate((uintptr_t) data, gAlTbl, 0x10);
1054
size = gAlTbl->seqCount * sizeof(ALSeqData) + 4;
1055
size = ALIGN16(size);
1056
gAlTbl = soundAlloc(&gAudioInitPool, size);
1057
audio_dma_copy_immediate((uintptr_t) gSoundDataRaw, gAlTbl, size);
1058
alSeqFileNew(gAlTbl, gSoundDataRaw);
1059
1060
// Load bank sets for each sequence
1061
gAlBankSets = soundAlloc(&gAudioInitPool, 0x100);
1062
audio_dma_copy_immediate((uintptr_t) gBankSetsData, gAlBankSets, 0x100);
1063
1064
init_sequence_players();
1065
gAudioLoadLock = AUDIO_LOCK_NOT_LOADING;
1066
// Should probably contain the sizes of the data banks, but those aren't
1067
// easily accessible from here.
1068
eu_stubbed_printf_0("---------- Init Completed. ------------\n");
1069
eu_stubbed_printf_1(" Syndrv :[%6d]\n", 0); // gSoundDataADSR
1070
eu_stubbed_printf_1(" Seqdrv :[%6d]\n", 0); // gMusicData
1071
eu_stubbed_printf_1(" audiodata :[%6d]\n", 0); // gSoundDataRaw
1072
eu_stubbed_printf_0("---------------------------------------\n");
1073
}
1074
#endif
1075
1076