Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
bgm_player.c
Go to the documentation of this file.
1#include "audio.h"
2#include "audio/core.h"
3
5
7extern u8 BgmTicksRates[8];
8extern u8 BgmCustomEnvLookup[40];
9
12extern u8 SeqCmdArgCounts[];
13
14static void au_bgm_stop_player(BGMPlayer* player);
15
16static s32 au_bgm_bpm_to_tempo(BGMPlayer* player, u32 tempo);
17
18static u8 au_bgm_get_random_pan(BGMPlayer* player, u8 arg1, u8 arg2);
19static s16 au_bgm_get_random_pitch(s32 arg0, s32 arg1, u8 arg2);
20static u8 au_bgm_get_random_vol(s32 arg0, u8 volume, u8 arg2);
21static u8 au_bgm_get_random_reverb(s32 arg0, u8 arg1, u8 arg2);
22
24 BGMHeader* bgmFile;
27 u32 compID;
28 s32 compOffset;
29 u32 value;
31 u8 var_a1;
32 u8 pos;
33 u32 i;
34
35 compID = 0;
36 unkType = -1;
37 player->frameCounter++;
38
39 if (player->cmdBufPending != 0) {
40 if (player->cmdBufPending < ARRAY_COUNT(player->cmdBufData)) {
41 pos = player->cmdBufReadPos;
42 for (var_a1 = 0; var_a1 < player->cmdBufPending; var_a1++) {
43 value = player->cmdBufData[pos];
44 if (value != 0) {
45 if (value < 16) {
46 unkType = value & 3;
47 compID = value >> 2;
48 }
49 pos++;
50 if (pos >= ARRAY_COUNT(player->cmdBufData)) {
51 pos = 0;
52 }
53 }
54 }
55 consumed = player->cmdBufWritePos - player->cmdBufReadPos;
56 if (consumed < 0) {
58 }
59 player->cmdBufPending -= consumed;
60 player->cmdBufReadPos = player->cmdBufWritePos;
61 } else {
62 player->cmdBufPending = 0;
63 }
64
65 if (unkType != -1) {
66 if (unkType != 0) {
67 if (unkType != player->unk_58) {
68 player->unk_58 = unkType & 0xFF;
69 player->unk_5A = unkType & 0xFF;
72 if (unkType == 2) {
73 bgmFile = player->globals->dataBGM[1];
74 } else {
75 bgmFile = player->globals->dataBGM[0];
76 }
77 player->bgmFile = bgmFile;
78 bgmData = &bgmFile->info;
80
81 compOffset = bgmData->compositions[compID];
82 if (compOffset == 0) {
83 compOffset = bgmData->compositions[0];
84 }
85 player->compStartPos = AU_FILE_RELATIVE(bgmFile, compOffset << 2);
86 player->compReadPos = AU_FILE_RELATIVE(bgmFile, compOffset << 2);
87
88 if (bgmData->drums != 0) {
89 player->drumsInfo = AU_FILE_RELATIVE(player->bgmFile, bgmData->drums << 2);
90 player->bgmDrumCount = bgmData->drumCount;
91 for (i = 0; i < player->bgmDrumCount; i++) {
92 BGMDrumInfo* drum = &player->drumsInfo[i];
93 player->drums[i] = drum;
94 }
95 for (; i < ARRAY_COUNT(player->drums); i++) {
96 player->drums[i] = player->drums[0];
97 }
98 } else {
99 player->drumsInfo = NULL;
100 player->bgmDrumCount = 0;
101 }
102
103 if (bgmData->instruments != 0) {
104 player->instrumentsInfo = AU_FILE_RELATIVE(player->bgmFile, bgmData->instruments << 2);
105 player->bgmInstrumentCount = bgmData->instrumentCount;
106 return;
107 }
108 player->instrumentsInfo = NULL;
109 player->bgmInstrumentCount = 0;
110 }
111 } else {
112 if (player->unk_58 != 0) {
114 player->nextUpdateCounter = 1;
115 player->nextUpdateStep = 1;
116 } else {
117 au_bgm_stop_player(player);
118 }
119 }
120 }
121 }
122}
123
127 return gBGMPlayerB;
128 }
129 } else {
130 return gBGMPlayerA;
131 }
132 return NULL;
133}
134
136 BGMPlayer* player;
138 s32 songName;
139 s32 variation;
140 s32 duration;
141 s32 volume0;
142 s32 volume1;
143 AuResult status;
144 u32 i;
145
146 status = AU_RESULT_OK;
147 songName = request->songName;
148 variation = request->variation;
149
150 if (songName != 0) {
151 player = au_bgm_get_player_with_song_name(songName);
152 if (player != NULL) {
153 fileInfo = &player->bgmFile->info;
154 duration = request->duration;
155 if (duration != 0) {
156 if (duration > SND_MAX_DURATION) {
157 duration = SND_MAX_DURATION;
158 } else if (duration < SND_MIN_DURATION) {
159 duration = SND_MIN_DURATION;
160 }
161 }
162 volume0 = request->startVolume;
163 if (volume0 > AU_MAX_VOLUME_8) {
165 }
166 if (volume0 != 0) {
168 }
169 volume1 = request->finalVolume;
170 if (volume1 > AU_MAX_VOLUME_8) {
172 }
173 if (volume1 != 0) {
175 } else {
177 }
178
179 au_fade_init(&player->fadeInfo, duration, volume0, volume1);
181 player->fadeInfo.envelopeTicks = 1;
183
184 if (variation < BGM_VARIATION_0 || variation > BGM_VARIATION_3 || fileInfo->compositions[variation] == 0) {
185 variation = BGM_VARIATION_0;
186 }
187 player->curVariation = variation;
188
189 player->compStartPos = AU_FILE_RELATIVE(player->bgmFile, fileInfo->compositions[variation] << 2);
190 player->compReadPos = player->compStartPos;
191
192 if (fileInfo->drums != 0) {
193 player->drumsInfo = AU_FILE_RELATIVE(player->bgmFile, fileInfo->drums << 2);
194 player->bgmDrumCount = fileInfo->drumCount;
195
196 for (i = 0; i < player->bgmDrumCount; i++) {
197 BGMDrumInfo* drum = &player->drumsInfo[i];
198 player->drums[i] = drum;
199 }
200 for (; i < ARRAY_COUNT(player->drums); i++) {
201 player->drums[i] = player->drums[0];
202 }
203 } else {
204 player->drumsInfo = NULL;
205 player->bgmDrumCount = 0;
206 }
207
208 if (fileInfo->instruments != 0) {
209 player->instrumentsInfo = AU_FILE_RELATIVE(player->bgmFile, fileInfo->instruments << 2);
210 player->bgmInstrumentCount = fileInfo->instrumentCount;
211 } else {
212 player->instrumentsInfo = NULL;
213 player->bgmInstrumentCount = 0;
214 }
215
216 player->songName = songName;
218 } else {
220 }
221 } else {
223 }
224 return status;
225}
226
228 BGMPlayer* player;
229 AuResult status = AU_RESULT_OK;
230
231 if (songName != 0) {
232 player = au_bgm_get_player_with_song_name(songName);
233 if (player != NULL) {
234 if (songName == player->songName) {
235 au_bgm_stop_player(player);
236 }
237 } else {
239 }
240 } else {
242 }
243
244 return status;
245}
246
247void au_bgm_stop_all(void) {
248 au_bgm_stop_player(gBGMPlayerA);
249 au_bgm_stop_player(gBGMPlayerB);
250}
251
252static void au_bgm_stop_player(BGMPlayer* player) {
253 if (player->masterState != BGM_PLAY_STATE_IDLE) {
255 player->nextUpdateCounter = 1;
256 player->nextUpdateStep = 1;
257 au_fade_clear(&player->fadeInfo);
258 }
259}
260
262 BGMPlayer* player;
263 AuResult result = AU_RESULT_OK;
264
265 if (songName != 0) {
266 player = au_bgm_get_player_with_song_name(songName);
267 if (player != NULL) {
268 result = (songName == player->songName);
269 } else {
271 }
272 } else {
274 }
275
276 return result;
277}
278
280 if (player->songName != 0 && player->masterState != 0) {
281 return TRUE;
282 } else {
283 return FALSE;
284 }
285}
286
288 AuResult status;
289 BGMPlayer* player;
290 u32 songName = request->songName;
291 u32 duration = request->duration;
292 s16 volume = request->finalVolume;
293
294 status = AU_RESULT_OK;
295 if (songName != 0) {
296 if (duration >= SND_MIN_DURATION && duration <= SND_MAX_DURATION) {
297 player = au_bgm_get_player_with_song_name(songName);
298 if (player != NULL) {
299 if (player->songName == songName) {
300 if (player->masterState != BGM_PLAY_STATE_IDLE) {
301 if (!player->paused) {
302 player->fadeInfo.baseTarget = volume;
303 player->fadeInfo.baseTicks = (duration * 1000) / AU_FRAME_USEC;
304 player->fadeInfo.baseStep = ((volume << 0x10) - player->fadeInfo.baseVolume) / player->fadeInfo.baseTicks;
305 player->fadeInfo.onCompleteCallback = request->doneCallback;
306 if (request->onPush == 1) {
307 player->pushSongName = songName;
308 }
309 }
310 }
311 }
312 } else {
314 }
315 } else {
317 }
318 } else {
320 }
321 return status;
322}
323
326
327 s.songName = songName;
328 s.duration = 0;
329 s.startVolume = 0;
330 s.finalVolume = 0;
332 s.pauseMode = FALSE;
333
334 return au_bgm_process_suspend(&s, 0); // force stop
335}
336
338 AuResult status;
339 BGMPlayer* player;
341 s32 songName;
342 s32 index;
343 u32 i;
344 u32 j;
345
346 songName = request->songName;
347 index = request->index;
348 status = AU_RESULT_OK;
349
350 if (songName != 0) {
351 player = au_bgm_get_player_with_song_name(songName);
352 if (player != NULL) {
353 if (!request->pauseMode) {
355 if (snapshot != NULL) {
356 if (songName == player->songName) {
357 if (!skipStop) {
358 for (i = 0; i < ARRAY_COUNT(player->tracks); i++) {
359 BGMPlayerTrack* track = &player->tracks[i];
360 if (track->bgmReadPos != NULL) {
361 for (j = track->firstVoice; j < track->lastVoice; j++) {
362 track->changed.all = 0;
363 }
364 }
365 }
366 }
367 player->globals->snapshots[index].priority = player->priority;
368 player->globals->snapshots[index].assigned = 1;
369 player->pushSongName = 0;
370 au_copy_words(player, snapshot, sizeof(*player));
371 if (!skipStop) {
372 au_bgm_stop_player(player);
373 }
374 }
375 } else {
377 }
378 } else {
379 if (songName == player->songName) {
380 if (player->masterState != BGM_PLAY_STATE_IDLE) {
381 player->paused = TRUE;
383 }
384 }
385 }
386 } else {
388 }
389 } else {
391 }
392 return status;
393}
394
396 AuResult status;
397 BGMPlayer* player;
399 s32 index;
400 s32 songName;
401 s32 volume0;
402 s32 volume1;
403 s32 duration;
404
405 songName = request->songName;
406 index = request->index;
407 status = AU_RESULT_OK;
408
409 if (songName != 0) {
410 if (!request->pauseMode) {
412 if (snapshot != NULL && snapshot->globals->snapshots[index].assigned == 1) {
413 player = au_get_client_by_priority(snapshot->globals->snapshots[index].priority);
414 if (player != NULL) {
415 if (!au_bgm_player_is_active(player)) {
416 status = au_reload_song_files(snapshot->songID, snapshot->bgmFile);
417 duration = request->duration;
418 if (duration != 0) {
419 if (duration > SND_MAX_DURATION) {
420 duration = SND_MAX_DURATION;
421 } else if (duration < SND_MIN_DURATION) {
422 duration = SND_MIN_DURATION;
423 }
424 }
425 volume0 = request->startVolume;
426 if (volume0 > AU_MAX_VOLUME_8) {
428 }
429 if (volume0 != 0) {
431 }
432 volume1 = request->finalVolume;
433 if (volume1 > AU_MAX_VOLUME_8) {
435 }
436 if (volume1 != 0) {
438 } else {
440 }
441 player->globals->resumeCopyTo = player;
443 player->globals->resumeSongName = songName;
444 player->globals->resumeFadeTime = duration;
446 player->globals->resumeFadeEnd = volume1;
447 player->globals->resumeRequested = TRUE;
448 } else {
449 status = AU_ERROR_7;
450 }
451 } else {
452 status = AU_ERROR_6;
453 }
454 } else {
456 }
457 } else {
458 player = au_bgm_get_player_with_song_name(songName);
459 if (player != NULL) {
460 if (songName == player->songName) {
461 if (player->paused) {
462 player->paused = FALSE;
463 }
464 }
465 }
466 }
467 } else {
469 }
470 return status;
471}
472
474 BGMPlayer* player;
476 SeqNote* note;
477 u32 i;
478 u32 j;
479 s32 k;
480
481 player = globals->resumeCopyTo;
482 au_copy_words(globals->resumeCopyFrom, globals->resumeCopyTo, sizeof(*player));
483 if (globals->resumeSongName == player->songName) {
484 for (i = 0; i < ARRAY_COUNT(player->tracks); i++) {
485 track = &player->tracks[i];
486 if (track->bgmReadPos != NULL) {
487 for (j = track->firstVoice; j < track->lastVoice; j++) {
488 note = &player->notes[j];
489 note->length = 0;
490 }
491 }
492 }
493 for (k = 0; k < ARRAY_COUNT(player->effectIndices); k++) {
494 if (player->effectIndices[k] != 0xFF) {
495 player->seqCmdArgs.MasterEffect.index = player->effectIndices[k];
496 player->seqCmdArgs.MasterEffect.value = player->effectValues[k];
498 }
499 }
500 au_fade_init(&player->fadeInfo, globals->resumeFadeTime, globals->resumeFadeStart, globals->resumeFadeEnd);
501 }
502 globals->resumeRequested = FALSE;
503}
504
506 BGMPlayer* player;
507 AuResult status = AU_RESULT_OK;
508
509 if (request->songName != 0) {
510 player = au_bgm_get_player_with_song_name(request->songName);
511 if (player != NULL) {
512 au_fade_calc_envelope(&player->fadeInfo, request->duration, request->finalVolume);
513 }
514 else {
516 }
517 } else {
519 }
520 return status;
521}
522
523void au_bgm_player_init(BGMPlayer* player, s32 priority, s32 busID, AuGlobals* globals) {
524 s16 i;
525
526 player->globals = globals;
530 player->masterVolume = AU_MAX_VOLUME_8 << 24;
531 player->frameCounter = 0;
532 player->songPlayingCounter = 0;
533 player->songName = 0;
534 player->pushSongName = 0;
535 player->unk_58 = 0;
536 player->unk_5A = 0;
537 player->compReadPos = NULL;
538 player->compStartPos = NULL;
539 player->phraseStartPos = 0;
540 player->masterTempoTicks = 0;
541 player->masterTempoTarget = 0;
542 player->masterTempoStep = 0;
543 player->masterVolumeTicks = 0;
544 player->masterVolumeTarget = 0;
545 player->masterVolumeStep = 0;
546 player->masterPitchShift = 0;
547 player->detune = 0;
548 player->paused = FALSE;
549 player->trackVolsConfig = NULL;
552 player->priority = priority;
553 player->busID = busID;
554 *(s32*)player->compLoopCounters = 0;
555 player->unused_222 = 0;
556 player->conditionalLoopFlags = 0;
557 player->playbackRate = 1.0f;
558 player->polyphonyCounts[BGM_POLYPHONY_0] = 0;
559 player->polyphonyCounts[BGM_POLYPHONY_1] = 1;
563 player->polyphonyCounts[BGM_POLYPHONY_2] = 2;
564 player->polyphonyCounts[BGM_POLYPHONY_3] = 3;
565 player->polyphonyCounts[BGM_POLYPHONY_4] = 4;
566
567 for (i = 0; i < ARRAY_COUNT(player->tracks); i++) {
568 BGMPlayerTrack* track = &player->tracks[i];
569
570 track->insVolume = 0;
571 track->delayTime = 0;
572 track->insCoarseDetune = 0;
573 track->insFineDetune = 0;
574 track->insPan = 0;
575 track->insReverb = 0;
576 track->patch = 0;
577 track->isDrumTrack = FALSE;
578 track->volume = AU_MAX_VOLUME_8;
579 track->pressOverride = 0;
580
581 if (i < ARRAY_COUNT(player->cmdBufData)) {
582 player->cmdBufData[i] = 0;
583 }
584 }
585
586 for (i = 0; i < ARRAY_COUNT(player->notes); i++) {
587 SeqNote* note = &player->notes[i];
588
589 note->volume = 0;
590 note->detune = 0;
591 note->length = 0;
592 note->randDetune = 0;
593 note->velocity = 0;
594 note->pendingTick = FALSE;
595 }
596
599}
600
602 s32 i;
604
605 for (i = 0; i < ARRAY_COUNT(player->effectIndices); i++) {
606 s8 idx = *list++;
607
608 if (idx < 0) {
609 break;
610 }
611 player->effectIndices[i] = idx;
612 }
613
614 remaining = ARRAY_COUNT(player->effectIndices) - i;
615 if (remaining > 0) {
616 while (remaining-- != 0) {
617 player->effectIndices[i++] = -1;
618 }
619 }
620}
621
623 player->fadeInfo.baseTicks--;
624
625 if (player->fadeInfo.baseTicks != 0) {
626 player->fadeInfo.baseVolume += player->fadeInfo.baseStep;
627 } else {
628 player->fadeInfo.baseVolume = player->fadeInfo.baseTarget << 16;
629
630 if (player->fadeInfo.onCompleteCallback != NULL) {
632 }
633
634 // Was this fade tagged as a push?
635 if (player->pushSongName != 0) {
637 } else if (player->fadeInfo.baseVolume == 0) {
638 au_bgm_stop_player(player);
639 }
640 }
642}
643
645 u16 volume = (
646 ((u32)player->fadeInfo.baseVolume >> 16) *
647 ((u32)player->fadeInfo.envelopeVolume >> 16)
648 ) >> 15;
649 s32 i;
650
651 for (i = 0; i < ARRAY_COUNT(player->effectIndices); i++) {
652 s8 busID = player->effectIndices[i];
653
654 if (busID < 0) {
655 return;
656 }
657 au_fade_set_volume(busID, volume, player->busVolume);
658 }
659}
660
662 u16 hasMore = TRUE;
663 s32 retVal = FALSE;
664
665 // update pseudorandom numbers with fast 'good enough' method
666 player->randomValue1 = (player->randomValue1 & 0xFFFF) + (player->songPlayingCounter & 0xFFFF) + (player->frameCounter & 0xFFFF);
667 player->randomValue2 = (player->randomValue2 & 0xFFFF) + ((player->songPlayingCounter << 4) & 0xFFFF) + ((player->frameCounter >> 4) & 0xFFFF);
668 do {
669 switch (player->masterState) {
671 hasMore = FALSE;
672 break;
674 if (!player->paused) {
676 if (player->masterState == BGM_PLAY_STATE_ACTIVE) {
677 hasMore = FALSE;
678 }
679 } else {
680 hasMore = FALSE;
681 }
682 break;
685 break;
688 hasMore = FALSE;
689 break;
692 break;
693 default:
694 retVal = TRUE;
695 hasMore = FALSE;
696 break;
697 }
698 } while (hasMore);
699 return retVal;
700}
701
703 s32* buf;
704 s32 cmd;
706 s32 i;
707
708 for (i = 0; i < ARRAY_COUNT(player->tracks); i++) {
709 BGMPlayerTrack* track = &player->tracks[i];
711 track->insVolume = AU_MAX_VOLUME_16 << 16; // @bug? incorrect format for 8.24 fixed, should be (AU_MAX_VOLUME_8 << 24)
712 track->insPan = 0x40;
713 track->insReverb = 0;
714 track->patch = 0;
715 track->insCoarseDetune = 0;
716 track->insFineDetune = 0;
717 track->volume = AU_MAX_VOLUME_8;
718 track->pressOverride = 0;
719 track->proxVolume = AU_MAX_VOLUME_16 << 16;
720 track->savedPos = NULL;
721 track->prevReadPos = NULL;
722 track->detourLength = 0;
723 track->detune = 0;
724 track->tremoloDepth = 0;
725 track->tremoloDelay = 0;
726 track->tremoloRate = 0;
727 track->insVolumeStep = 0;
728 track->insVolumeTarget = 0;
729 track->insVolumeTicks = 0;
730 track->proxVolumeStep = 0;
731 track->proxVolumeTarget = 0;
732 track->proxVolumeTicks = 0;
733 track->proxMixSetChanged = FALSE;
734 track->proxMixValChanged = FALSE;
735 track->proxVol1 = 0;
736 track->proxVol2 = 0;
737 track->polyVoiceCount = 0;
738 track->polyphonicIdx = 0;
739 track->randomPanAmount = 0;
740 track->isDrumTrack = FALSE;
741 track->linkedTrackID = 0;
742 track->muted = FALSE;
743 track->busID = player->busID;
744 track->index = i;
745 }
746
747 for (i = 0; i < ARRAY_COUNT(player->notes); i++) {
748 SeqNote* note = &player->notes[i];
750 note->pitchRatio = 2.0f;
751 note->randDetune = 0;
752 note->velocity = 0;
753 note->length = 0;
754 note->tremoloDepth = 0;
755 }
756
758 player->playbackRate = 128.0f; // set to 1.0 later om...
761 player->unused_21E = 0x80;
762 player->masterVolume = AU_MAX_VOLUME_8 << 24;
763 player->pushSongName = 0;
764 player->tickRatePtr = NULL;
765 player->masterTempoTarget = 0;
766 player->masterPitchShift = 0;
767 player->detune = 0;
768 player->masterVolumeTicks = 0;
769 player->masterVolumeTarget = 0;
770 player->masterVolumeStep = 0;
771 player->proxMixValue = 0;
772 player->proxMixID = 0;
773 player->proxMixVolume = 0;
774 player->compActiveLoopEndPos[3] = NULL;
775 player->compActiveLoopEndPos[2] = NULL;
776 player->compActiveLoopEndPos[1] = NULL;
777 player->compActiveLoopEndPos[0] = NULL;
778 *(s32*)player->compLoopCounters = 0;
779 player->compLoopDepth = 0;
780 player->unused_222 = 0;
781 player->conditionalLoopFlags = 0;
782 player->trackVolsConfig = NULL;
784 player->initLinkMute = TRUE;
785 player->writingCustomEnvelope = 0;
786 player->playbackRate = 1.0f;
787
788 for (i = 0; i < ARRAY_COUNT(player->customEnvelopeWritePos); i++) {
790 }
791
792 for (i = 0; i < ARRAY_COUNT(player->effectValues); i++) {
793 player->effectValues[i] = 0;
794 }
795
796 player->paused = FALSE;
797 player->songPlayingCounter = 0;
798 for (i = 0; i < ARRAY_COUNT(player->compLoopStartLabels); i++) {
799 player->compLoopStartLabels[i] = player->compReadPos;
800 }
801
802 // find labels
803 buf = player->compReadPos;
805 while (keepReading) {
806 cmd = *buf++;
807 if (cmd == 0) {
809 } else if ((cmd & 0xF0000000) == BGM_COMP_START_LOOP << 28) {
810 player->compLoopStartLabels[cmd & 0x1F] = buf;
811 }
812 }
813
815}
816
818 s32 i;
819 u16* pos = player->customPressEnvelopes[index];
820 player->customEnvelopeWritePos[index] = 0;
821
822 for (i = 0; i < 9; i++) {
823 *pos++ = 0xFF00;
824 }
825}
826
828 // compute how many audio frames before the next tick
830
831 // Clamp samples per tick to stay in a valid range
832 if (mFramesPerTick > 500000) {
833 mFramesPerTick = 500000;
834 } else if (mFramesPerTick < 80000) {
835 mFramesPerTick = 80000;
836 }
837
838 // Clamp to sample rate
841 }
842
843 // breakdown of units:
844 //
845 // tickUpdateInterval / nextUpdateStep = framesPerTick
846 //
847 // 1000 x frames beat min frames
848 // ------------- x ------ x --------------- = ------
849 // min tick 1000 x beat tick
850
854
856}
857
858// runs whenever a new composition begins playing
861 u32 cmd;
862
863 player->masterTempoStep = 0;
864 player->masterTempoTicks = 0;
865
866 while (continueReading) {
867 cmd = *player->compReadPos++;
868 if (cmd == BGM_COMP_END) {
871 } else {
872 switch (cmd >> 12) {
873 case BGM_COMP_PLAY_PHRASE << 16:
874 au_bgm_load_phrase(player, cmd);
877 break;
878 case BGM_COMP_START_LOOP << 16:
879 break;
880 case BGM_COMP_WAIT << 16:
882 break;
883 case BGM_COMP_END_LOOP << 16:
885 break;
887 if (!(player->conditionalLoopFlags & 1)) {
889 }
890 break;
892 if (player->conditionalLoopFlags & 1) {
894 }
895 break;
896 default:
898 break;
899 }
900 }
901 }
902}
903
905 s32 labelIndex = cmd & 0x1F; // 01F (bits 0-4)
906 s32 iterCount = (cmd >> 5) & 0x7F; // FE0 (bits 5-11)
907 u32 depth;
908
909 depth = player->compLoopDepth;
910 if (player->compActiveLoopEndPos[depth] != NULL) {
911 if (player->compActiveLoopEndPos[depth] == player->compReadPos) {
912 if (player->compLoopCounters[depth] != 0) {
913 player->compLoopCounters[depth]--;
914 if ((player->compLoopCounters[depth]) == 0) {
915 player->compActiveLoopEndPos[depth] = NULL;
916 if (depth > 0) {
917 depth--;
918 }
919 } else {
920 player->compReadPos = player->compLoopStartLabels[labelIndex];
921 }
922 } else {
923 player->compReadPos = player->compLoopStartLabels[labelIndex];
924 }
925 } else if (depth < 4) {
926 depth++;
927 player->compActiveLoopEndPos[depth] = player->compReadPos;
928 player->compLoopCounters[depth] = iterCount;
929 player->compReadPos = player->compLoopStartLabels[labelIndex];
930 }
931 } else {
932 player->compActiveLoopEndPos[depth] = player->compReadPos;
933 player->compLoopCounters[depth] = iterCount;
934 player->compReadPos = player->compLoopStartLabels[labelIndex];
935 }
936 player->compLoopDepth = depth;
937}
938
942 s32* trackList;
944 s32 count;
945 s32 curVoice;
947 s32 i;
948
949 curVoice = 0;
951 player->phraseStartPos = AU_FILE_RELATIVE(player->compStartPos, (cmd & 0xFFFF) << 2);
952 trackList = player->phraseStartPos;
953 for (i = 0; i < ARRAY_COUNT(player->tracks); i++) {
954 track = &player->tracks[i];
955 trackInfo = *trackList++;
956 track->bgmReadPos = (AuFilePos) (trackInfo >> 0x10);
957 if (track->bgmReadPos != NULL) {
958 if ((trackInfo & 0x100) == 0) {
959 track->polyphonicIdx = (trackInfo & (0x7 << 0xD)) >> 0xD;
960 track->isDrumTrack = (trackInfo >> 7) & 1;
961 linkedID = (trackInfo & (0xF << 9)) >> 9;
962 track->linkedTrackID = 0;
963 if (linkedID != 0) {
964 BGMPlayerTrack* linkedTrack = &player->tracks[linkedID - 1];
965 if ((linkedID - 1) < i) {
966 track->polyVoiceCount = linkedTrack->polyVoiceCount;
967 track->firstVoice = linkedTrack->firstVoice;
968 track->lastVoice = linkedTrack->lastVoice;
969
970 track->bgmReadPos = (track->bgmReadPos + (s32)player->phraseStartPos);
971 track->delayTime = 1;
972
973 track->linkedTrackID = linkedID;
974 if (player->initLinkMute) {
975 track->muted = TRUE;
976 }
978 } else {
979 track->bgmReadPos = NULL;
980 }
981 } else {
982 count = player->polyphonyCounts[track->polyphonicIdx];
983 track->polyVoiceCount = count;
984 track->firstVoice = curVoice;
985 curVoice += count;
986 track->lastVoice = curVoice;
987
988 track->bgmReadPos = (track->bgmReadPos + (s32)player->phraseStartPos);
989 track->delayTime = 1;
990 }
991 } else {
992 track->bgmReadPos = NULL;
993 }
994 }
995 }
996 player->totalVoices = curVoice;
997 if (bFoundLinkedTrack) {
998 player->initLinkMute = FALSE;
999 }
1000}
1001
1003 s32 i;
1004
1005 player->paused = FALSE;
1006 player->songName = 0;
1007 player->pushSongName = 0;
1008 player->unk_58 = 0;
1009 player->unk_5A = 0;
1010 for (i = 0; i < ARRAY_COUNT(player->tracks); i++) {
1011 player->tracks[i].bgmReadPos = NULL;
1012 }
1016}
1017
1018#define POST_BGM_READ() \
1019if (track->detourLength != 0) {\
1020 track->detourLength--;\
1021 if (track->detourLength == 0) {\
1022 track->bgmReadPos = track->savedPos;\
1023 }\
1024}
1025
1029 u8 sp1F;
1030 s16 notePitch;
1031 u8 bFinished;
1032
1033 AuVoice* voice;
1036 SeqNote* note;
1037 s32 var_a0;
1038 s32 temp;
1041 u8 opcode;
1044 u32 i;
1045 u8 voiceIdx;
1046 s32 temp2;
1048 bFinished = FALSE;
1049
1050 if (player->masterTempoTicks != 0) {
1051 player->masterTempoTicks--;
1052 if (player->masterTempoTicks == 0) {
1053 player->masterTempo = player->masterTempoTarget;
1054 player->masterTempoTarget = 0;
1055 player->masterTempoStep = 0;
1056 } else {
1057 player->masterTempo += player->masterTempoStep;
1058 }
1060 }
1061 if (player->masterVolumeTicks != 0) {
1062 player->masterVolumeTicks--;
1063 if (player->masterVolumeTicks == 0) {
1064 player->masterVolume = player->masterVolumeTarget;
1065 player->masterVolumeTarget = 0;
1066 player->masterVolumeStep = 0;
1067 } else {
1068 player->masterVolume += player->masterVolumeStep;
1069 }
1071 }
1072 player->volumeChanged = FALSE;
1073 if (player->trackVolsConfig != NULL) {
1074 if (player->bFadeConfigSetsVolume) {
1075 // setting track volumes
1076 s32 lenLimit = 16;
1077 while (lenLimit-- != 0) {
1078 i = *player->trackVolsConfig++;
1079 if (i == 0) {
1080 break;
1081 }
1082 track = &player->tracks[i - 1];
1083 player->seqCmdArgs.TrackVolumeFade.time = 48;
1084 player->seqCmdArgs.TrackVolumeFade.value = *(player->trackVolsConfig++);
1085 if (track->bgmReadPos != 0) {
1087 }
1088 }
1089 }
1090 else {
1091 // clearing track volumes
1092 s32 lenLimit = 16;
1093 while (lenLimit-- != 0) {
1094 i = *player->trackVolsConfig++;
1095 if (i == 0) {
1096 break;
1097 }
1098 track = &player->tracks[i - 1];
1099 player->seqCmdArgs.TrackVolumeFade.time = 48;
1100 player->trackVolsConfig++; // ignore arg
1101 player->seqCmdArgs.TrackVolumeFade.value = 0;
1102 if (track->bgmReadPos != 0) {
1104 }
1105 }
1106 }
1107 player->trackVolsConfig = NULL;
1108 player->bFadeConfigSetsVolume = FALSE;
1109 }
1110 for (i = 0; i < ARRAY_COUNT(player->tracks); i++) {
1111 track = &player->tracks[i];
1112 if (track->bgmReadPos != NULL) {
1113 track->changed.all = 0;
1114 if (bVolumeFading || player->volumeChanged) {
1115 track->changed.volume = TRUE;
1116 } else {
1117 track->changed.volume = FALSE;
1118 }
1119 if (track->insVolumeTicks != 0) {
1120 track->insVolumeTicks--;
1121 if (track->insVolumeTicks == 0) {
1122 track->insVolume = track->insVolumeTarget;
1123 } else {
1124 track->insVolume += track->insVolumeStep;
1125 }
1126 track->changed.volume = TRUE;
1127 }
1128 if (track->proxVolumeTicks != 0) {
1129 track->proxVolumeTicks--;
1130 if (track->proxVolumeTicks == 0) {
1131 track->proxVolume = track->proxVolumeTarget << 16;
1132 } else {
1133 track->proxVolume += track->proxVolumeStep;
1134 }
1135 track->changed.volume = TRUE;
1136 }
1137 track->delayTime--;
1138 if (track->delayTime <= 0) {
1139 sp1F = track->firstVoice;
1140 while (track->delayTime == 0) {
1141 opcode = *(track->bgmReadPos++);
1142 POST_BGM_READ();
1143
1144 if (opcode < 0x80) {
1145 if (opcode == 0) {
1146 if (track->prevReadPos != 0) {
1147 track->bgmReadPos = track->prevReadPos;
1148 track->prevReadPos = 0;
1149 } else {
1150 bFinished = TRUE;
1151 break;
1152 }
1153 } else {
1154 if (opcode >= 0x78) {
1155 // long delay
1156 track->delayTime = (((opcode & 7) << 8) + *(track->bgmReadPos++)) + 0x78;
1157 POST_BGM_READ();
1158
1159 } else {
1160 // delay
1161 track->delayTime = opcode;
1162 }
1163 }
1164 } else {
1165 // note
1166 if (opcode < 0xD4) {
1167 notePitch = (opcode & 0x7F);
1168 noteVelocity = *(track->bgmReadPos++);
1169 POST_BGM_READ();
1170 noteLength = *(track->bgmReadPos++);
1171 POST_BGM_READ();
1172 if (!(noteLength < 0xC0)) {
1173 noteLength = (((u8)noteLength & ~0xC0) << 8) + *(track->bgmReadPos++) + 0xC0;
1174 POST_BGM_READ();
1175 }
1177 if (!track->muted) {
1178 // find first free voice
1179 for (voiceIdx = sp1F; voiceIdx < track->lastVoice; voiceIdx++) {
1180 voice = &player->globals->voices[voiceIdx];
1181 sp1F++;
1182 if (voice->priority == AU_PRIORITY_FREE) {
1184 break;
1185 }
1186 }
1187
1188 if (!bAcquiredVoiceIdx) {
1189 if (track->polyphonicIdx >= BGM_POLYPHONY_2) {
1190 // try stealing a voice with lower priority
1191 for (voiceIdx = track->firstVoice; voiceIdx < track->lastVoice; voiceIdx++) {
1192 voice = &player->globals->voices[voiceIdx];
1193 if (voice->priority < player->priority) {
1196 break;
1197 }
1198 }
1199 // try stealing a voice with equal priority and zero note length
1200 if (!bAcquiredVoiceIdx) {
1201 for (voiceIdx = track->firstVoice; voiceIdx < track->lastVoice; voiceIdx++) {
1202 voice = &player->globals->voices[voiceIdx];
1203 if (voice->priority == player->priority) {
1204 note = &player->notes[voiceIdx];
1205 if (note->length == 0) {
1208 break;
1209 }
1210 }
1211 }
1212 }
1213 // try stealing a voice with equal priority and lowest note length
1214 if (!bAcquiredVoiceIdx) {
1215 s32 shortestLength = 0xFFFF;
1216 u8 voice_it;
1217 AuVoice* curVoice;
1219 for (voice_it = track->firstVoice; voice_it < track->lastVoice; voice_it++) {
1220 curVoice = &player->globals->voices[voice_it];
1221 if (curVoice->priority == player->priority) {
1222 curNote = &player->notes[voice_it];
1223 if (!curNote->pendingTick && curNote->length < shortestLength) {
1225 voice = curVoice;
1226 note = curNote;
1229 }
1230 }
1231 }
1232 if (bAcquiredVoiceIdx) {
1233 note->length = 0;
1235 }
1236 }
1237
1238 } else {
1239 voiceIdx = track->firstVoice;
1240 voice = &player->globals->voices[voiceIdx];
1241 note = &player->notes[voiceIdx];
1242 note->length = 0;
1243 if (voice->priority <= player->priority) {
1246 }
1247 }
1248 }
1249 }
1250 if (bAcquiredVoiceIdx) {
1251 note = &player->notes[voiceIdx];
1252 note->tremoloDepth = 0;
1253 if (noteVelocity > 0) {
1254 note->velocity = noteVelocity + 1;
1255 } else {
1256 note->velocity = 0;
1257 }
1258 note->length = noteLength;
1259 if (track->isDrumTrack) {
1260 if (notePitch < 72) { // = 6 * 12
1261 drumInfo = &player->globals->dataPER->drums[notePitch];
1262 } else {
1263 drumInfo = player->drums[notePitch - 72]; // = 6 * 12
1264 }
1265 note->ins = au_get_instrument(player->globals, drumInfo->bankPatch >> 8, drumInfo->bankPatch & 0xFF, &voice->envelope);
1266 if (drumInfo->randVolume != 0) {
1267 note->volume = note->velocity * au_bgm_get_random_vol(player->randomValue1, drumInfo->volume, drumInfo->randVolume);
1268 } else {
1269 note->volume = note->velocity * drumInfo->volume;
1270 }
1271 // combining formats: 7.24 * 7.24 * 15.16 * 7.0 * 15.0 --> 16.16
1272 // first step, shifting fractional factors by 21:
1273 // 7.24 * 7.24 * 15.16 --> 7.3 * 7.3 * 10.0 --> 24.6
1274 // shifting this down by 20 transforms 24.6 --> 10.0
1275 // now for the second step with whole:
1276 // 10.0 * 7.0 * 15.0 --> 32.0
1277 // and a final shift by 16 transforms 32.0 --> 16.16
1278 voice->clientVolume = ((
1279 ((player->masterVolume >> 21) // 7.24 --> 7.3
1280 * (track->insVolume >> 21) // 7.24 --> 7.3
1281 * (track->proxVolume >> 21)) >> 20) // 15.16 --> 10.0 (fractional part truncated?)
1282 * (track->volume * note->volume)) >> 16;
1283 note->detune =
1284 drumInfo->keyBase
1285 + track->insCoarseDetune
1286 + track->insFineDetune
1287 - note->ins->keyBase;
1288 temp = (note->detune + track->detune) + player->detune;
1289 if (drumInfo->randTune != 0) {
1290 note->randDetune = au_bgm_get_random_pitch(player->randomValue1, temp, drumInfo->randTune);
1291 temp = note->randDetune;
1292 }
1293 note->pitchRatio = au_compute_pitch_ratio(temp) * note->ins->pitchRatio;
1294 if (drumInfo->randPan != 0) {
1295 voice->pan = au_bgm_get_random_pan(player, drumInfo->pan, drumInfo->randPan);
1296 } else {
1297 voice->pan = drumInfo->pan;
1298 }
1299 if (drumInfo->randReverb != 0) {
1300 voice->reverb = au_bgm_get_random_reverb(player->randomValue1, drumInfo->reverb, drumInfo->randReverb);
1301 } else {
1302 voice->reverb = drumInfo->reverb;
1303 }
1304 } else {
1305 // combining formats: 7.24 * 7.24 * 15.16 * 7.0 * 15.0 --> 16.16
1306 // first step, shifting fractional factors by 21:
1307 // 7.24 * 7.24 * 15.16 --> 7.3 * 7.3 * 10.0 --> 24.6
1308 // shifting this down by 20 transforms 24.6 --> 10.0
1309 // now for the second step with whole:
1310 // 10.0 * 7.0 * 7.0 --> 24.0
1311 // and a final shift by 9 transforms 24.0 --> 15.16
1312 voice->clientVolume = note->volume = ((
1313 ((player->masterVolume >> 21) // 7.24 --> 7.3
1314 * (track->insVolume >> 21) // 7.24 --> 7.3
1315 * (track->proxVolume >> 21)) >> 20) // 15.16 --> 10.0 (fractional part truncated?)
1316 * (track->volume * note->velocity)) >> 9;
1317 note->ins = track->instrument;
1318 note->detune =
1319 (notePitch * 100)
1320 + track->insCoarseDetune
1321 + player->masterPitchShift
1322 + track->insFineDetune
1323 - note->ins->keyBase;
1324 note->pitchRatio = au_compute_pitch_ratio(
1325 note->detune
1326 + track->detune
1327 + player->detune)
1328 * track->instrument->pitchRatio;
1329
1330 if (track->randomPanAmount != 0) {
1331 voice->pan = au_bgm_get_random_pan(player, track->insPan, track->randomPanAmount);
1332 } else {
1333 voice->pan = track->insPan;
1334 }
1335 voice->reverb = track->insReverb;
1336
1337 if (track->pressOverride != 0) {
1338 voice->envelope.cmdListPress = (u8*) player->customPressEnvelopes[track->pressOverride - 1];
1339 } else {
1340 voice->envelope.cmdListPress = track->envelope.cmdListPress;
1341 }
1342 voice->envelope.cmdListRelease = track->envelope.cmdListRelease;
1343 }
1344 voice->instrument = note->ins;
1345 voice->pitchRatio = note->pitchRatio;
1346 voice->busID = track->busID;
1347 if (note->length > 1) {
1348 note->pendingTick = TRUE;
1349 note->tremoloDepth = track->tremoloDepth;
1350 note->tremoloPhase = 0;
1351 note->tremoloDelay = track->tremoloDelay;
1352 voice->syncFlags = AU_VOICE_SYNC_FLAG_ALL;
1353 voice->priority = player->priority;
1354 voice->clientPriority = voice->priority;
1355 }
1356 }
1357 } else {
1358 //TODO variable is nargs, but reusing temp is required to match
1359 temp = SeqCmdArgCounts[opcode - 0xE0];
1360 if (temp != 0) {
1361 player->seqCmdArgs.raw[0] = *(track->bgmReadPos++);
1362 POST_BGM_READ();
1363 } else {
1364 goto bgm_args_done;
1365 }
1366 if (temp > 1) {
1367 player->seqCmdArgs.raw[1] = *(track->bgmReadPos++);
1368 POST_BGM_READ();
1369 } else {
1370 goto bgm_args_done;
1371 }
1372 if (temp > 2) {
1373 player->seqCmdArgs.raw[2] = *(track->bgmReadPos++);
1374 POST_BGM_READ();
1375 } else {
1376 goto bgm_args_done;
1377 }
1378 if (temp > 3) {
1379 player->seqCmdArgs.raw[3] = *(track->bgmReadPos++);
1380 POST_BGM_READ();
1381 }
1384 CurrentSeqCmdHandler(player, track);
1385 }
1386 }
1387 } // end while
1388 }
1389
1390 for (voiceIdx = track->firstVoice; voiceIdx < track->lastVoice; voiceIdx++) {
1391 if (!track->muted) {
1392 voice = &player->globals->voices[voiceIdx];
1393 if (voice->priority == player->priority) {
1394 note = &player->notes[voiceIdx];
1395 if (!note->pendingTick) {
1396 if (note->length > 0) {
1397 note->length--;
1398 if (note->length == 0) {
1399 voice->envelopeFlags |= AU_VOICE_ENV_FLAG_KEY_RELEASED;
1400 }
1401 }
1402 if (track->isDrumTrack) {
1403 if (track->changed.tune || (player->detune != 0)) {
1404 note->pitchRatio = au_compute_pitch_ratio(((note->detune + note->randDetune) + track->detune) + player->detune) * note->ins->pitchRatio;
1405 if (voice->pitchRatio != note->pitchRatio) {
1406 voice->pitchRatio = note->pitchRatio;
1407 voice->syncFlags |= AU_VOICE_SYNC_FLAG_PITCH;
1408 }
1409 }
1410 if (track->changed.volume) {
1411 // combining formats: 7.24 * 7.24 * 15.16 * 7.0 * 15.0 --> 16.16
1412 // first step, shifting fractional factors by 21:
1413 // 7.24 * 7.24 * 15.16 --> 7.3 * 7.3 * 10.0 --> 24.6
1414 // shifting this down by 20 transforms 24.6 --> 10.0
1415 // now for the second step with whole:
1416 // 10.0 * 7.0 * 15.0 --> 32.0
1417 // and a final shift by 16 transforms 32.0 --> 16.16
1418 voice->clientVolume = (
1419 ((((player->masterVolume >> 21) // 7.24 --> 7.3
1420 * (track->insVolume >> 21)) // 7.24 --> 7.3
1421 * (track->proxVolume >> 21)) >> 20) // 15.16 --> 10.0 (fractional part truncated?)
1422 * (track->volume * note->volume)) >> 16;
1423 voice->envelopeFlags |= AU_VOICE_ENV_FLAG_VOL_CHANGED;
1424 }
1425 } else {
1426 // Modulate pitch using a triange wave for tremolo effect
1427 if (note->tremoloDepth != 0) {
1428 if (note->tremoloDelay != 0) {
1429 note->tremoloDelay--;
1430 } else {
1431 u8 quadrant;
1432 note->tremoloPhase += track->tremoloRate;
1433 opcode = (note->tremoloPhase << 2) + 3; // +3 just to fill lower 2 bits
1434
1435 // Determine what part of the triangle wave we are in (using top 2 bits of u8)
1436 quadrant = note->tremoloPhase >> 6;
1437
1438 // Invert the triangle for quadrants 1 and 3 (ugly code required to match)
1439 /* visualized: //// --> /\/\ */
1440 if ((quadrant == 1) || (quadrant == 3)) {
1441 u8 temp2 = ~opcode;
1442 tremoloDetune = temp2 + 1;
1443 } else {
1445 }
1446
1447 // Scale by depth
1448 tremoloDetune = (tremoloDetune * track->tremoloDepth) >> 8;
1449
1450 // Invert sign for the second half of triangle wave
1451 if ((quadrant == 2) || (quadrant == 3)) {
1453 }
1454
1455 // Apply pitch detune from tremolo
1456 note->pitchRatio = au_compute_pitch_ratio(tremoloDetune + ((note->detune + track->detune) + player->detune)) * note->ins->pitchRatio;
1457 if (voice->pitchRatio != note->pitchRatio) {
1458 voice->pitchRatio = note->pitchRatio;
1459 voice->syncFlags |= AU_VOICE_SYNC_FLAG_PITCH;
1460 }
1461 }
1462 } else if (track->changed.tune || (player->detune != 0)) {
1463
1464 note->pitchRatio = au_compute_pitch_ratio((note->detune + track->detune) + player->detune) * note->ins->pitchRatio;
1465 if (voice->pitchRatio != note->pitchRatio) {
1466 voice->pitchRatio = note->pitchRatio;
1467 voice->syncFlags |= AU_VOICE_SYNC_FLAG_PITCH;
1468 }
1469 }
1470 if (track->changed.volume) {
1471 // combining formats: 7.24 * 7.24 * 15.16 * 7.0 * 15.0 --> 16.16
1472 // first step, shifting fractional factors by 21:
1473 // 7.24 * 7.24 * 15.16 --> 7.3 * 7.3 * 10.0 --> 24.6
1474 // shifting this down by 20 transforms 24.6 --> 10.0
1475 // now for the second step with whole:
1476 // 10.0 * 7.0 * 7.0 --> 24.0
1477 // and a final shift by 9 transforms 24.0 --> 15.16
1478 note->volume = ((
1479 (player->masterVolume >> 21) // 7.24 --> 7.3
1480 * (track->insVolume >> 21) // 7.24 --> 7.3
1481 * (track->proxVolume >> 21)) >> 20)
1482 * (track->volume * note->velocity) >> 9;
1483 voice->clientVolume = note->volume;
1484 voice->envelopeFlags |= AU_VOICE_ENV_FLAG_VOL_CHANGED;
1485 voice->pan = track->insPan;
1486 voice->reverb = track->insReverb;
1487 } else if (track->changed.pan || track->changed.reverb) {
1488 voice->pan = track->insPan;
1489 voice->reverb = track->insReverb;
1490 voice->syncFlags |= AU_VOICE_SYNC_FLAG_PAN_FXMIX;
1491 }
1492 }
1493 }
1494 note->pendingTick = FALSE;
1495 }
1496 }
1497 }
1498 }
1499 }
1500
1501 if (bFinished) {
1503 }
1504}
1505
1506static const f32 padding[] = {0.0f}; // at least after au_bgm_player_audio_frame_update
1507
1509 u32 bpm = player->seqCmdArgs.MasterTempo.value;
1510 s32 tempo;
1511
1512 player->masterTempoBPM = bpm;
1513 tempo = au_bgm_bpm_to_tempo(player, bpm);
1514 player->masterTempo = tempo;
1516 player->masterTempoTicks = 0;
1517 player->masterTempoTarget = 0;
1518 player->masterTempoStep = 0;
1519}
1520
1521static s32 au_bgm_bpm_to_tempo(BGMPlayer* player, u32 tempo) {
1522 u32 maxTempo = player->maxTempo;
1523 u32 ret = tempo;
1524
1525 ret *= player->playbackRate;
1526
1527 if (maxTempo < ret) {
1528 ret = maxTempo;
1529 } else if (ret == 0) {
1530 ret = 1;
1531 }
1532
1533 return ret * 100;
1534}
1535
1537 s8_24 volume = player->seqCmdArgs.MasterVolume.value & 0x7F;
1538
1539 if (volume != 0) {
1540 volume = volume << 24;
1541 }
1542
1543 player->masterVolume = volume;
1544 player->masterVolumeTicks = 0;
1545 player->masterVolumeTarget = 0;
1546 player->masterVolumeStep = 0;
1547 player->volumeChanged = TRUE;
1548 track->changed.volume = TRUE;
1549}
1550
1552 player->masterPitchShift = (s8)player->seqCmdArgs.MasterPitchShift.cent * 100;
1553}
1554
1556 player->globals->effectChanges[player->busID].type = player->seqCmdArgs.UnkCmdE3.effectType;
1557 player->globals->effectChanges[player->busID].changed = TRUE;
1558}
1559
1561 u8 index = player->seqCmdArgs.MasterEffect.index;
1562 u32 busID = player->effectIndices[index];
1563
1564 if ((index < 4) && (busID < 0x80)) {
1565 if (player->globals->effectChanges[busID].type != player->seqCmdArgs.MasterEffect.value) {
1566 player->globals->effectChanges[busID].type = player->seqCmdArgs.MasterEffect.value;
1567 player->globals->effectChanges[busID].changed = TRUE;
1568 }
1569 player->effectValues[index] = player->seqCmdArgs.MasterEffect.value;
1570 }
1571}
1572
1574 s32 time = player->seqCmdArgs.MasterTempoFade.time;
1575 s32 tempo = au_bgm_bpm_to_tempo(player, player->seqCmdArgs.MasterTempoFade.value);
1576
1577 if (time <= 0) {
1578 time = 1;
1579 }
1580
1581 player->masterTempoTicks = time;
1582 player->masterTempoTarget = tempo;
1583 player->masterTempoStep = (tempo - player->masterTempo) / time;
1584}
1585
1587 s32 time = player->seqCmdArgs.MasterVolumeFade.time;
1588 s8_24 volume = player->seqCmdArgs.MasterVolumeFade.value & 0x7F;
1589
1590 if (volume != 0) {
1591 volume = volume << 24;
1592 }
1593
1594 if (time <= 0) {
1595 time = 1;
1596 }
1597
1598 player->masterVolumeTicks = time;
1599 player->masterVolumeTarget = volume;
1600 player->masterVolumeStep = (volume - player->masterVolume) / time;
1601}
1602
1604 track->patch = player->seqCmdArgs.OverridePatch.patch;
1605 track->instrument = au_get_instrument(player->globals, player->seqCmdArgs.OverridePatch.bank, track->patch, &track->envelope);
1606}
1607
1609 s8_24 volume = arg0->seqCmdArgs.InstrumentVolume.value & 0x7F;
1610
1611 if (volume != 0) {
1612 volume = volume << 24;
1613 }
1614
1615 track->insVolume = volume;
1616 track->changed.volume = TRUE;
1617}
1618
1620 s32 time = player->seqCmdArgs.TrackVolumeFade.time;
1621 s8_24 volume = player->seqCmdArgs.TrackVolumeFade.value & 0x7F;
1622
1623 if (volume != 0) {
1624 volume = volume << 24;
1625 }
1626
1627 if (volume != track->insVolume) {
1628 if (time <= 0) {
1629 time = 1;
1630 }
1631
1632 track->insVolumeTicks = time;
1633 track->insVolumeTarget = volume;
1634 track->insVolumeStep = (volume - track->insVolume) / time;
1635 }
1636}
1637
1639 track->insPan = player->seqCmdArgs.InstrumentPan.value & 0x7F;
1640 track->randomPanAmount = 0;
1641 track->changed.pan = TRUE;
1642}
1643
1645 track->insReverb = player->seqCmdArgs.InstrumentReverb.value & 0x7F;
1646 track->changed.reverb = TRUE;
1647}
1648
1650 track->volume = player->seqCmdArgs.TrackVolume.value & 0x7F;
1651 track->changed.volume = TRUE;
1652}
1653
1657
1659 track->insFineDetune = player->seqCmdArgs.InstrumentFineTune.cent;
1660}
1661
1663 track->detune = player->seqCmdArgs.TrackDetune.cents;
1664 track->changed.tune = TRUE;
1665}
1666
1668 track->tremoloDelay = player->seqCmdArgs.TrackTremolo.delay;
1669 track->tremoloRate = player->seqCmdArgs.TrackTremolo.speed;
1670 track->tremoloDepth = player->seqCmdArgs.TrackTremolo.depth;
1671}
1672
1674 track->tremoloRate = player->seqCmdArgs.TrackTremoloRate.value;
1675}
1676
1678 track->tremoloDepth = player->seqCmdArgs.TrackTremoloDepth.value;
1679}
1680
1682 track->tremoloDepth = 0;
1683}
1684
1686 track->insPan = player->seqCmdArgs.RandomPan.pan0 & 0x7F;
1687 track->randomPanAmount = player->seqCmdArgs.RandomPan.pan1 & 0x7F;
1688}
1689
1691 BGMInstrumentInfo* instrument;
1692 s32 volume;
1693 u32 insIndex;
1694 u32 patch;
1695 u32 bank;
1696
1697 insIndex = player->seqCmdArgs.UseInstrument.index;
1699 if (insIndex < player->bgmInstrumentCount) {
1700 instrument = &player->instrumentsInfo[insIndex];
1701 } else {
1702 instrument = &player->globals->defaultPRGEntry;
1703 }
1704 } else {
1706 if (insIndex < PRG_MAX_COUNT) {
1707 instrument = &player->globals->dataPRG[insIndex];
1708 } else {
1709 instrument = &player->globals->defaultPRGEntry;
1710 }
1711 }
1712 bank = instrument->bankPatch >> 8;
1713 patch = (u8)instrument->bankPatch;
1714 volume = instrument->volume & 0x7F;
1715 track->patch = patch;
1716 track->instrument = au_get_instrument(player->globals, bank, patch, &track->envelope);
1717 if (volume != 0) {
1718 volume <<= 24;
1719 }
1720 track->insVolume = volume;
1721 track->insPan = instrument->pan & 0x7F;
1722 track->insReverb = instrument->reverb & 0x7F;
1723 track->insCoarseDetune = instrument->coarseTune * AU_SEMITONE_CENTS;
1724 track->insFineDetune = instrument->fineTune;
1725 track->changed.all |= 0x10101; // volume, pan, and reverb
1726}
1727
1729 u8 index = player->seqCmdArgs.ReverbType.index;
1730 s8 busID = player->effectIndices[index];
1731
1732 if ((index < ARRAY_COUNT(player->effectIndices)) && (busID >= 0)) {
1733 track->busID = busID;
1734 } else {
1735 track->busID = player->busID;
1736 }
1737}
1738
1742
1743// jump to another part of the track and return after a specified read length
1745 AuFilePos readPos = AU_FILE_RELATIVE(player->bgmFile, player->seqCmdArgs.Detour.offset);
1746
1747 track->detourLength = player->seqCmdArgs.Detour.length;
1748 track->savedPos = track->bgmReadPos;
1749 track->bgmReadPos = readPos;
1750}
1751
1752// jump to another part of the track, selected by player->branchVar
1754 AuFilePos args;
1755 u32 i;
1756
1757 // get jump table
1758 args = AU_FILE_RELATIVE(player->bgmFile, player->seqCmdArgs.Branch.offset);
1759 if (player->proxMixID < player->seqCmdArgs.Branch.tableCount) {
1760 args += player->proxMixID * 3;
1761 }
1762 // read new position from jump table
1763 track->prevReadPos = track->bgmReadPos;
1764 track->bgmReadPos = AU_FILE_RELATIVE(player->bgmFile, (args[0] << 8) + args[1]);
1765 track->isDrumTrack = args[2];
1766
1767 if (track->proxMixSetChanged) {
1768 track->proxMixSetChanged = FALSE;
1769 track->proxVolume = 0;
1770 for (i = track->firstVoice; i < track->lastVoice; i++) {
1771 AuVoice* voice = &player->globals->voices[i];
1772 if ((voice->priority == player->priority) && (voice->cmdPtr != NULL)) {
1774 }
1775 }
1776 }
1777 if (track->proxMixValChanged) {
1778 track->proxMixValChanged = FALSE;
1779 au_bgm_set_prox_mix_fade(player, track, player->proxMixVolume, 144);
1780 }
1781 // reset an odd subset of parameters
1782 track->insCoarseDetune = 0;
1783 track->insFineDetune = 0;
1784 track->pressOverride = 0;
1785 track->detune = 0;
1786 track->tremoloDepth = 0;
1787 track->insVolumeTicks = 0;
1788 track->randomPanAmount = 0;
1789 track->busID = player->busID;
1790}
1791
1793 u32 writePos;
1794 u8 delaySide;
1795 u8 delayTime;
1796 u32 i;
1797
1798 u32 type = player->seqCmdArgs.Special.type;
1799 u32 arg1 = player->seqCmdArgs.Special.arg1;
1800 u32 arg2 = player->seqCmdArgs.Special.arg2;
1801
1802 switch (type) {
1804 if ((arg1 < ARRAY_COUNT(player->effectIndices)) && ((s8)player->effectIndices[arg1] >= 0)) {
1805 player->globals->channelDelayBusID = player->effectIndices[arg1];
1806 if (arg2 != 0) {
1807 delayTime = arg2 & 0xF;
1808 delaySide = ((arg2 >> 4) & 1) + 1;
1809 if ((player->globals->channelDelayTime != delayTime) || (player->globals->channelDelaySide != delaySide)) {
1810 player->globals->channelDelayTime = delayTime;
1812 player->globals->channelDelayPending = TRUE;
1813 }
1814 } else {
1817 player->globals->channelDelayPending = TRUE;
1818 }
1819 }
1820 }
1821 break;
1823 if (arg1 - 1 < ARRAY_COUNT(player->customPressEnvelopes)) {
1824 player->writingCustomEnvelope = arg1;
1825 au_bgm_clear_custom_note_press(player, arg1 - 1);
1826 } else {
1827 player->writingCustomEnvelope = 0;
1828 }
1829 break;
1831 i = player->writingCustomEnvelope;
1832 if (i - 1 < ARRAY_COUNT(player->customPressEnvelopes)) {
1833 i--; // convert ID --> array index, needed to match
1834 writePos = player->customEnvelopeWritePos[i];
1835 if (writePos < ARRAY_COUNT(player->customPressEnvelopes[i]) - 1) {
1836 if (arg1 >= ARRAY_COUNT(BgmCustomEnvLookup)) {
1837 player->customPressEnvelopes[i][writePos] = (arg1 << 8) + arg2;
1838 } else {
1839 player->customPressEnvelopes[i][writePos] = (BgmCustomEnvLookup[arg1] << 8) + arg2;
1840 }
1841 player->customEnvelopeWritePos[i] = writePos + 1;
1842 }
1843 }
1844 break;
1846 if (arg1 <= ARRAY_COUNT(player->customPressEnvelopes)) {
1847 track->pressOverride = arg1;
1848 } else {
1849 track->pressOverride = 0;
1850 }
1851 break;
1853 if (player->soundManager != NULL) {
1854 for (i = 0; i < ARRAY_COUNT(player->soundManager->bgmSounds); i++) {
1855 if ((player->soundManager->bgmSounds[i].index) == 0) {
1856 player->soundManager->bgmSounds[i].index = arg1;
1857 player->soundManager->bgmSounds[i].volume =
1858 ((s32)(
1859 ((u32)player->fadeInfo.baseVolume >> 16) *
1860 ((u32)player->fadeInfo.envelopeVolume >> 16)
1861 ) + AU_MAX_VOLUME_16) >> 0x17;
1862 break;
1863 }
1864 }
1865 }
1866 break;
1868 if (arg1 == 0) {
1869 if (track->proxMixValChanged) {
1870 track->proxMixValChanged = FALSE;
1871 for (i = 0; i < ARRAY_COUNT(player->tracks); i++) {
1872 BGMPlayerTrack* otherTrack = &player->tracks[i];
1873 if (player->proxMixVolume == AU_MAX_VOLUME_8) {
1874 if (otherTrack->proxVol1 != 0) {
1876 au_bgm_set_prox_mix_fade(player, otherTrack, otherTrack->proxVol1, 72);
1877 }
1878 } else {
1879 if (otherTrack->proxVol2 != 0) {
1880 otherTrack->proxMixValChanged = FALSE;
1881 au_bgm_set_prox_mix_fade(player, otherTrack, otherTrack->proxVol2, 72);
1882 }
1883 }
1884 }
1885 }
1886 } else {
1887 track->proxVol1 = arg1;
1888 track->proxVol2 = arg2;
1889 }
1890 break;
1891 }
1892}
1893
1896
1897/*
1898Uses bit masks:
18993F00 = 0011 1111 0000 0000 -> 0011 1111
1900000C = 0000 0000 0000 1100 -> 1100 0000
1901*/
1902static u8 au_bgm_get_random_pan(BGMPlayer* player, u8 pan, u8 amplitude) {
1903 s32 seed = player->randomValue1;
1904 s32 tap7 = seed >> 7;
1905 s32 tap2 = seed >> 2;
1906 s32 parity = (tap7 + tap2) & 1;
1907 s32 lo = (seed >> 8) & 0x3F; // bitmask 0x3F00
1908 s32 hi = (seed << 4) & 0xC0; // bitmask 0x000C
1909 s32 random = lo + hi;
1910 s32 base = pan;
1911 s32 retPan;
1912
1913 if (parity) {
1914 retPan = base + ((amplitude * random) >> 8);
1915 } else {
1916 retPan = base - ((amplitude * random) >> 8);
1917 }
1918 if (retPan < AU_PAN_MIN) {
1920 } else if (retPan > AU_PAN_MAX) {
1922 }
1923 return retPan;
1924}
1925
1926/*
1927Uses bit masks:
19283C0 = 0000 0011 1100 0000 -> 0001 1111
192903C = 0000 0000 0011 1100 -> 1110 0000
1930*/
1931static s16 au_bgm_get_random_pitch(s32 seed, s32 pitch, u8 amplitude) {
1932 s32 tap4 = seed >> 4;
1933 s32 tap1 = seed >> 1;
1934 s32 parity = (tap4 + tap1) & 1;
1935 s32 lo = (seed >> 6) & 0xF; // bitmask 0x3C0
1936 s32 hi = (seed << 2) & 0xF0; // bitmask 0x03C
1937 s32 random = lo + hi;
1938 s32 retVal;
1939
1940 if (parity) {
1941 retVal = pitch + ((amplitude * 5 * random) >> 8);
1942 } else {
1943 retVal = pitch - ((amplitude * 5 * random) >> 8);
1944 }
1945 return retVal;
1946}
1947
1948/*
1949Uses bit masks:
19501F00 = 0001 1111 0000 0000 -> 0001 1111
195100E0 = 0000 0000 1110 0000 -> 1110 0000
1952*/
1953static u8 au_bgm_get_random_vol(s32 seed, u8 volume, u8 amplitude) {
1954 s32 lo = (seed >> 8) & 0x1F; // bitmask 0x1F00
1955 s32 hi = seed & 0xE0;
1956 s32 random = lo + hi;
1957
1958 return volume * (0x8000 - amplitude * random);
1959}
1960
1961/*
1962Uses bit masks:
19630380 = 0000 0011 1000 0000 -> 0000 0111
1964001F = 0000 0000 0001 1111 -> 1111 1000
1965*/
1966static u8 au_bgm_get_random_reverb(s32 seed, u8 reverb, u8 amplitude) {
1967 s32 lo = (seed >> 7) & 7; // bitmask 0x380
1968 s32 hi = (seed << 3) & 0xF8; // bitmask 0x01F
1969 s32 random = lo + hi;
1970
1971 return reverb * (0x8000 - (amplitude * random));
1972}
1973
1975 BGMPlayer* player;
1977 s32 changed = FALSE;
1978 u8 mixID = mix & 0xFF;
1979 s32 i;
1980
1981 if (songName != 0) {
1982 player = au_bgm_get_player_with_song_name(songName);
1983 if ((player != NULL) && (player->proxMixValue != mix)) {
1984 player->proxMixValue = mix;
1985 if (player->proxMixID != mixID) {
1986 player->proxMixID = mixID;
1987 changed = TRUE;
1988 }
1989 player->proxMixVolume = (mix >> 0x18) & 0x7F;
1990 for (i = 0; i < ARRAY_COUNT(player->tracks); i++) {
1991 track = &player->tracks[i];
1992 if (changed) {
1994 }
1995 track->proxMixValChanged = TRUE;
1996 }
1997 }
1998 }
1999}
2000
2002 if (rate > 2.0) {
2003 rate = 2.0f;
2004 } else if (rate < 0.25) {
2005 rate = 0.25f;
2006 }
2007
2008 player->playbackRate = rate;
2009 player->masterTempo = au_bgm_bpm_to_tempo(player, player->masterTempoBPM);
2011 player->masterTempoTicks = 0;
2012 player->masterTempoTarget = 0;
2013 player->masterTempoStep = 0;
2014}
2015
2017 if (detune > AU_OCTAVE_CENTS) {
2018 detune = AU_OCTAVE_CENTS;
2019 } else if (detune < -2 * AU_OCTAVE_CENTS) {
2020 detune = -2 * AU_OCTAVE_CENTS;
2021 }
2022
2023 player->detune = detune;
2024}
2025
2027 BGMPlayerTrack* track = &player->tracks[trackIdx];
2028
2029 if (track->bgmReadPos != 0) {
2030 player->seqCmdArgs.TrackVolumeFade.time = time;
2031 player->seqCmdArgs.TrackVolumeFade.value = volume;
2033 }
2034}
2035
2037 player->trackVolsConfig = trackVols;
2038 player->bFadeConfigSetsVolume = mode;
2039}
2040
2042 if (target != 0) {
2044 }
2045 if (duration <= 0) {
2046 duration = 1;
2047 } else if (duration > 1000) {
2048 duration = 1000;
2049 }
2050 if (target == track->proxVolume) {
2051 track->proxVolumeTicks = 0;
2052 return;
2053 }
2054 track->proxVolumeTicks = duration;
2055 track->proxVolumeTarget = target;
2056 track->proxVolumeStep = ((target << 0x10) - track->proxVolume) / duration;
2057}
2058
2060 u8 i;
2061
2062 for (i = 0; i < ARRAY_COUNT(player->globals->voices); i++) {
2063 AuVoice* voice = &player->globals->voices[i];
2064 if (voice->priority == player->priority) {
2066 }
2067 }
2068}
2069
2071 BGMPlayer* player;
2074 AuVoice* voice;
2075 s32 trackIdx;
2076 s32 voiceIdx;
2077 s8 oldVolume;
2078
2079 s32 songName = request->songName;
2080 b32 enabled = request->enabled;
2081 AuResult status = AU_RESULT_OK;
2082
2083 if (songName != 0) {
2084 player = au_bgm_get_player_with_song_name(songName);
2085 if (player != NULL) {
2086 for (trackIdx = 0; trackIdx < ARRAY_COUNT(player->tracks); trackIdx++) {
2087 track = &player->tracks[trackIdx];
2088 if (track->bgmReadPos != NULL) {
2089 if (track->linkedTrackID != 0) {
2090 linkTrack = &player->tracks[track->linkedTrackID - 1];
2091 if (enabled) {
2092 if (track->muted) {
2093 track->muted = FALSE;
2094 linkTrack->muted = TRUE;
2095 // release all voices for linked track
2096 for (voiceIdx = linkTrack->firstVoice; voiceIdx < linkTrack->lastVoice; voiceIdx++) {
2097 voice = &player->globals->voices[voiceIdx];
2098 if (voice->priority == player->priority) {
2100 voice->envelopeFlags |= AU_VOICE_ENV_FLAG_KEY_RELEASED;
2101 }
2102 }
2103 // fade in main track
2104 oldVolume = track->insVolume >> 24;
2106 player->seqCmdArgs.raw[0] = 0;
2107 player->seqCmdArgs.TrackVolumeFade.time = 96;
2108 player->seqCmdArgs.TrackVolumeFade.value = oldVolume;
2110 }
2111 } else {
2112 if (!track->muted) {
2113 track->muted = TRUE;
2114 linkTrack->muted = FALSE;
2115 // release all voices for main track
2116 for (voiceIdx = track->firstVoice; voiceIdx < track->lastVoice; voiceIdx++) {
2117 voice = &player->globals->voices[voiceIdx];
2118 if (voice->priority == player->priority) {
2120 voice->envelopeFlags |= AU_VOICE_ENV_FLAG_KEY_RELEASED;
2121 }
2122 }
2123 // fade in linked track
2124 oldVolume = linkTrack->insVolume >> 24;
2126 player->seqCmdArgs.raw[0] = 0;
2127 player->seqCmdArgs.TrackVolumeFade.time = 96;
2128 player->seqCmdArgs.TrackVolumeFade.value = oldVolume;
2130 }
2131 }
2132 }
2133 }
2134 }
2135 } else {
2137 }
2138 } else {
2139 status = AU_ERROR_NULL_SONG_NAME;
2140 }
2141
2142 return status;
2143}
BSS s32 PopupMenu_SelectedIndex
s32 randomValue2
Definition audio.h:1154
u8 channelDelayPending
Definition audio.h:1041
BGMInstrumentInfo * instrumentsInfo
Definition audio.h:1166
u16 unk_5A
Definition audio.h:1156
struct BGMHeader * bgmFile
Definition audio.h:1160
#define BGM_TEMPO_TO_UPDATE_UNITS(tempo)
Definition audio.h:100
struct SeqArgs::@74 TrackTremoloDepth
SoundManagerMusicEvent bgmSounds[4]
Definition audio.h:800
struct SeqArgs::@67 InstrumentReverb
s8 volumeChanged
Current write position for each custom envelope.
Definition audio.h:1194
u8 cmdBufPending
Buffer for an unused (legacy) system for controlling the BGMPlayer from the main thread.
Definition audio.h:1213
s16_16 envelopeVolume
Definition audio.h:510
#define BGM_MFRAMES_PER_MINUTE
Definition audio.h:86
SoundManager * soundManager
Definition audio.h:1140
struct SeqArgs::@81 Detour
AuVoice voices[24]
Definition audio.h:1075
struct SeqArgs::@79 Branch
struct SeqArgs::@72 TrackTremolo
u8 * tickRatePtr
Definition audio.h:1164
BGMPlayer * gBGMPlayerB
Definition engine.c:7
u16 unk_58
Definition audio.h:1155
s32 songPlayingCounter
video frames (60 fps)
Definition audio.h:1145
u8 proxMixSetChanged
Definition audio.h:1105
SoundPlayChange changed
Definition audio.h:1097
SegData * compReadPos
Definition audio.h:1161
#define BGM_DEFAULT_TICKS_PER_BEAT
Definition audio.h:77
s16 baseTicks
Definition audio.h:508
u8 * cmdListRelease
Definition audio.h:659
EnvelopeData envelope
Definition audio.h:845
s16 customPressEnvelopes[8][9]
Definition audio.h:1185
u8 initLinkMute
Definition audio.h:1208
s32 masterVolumeTicks
Definition audio.h:1175
#define AU_SEMITONE_CENTS
Definition audio.h:111
s32 songName
Definition audio.h:1146
#define BGM_DEFAULT_TEMPO
Definition audio.h:91
u8 proxMixValChanged
Definition audio.h:1106
AuCallback onCompleteCallback
Definition audio.h:509
s32 baseStep
Definition audio.h:506
s32 frameCounter
current update counter value
Definition audio.h:1144
#define NO_INSTRUMENT
Definition audio.h:14
u8 unused_21E
Definition audio.h:1198
BGMDrumInfo * drumsInfo
Definition audio.h:1165
#define AU_PAN_MIN
Definition audio.h:65
AuGlobals * globals
Definition audio.h:1139
@ AU_DELAY_CHANNEL_NONE
Definition audio.h:241
u8 raw[4]
Definition audio.h:407
u8 proxMixID
Definition audio.h:1182
s32 randomValue1
Definition audio.h:1153
s32 masterVolumeTarget
Definition audio.h:1174
u8 bgmDrumCount
Definition audio.h:1196
s32 nextUpdateCounter
update counter threshold for a single tick
Definition audio.h:1143
u8 busID
Definition audio.h:1210
u16 masterTempoBPM
Definition audio.h:1187
s32 masterTempo
Definition audio.h:1168
s8_24 masterVolume
Definition audio.h:1172
#define AU_FILE_RELATIVE(base, offset)
Definition audio.h:43
u8 unused_222
Definition audio.h:1202
struct BGMPlayer * resumeCopyTo
Definition audio.h:1050
s8_24 insVolume
Definition audio.h:1084
SeqNote notes[24]
Definition audio.h:1218
s32 masterTempoStep
Definition audio.h:1169
struct SeqArgs::@69 InstrumentCoarseTune
BGMDrumInfo drums[12]
Definition audio.h:981
struct SeqArgs::@62 MasterVolumeFade
u8 channelDelayBusID
Definition audio.h:1042
u8 effectIndices[4]
Definition audio.h:1152
@ BGM_SPECIAL_PROX_MIX_OVERRIDE
Definition audio.h:230
@ BGM_SPECIAL_SEEK_CUSTOM_ENV
Definition audio.h:226
@ BGM_SPECIAL_USE_CUSTOM_ENV
Definition audio.h:228
@ BGM_SPECIAL_WRITE_CUSTOM_ENV
Definition audio.h:227
@ BGM_SPECIAL_TRIGGER_SOUND
Definition audio.h:229
@ BGM_SPECIAL_SET_STEREO_DELAY
Definition audio.h:225
s32 masterTempoTarget
Definition audio.h:1170
BGMInstrumentInfo * dataPRG
Definition audio.h:1046
#define AU_MAX_VOLUME_8
Definition audio.h:61
SeqArgs seqCmdArgs
Definition audio.h:1177
#define BGM_DEFAULT_BPM
Definition audio.h:89
BGMFileInfo info
Definition audio.h:884
struct BGMPlayer * resumeCopyFrom
Definition audio.h:1051
@ AU_VOICE_SYNC_FLAG_PAN_FXMIX
Definition audio.h:151
@ AU_VOICE_SYNC_FLAG_PITCH
Definition audio.h:150
@ AU_VOICE_SYNC_FLAG_ALL
Definition audio.h:148
struct SeqArgs::@59 MasterPitchShift
BGMDrumInfo * drums[12]
Definition audio.h:1167
u16 maxTempo
Definition audio.h:1188
u8 paused
Definition audio.h:1200
s32 name
Definition audio.h:882
SegData * phraseStartPos
Definition audio.h:1163
SegData * compStartPos
Definition audio.h:1162
s16 baseTarget
Definition audio.h:507
@ BGM_PLAY_STATE_IDLE
Definition audio.h:207
@ BGM_PLAY_STATE_FETCH
Definition audio.h:209
@ BGM_PLAY_STATE_STOP
Definition audio.h:211
@ BGM_PLAY_STATE_ACTIVE
Definition audio.h:208
@ BGM_PLAY_STATE_INIT
Definition audio.h:210
u8 polyVoiceCount
Definition audio.h:1109
u8 * trackVolsConfig
Dynamically customizable press envelopes.
Definition audio.h:1186
struct SeqArgs::@64 OverridePatch
s32 nextUpdateStep
Definition audio.h:1141
struct SeqArgs::@80 EventTrigger
u8 bgmInstrumentCount
Definition audio.h:1197
BGMPlayerSnapshot snapshots[1]
Definition audio.h:1049
struct SeqArgs::@75 RandomPan
s16 envelopeTarget
Definition audio.h:512
u8 effectValues[4]
No means to modify value is implemented.
Definition audio.h:1204
s16 volume
Definition audio.h:1127
u16 masterPitchShift
Definition audio.h:1189
s32 pushSongName
Definition audio.h:1147
struct SeqArgs::@63 MasterEffect
BGMPlayer * gBGMPlayerA
Definition engine.c:6
u8 customEnvelopeWritePos[8]
Currently active (for writing) custom envelope.
Definition audio.h:1193
s16 envelopeTicks
Definition audio.h:513
s32 tickUpdateInterval
update counter amount to add per audio frame
Definition audio.h:1142
#define BGM_DEFAULT_UPDATE_STEP
Definition audio.h:97
struct SeqArgs::@77 TrackVolumeFade
s32 busVolume
Definition audio.h:1151
#define SND_MIN_DURATION
Definition audio.h:102
s32 cmdBufData[8]
Definition audio.h:1212
s32 resumeFadeEnd
Definition audio.h:1056
#define PRG_MAX_COUNT
Definition audio.h:119
Fade fadeInfo
Definition audio.h:1150
u8 bFadeConfigSetsVolume
Definition audio.h:1207
struct SeqArgs::@82 Special
#define AU_FRAME_USEC
Definition audio.h:27
u8 tremoloDepth
Definition audio.h:1131
@ BGM_SNAPSHOT_0
Definition audio.h:192
@ BGM_COMP_PLAY_PHRASE
Definition audio.h:216
@ BGM_COMP_START_LOOP
Definition audio.h:217
@ BGM_COMP_END
Definition audio.h:215
@ BGM_COMP_END_COND_LOOP_FALSE
Definition audio.h:220
@ BGM_COMP_END_COND_LOOP_TRUE
Definition audio.h:221
@ BGM_COMP_WAIT
Definition audio.h:218
@ BGM_COMP_END_LOOP
Definition audio.h:219
u8 channelDelaySide
Definition audio.h:1044
u8 cmdBufWritePos
Definition audio.h:1215
struct SeqArgs::@78 ReverbType
s16_16 baseVolume
Definition audio.h:505
struct SeqArgs::@73 TrackTremoloRate
struct BGMHeader * dataBGM[2]
Definition audio.h:1047
u8 conditionalLoopFlags
Definition audio.h:1203
#define AU_PAN_MAX
Definition audio.h:67
u8 writingCustomEnvelope
Definition audio.h:1192
s32 masterTempoTicks
Definition audio.h:1171
PEREntry * dataPER
Definition audio.h:1045
u8 cmdBufReadPos
Definition audio.h:1214
#define BGM_UPDATE_SCALE
Definition audio.h:81
BGMInstrumentInfo defaultPRGEntry
Definition audio.h:1030
#define AU_OCTAVE_CENTS
Definition audio.h:114
u8 priority
Used to mute any linked tracks after the first one encountered.
Definition audio.h:1209
#define SND_MAX_DURATION
Definition audio.h:103
struct SeqArgs::@58 MasterVolume
s32 resumeFadeStart
Definition audio.h:1055
s32 resumeSongName
Definition audio.h:1052
s32 masterVolumeStep
Definition audio.h:1173
BGMPlayerTrack tracks[16]
Definition audio.h:1217
struct SeqArgs::@76 UseInstrument
AuFilePos bgmReadPos
Definition audio.h:1079
struct SeqArgs::@68 TrackVolume
@ AU_PRIORITY_FREE
Definition audio.h:133
struct SeqArgs::@57 MasterTempo
SegData * compActiveLoopEndPos[4]
Definition audio.h:1179
struct SeqArgs::@60 UnkCmdE3
SegData * compLoopStartLabels[32]
Definition audio.h:1178
struct SeqArgs::@61 MasterTempoFade
s32 resumeFadeTime
Definition audio.h:1054
AuEffectChange effectChanges[4]
copied from INIT to the audio heap, seems to exist only to find SEF, PER, and PRG
Definition audio.h:1040
#define BGM_MAX_INSTRUMNETS
Definition audio.h:75
@ BGM_POLYPHONY_UNUSED_A
Definition audio.h:198
@ BGM_POLYPHONY_4
Definition audio.h:203
@ BGM_POLYPHONY_UNUSED_C
Definition audio.h:200
@ BGM_POLYPHONY_2
Definition audio.h:201
@ BGM_POLYPHONY_1
Definition audio.h:197
@ BGM_POLYPHONY_0
Definition audio.h:196
@ BGM_POLYPHONY_UNUSED_B
Definition audio.h:199
@ BGM_POLYPHONY_3
Definition audio.h:202
u8 masterState
Definition audio.h:1201
#define AU_MAX_VOLUME_16
Definition audio.h:62
f32 playbackRate
Definition audio.h:1176
u8 * AuFilePos
Definition audio.h:11
#define AU_MAX_BUS_VOLUME
Definition audio.h:40
Instrument * ins
Definition audio.h:1125
b32 resumeRequested
Definition audio.h:1053
u8 compLoopDepth
Definition audio.h:1191
@ AU_VOICE_ENV_FLAG_KEY_RELEASED
Definition audio.h:143
@ AU_VOICE_ENV_FLAG_VOL_CHANGED
Definition audio.h:144
u8 compLoopCounters[4]
Definition audio.h:1180
s32 length
Definition audio.h:1129
#define AU_VOL_8_TO_16(vol)
Definition audio.h:70
struct SeqArgs::@71 TrackDetune
Instrument * instrument
Definition audio.h:1082
struct SeqArgs::@70 InstrumentFineTune
s32 curVariation
Definition audio.h:1159
u8 polyphonyCounts[8]
Definition audio.h:1206
u8 totalVoices
Definition audio.h:1195
u8 priority
Definition audio.h:865
s32 s8_24
Definition audio.h:8
s16 detune
Definition audio.h:1190
u8 channelDelayTime
Definition audio.h:1043
s32 proxMixValue
Definition audio.h:1181
u8 proxMixVolume
Definition audio.h:1183
struct SeqArgs::@66 InstrumentPan
void au_bgm_load_phrase(BGMPlayer *player, u32 cmd)
Definition bgm_player.c:939
s32 au_bgm_player_audio_frame_update(BGMPlayer *player)
Definition bgm_player.c:661
void au_bgm_player_update_stop(BGMPlayer *player)
void au_bgm_update_bus_volumes(BGMPlayer *player)
Definition bgm_player.c:644
void au_bgm_player_read_composition(BGMPlayer *player)
Definition bgm_player.c:859
void au_BGMCmd_F1_TrackTremoloRate(BGMPlayer *player, BGMPlayerTrack *track)
void au_bgm_set_proximity_mix(s32 songName, u32 mix)
void au_BGMCmd_F7_ReverbType(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_FF_Special(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_FD_EventTrigger(BGMPlayer *player, BGMPlayerTrack *track)
u8 BgmTicksRates[8]
Definition sfx_player.c:279
AuResult au_bgm_set_linked_tracks(SongSwapLinkedRequest *request)
BGMPlayer * au_bgm_get_player_with_song_name(s32 songString)
Definition bgm_player.c:124
AuResult au_bgm_is_song_playing(s32 songName)
Definition bgm_player.c:261
void au_BGMCmd_FC_Branch(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_FE_Detour(BGMPlayer *player, BGMPlayerTrack *track)
void au_bgm_set_prox_mix_fade(BGMPlayer *player, BGMPlayerTrack *track, s32 target, s32 duration)
AuResult au_bgm_process_suspend(SongSuspendRequest *request, b32 skipStop)
Definition bgm_player.c:337
void au_BGMCmd_F4_SubTrackRandomPan(BGMPlayer *player, BGMPlayerTrack *track)
void(* SefCmdHandlers[])(SoundManager *, SoundPlayer *)
Definition sfx_player.c:200
void au_BGMCmd_E3(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_EA_InstrumentPan(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_ED_InstrumentCoarseTune(BGMPlayer *player, BGMPlayerTrack *track)
u8 EnvelopeReleaseDefaultFast[]
Definition sfx_player.c:327
void au_BGMCmd_EC_TrackVolume(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_E2_MasterDetune(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_E5_MasterVolumeFade(BGMPlayer *player, BGMPlayerTrack *track)
void au_bgm_change_track_volume(BGMPlayer *player, s32 trackIdx, s16 time, u8 volume)
u8 SeqCmdArgCounts[]
Definition sfx_player.c:272
void au_bgm_player_update_playing(BGMPlayer *player)
play next tick
void au_bgm_set_track_volumes(BGMPlayer *player, u8 *trackVols, s32 mode)
#define POST_BGM_READ()
void au_bgm_end_composition_loop(BGMPlayer *player, u32 cmd)
Definition bgm_player.c:904
void au_bgm_restore_copied_player(AuGlobals *globals)
Definition bgm_player.c:473
u8 BgmCustomEnvLookup[40]
Definition sfx_player.c:335
void au_bgm_set_tick_resolution(BGMPlayer *player, s32 mBeatsPerMinute, u32 ticksPerBeat)
Definition bgm_player.c:827
AuResult au_bgm_process_fade_out(SongFadeOutRequest *request)
Definition bgm_player.c:287
void au_bgm_player_init(BGMPlayer *player, s32 priority, s32 busID, AuGlobals *globals)
Definition bgm_player.c:523
void au_BGMCmd_E0_MasterTempo(BGMPlayer *player, BGMPlayerTrack *track)
BSS void(* CurrentSeqCmdHandler)(BGMPlayer *, BGMPlayerTrack *)
Definition bgm_player.c:4
b32 au_bgm_player_is_active(BGMPlayer *player)
Definition bgm_player.c:279
AuResult au_bgm_process_resume(SongResumeRequest *request)
Definition bgm_player.c:395
void au_bgm_begin_video_frame(BGMPlayer *player)
Definition bgm_player.c:23
void au_bgm_set_effect_indices(BGMPlayer *player, u8 *list)
Definition bgm_player.c:601
AuResult au_bgm_stop_song(s32 songName)
Definition bgm_player.c:227
void au_bgm_update_fade(BGMPlayer *player)
Definition bgm_player.c:622
void au_BGMCmd_E8_TrackOverridePatch(BGMPlayer *player, BGMPlayerTrack *track)
void au_bgm_player_initialize(BGMPlayer *player)
Definition bgm_player.c:702
void au_BGMCmd_F0_TrackTremolo(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_EE_InstrumentFineTune(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_F5_UseInstrument(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_EC_TrackDetune(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_NOP(BGMPlayer *player, BGMPlayerTrack *track)
void au_bgm_stop_all(void)
Definition bgm_player.c:247
void au_BGMCmd_F2_TrackTremoloDepth(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_E6_MasterEffect(BGMPlayer *player, BGMPlayerTrack *track)
void au_bgm_set_playback_rate(BGMPlayer *player, f32 rate)
void(* SeqCmdHandlers[])(BGMPlayer *, BGMPlayerTrack *)
Definition sfx_player.c:237
void au_bgm_clear_custom_note_press(BGMPlayer *player, s32 index)
Definition bgm_player.c:817
AuResult au_bgm_adjust_volume(SongStartRequest *request)
Definition bgm_player.c:505
void au_bgm_reset_all_voices(BGMPlayer *player)
void au_bgm_player_set_detune(BGMPlayer *player, s32 detune)
void au_BGMCmd_EB_InstrumentReverb(BGMPlayer *player, BGMPlayerTrack *track)
AuResult au_bgm_process_init_song(SongStartRequest *request)
Definition bgm_player.c:135
void au_BGMCmd_E9_InstrumentVolume(BGMPlayer *arg0, BGMPlayerTrack *track)
void au_BGMCmd_F6_InstrumentVolumeLerp(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_E1_MasterVolume(BGMPlayer *player, BGMPlayerTrack *track)
AuResult au_bgm_complete_push(s32 songName)
Definition bgm_player.c:324
void au_BGMCmd_F3_TrackTremoloStop(BGMPlayer *player, BGMPlayerTrack *track)
void au_BGMCmd_E4_MasterTempoFade(BGMPlayer *player, BGMPlayerTrack *track)
s32 b32
void au_reset_voice(AuVoice *voice, u8 voiceIdx)
Definition engine.c:393
AuResult au_reload_song_files(s32 songID, BGMHeader *arg1)
Definition engine.c:618
void au_fade_set_envelope(Fade *fade, s16 value)
Definition engine.c:465
f32 au_compute_pitch_ratio(s32 tuning)
Converts a linear pitch value (in cents) into a frequency ratio suitable for adjusting playback speed...
Definition engine.c:406
Instrument * au_get_instrument(AuGlobals *globals, BankSetIndex bank, s32 patch, EnvelopeData *arg3)
Note that bank is supplied as BankSetIndex and not BankSet, which means it will be used to perform a ...
Definition engine.c:502
BGMPlayer * au_get_snapshot_by_index(s32 index)
Definition engine.c:656
BGMPlayer * au_get_client_by_priority(u8 arg0)
Definition engine.c:732
void au_fade_init(Fade *fade, s32 time, s32 startValue, s32 endValue)
Definition engine.c:417
void au_fade_calc_envelope(Fade *fade, u32 arg1, s32 target)
Definition engine.c:472
void au_fade_set_volume(u8 arg0, u16 arg1, s32 arg2)
Definition engine.c:453
void au_copy_words(void *src, void *dst, s32 size)
Definition engine.c:1273
void au_fade_clear(Fade *fade)
Definition engine.c:432
Vec3s pos
Definition demo_api.c:17
@ BGM_VARIATION_0
Definition enums.h:1805
@ BGM_VARIATION_3
Definition enums.h:1808
AuResult
Definition enums.h:1758
@ AU_ERROR_NULL_SONG_NAME
Definition enums.h:1766
@ AU_ERROR_7
Definition enums.h:1770
@ AU_RESULT_OK
Definition enums.h:1759
@ AU_ERROR_6
Definition enums.h:1769
@ AU_ERROR_SONG_NOT_PLAYING
Definition enums.h:1764
@ AU_ERROR_INVALID_SONG_DURATION
Definition enums.h:1768
void snd_bgm_clear_legacy_commands(BGMPlayer *player)
Part of an unused system for inter-thread communication with a BGM player using commands.
void snd_song_trigger_music_event(s32 playerID, s32 trackIndex, s32 eventInfo)
#define BSS
Definition macros.h:7
#define ARRAY_COUNT(arr)
Definition macros.h:40