diff options
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/audio_data.c | 735 | ||||
| -rw-r--r-- | src/code/audio_effects.c | 337 | ||||
| -rw-r--r-- | src/code/audio_external_data.c | 69 | ||||
| -rw-r--r-- | src/code/audio_heap.c | 1485 | ||||
| -rw-r--r-- | src/code/audio_init_params.c | 106 | ||||
| -rw-r--r-- | src/code/audio_load.c | 2127 | ||||
| -rw-r--r-- | src/code/audio_playback.c | 952 | ||||
| -rw-r--r-- | src/code/audio_seqplayer.c | 2149 | ||||
| -rw-r--r-- | src/code/audio_sfx_params.c | 41 | ||||
| -rw-r--r-- | src/code/audio_stop_all_sfx.c (renamed from src/code/code_800C3C20.c) | 0 | ||||
| -rw-r--r-- | src/code/audio_synthesis.c | 1338 | ||||
| -rw-r--r-- | src/code/audio_thread_manager.c (renamed from src/code/audioMgr.c) | 0 | ||||
| -rw-r--r-- | src/code/code_800E4FE0.c | 875 | ||||
| -rw-r--r-- | src/code/code_800E6840.c | 15 | ||||
| -rw-r--r-- | src/code/code_800EC960.c | 5355 | ||||
| -rw-r--r-- | src/code/code_800F7260.c | 729 | ||||
| -rw-r--r-- | src/code/code_800F9280.c | 827 |
17 files changed, 0 insertions, 17140 deletions
diff --git a/src/code/audio_data.c b/src/code/audio_data.c deleted file mode 100644 index d1bd4acc1..000000000 --- a/src/code/audio_data.c +++ /dev/null @@ -1,735 +0,0 @@ -#include "global.h" - -// clang-format off -s16 gSawtoothWaveSample[] = { - // Frequency of 1 - 0, 1023, 2047, 3071, 4095, 5119, 6143, 7167, - 8191, 9215, 10239, 11263, 12287, 13311, 14335, 15359, - 16383, 17407, 18431, 19455, 20479, 21503, 22527, 23551, - 24575, 25599, 26623, 27647, 28671, 29695, 30719, 31743, - -32767, -31743, -30719, -29695, -28671, -27647, -26623, -25599, - -24575, -23551, -22527, -21503, -20479, -19455, -18431, -17407, - -16383, -15359, -14335, -13311, -12287, -11263, -10239, -9215, - -8191, -7167, -6143, -5119, -4095, -3071, -2047, -1023, - - // Frequency of 2 - 0, 2047, 4095, 6143, 8191, 10239, 12287, 14335, - 16383, 18431, 20479, 22527, 24575, 26623, 28671, 30719, - -32767, -30719, -28671, -26623, -24575, -22527, -20479, -18431, - -16383, -14335, -12287, -10239, -8191, -6143, -4095, -2047, - 0, 2047, 4095, 6143, 8191, 10239, 12287, 14335, - 16383, 18431, 20479, 22527, 24575, 26623, 28671, 30719, - -32767, -30719, -28671, -26623, -24575, -22527, -20479, -18431, - -16383, -14335, -12287, -10239, -8191, -6143, -4095, -2047, - - // Frequency of 4 - 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, - -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, - 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, - -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, - 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, - -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, - 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, - -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, - - // Frequency of 8 - 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, - 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, - 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, - 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, - 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, - 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, - 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, - 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, -}; - -s16 gTriangleWaveSample[] = { - // Frequency of 1 - 0, 2047, 4095, 6143, 8191, 10239, 12287, 14335, - 16383, 18431, 20479, 22527, 24575, 26623, 28671, 30719, - 32767, 30719, 28671, 26623, 24575, 22527, 20479, 18431, - 16383, 14335, 12287, 10239, 8191, 6143, 4095, 2047, - 0, -2047, -4095, -6143, -8191, -10239, -12287, -14335, - -16383, -18431, -20479, -22527, -24575, -26623, -28671, -30719, - -32767, -30719, -28671, -26623, -24575, -22527, -20479, -18431, - -16383, -14335, -12287, -10239, -8191, -6143, -4095, -2047, - - // Frequency of 2 - 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, - 32767, 28671, 24575, 20479, 16383, 12287, 8191, 4095, - 0, -4095, -8191, -12287, -16383, -20479, -24575, -28671, - -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, - 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, - 32767, 28671, 24575, 20479, 16383, 12287, 8191, 4095, - 0, -4095, -8191, -12287, -16383, -20479, -24575, -28671, - -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, - - // Frequency of 4 - 0, 8191, 16383, 24575, 32767, 24575, 16383, 8191, - 0, -8191, -16383, -24575, -32767, -24575, -16383, -8191, - 0, 8191, 16383, 24575, 32767, 24575, 16383, 8191, - 0, -8191, -16383, -24575, -32767, -24575, -16383, -8191, - 0, 8191, 16383, 24575, 32767, 24575, 16383, 8191, - 0, -8191, -16383, -24575, -32767, -24575, -16383, -8191, - 0, 8191, 16383, 24575, 32767, 24575, 16383, 8191, - 0, -8191, -16383, -24575, -32767, -24575, -16383, -8191, - - // Frequency of 8 - 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, - 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, - 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, - 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, - 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, - 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, - 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, - 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, -}; - -s16 gSineWaveSample[] = { - // Frequency of 1 - 0, 3211, 6392, 9511, 12539, 15446, 18204, 20787, - 23169, 25329, 27244, 28897, 30272, 31356, 32137, 32609, - 32767, 32609, 32137, 31356, 30272, 28897, 27244, 25329, - 23169, 20787, 18204, 15446, 12539, 9511, 6392, 3211, - 0, -3211, -6392, -9511, -12539, -15446, -18204, -20787, - -23169, -25329, -27244, -28897, -30272, -31356, -32137, -32609, - -32767, -32609, -32137, -31356, -30272, -28897, -27244, -25329, - -23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211, - - // Frequency of 2 - 0, 6392, 12539, 18204, 23169, 27244, 30272, 32137, - 32767, 32137, 30272, 27244, 23169, 18204, 12539, 6392, - 0, -6392, -12539, -18204, -23169, -27244, -30272, -32137, - -32767, -32137, -30272, -27244, -23169, -18204, -12539, -6392, - 0, 6392, 12539, 18204, 23169, 27244, 30272, 32137, - 32767, 32137, 30272, 27244, 23169, 18204, 12539, 6392, - 0, -6392, -12539, -18204, -23169, -27244, -30272, -32137, - -32767, -32137, -30272, -27244, -23169, -18204, -12539, -6392, - - // Frequency of 4 - 0, 12539, 23169, 30272, 32767, 30272, 23169, 12539, - 0, -12539, -23169, -30272, -32767, -30272, -23169, -12539, - 0, 12539, 23169, 30272, 32767, 30272, 23169, 12539, - 0, -12539, -23169, -30272, -32767, -30272, -23169, -12539, - 0, 12539, 23169, 30272, 32767, 30272, 23169, 12539, - 0, -12539, -23169, -30272, -32767, -30272, -23169, -12539, - 0, 12539, 23169, 30272, 32767, 30272, 23169, 12539, - 0, -12539, -23169, -30272, -32767, -30272, -23169, -12539, - - // Frequency of 8 - 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, - 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, - 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, - 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, - 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, - 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, - 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, - 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, -}; - -s16 gSquareWaveSample[] = { - // Frequency of 1 - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, - 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767, - -32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767, - - // Frequency of 2 - 0, 0, 0, 0, 0, 0, 0, 0, - 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, - 0, 0, 0, 0, 0, 0, 0, 0, - -32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767, - 0, 0, 0, 0, 0, 0, 0, 0, - 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, - 0, 0, 0, 0, 0, 0, 0, 0, - - // Frequency of 4 - -32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767, - 0, 0, 0, 0, 32767, 32767, 32767, 32767, - 0, 0, 0, 0, -32767, -32767, -32767, -32767, - 0, 0, 0, 0, 32767, 32767, 32767, 32767, - 0, 0, 0, 0, -32767, -32767, -32767, -32767, - 0, 0, 0, 0, 32767, 32767, 32767, 32767, - 0, 0, 0, 0, -32767, -32767, -32767, -32767, - 0, 0, 0, 0, 32767, 32767, 32767, 32767, - 0, 0, 0, 0, -32767, -32767, -32767, -32767, - - // Frequency of 8 - 0, 0, 32767, 32767, 0, 0, -32767, -32767, - 0, 0, 32767, 32767, 0, 0, -32767, -32767, - 0, 0, 32767, 32767, 0, 0, -32767, -32767, - 0, 0, 32767, 32767, 0, 0, -32767, -32767, - 0, 0, 32767, 32767, 0, 0, -32767, -32767, - 0, 0, 32767, 32767, 0, 0, -32767, -32767, - 0, 0, 32767, 32767, 0, 0, -32767, -32767, - 0, 0, 32767, 32767, 0, 0, -32767, -32767, -}; - -s16 gWhiteNoiseSample[] = { - // Frequency of 1 - 0, -25689, -25791, 27803, -27568, -21030, 22174, 6298, - 27071, -18531, 28649, 2284, 3380, 6890, -12682, -21114, - 10000, -24520, 32296, 12248, 15096, 15354, -12021, -31545, - -12929, 6388, -11064, 30456, -30316, -21999, 29691, 27649, - 0, -27649, -29691, 21999, 30316, -30457, 11064, -6387, - 12929, 31544, 12021, -15353, -15096, -12249, -32296, 24521, - -10000, 21113, 12682, -6889, -3380, -2285, -28649, 18532, - -27071, -6299, -22174, 21031, 27568, -27804, 25791, 25690, - - // Frequency of 2 - 0, -25791, -27568, 22174, 27071, 28649, 3380, -12682, - 10000, 32296, 15096, -12021, -12929, -11064, -30316, 29691, - 0, -29691, 30316, 11064, 12929, 12021, -15096, -32296, - -10000, 12682, -3380, -28649, -27071, -22174, 27568, 25791, - 0, -25791, -27568, 22174, 27071, 28649, 3380, -12682, - 10000, 32296, 15096, -12021, -12929, -11064, -30316, 29691, - 0, -29691, 30316, 11064, 12929, 12021, -15096, -32296, - -10000, 12682, -3380, -28649, -27071, -22174, 27568, 25791, - - // Frequency of 4 - 0, -27568, 27071, 3380, 10000, 15096, -12929, -30316, - 0, 30316, 12929, -15096, -10000, -3380, -27071, 27568, - 0, -27568, 27071, 3380, 10000, 15096, -12929, -30316, - 0, 30316, 12929, -15096, -10000, -3380, -27071, 27568, - 0, -27568, 27071, 3380, 10000, 15096, -12929, -30316, - 0, 30316, 12929, -15096, -10000, -3380, -27071, 27568, - 0, -27568, 27071, 3380, 10000, 15096, -12929, -30316, - 0, 30316, 12929, -15096, -10000, -3380, -27071, 27568, - - // Frequency of 8 - 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, - 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, - 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, - 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, - 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, - 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, - 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, - 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, -}; - -// Sine White Noise? -s16 D_8012EA90[] = { - // Frequency of 1 - 0, 16316, 20148, 20257, 27209, -32657, 29264, 27259, - -29394, -21494, -26410, 30770, 30033, 29130, 20206, 14129, - 20000, 25677, 19024, 9146, 6921, 4506, -5868, -13122, - -7858, -1885, -7042, -14025, -11903, -8647, -12346, -12396, - 0, 12396, 12346, 8647, 11903, 14024, 7042, 1886, - 7858, 13121, 5868, -4505, -6921, -9147, -19024, -25676, - -20000, -14130, -20206, -29129, -30033, -30771, 26410, 21495, - 29394, -27260, -29264, 32658, -27209, -20258, -20148, -16315, - - // Frequency of 2 - 0, 20148, 27209, 29264, -29394, -26410, 30033, 20206, - 20000, 19024, 6921, -5868, -7858, -7042, -11903, -12346, - 0, 12346, 11903, 7042, 7858, 5868, -6921, -19024, - -20000, -20206, -30033, 26410, 29394, -29264, -27209, -20148, - 0, 20148, 27209, 29264, -29394, -26410, 30033, 20206, - 20000, 19024, 6921, -5868, -7858, -7042, -11903, -12346, - 0, 12346, 11903, 7042, 7858, 5868, -6921, -19024, - -20000, -20206, -30033, 26410, 29394, -29264, -27209, -20148, - - // Frequency of 4 - 0, 27209, -29394, 30033, 20000, 6921, -7858, -11903, - 0, 11903, 7858, -6921, -20000, -30033, 29394, -27209, - 0, 27209, -29394, 30033, 20000, 6921, -7858, -11903, - 0, 11903, 7858, -6921, -20000, -30033, 29394, -27209, - 0, 27209, -29394, 30033, 20000, 6921, -7858, -11903, - 0, 11903, 7858, -6921, -20000, -30033, 29394, -27209, - 0, 27209, -29394, 30033, 20000, 6921, -7858, -11903, - 0, 11903, 7858, -6921, -20000, -30033, 29394, -27209, - - // Frequency of 8 - 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, - 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, - 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, - 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, - 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, - 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, - 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, - 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, -}; - -// Pulse Wave (duty cycle = 12.5%) -s16 gEighthPulseWaveSample[] = { - // Frequency of 1 - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 32767, 32767, 32767, 32767, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -32767, -32767, -32767, -32767, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - // Frequency of 2 - 0, 0, 0, 0, 0, 0, 0, 0, - 32767, 32767, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -32767, -32767, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 32767, 32767, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -32767, -32767, 0, 0, 0, 0, 0, 0, - - // Frequency of 4 - 0, 0, 0, 0, 32767, 0, 0, 0, - 0, 0, 0, 0, -32767, 0, 0, 0, - 0, 0, 0, 0, 32767, 0, 0, 0, - 0, 0, 0, 0, -32767, 0, 0, 0, - 0, 0, 0, 0, 32767, 0, 0, 0, - 0, 0, 0, 0, -32767, 0, 0, 0, - 0, 0, 0, 0, 32767, 0, 0, 0, - 0, 0, 0, 0, -32767, 0, 0, 0, - - // Frequency of 8 - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, -}; - -// Pulse Wave (duty cycle = 25%) -s16 gQuarterPulseWaveSample[] = { - // Frequency of 1 - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767, - 0, 0, 0, 0, 0, 0, 0, 0, - - // Frequency of 2 - 0, 0, 0, 0, 0, 0, 0, 0, - 32767, 32767, 32767, 32767, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -32767, -32767, -32767, -32767, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 32767, 32767, 32767, 32767, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - -32767, -32767, -32767, -32767, 0, 0, 0, 0, - - // Frequency of 4 - 0, 0, 0, 0, 32767, 32767, 0, 0, - 0, 0, 0, 0, -32767, -32767, 0, 0, - 0, 0, 0, 0, 32767, 32767, 0, 0, - 0, 0, 0, 0, -32767, -32767, 0, 0, - 0, 0, 0, 0, 32767, 32767, 0, 0, - 0, 0, 0, 0, -32767, -32767, 0, 0, - 0, 0, 0, 0, 32767, 32767, 0, 0, - 0, 0, 0, 0, -32767, -32767, 0, 0, - - // Frequency of 8 - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, - 0, 0, 32767, 0, 0, 0, -32767, 0, -}; -// clang-format on - -s16* gWaveSamples[] = { - gSawtoothWaveSample, gTriangleWaveSample, gSineWaveSample, gSquareWaveSample, gWhiteNoiseSample, - D_8012EA90, gEighthPulseWaveSample, gQuarterPulseWaveSample, gQuarterPulseWaveSample, -}; - -f32 gBendPitchOneOctaveFrequencies[] = { - 0.5f, 0.5f, 0.502736f, 0.505488f, 0.508254f, 0.511036f, 0.513833f, 0.516645f, 0.519472f, 0.522315f, - 0.525174f, 0.528048f, 0.530938f, 0.533843f, 0.536765f, 0.539702f, 0.542656f, 0.545626f, 0.548612f, 0.551614f, - 0.554633f, 0.557669f, 0.560721f, 0.563789f, 0.566875f, 0.569977f, 0.573097f, 0.576233f, 0.579387f, 0.582558f, - 0.585746f, 0.588951f, 0.592175f, 0.595415f, 0.598674f, 0.60195f, 0.605245f, 0.608557f, 0.611888f, 0.615236f, - 0.618603f, 0.621989f, 0.625393f, 0.628815f, 0.632257f, 0.635717f, 0.639196f, 0.642694f, 0.646212f, 0.649748f, - 0.653304f, 0.65688f, 0.660475f, 0.664089f, 0.667724f, 0.671378f, 0.675052f, 0.678747f, 0.682461f, 0.686196f, - 0.689952f, 0.693727f, 0.697524f, 0.701341f, 0.70518f, 0.709039f, 0.712919f, 0.716821f, 0.720744f, 0.724689f, - 0.728655f, 0.732642f, 0.736652f, 0.740684f, 0.744737f, 0.748813f, 0.752911f, 0.757031f, 0.761175f, 0.76534f, - 0.769529f, 0.77374f, 0.777975f, 0.782232f, 0.786513f, 0.790818f, 0.795146f, 0.799497f, 0.803873f, 0.808272f, - 0.812696f, 0.817144f, 0.821616f, 0.826112f, 0.830633f, 0.835179f, 0.83975f, 0.844346f, 0.848966f, 0.853613f, - 0.858284f, 0.862982f, 0.867704f, 0.872453f, 0.877228f, 0.882029f, 0.886856f, 0.891709f, 0.89659f, 0.901496f, - 0.90643f, 0.911391f, 0.916379f, 0.921394f, 0.926436f, 0.931507f, 0.936604f, 0.94173f, 0.946884f, 0.952066f, - 0.957277f, 0.962516f, 0.967783f, 0.97308f, 0.978405f, 0.98376f, 0.989144f, 0.994557f, 1.0f, 1.005473f, - 1.010975f, 1.016508f, 1.022071f, 1.027665f, 1.033289f, 1.038944f, 1.04463f, 1.050347f, 1.056095f, 1.061875f, - 1.067687f, 1.07353f, 1.079405f, 1.085312f, 1.091252f, 1.097224f, 1.103229f, 1.109267f, 1.115337f, 1.121441f, - 1.127579f, 1.13375f, 1.139955f, 1.146193f, 1.152466f, 1.158773f, 1.165115f, 1.171491f, 1.177903f, 1.184349f, - 1.190831f, 1.197348f, 1.203901f, 1.210489f, 1.217114f, 1.223775f, 1.230473f, 1.237207f, 1.243978f, 1.250786f, - 1.257631f, 1.264514f, 1.271434f, 1.278392f, 1.285389f, 1.292423f, 1.299497f, 1.306608f, 1.313759f, 1.320949f, - 1.328178f, 1.335447f, 1.342756f, 1.350104f, 1.357493f, 1.364922f, 1.372392f, 1.379903f, 1.387455f, 1.395048f, - 1.402683f, 1.41036f, 1.418078f, 1.425839f, 1.433642f, 1.441488f, 1.449377f, 1.457309f, 1.465285f, 1.473304f, - 1.481367f, 1.489474f, 1.497626f, 1.505822f, 1.514063f, 1.522349f, 1.530681f, 1.539058f, 1.547481f, 1.55595f, - 1.564465f, 1.573027f, 1.581636f, 1.590292f, 1.598995f, 1.607746f, 1.616545f, 1.625392f, 1.634287f, 1.643231f, - 1.652224f, 1.661266f, 1.670358f, 1.6795f, 1.688691f, 1.697933f, 1.707225f, 1.716569f, 1.725963f, 1.735409f, - 1.744906f, 1.754456f, 1.764058f, 1.773712f, 1.783419f, 1.793179f, 1.802993f, 1.81286f, 1.822782f, 1.832757f, - 1.842788f, 1.852873f, 1.863013f, 1.873209f, 1.883461f, 1.893768f, 1.904132f, 1.914553f, 1.925031f, 1.935567f, - 1.946159f, 1.95681f, 1.96752f, 1.978287f, 1.989114f, 2.0f, -}; - -f32 gBendPitchTwoSemitonesFrequencies[] = { - 0.890899f, 0.890899f, 0.89171f, 0.892521f, 0.893333f, 0.894146f, 0.89496f, 0.895774f, 0.89659f, 0.897406f, - 0.898222f, 0.89904f, 0.899858f, 0.900677f, 0.901496f, 0.902317f, 0.903138f, 0.90396f, 0.904783f, 0.905606f, - 0.90643f, 0.907255f, 0.908081f, 0.908907f, 0.909734f, 0.910562f, 0.911391f, 0.91222f, 0.91305f, 0.913881f, - 0.914713f, 0.915545f, 0.916379f, 0.917213f, 0.918047f, 0.918883f, 0.919719f, 0.920556f, 0.921394f, 0.922232f, - 0.923072f, 0.923912f, 0.924752f, 0.925594f, 0.926436f, 0.927279f, 0.928123f, 0.928968f, 0.929813f, 0.93066f, - 0.931507f, 0.932354f, 0.933203f, 0.934052f, 0.934902f, 0.935753f, 0.936604f, 0.937457f, 0.93831f, 0.939164f, - 0.940019f, 0.940874f, 0.94173f, 0.942587f, 0.943445f, 0.944304f, 0.945163f, 0.946023f, 0.946884f, 0.947746f, - 0.948608f, 0.949472f, 0.950336f, 0.951201f, 0.952066f, 0.952933f, 0.9538f, 0.954668f, 0.955537f, 0.956406f, - 0.957277f, 0.958148f, 0.95902f, 0.959893f, 0.960766f, 0.961641f, 0.962516f, 0.963392f, 0.964268f, 0.965146f, - 0.966024f, 0.966903f, 0.967783f, 0.968664f, 0.969546f, 0.970428f, 0.971311f, 0.972195f, 0.97308f, 0.973965f, - 0.974852f, 0.975739f, 0.976627f, 0.977516f, 0.978405f, 0.979296f, 0.980187f, 0.981079f, 0.981972f, 0.982865f, - 0.98376f, 0.984655f, 0.985551f, 0.986448f, 0.987346f, 0.988244f, 0.989144f, 0.990044f, 0.990945f, 0.991847f, - 0.992749f, 0.993653f, 0.994557f, 0.995462f, 0.996368f, 0.997275f, 0.998182f, 0.999091f, 1.0f, 1.00091f, - 1.001821f, 1.002733f, 1.003645f, 1.004559f, 1.005473f, 1.006388f, 1.007304f, 1.00822f, 1.009138f, 1.010056f, - 1.010975f, 1.011896f, 1.012816f, 1.013738f, 1.014661f, 1.015584f, 1.016508f, 1.017433f, 1.018359f, 1.019286f, - 1.020214f, 1.021142f, 1.022071f, 1.023002f, 1.023933f, 1.024864f, 1.025797f, 1.026731f, 1.027665f, 1.0286f, - 1.029536f, 1.030473f, 1.031411f, 1.03235f, 1.033289f, 1.03423f, 1.035171f, 1.036113f, 1.037056f, 1.038f, - 1.038944f, 1.03989f, 1.040836f, 1.041783f, 1.042731f, 1.04368f, 1.04463f, 1.045581f, 1.046532f, 1.047485f, - 1.048438f, 1.049392f, 1.050347f, 1.051303f, 1.05226f, 1.053217f, 1.054176f, 1.055135f, 1.056095f, 1.057056f, - 1.058018f, 1.058981f, 1.059945f, 1.06091f, 1.061875f, 1.062842f, 1.063809f, 1.064777f, 1.065746f, 1.066716f, - 1.067687f, 1.068658f, 1.069631f, 1.070604f, 1.071578f, 1.072554f, 1.07353f, 1.074507f, 1.075485f, 1.076463f, - 1.077443f, 1.078424f, 1.079405f, 1.080387f, 1.08137f, 1.082355f, 1.08334f, 1.084325f, 1.085312f, 1.0863f, - 1.087289f, 1.088278f, 1.089268f, 1.09026f, 1.091252f, 1.092245f, 1.093239f, 1.094234f, 1.09523f, 1.096226f, - 1.097224f, 1.098223f, 1.099222f, 1.100222f, 1.101224f, 1.102226f, 1.103229f, 1.104233f, 1.105238f, 1.106244f, - 1.10725f, 1.108258f, 1.109267f, 1.110276f, 1.111287f, 1.112298f, 1.11331f, 1.114323f, 1.115337f, 1.116352f, - 1.117368f, 1.118385f, 1.119403f, 1.120422f, 1.121441f, 1.122462f, -}; - -f32 gPitchFrequencies[] = { - /* 0x00 */ 0.105112f, // PITCH_A0 - /* 0x01 */ 0.111362f, // PITCH_BFLAT0 - /* 0x02 */ 0.117984f, // PITCH_B0 - /* 0x03 */ 0.125f, // PITCH_C1 - /* 0x04 */ 0.132433f, // PITCH_DFLAT1 - /* 0x05 */ 0.140308f, // PITCH_D1 - /* 0x06 */ 0.148651f, // PITCH_EFLAT1 - /* 0x07 */ 0.15749f, // PITCH_E1 - /* 0x08 */ 0.166855f, // PITCH_F1 - /* 0x09 */ 0.176777f, // PITCH_GFLAT1 - /* 0x0A */ 0.187288f, // PITCH_G1 - /* 0x0B */ 0.198425f, // PITCH_AFLAT1 - /* 0x0C */ 0.210224f, // PITCH_A1 - /* 0x0D */ 0.222725f, // PITCH_BFLAT1 - /* 0x0E */ 0.235969f, // PITCH_B1 - /* 0x0F */ 0.25f, // PITCH_C2 - /* 0x10 */ 0.264866f, // PITCH_DFLAT2 - /* 0x11 */ 0.280616f, // PITCH_D2 - /* 0x12 */ 0.297302f, // PITCH_EFLAT2 - /* 0x13 */ 0.31498f, // PITCH_E2 - /* 0x14 */ 0.33371f, // PITCH_F2 - /* 0x15 */ 0.353553f, // PITCH_GFLAT2 - /* 0x16 */ 0.374577f, // PITCH_G2 - /* 0x17 */ 0.39685f, // PITCH_AFLAT2 - /* 0x18 */ 0.420448f, // PITCH_A2 - /* 0x19 */ 0.445449f, // PITCH_BFLAT2 - /* 0x1A */ 0.471937f, // PITCH_B2 - /* 0x1B */ 0.5f, // PITCH_C3 - /* 0x1C */ 0.529732f, // PITCH_DFLAT3 - /* 0x1D */ 0.561231f, // PITCH_D3 - /* 0x1E */ 0.594604f, // PITCH_EFLAT3 - /* 0x1F */ 0.629961f, // PITCH_E3 - /* 0x20 */ 0.66742f, // PITCH_F3 - /* 0x21 */ 0.707107f, // PITCH_GFLAT3 - /* 0x22 */ 0.749154f, // PITCH_G3 - /* 0x23 */ 0.793701f, // PITCH_AFLAT3 - /* 0x24 */ 0.840897f, // PITCH_A3 - /* 0x25 */ 0.890899f, // PITCH_BFLAT3 - /* 0x26 */ 0.943875f, // PITCH_B3 - /* 0x27 */ 1.0f, // PITCH_C4 (Middle C) - /* 0x28 */ 1.059463f, // PITCH_DFLAT4 - /* 0x29 */ 1.122462f, // PITCH_D4 - /* 0x2A */ 1.189207f, // PITCH_EFLAT4 - /* 0x2B */ 1.259921f, // PITCH_E4 - /* 0x2C */ 1.33484f, // PITCH_F4 - /* 0x2D */ 1.414214f, // PITCH_GFLAT4 - /* 0x2E */ 1.498307f, // PITCH_G4 - /* 0x2F */ 1.587401f, // PITCH_AFLAT4 - /* 0x30 */ 1.681793f, // PITCH_A4 - /* 0x31 */ 1.781798f, // PITCH_BFLAT4 - /* 0x32 */ 1.887749f, // PITCH_B4 - /* 0x33 */ 2.0f, // PITCH_C5 - /* 0x34 */ 2.118926f, // PITCH_DFLAT5 - /* 0x35 */ 2.244924f, // PITCH_D5 - /* 0x36 */ 2.378414f, // PITCH_EFLAT5 - /* 0x37 */ 2.519842f, // PITCH_E5 - /* 0x38 */ 2.66968f, // PITCH_F5 - /* 0x39 */ 2.828428f, // PITCH_GFLAT5 - /* 0x3A */ 2.996615f, // PITCH_G5 - /* 0x3B */ 3.174803f, // PITCH_AFLAT5 - /* 0x3C */ 3.363586f, // PITCH_A5 - /* 0x3D */ 3.563596f, // PITCH_BFLAT5 - /* 0x3E */ 3.775498f, // PITCH_B5 - /* 0x3F */ 4.0f, // PITCH_C6 - /* 0x40 */ 4.237853f, // PITCH_DFLAT6 - /* 0x41 */ 4.489849f, // PITCH_D6 - /* 0x42 */ 4.756829f, // PITCH_EFLAT6 - /* 0x43 */ 5.039685f, // PITCH_E6 - /* 0x44 */ 5.33936f, // PITCH_F6 - /* 0x45 */ 5.656855f, // PITCH_GFLAT6 - /* 0x46 */ 5.993229f, // PITCH_G6 - /* 0x47 */ 6.349606f, // PITCH_AFLAT6 - /* 0x48 */ 6.727173f, // PITCH_A6 - /* 0x49 */ 7.127192f, // PITCH_BFLAT6 - /* 0x4A */ 7.550996f, // PITCH_B6 - /* 0x4B */ 8.0f, // PITCH_C7 - /* 0x4C */ 8.475705f, // PITCH_DFLAT7 - /* 0x4D */ 8.979697f, // PITCH_D7 - /* 0x4E */ 9.513658f, // PITCH_EFLAT7 - /* 0x4F */ 10.07937f, // PITCH_E7 - /* 0x50 */ 10.6787205f, // PITCH_F7 - /* 0x51 */ 11.31371f, // PITCH_GFLAT7 - /* 0x52 */ 11.986459f, // PITCH_G7 - /* 0x53 */ 12.699211f, // PITCH_AFLAT7 - /* 0x54 */ 13.454346f, // PITCH_A7 - /* 0x55 */ 14.254383f, // PITCH_BFLAT7 - /* 0x56 */ 15.101993f, // PITCH_B7 - /* 0x57 */ 16.0f, // PITCH_C8 - /* 0x58 */ 16.95141f, // PITCH_DFLAT8 - /* 0x59 */ 17.959395f, // PITCH_D8 - /* 0x5A */ 19.027315f, // PITCH_EFLAT8 - /* 0x5B */ 20.15874f, // PITCH_E8 - /* 0x5C */ 21.35744f, // PITCH_F8 - /* 0x5D */ 22.62742f, // PITCH_GFLAT8 - /* 0x5E */ 23.972918f, // PITCH_G8 - /* 0x5F */ 25.398422f, // PITCH_AFLAT8 - /* 0x60 */ 26.908691f, // PITCH_A8 - /* 0x61 */ 28.508766f, // PITCH_BFLAT8 - /* 0x62 */ 30.203985f, // PITCH_B8 - /* 0x63 */ 32.0f, // PITCH_C9 - /* 0x64 */ 33.90282f, // PITCH_DFLAT9 - /* 0x65 */ 35.91879f, // PITCH_D9 - /* 0x66 */ 38.05463f, // PITCH_EFLAT9 - /* 0x67 */ 40.31748f, // PITCH_E9 - /* 0x68 */ 42.71488f, // PITCH_F9 - /* 0x69 */ 45.25484f, // PITCH_GFLAT9 - /* 0x6A */ 47.945835f, // PITCH_G9 - /* 0x6B */ 50.796845f, // PITCH_AFLAT9 - /* 0x6C */ 53.817383f, // PITCH_A9 - /* 0x6D */ 57.017532f, // PITCH_BFLAT9 - /* 0x6E */ 60.40797f, // PITCH_B9 - /* 0x6F */ 64.0f, // PITCH_C10 - /* 0x70 */ 67.80564f, // PITCH_DFLAT10 - /* 0x71 */ 71.83758f, // PITCH_D10 - /* 0x72 */ 76.10926f, // PITCH_EFLAT10 - /* 0x73 */ 80.63496f, // PITCH_E10 - /* 0x74 */ 85.42976f, // PITCH_F10 - /* 0x75 */ 0.055681f, // PITCH_BFLATNEG1 - /* 0x76 */ 0.058992f, // PITCH_BNEG1 - /* 0x77 */ 0.0625f, // PITCH_C0 - /* 0x78 */ 0.066216f, // PITCH_DFLAT0 - /* 0x79 */ 0.070154f, // PITCH_D0 - /* 0x7A */ 0.074325f, // PITCH_EFLAT0 - /* 0x7B */ 0.078745f, // PITCH_E0 - /* 0x7C */ 0.083427f, // PITCH_F0 - /* 0x7D */ 0.088388f, // PITCH_GFLAT0 - /* 0x7E */ 0.093644f, // PITCH_G0 - /* 0x7F */ 0.099213f, // PITCH_AFLAT0 -}; - -u8 gDefaultShortNoteVelocityTable[] = { - 12, 25, 38, 51, 57, 64, 71, 76, 83, 89, 96, 102, 109, 115, 121, 127, -}; - -u8 gDefaultShortNoteGateTimeTable[] = { - 229, 203, 177, 151, 139, 126, 113, 100, 87, 74, 61, 48, 36, 23, 10, 0, -}; - -EnvelopePoint gDefaultEnvelope[] = { - { 1, 32000 }, - { 1000, 32000 }, - { ADSR_HANG, 0 }, - { ADSR_DISABLE, 0 }, -}; - -NoteSubEu gZeroNoteSub = { 0 }; - -NoteSubEu gDefaultNoteSub = { - { 1, 1, 0, 0, 0, 0, 0, 0 }, { 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, -}; - -u16 gHaasEffectDelaySizes[64] = { - 30 * SAMPLE_SIZE, - 29 * SAMPLE_SIZE, - 28 * SAMPLE_SIZE, - 27 * SAMPLE_SIZE, - 26 * SAMPLE_SIZE, - 25 * SAMPLE_SIZE, - 24 * SAMPLE_SIZE, - 23 * SAMPLE_SIZE, - 22 * SAMPLE_SIZE, - 21 * SAMPLE_SIZE, - 20 * SAMPLE_SIZE, - 19 * SAMPLE_SIZE, - 18 * SAMPLE_SIZE, - 17 * SAMPLE_SIZE, - 16 * SAMPLE_SIZE, - 15 * SAMPLE_SIZE, - 14 * SAMPLE_SIZE, - 13 * SAMPLE_SIZE, - 12 * SAMPLE_SIZE, - 11 * SAMPLE_SIZE, - 10 * SAMPLE_SIZE, - 9 * SAMPLE_SIZE, - 8 * SAMPLE_SIZE, - 7 * SAMPLE_SIZE, - 6 * SAMPLE_SIZE, - 5 * SAMPLE_SIZE, - 4 * SAMPLE_SIZE, - 3 * SAMPLE_SIZE, - 2 * SAMPLE_SIZE, - 1 * SAMPLE_SIZE, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -}; - -s32 D_8012FBA4 = 0; - -// clang-format off -s16 D_8012FBA8[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 500, 0, 0, 0, 0, - 0, 0, 0, 500, 0, 0, 0, 0, - 0, 0, 0, 500, 0, 0, 0, 0, - 0, 0, 0, 500, 0, 0, 0, 0, -}; -// clang-format on - -f32 gHeadsetPanVolume[] = { - 1.0f, 0.995386f, 0.990772f, 0.986157f, 0.981543f, 0.976929f, 0.972315f, 0.967701f, 0.963087f, 0.958472f, - 0.953858f, 0.949244f, 0.94463f, 0.940016f, 0.935402f, 0.930787f, 0.926173f, 0.921559f, 0.916945f, 0.912331f, - 0.907717f, 0.903102f, 0.898488f, 0.893874f, 0.88926f, 0.884646f, 0.880031f, 0.875417f, 0.870803f, 0.866189f, - 0.861575f, 0.856961f, 0.852346f, 0.847732f, 0.843118f, 0.838504f, 0.83389f, 0.829276f, 0.824661f, 0.820047f, - 0.815433f, 0.810819f, 0.806205f, 0.801591f, 0.796976f, 0.792362f, 0.787748f, 0.783134f, 0.77852f, 0.773906f, - 0.769291f, 0.764677f, 0.760063f, 0.755449f, 0.750835f, 0.74622f, 0.741606f, 0.736992f, 0.732378f, 0.727764f, - 0.72315f, 0.718535f, 0.713921f, 0.709307f, 0.70537f, 0.70211f, 0.69885f, 0.695591f, 0.692331f, 0.689071f, - 0.685811f, 0.682551f, 0.679291f, 0.676031f, 0.672772f, 0.669512f, 0.666252f, 0.662992f, 0.659732f, 0.656472f, - 0.653213f, 0.649953f, 0.646693f, 0.643433f, 0.640173f, 0.636913f, 0.633654f, 0.630394f, 0.627134f, 0.623874f, - 0.620614f, 0.617354f, 0.614094f, 0.610835f, 0.607575f, 0.604315f, 0.601055f, 0.597795f, 0.594535f, 0.591276f, - 0.588016f, 0.584756f, 0.581496f, 0.578236f, 0.574976f, 0.571717f, 0.568457f, 0.565197f, 0.561937f, 0.558677f, - 0.555417f, 0.552157f, 0.548898f, 0.545638f, 0.542378f, 0.539118f, 0.535858f, 0.532598f, 0.529339f, 0.526079f, - 0.522819f, 0.519559f, 0.516299f, 0.513039f, 0.50978f, 0.50652f, 0.50326f, 0.5f, -}; - -f32 gStereoPanVolume[] = { - 0.707f, 0.716228f, 0.725457f, 0.734685f, 0.743913f, 0.753142f, 0.76237f, 0.771598f, 0.780827f, 0.790055f, - 0.799283f, 0.808512f, 0.81774f, 0.826968f, 0.836197f, 0.845425f, 0.854654f, 0.863882f, 0.87311f, 0.882339f, - 0.891567f, 0.900795f, 0.910024f, 0.919252f, 0.92848f, 0.937709f, 0.946937f, 0.956165f, 0.965394f, 0.974622f, - 0.98385f, 0.993079f, 0.997693f, 0.988465f, 0.979236f, 0.970008f, 0.960779f, 0.951551f, 0.942323f, 0.933095f, - 0.923866f, 0.914638f, 0.905409f, 0.896181f, 0.886953f, 0.877724f, 0.868496f, 0.859268f, 0.850039f, 0.840811f, - 0.831583f, 0.822354f, 0.813126f, 0.803898f, 0.794669f, 0.785441f, 0.776213f, 0.766984f, 0.757756f, 0.748528f, - 0.739299f, 0.730071f, 0.720843f, 0.711614f, 0.695866f, 0.673598f, 0.651331f, 0.629063f, 0.606795f, 0.584528f, - 0.56226f, 0.539992f, 0.517724f, 0.495457f, 0.473189f, 0.450921f, 0.428654f, 0.406386f, 0.384118f, 0.36185f, - 0.339583f, 0.317315f, 0.295047f, 0.27278f, 0.250512f, 0.228244f, 0.205976f, 0.183709f, 0.161441f, 0.139173f, - 0.116905f, 0.094638f, 0.07237f, 0.050102f, 0.027835f, 0.005567f, 0.00835f, 0.019484f, 0.030618f, 0.041752f, - 0.052886f, 0.06402f, 0.075154f, 0.086287f, 0.097421f, 0.108555f, 0.119689f, 0.130823f, 0.141957f, 0.153091f, - 0.164224f, 0.175358f, 0.186492f, 0.197626f, 0.20876f, 0.219894f, 0.231028f, 0.242161f, 0.253295f, 0.264429f, - 0.275563f, 0.286697f, 0.297831f, 0.308965f, 0.320098f, 0.331232f, 0.342366f, 0.3535f, -}; - -f32 gDefaultPanVolume[] = { - 1.0f, 0.999924f, 0.999694f, 0.999312f, 0.998776f, 0.998088f, 0.997248f, 0.996254f, 0.995109f, 0.993811f, - 0.992361f, 0.990759f, 0.989006f, 0.987101f, 0.985045f, 0.982839f, 0.980482f, 0.977976f, 0.97532f, 0.972514f, - 0.96956f, 0.966457f, 0.963207f, 0.959809f, 0.956265f, 0.952574f, 0.948737f, 0.944755f, 0.940629f, 0.936359f, - 0.931946f, 0.92739f, 0.922692f, 0.917853f, 0.912873f, 0.907754f, 0.902497f, 0.897101f, 0.891567f, 0.885898f, - 0.880093f, 0.874153f, 0.868079f, 0.861873f, 0.855535f, 0.849066f, 0.842467f, 0.835739f, 0.828884f, 0.821901f, - 0.814793f, 0.807561f, 0.800204f, 0.792725f, 0.785125f, 0.777405f, 0.769566f, 0.76161f, 0.753536f, 0.745348f, - 0.737045f, 0.72863f, 0.720103f, 0.711466f, 0.70272f, 0.693867f, 0.684908f, 0.675843f, 0.666676f, 0.657406f, - 0.648036f, 0.638567f, 0.629f, 0.619337f, 0.609579f, 0.599728f, 0.589785f, 0.579752f, 0.56963f, 0.559421f, - 0.549126f, 0.538748f, 0.528287f, 0.517745f, 0.507124f, 0.496425f, 0.485651f, 0.474802f, 0.46388f, 0.452888f, - 0.441826f, 0.430697f, 0.419502f, 0.408243f, 0.396921f, 0.385538f, 0.374097f, 0.362598f, 0.351044f, 0.339436f, - 0.327776f, 0.316066f, 0.304308f, 0.292503f, 0.280653f, 0.268761f, 0.256827f, 0.244854f, 0.232844f, 0.220798f, - 0.208718f, 0.196606f, 0.184465f, 0.172295f, 0.160098f, 0.147877f, 0.135634f, 0.12337f, 0.111087f, 0.098786f, - 0.086471f, 0.074143f, 0.061803f, 0.049454f, 0.037097f, 0.024734f, 0.012368f, 0.0f, -}; - -s16 gLowPassFilterData[16 * 8] = { - /* 0x0 */ 0, 0, 0, 32767, 0, 0, 0, 0, // Identity filter (delta function) - /* 0x1 */ 3854, 4188, 4398, 4469, 4398, 4188, 3854, 3416, - /* 0x2 */ 3415, 4314, 4915, 5126, 4915, 4314, 3415, 2351, - /* 0x3 */ 2636, 4433, 5762, 6252, 5762, 4433, 2636, 849, - /* 0x4 */ 1334, 4196, 6646, 7609, 6646, 4196, 1334, -802, - /* 0x5 */ -265, 3421, 7292, 8944, 7292, 3421, -265, -1863, - /* 0x6 */ -1558, 2065, 7146, 9546, 7146, 2065, -1558, -1682, - /* 0x7 */ -2353, 726, 7441, 11028, 7441, 726, -2353, -697, - /* 0x8 */ -2252, -693, 7121, 11962, 7121, -693, -2252, 668, - /* 0x9 */ -1373, -1819, 6299, 12298, 6299, -1819, -1373, 1484, - /* 0xA */ -213, -2740, 5843, 13680, 5843, -2740, -213, 1494, - /* 0xB */ 980, -3081, 4883, 14286, 4883, -3081, 980, 590, - /* 0xC */ 1769, -2973, 3866, 14981, 3866, -2973, 1769, -568, - /* 0xD */ 2023, -2554, 2911, 16397, 2911, -2554, 2023, -1391, - /* 0xE */ 1766, -1918, 2016, 19800, 2016, -1918, 1766, -1564, - /* 0xF */ 841, -853, 863, 26829, 863, -853, 841, -820, -}; - -s16 gHighPassFilterData[15 * 8] = { - /* 0x0 */ -289, -291, -289, 30736, -289, -291, -289, -290, - /* 0x1 */ -464, -467, -467, 29506, -467, -467, -464, -463, - /* 0x2 */ -662, -670, -672, 28101, -672, -670, -662, -656, - /* 0x3 */ -839, -855, -861, 26830, -861, -855, -839, -822, - /* 0x4 */ -996, -1024, -1038, 25685, -1038, -1024, -996, -963, - /* 0x5 */ -1184, -1236, -1266, 24272, -1266, -1236, -1184, -1118, - /* 0x6 */ -1357, -1450, -1506, 22900, -1506, -1450, -1357, -1238, - /* 0x7 */ -1514, -1680, -1784, 21498, -1784, -1680, -1514, -1307, - /* 0x8 */ -1613, -1877, -2048, 20390, -2048, -1877, -1613, -1298, - /* 0x9 */ -1657, -2185, -2559, 18869, -2559, -2185, -1657, -1093, - /* 0xA */ -1524, -2395, -3078, 18030, -3078, -2395, -1524, -739, - /* 0xB */ -1253, -2504, -3621, 17642, -3621, -2504, -1253, -367, - /* 0xC */ -525, -2367, -4732, 17517, -4732, -2367, -525, 0, - /* 0xD */ -34, -1762, -5706, 17503, -5706, -1762, -34, -258, - /* 0xE */ -772, -3, -6985, 17240, -6985, -3, -772, -3, -}; - -s16 D_80130418[8 * 8] = { - /* 0x0 */ 0, 6392, 12539, 18204, 23169, 27244, 30272, 32137, - /* 0x1 */ 32767, 32137, 30272, 27244, 23169, 18204, 12539, 6392, - /* 0x2 */ 0, -3211, -6392, -9511, -12539, -15446, -18204, -20787, - /* 0x3 */ -23169, -25329, -27244, -28897, -30272, -31356, -32137, -32609, - /* 0x4 */ -32767, -32609, -32137, -31356, -30272, -28897, -27244, -25329, - /* 0x5 */ -23169, -25329, -27244, -28897, -30272, -31356, -32137, -32609, - /* 0x6 */ -32767, -32609, -32137, -31356, -30272, -28897, -27244, -25329, - /* 0x7 */ -23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211, -}; diff --git a/src/code/audio_effects.c b/src/code/audio_effects.c deleted file mode 100644 index 6844d8ae5..000000000 --- a/src/code/audio_effects.c +++ /dev/null @@ -1,337 +0,0 @@ -#include "ultra64.h" -#include "global.h" - -void Audio_SequenceChannelProcessSound(SequenceChannel* channel, s32 recalculateVolume, s32 applyBend) { - f32 channelVolume; - f32 chanFreqScale; - s32 i; - - if (channel->changes.s.volume || recalculateVolume) { - channelVolume = channel->volume * channel->volumeScale * channel->seqPlayer->appliedFadeVolume; - if (channel->seqPlayer->muted && (channel->muteBehavior & MUTE_BEHAVIOR_SOFTEN)) { - channelVolume = channel->seqPlayer->muteVolumeScale * channelVolume; - } - channel->appliedVolume = channelVolume * channelVolume; - } - - if (channel->changes.s.pan) { - channel->pan = channel->newPan * channel->panChannelWeight; - } - - chanFreqScale = channel->freqScale; - if (applyBend) { - chanFreqScale *= channel->seqPlayer->bend; - channel->changes.s.freqScale = true; - } - - for (i = 0; i < 4; i++) { - SequenceLayer* layer = channel->layers[i]; - - if (layer != NULL && layer->enabled && layer->note != NULL) { - if (layer->notePropertiesNeedInit) { - layer->noteFreqScale = layer->freqScale * chanFreqScale; - layer->noteVelocity = layer->velocitySquare2 * channel->appliedVolume; - layer->notePan = (channel->pan + layer->pan * (0x80 - channel->panChannelWeight)) >> 7; - layer->notePropertiesNeedInit = false; - } else { - if (channel->changes.s.freqScale) { - layer->noteFreqScale = layer->freqScale * chanFreqScale; - } - if (channel->changes.s.volume || recalculateVolume) { - layer->noteVelocity = layer->velocitySquare2 * channel->appliedVolume; - } - if (channel->changes.s.pan) { - layer->notePan = (channel->pan + layer->pan * (0x80 - channel->panChannelWeight)) >> 7; - } - } - } - } - channel->changes.asByte = 0; -} - -void Audio_SequencePlayerProcessSound(SequencePlayer* seqPlayer) { - s32 i; - - if (seqPlayer->fadeTimer != 0) { - seqPlayer->fadeVolume += seqPlayer->fadeVelocity; - seqPlayer->recalculateVolume = true; - - if (seqPlayer->fadeVolume > 1.0f) { - seqPlayer->fadeVolume = 1.0f; - } - if (seqPlayer->fadeVolume < 0.0f) { - seqPlayer->fadeVolume = 0.0f; - } - - seqPlayer->fadeTimer--; - if (seqPlayer->fadeTimer == 0 && seqPlayer->state == 2) { - AudioSeq_SequencePlayerDisable(seqPlayer); - return; - } - } - - if (seqPlayer->recalculateVolume) { - seqPlayer->appliedFadeVolume = seqPlayer->fadeVolume * seqPlayer->fadeVolumeScale; - } - - for (i = 0; i < 16; i++) { - if (seqPlayer->channels[i]->enabled == 1) { - Audio_SequenceChannelProcessSound(seqPlayer->channels[i], seqPlayer->recalculateVolume, - seqPlayer->applyBend); - } - } - - seqPlayer->recalculateVolume = false; -} - -f32 Audio_GetPortamentoFreqScale(Portamento* portamento) { - u32 loResCur; - f32 portamentoFreq; - - portamento->cur += portamento->speed; - loResCur = (portamento->cur >> 8) & 0xFF; - - if (loResCur >= 127) { - loResCur = 127; - portamento->mode = 0; - } - - portamentoFreq = 1.0f + portamento->extent * (gBendPitchOneOctaveFrequencies[loResCur + 128] - 1.0f); - - return portamentoFreq; -} - -s16 Audio_GetVibratoPitchChange(VibratoState* vib) { - s32 index; - - vib->time += (s32)vib->rate; - index = (vib->time >> 10) & 0x3F; - return vib->curve[index]; -} - -f32 Audio_GetVibratoFreqScale(VibratoState* vib) { - static f32 D_80130510 = 0.0f; - static s32 D_80130514 = 0; - f32 pitchChange; - f32 extent; - f32 invExtent; - f32 result; - f32 temp; - SequenceChannel* channel = vib->channel; - - if (vib->delay != 0) { - vib->delay--; - return 1.0f; - } - - //! @bug this probably meant to compare with gAudioCtx.sequenceChannelNone. - //! -1 isn't used as a channel pointer anywhere else. - if (channel != ((SequenceChannel*)(-1))) { - if (vib->extentChangeTimer) { - if (vib->extentChangeTimer == 1) { - vib->extent = (s32)channel->vibratoExtentTarget; - } else { - vib->extent += ((s32)channel->vibratoExtentTarget - vib->extent) / (s32)vib->extentChangeTimer; - } - - vib->extentChangeTimer--; - } else if (channel->vibratoExtentTarget != (s32)vib->extent) { - if ((vib->extentChangeTimer = channel->vibratoExtentChangeDelay) == 0) { - vib->extent = (s32)channel->vibratoExtentTarget; - } - } - - if (vib->rateChangeTimer) { - if (vib->rateChangeTimer == 1) { - vib->rate = (s32)channel->vibratoRateTarget; - } else { - vib->rate += ((s32)channel->vibratoRateTarget - vib->rate) / (s32)vib->rateChangeTimer; - } - - vib->rateChangeTimer--; - } else if (channel->vibratoRateTarget != (s32)vib->rate) { - if ((vib->rateChangeTimer = channel->vibratoRateChangeDelay) == 0) { - vib->rate = (s32)channel->vibratoRateTarget; - } - } - } - - if (vib->extent == 0.0f) { - return 1.0f; - } - - pitchChange = Audio_GetVibratoPitchChange(vib) + 32768.0f; - temp = vib->extent / 4096.0f; - extent = temp + 1.0f; - invExtent = 1.0f / extent; - - result = 1.0f / ((extent - invExtent) * pitchChange / 65536.0f + invExtent); - - D_80130510 += result; - D_80130514++; - - return result; -} - -void Audio_NoteVibratoUpdate(Note* note) { - if (note->playbackState.portamento.mode != 0) { - note->playbackState.portamentoFreqScale = Audio_GetPortamentoFreqScale(¬e->playbackState.portamento); - } - if (note->playbackState.vibratoState.active) { - note->playbackState.vibratoFreqScale = Audio_GetVibratoFreqScale(¬e->playbackState.vibratoState); - } -} - -void Audio_NoteVibratoInit(Note* note) { - VibratoState* vib; - SequenceChannel* channel; - - note->playbackState.vibratoFreqScale = 1.0f; - - vib = ¬e->playbackState.vibratoState; - - vib->active = 1; - vib->time = 0; - - vib->curve = gWaveSamples[2]; - vib->channel = note->playbackState.parentLayer->channel; - channel = vib->channel; - if ((vib->extentChangeTimer = channel->vibratoExtentChangeDelay) == 0) { - vib->extent = (s32)channel->vibratoExtentTarget; - } else { - vib->extent = (s32)channel->vibratoExtentStart; - } - - if ((vib->rateChangeTimer = channel->vibratoRateChangeDelay) == 0) { - vib->rate = (s32)channel->vibratoRateTarget; - } else { - vib->rate = (s32)channel->vibratoRateStart; - } - vib->delay = channel->vibratoDelay; -} - -void Audio_NotePortamentoInit(Note* note) { - note->playbackState.portamentoFreqScale = 1.0f; - note->playbackState.portamento = note->playbackState.parentLayer->portamento; -} - -void Audio_AdsrInit(AdsrState* adsr, EnvelopePoint* envelope, s16* volOut) { - adsr->action.asByte = 0; - adsr->delay = 0; - adsr->envelope = envelope; - adsr->sustain = 0.0f; - adsr->current = 0.0f; - // (An older versions of the audio engine used in Super Mario 64 did - // adsr->volOut = volOut. That line and associated struct member were - // removed, but the function parameter was forgotten and remains.) -} - -f32 Audio_AdsrUpdate(AdsrState* adsr) { - u8 state = adsr->action.s.state; - - switch (state) { - case ADSR_STATE_DISABLED: - return 0.0f; - - case ADSR_STATE_INITIAL: - if (adsr->action.s.hang) { - adsr->action.s.state = ADSR_STATE_HANG; - break; - } - FALLTHROUGH; - case ADSR_STATE_START_LOOP: - adsr->envIndex = 0; - adsr->action.s.state = ADSR_STATE_LOOP; - retry:; - FALLTHROUGH; - case ADSR_STATE_LOOP: - adsr->delay = adsr->envelope[adsr->envIndex].delay; - switch (adsr->delay) { - case ADSR_DISABLE: - adsr->action.s.state = ADSR_STATE_DISABLED; - break; - - case ADSR_HANG: - adsr->action.s.state = ADSR_STATE_HANG; - break; - - case ADSR_GOTO: - adsr->envIndex = adsr->envelope[adsr->envIndex].arg; - goto retry; - - case ADSR_RESTART: - adsr->action.s.state = ADSR_STATE_INITIAL; - break; - - default: - adsr->delay *= gAudioCtx.audioBufferParameters.updatesPerFrameScaled; - if (adsr->delay == 0) { - adsr->delay = 1; - } - adsr->target = adsr->envelope[adsr->envIndex].arg / 32767.0f; - adsr->target = adsr->target * adsr->target; - adsr->velocity = (adsr->target - adsr->current) / adsr->delay; - adsr->action.s.state = ADSR_STATE_FADE; - adsr->envIndex++; - break; - } - if (adsr->action.s.state != ADSR_STATE_FADE) { - break; - } - FALLTHROUGH; - case ADSR_STATE_FADE: - adsr->current += adsr->velocity; - adsr->delay--; - if (adsr->delay <= 0) { - adsr->action.s.state = ADSR_STATE_LOOP; - } - FALLTHROUGH; - case ADSR_STATE_HANG: - break; - - case ADSR_STATE_DECAY: - case ADSR_STATE_RELEASE: - adsr->current -= adsr->fadeOutVel; - if (adsr->sustain != 0.0f && state == ADSR_STATE_DECAY) { - if (adsr->current < adsr->sustain) { - adsr->current = adsr->sustain; - adsr->delay = 128; - adsr->action.s.state = ADSR_STATE_SUSTAIN; - } - break; - } - - if (adsr->current < 0.00001f) { - adsr->current = 0.0f; - adsr->action.s.state = ADSR_STATE_DISABLED; - } - break; - - case ADSR_STATE_SUSTAIN: - adsr->delay--; - if (adsr->delay == 0) { - adsr->action.s.state = ADSR_STATE_RELEASE; - } - break; - } - - if (adsr->action.s.decay) { - adsr->action.s.state = ADSR_STATE_DECAY; - adsr->action.s.decay = false; - } - - if (adsr->action.s.release) { - adsr->action.s.state = ADSR_STATE_RELEASE; - adsr->action.s.release = false; - } - - if (adsr->current < 0.0f) { - return 0.0f; - } - - if (adsr->current > 1.0f) { - return 1.0f; - } - - return adsr->current; -} diff --git a/src/code/audio_external_data.c b/src/code/audio_external_data.c deleted file mode 100644 index 6a4c29eda..000000000 --- a/src/code/audio_external_data.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "ultra64.h" -#include "global.h" - -// sSfxRequests ring buffer endpoints. read index <= write index, wrapping around mod 256. -u8 gSfxRequestWriteIndex = 0; -u8 gSfxRequestReadIndex = 0; - -/** - * Array of pointers to arrays of SfxBankEntry of sizes: 9, 12, 22, 20, 8, 3, 5 - * - * 0 : Player Bank size 9 - * 1 : Item Bank size 12 - * 2 : Environment Bank size 22 - * 3 : Enemy Bank size 20 - * 4 : System Bank size 8 - * 5 : Ocarina Bank size 3 - * 6 : Voice Bank size 5 - */ -SfxBankEntry* gSfxBanks[7] = { - D_8016BAD0, D_8016BC80, D_8016BEC0, D_8016C2E0, D_8016C6A0, D_8016C820, D_8016C8B0, -}; - -u8 gSfxBankSizes[ARRAY_COUNT(gSfxBanks)] = { - ARRAY_COUNT(D_8016BAD0), ARRAY_COUNT(D_8016BC80), ARRAY_COUNT(D_8016BEC0), ARRAY_COUNT(D_8016C2E0), - ARRAY_COUNT(D_8016C6A0), ARRAY_COUNT(D_8016C820), ARRAY_COUNT(D_8016C8B0), -}; - -u8 gSfxChannelLayout = 0; - -u16 D_801333D0 = 0; - -// The center of the screen in projected coordinates. -// Gives the impression that the sfx has no specific location -Vec3f gSfxDefaultPos = { 0.0f, 0.0f, 0.0f }; - -// Reused as either frequency or volume multiplicative scaling factor -// Does not alter or change frequency or volume -f32 gSfxDefaultFreqAndVolScale = 1.0f; - -s32 D_801333E4 = 0; // unused - -// Adds no reverb to the existing reverb -s8 gSfxDefaultReverb = 0; - -s32 D_801333EC = 0; // unused - -u8 D_801333F0 = 0; - -u8 gAudioSfxSwapOff = 0; - -u8 D_801333F8 = 0; - -s32 D_801333FC = 0; // unused - -u8 gSeqCmdWritePos = 0; -u8 gSeqCmdReadPos = 0; -u8 gStartSeqDisabled = false; -u8 gAudioDebugPrintSeqCmd = true; - -u8 gSoundModeList[] = { - SOUNDMODE_STEREO, - SOUNDMODE_HEADSET, - SOUNDMODE_SURROUND, - SOUNDMODE_MONO, -}; - -u8 gAudioSpecId = 0; - -u8 D_80133418 = 0; diff --git a/src/code/audio_heap.c b/src/code/audio_heap.c deleted file mode 100644 index 4b586c8c5..000000000 --- a/src/code/audio_heap.c +++ /dev/null @@ -1,1485 +0,0 @@ -#include "ultra64.h" -#include "global.h" - -void AudioHeap_InitSampleCaches(u32 persistentSampleCacheSize, u32 temporarySampleCacheSize); -SampleCacheEntry* AudioHeap_AllocTemporarySampleCacheEntry(u32 size); -SampleCacheEntry* AudioHeap_AllocPersistentSampleCacheEntry(u32 size); -void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry); -void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, Sample* sample); -void AudioHeap_DiscardSampleCaches(void); -void AudioHeap_DiscardSampleBank(s32 sampleBankId); -void AudioHeap_DiscardSampleBanks(void); - -/** - * Effectively scales `updatesPerFrameInv` by the reciprocal of `scaleInv` - * `updatesPerFrameInvScaled` is just `updatesPerFrameInv` scaled down by a factor of 256.0f - * i.e. (256.0f * `updatesPerFrameInvScaled`) is just `updatesPerFrameInv` - */ -f32 AudioHeap_CalculateAdsrDecay(f32 scaleInv) { - return (256.0f * gAudioCtx.audioBufferParameters.updatesPerFrameInvScaled) / scaleInv; -} - -/** - * Initialize the decay rate table used for decaying notes as part of adsr - */ -void AudioHeap_InitAdsrDecayTable(void) { - s32 i; - - gAudioCtx.adsrDecayTable[255] = AudioHeap_CalculateAdsrDecay(0.25f); - gAudioCtx.adsrDecayTable[254] = AudioHeap_CalculateAdsrDecay(0.33f); - gAudioCtx.adsrDecayTable[253] = AudioHeap_CalculateAdsrDecay(0.5f); - gAudioCtx.adsrDecayTable[252] = AudioHeap_CalculateAdsrDecay(0.66f); - gAudioCtx.adsrDecayTable[251] = AudioHeap_CalculateAdsrDecay(0.75f); - - for (i = 128; i < 251; i++) { - gAudioCtx.adsrDecayTable[i] = AudioHeap_CalculateAdsrDecay(251 - i); - } - - for (i = 16; i < 128; i++) { - gAudioCtx.adsrDecayTable[i] = AudioHeap_CalculateAdsrDecay(4 * (143 - i)); - } - - for (i = 1; i < 16; i++) { - gAudioCtx.adsrDecayTable[i] = AudioHeap_CalculateAdsrDecay(60 * (23 - i)); - } - - gAudioCtx.adsrDecayTable[0] = 0.0f; -} - -void AudioHeap_ResetLoadStatus(void) { - s32 i; - - for (i = 0; i < 0x30; i++) { - if (gAudioCtx.fontLoadStatus[i] != LOAD_STATUS_PERMANENTLY_LOADED) { - gAudioCtx.fontLoadStatus[i] = LOAD_STATUS_NOT_LOADED; - } - } - - for (i = 0; i < 0x30; i++) { - if (gAudioCtx.sampleFontLoadStatus[i] != LOAD_STATUS_PERMANENTLY_LOADED) { - gAudioCtx.sampleFontLoadStatus[i] = LOAD_STATUS_NOT_LOADED; - } - } - - for (i = 0; i < 0x80; i++) { - if (gAudioCtx.seqLoadStatus[i] != LOAD_STATUS_PERMANENTLY_LOADED) { - gAudioCtx.seqLoadStatus[i] = LOAD_STATUS_NOT_LOADED; - } - } -} - -void AudioHeap_DiscardFont(s32 fontId) { - s32 i; - - for (i = 0; i < gAudioCtx.numNotes; i++) { - Note* note = &gAudioCtx.notes[i]; - - if (note->playbackState.fontId == fontId) { - if (note->playbackState.unk_04 == 0 && note->playbackState.priority != 0) { - note->playbackState.parentLayer->enabled = false; - note->playbackState.parentLayer->finished = true; - } - Audio_NoteDisable(note); - Audio_AudioListRemove(¬e->listItem); - AudioSeq_AudioListPushBack(&gAudioCtx.noteFreeLists.disabled, ¬e->listItem); - } - } -} - -void AudioHeap_ReleaseNotesForFont(s32 fontId) { - s32 i; - - for (i = 0; i < gAudioCtx.numNotes; i++) { - Note* note = &gAudioCtx.notes[i]; - NotePlaybackState* playbackState = ¬e->playbackState; - - if (playbackState->fontId == fontId) { - if ((playbackState->priority != 0) && (playbackState->adsr.action.s.state == ADSR_STATE_DECAY)) { - playbackState->priority = 1; - playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; - playbackState->adsr.action.s.release = true; - } - } - } -} - -void AudioHeap_DiscardSequence(s32 seqId) { - s32 i; - - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - if (gAudioCtx.seqPlayers[i].enabled && gAudioCtx.seqPlayers[i].seqId == seqId) { - AudioSeq_SequencePlayerDisable(&gAudioCtx.seqPlayers[i]); - } - } -} - -/** - * Perform a writeback from the data cache to the ram. - */ -void AudioHeap_WritebackDCache(void* ramAddr, u32 size) { - Audio_WritebackDCache(ramAddr, size); -} - -/** - * Attempt to allocate space externally to the audio heap. If no external pool is available, - * then allocate space on the pool provided in the argument. - * The newly allocated space is zero'ed - */ -void* AudioHeap_AllocZeroedAttemptExternal(AudioAllocPool* pool, u32 size) { - void* ramAddr = NULL; - - if (gAudioCtx.externalPool.startRamAddr != NULL) { - ramAddr = AudioHeap_AllocZeroed(&gAudioCtx.externalPool, size); - } - if (ramAddr == NULL) { - ramAddr = AudioHeap_AllocZeroed(pool, size); - } - return ramAddr; -} - -void* AudioHeap_AllocAttemptExternal(AudioAllocPool* pool, u32 size) { - void* ramAddr = NULL; - - if (gAudioCtx.externalPool.startRamAddr != NULL) { - ramAddr = AudioHeap_Alloc(&gAudioCtx.externalPool, size); - } - if (ramAddr == NULL) { - ramAddr = AudioHeap_Alloc(pool, size); - } - return ramAddr; -} - -void* AudioHeap_AllocDmaMemory(AudioAllocPool* pool, u32 size) { - void* ramAddr = AudioHeap_Alloc(pool, size); - - if (ramAddr != NULL) { - AudioHeap_WritebackDCache(ramAddr, size); - } - return ramAddr; -} - -void* AudioHeap_AllocDmaMemoryZeroed(AudioAllocPool* pool, u32 size) { - void* ramAddr; - - ramAddr = AudioHeap_AllocZeroed(pool, size); - if (ramAddr != NULL) { - AudioHeap_WritebackDCache(ramAddr, size); - } - return ramAddr; -} - -/** - * Allocates space on a pool contained within the heap and sets all the allocated space to 0 - */ -void* AudioHeap_AllocZeroed(AudioAllocPool* pool, u32 size) { - u8* ramAddr = AudioHeap_Alloc(pool, size); - u8* ptr; - - if (ramAddr != NULL) { - for (ptr = ramAddr; ptr < pool->curRamAddr; ptr++) { - *ptr = 0; - } - } - - return ramAddr; -} - -void* AudioHeap_Alloc(AudioAllocPool* pool, u32 size) { - u32 aligned = ALIGN16(size); - u8* ramAddr = pool->curRamAddr; - - if (pool->startRamAddr + pool->size >= pool->curRamAddr + aligned) { - pool->curRamAddr += aligned; - } else { - return NULL; - } - pool->numEntries++; - return ramAddr; -} - -/** - * Initialize a pool to allocate memory from the specified address, up to the specified size. - * Store the metadata of this pool in AudioAllocPool* pool - */ -void AudioHeap_InitPool(AudioAllocPool* pool, void* ramAddr, u32 size) { - pool->curRamAddr = pool->startRamAddr = (u8*)ALIGN16((u32)ramAddr); - pool->size = size - ((u32)ramAddr & 0xF); - pool->numEntries = 0; -} - -void AudioHeap_InitPersistentCache(AudioPersistentCache* persistent) { - persistent->pool.numEntries = 0; - persistent->numEntries = 0; - persistent->pool.curRamAddr = persistent->pool.startRamAddr; -} - -void AudioHeap_InitTemporaryCache(AudioTemporaryCache* temporary) { - temporary->pool.numEntries = 0; - temporary->pool.curRamAddr = temporary->pool.startRamAddr; - temporary->nextSide = 0; - temporary->entries[0].ramAddr = temporary->pool.startRamAddr; - temporary->entries[1].ramAddr = temporary->pool.startRamAddr + temporary->pool.size; - temporary->entries[0].id = -1; - temporary->entries[1].id = -1; -} - -void AudioHeap_ResetPool(AudioAllocPool* pool) { - pool->numEntries = 0; - pool->curRamAddr = pool->startRamAddr; -} - -void AudioHeap_PopPersistentCache(s32 tableType) { - AudioCache* loadedCache; - AudioAllocPool* persistentPool; - AudioPersistentCache* persistent; - void* entryRamAddr; - u8* loadStatus; - - switch (tableType) { - case SEQUENCE_TABLE: - loadedCache = &gAudioCtx.seqCache; - loadStatus = gAudioCtx.seqLoadStatus; - break; - - case FONT_TABLE: - loadedCache = &gAudioCtx.fontCache; - loadStatus = gAudioCtx.fontLoadStatus; - break; - - case SAMPLE_TABLE: - loadedCache = &gAudioCtx.sampleBankCache; - loadStatus = gAudioCtx.sampleFontLoadStatus; - break; - } - - persistent = &loadedCache->persistent; - persistentPool = &persistent->pool; - - if (persistent->numEntries == 0) { - return; - } - - entryRamAddr = persistent->entries[persistent->numEntries - 1].ramAddr; - persistentPool->curRamAddr = entryRamAddr; - persistentPool->numEntries--; - - if (tableType == SAMPLE_TABLE) { - AudioHeap_DiscardSampleBank(persistent->entries[persistent->numEntries - 1].id); - } - if (tableType == FONT_TABLE) { - AudioHeap_DiscardFont(persistent->entries[persistent->numEntries - 1].id); - } - - loadStatus[persistent->entries[persistent->numEntries - 1].id] = LOAD_STATUS_NOT_LOADED; - persistent->numEntries--; -} - -void AudioHeap_InitMainPools(s32 initPoolSize) { - AudioHeap_InitPool(&gAudioCtx.initPool, gAudioCtx.audioHeap, initPoolSize); - AudioHeap_InitPool(&gAudioCtx.sessionPool, gAudioCtx.audioHeap + initPoolSize, - gAudioCtx.audioHeapSize - initPoolSize); - gAudioCtx.externalPool.startRamAddr = NULL; -} - -void AudioHeap_InitSessionPools(AudioSessionPoolSplit* split) { - gAudioCtx.sessionPool.curRamAddr = gAudioCtx.sessionPool.startRamAddr; - AudioHeap_InitPool(&gAudioCtx.miscPool, AudioHeap_Alloc(&gAudioCtx.sessionPool, split->miscPoolSize), - split->miscPoolSize); - AudioHeap_InitPool(&gAudioCtx.cachePool, AudioHeap_Alloc(&gAudioCtx.sessionPool, split->cachePoolSize), - split->cachePoolSize); -} - -void AudioHeap_InitCachePools(AudioCachePoolSplit* split) { - gAudioCtx.cachePool.curRamAddr = gAudioCtx.cachePool.startRamAddr; - AudioHeap_InitPool(&gAudioCtx.persistentCommonPool, - AudioHeap_Alloc(&gAudioCtx.cachePool, split->persistentCommonPoolSize), - split->persistentCommonPoolSize); - AudioHeap_InitPool(&gAudioCtx.temporaryCommonPool, - AudioHeap_Alloc(&gAudioCtx.cachePool, split->temporaryCommonPoolSize), - split->temporaryCommonPoolSize); -} - -void AudioHeap_InitPersistentPoolsAndCaches(AudioCommonPoolSplit* split) { - gAudioCtx.persistentCommonPool.curRamAddr = gAudioCtx.persistentCommonPool.startRamAddr; - AudioHeap_InitPool(&gAudioCtx.seqCache.persistent.pool, - AudioHeap_Alloc(&gAudioCtx.persistentCommonPool, split->seqCacheSize), split->seqCacheSize); - AudioHeap_InitPool(&gAudioCtx.fontCache.persistent.pool, - AudioHeap_Alloc(&gAudioCtx.persistentCommonPool, split->fontCacheSize), split->fontCacheSize); - AudioHeap_InitPool(&gAudioCtx.sampleBankCache.persistent.pool, - AudioHeap_Alloc(&gAudioCtx.persistentCommonPool, split->sampleBankCacheSize), - split->sampleBankCacheSize); - AudioHeap_InitPersistentCache(&gAudioCtx.seqCache.persistent); - AudioHeap_InitPersistentCache(&gAudioCtx.fontCache.persistent); - AudioHeap_InitPersistentCache(&gAudioCtx.sampleBankCache.persistent); -} - -void AudioHeap_InitTemporaryPoolsAndCaches(AudioCommonPoolSplit* split) { - gAudioCtx.temporaryCommonPool.curRamAddr = gAudioCtx.temporaryCommonPool.startRamAddr; - AudioHeap_InitPool(&gAudioCtx.seqCache.temporary.pool, - AudioHeap_Alloc(&gAudioCtx.temporaryCommonPool, split->seqCacheSize), split->seqCacheSize); - AudioHeap_InitPool(&gAudioCtx.fontCache.temporary.pool, - AudioHeap_Alloc(&gAudioCtx.temporaryCommonPool, split->fontCacheSize), split->fontCacheSize); - AudioHeap_InitPool(&gAudioCtx.sampleBankCache.temporary.pool, - AudioHeap_Alloc(&gAudioCtx.temporaryCommonPool, split->sampleBankCacheSize), - split->sampleBankCacheSize); - AudioHeap_InitTemporaryCache(&gAudioCtx.seqCache.temporary); - AudioHeap_InitTemporaryCache(&gAudioCtx.fontCache.temporary); - AudioHeap_InitTemporaryCache(&gAudioCtx.sampleBankCache.temporary); -} - -void* AudioHeap_AllocCached(s32 tableType, s32 size, s32 cache, s32 id) { - AudioCache* loadedCache; - AudioTemporaryCache* temporaryCache; - AudioAllocPool* temporaryPool; - void* persistentRamAddr; - void* temporaryRamAddr; - u8 loadStatusEntry0; - u8 loadStatusEntry1; - s32 i; - u8* loadStatus; - s32 side; - - switch (tableType) { - case SEQUENCE_TABLE: - loadedCache = &gAudioCtx.seqCache; - loadStatus = gAudioCtx.seqLoadStatus; - break; - - case FONT_TABLE: - loadedCache = &gAudioCtx.fontCache; - loadStatus = gAudioCtx.fontLoadStatus; - break; - - case SAMPLE_TABLE: - loadedCache = &gAudioCtx.sampleBankCache; - loadStatus = gAudioCtx.sampleFontLoadStatus; - break; - } - - if (cache == CACHE_TEMPORARY) { - temporaryCache = &loadedCache->temporary; - temporaryPool = &temporaryCache->pool; - - if (temporaryPool->size < size) { - return NULL; - } - - loadStatusEntry0 = - (temporaryCache->entries[0].id == -1) ? LOAD_STATUS_NOT_LOADED : loadStatus[temporaryCache->entries[0].id]; - loadStatusEntry1 = - (temporaryCache->entries[1].id == -1) ? LOAD_STATUS_NOT_LOADED : loadStatus[temporaryCache->entries[1].id]; - - if (tableType == FONT_TABLE) { - if (loadStatusEntry0 == LOAD_STATUS_MAYBE_DISCARDABLE) { - for (i = 0; i < gAudioCtx.numNotes; i++) { - if (gAudioCtx.notes[i].playbackState.fontId == temporaryCache->entries[0].id && - gAudioCtx.notes[i].noteSubEu.bitField0.enabled) { - break; - } - } - - if (i == gAudioCtx.numNotes) { - AudioLoad_SetFontLoadStatus(temporaryCache->entries[0].id, LOAD_STATUS_DISCARDABLE); - loadStatusEntry0 = LOAD_STATUS_DISCARDABLE; - } - } - - if (loadStatusEntry1 == LOAD_STATUS_MAYBE_DISCARDABLE) { - for (i = 0; i < gAudioCtx.numNotes; i++) { - if (gAudioCtx.notes[i].playbackState.fontId == temporaryCache->entries[1].id && - gAudioCtx.notes[i].noteSubEu.bitField0.enabled) { - break; - } - } - - if (i == gAudioCtx.numNotes) { - AudioLoad_SetFontLoadStatus(temporaryCache->entries[1].id, LOAD_STATUS_DISCARDABLE); - loadStatusEntry1 = LOAD_STATUS_DISCARDABLE; - } - } - } - - if (loadStatusEntry0 == LOAD_STATUS_NOT_LOADED) { - temporaryCache->nextSide = 0; - } else if (loadStatusEntry1 == LOAD_STATUS_NOT_LOADED) { - temporaryCache->nextSide = 1; - } else if (loadStatusEntry0 == LOAD_STATUS_DISCARDABLE && loadStatusEntry1 == LOAD_STATUS_DISCARDABLE) { - // Use the opposite side from last time. - } else if (loadStatusEntry0 == LOAD_STATUS_DISCARDABLE) { - temporaryCache->nextSide = 0; - } else if (loadStatusEntry1 == LOAD_STATUS_DISCARDABLE) { - temporaryCache->nextSide = 1; - } else { - // Check if there is a side which isn't in active use, if so, evict that one. - if (tableType == SEQUENCE_TABLE) { - if (loadStatusEntry0 == LOAD_STATUS_COMPLETE) { - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - if (gAudioCtx.seqPlayers[i].enabled && - gAudioCtx.seqPlayers[i].seqId == temporaryCache->entries[0].id) { - break; - } - } - - if (i == gAudioCtx.audioBufferParameters.numSequencePlayers) { - temporaryCache->nextSide = 0; - goto done; - } - } - - if (loadStatusEntry1 == LOAD_STATUS_COMPLETE) { - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - if (gAudioCtx.seqPlayers[i].enabled && - gAudioCtx.seqPlayers[i].seqId == temporaryCache->entries[1].id) { - break; - } - } - - if (i == gAudioCtx.audioBufferParameters.numSequencePlayers) { - temporaryCache->nextSide = 1; - goto done; - } - } - } else if (tableType == FONT_TABLE) { - if (loadStatusEntry0 == LOAD_STATUS_COMPLETE) { - for (i = 0; i < gAudioCtx.numNotes; i++) { - if (gAudioCtx.notes[i].playbackState.fontId == temporaryCache->entries[0].id && - gAudioCtx.notes[i].noteSubEu.bitField0.enabled) { - break; - } - } - if (i == gAudioCtx.numNotes) { - temporaryCache->nextSide = 0; - goto done; - } - } - - if (loadStatusEntry1 == LOAD_STATUS_COMPLETE) { - for (i = 0; i < gAudioCtx.numNotes; i++) { - if (gAudioCtx.notes[i].playbackState.fontId == temporaryCache->entries[1].id && - gAudioCtx.notes[i].noteSubEu.bitField0.enabled) { - break; - } - } - if (i == gAudioCtx.numNotes) { - temporaryCache->nextSide = 1; - goto done; - } - } - } - - // No such luck. Evict the side that wasn't chosen last time, except - // if it is being loaded into. - if (temporaryCache->nextSide == 0) { - if (loadStatusEntry0 == LOAD_STATUS_IN_PROGRESS) { - if (loadStatusEntry1 == LOAD_STATUS_IN_PROGRESS) { - goto fail; - } - temporaryCache->nextSide = 1; - } - } else { - if (loadStatusEntry1 == LOAD_STATUS_IN_PROGRESS) { - if (loadStatusEntry0 == LOAD_STATUS_IN_PROGRESS) { - goto fail; - } - temporaryCache->nextSide = 0; - } - } - - if (0) { - fail: - // Both sides are being loaded into. - return NULL; - } - } - done: - - side = temporaryCache->nextSide; - - if (temporaryCache->entries[side].id != -1) { - if (tableType == SAMPLE_TABLE) { - AudioHeap_DiscardSampleBank(temporaryCache->entries[side].id); - } - - loadStatus[temporaryCache->entries[side].id] = LOAD_STATUS_NOT_LOADED; - - if (tableType == FONT_TABLE) { - AudioHeap_DiscardFont(temporaryCache->entries[side].id); - } - } - - switch (side) { - case 0: - temporaryCache->entries[0].ramAddr = temporaryPool->startRamAddr; - temporaryCache->entries[0].id = id; - temporaryCache->entries[0].size = size; - temporaryPool->curRamAddr = temporaryPool->startRamAddr + size; - - if (temporaryCache->entries[1].id != -1 && - temporaryCache->entries[1].ramAddr < temporaryPool->curRamAddr) { - if (tableType == SAMPLE_TABLE) { - AudioHeap_DiscardSampleBank(temporaryCache->entries[1].id); - } - - loadStatus[temporaryCache->entries[1].id] = LOAD_STATUS_NOT_LOADED; - - switch (tableType) { - case SEQUENCE_TABLE: - AudioHeap_DiscardSequence((s32)temporaryCache->entries[1].id); - break; - - case FONT_TABLE: - AudioHeap_DiscardFont((s32)temporaryCache->entries[1].id); - break; - } - - temporaryCache->entries[1].id = -1; - temporaryCache->entries[1].ramAddr = temporaryPool->startRamAddr + temporaryPool->size; - } - - temporaryRamAddr = temporaryCache->entries[0].ramAddr; - break; - - case 1: - temporaryCache->entries[1].ramAddr = - (u8*)((u32)(temporaryPool->startRamAddr + temporaryPool->size - size) & ~0xF); - temporaryCache->entries[1].id = id; - temporaryCache->entries[1].size = size; - if (temporaryCache->entries[0].id != -1 && - temporaryCache->entries[1].ramAddr < temporaryPool->curRamAddr) { - if (tableType == SAMPLE_TABLE) { - AudioHeap_DiscardSampleBank(temporaryCache->entries[0].id); - } - - loadStatus[temporaryCache->entries[0].id] = LOAD_STATUS_NOT_LOADED; - switch (tableType) { - case SEQUENCE_TABLE: - AudioHeap_DiscardSequence(temporaryCache->entries[0].id); - break; - - case FONT_TABLE: - AudioHeap_DiscardFont(temporaryCache->entries[0].id); - break; - } - - temporaryCache->entries[0].id = -1; - temporaryPool->curRamAddr = temporaryPool->startRamAddr; - } - temporaryRamAddr = temporaryCache->entries[1].ramAddr; - break; - - default: - return NULL; - } - - temporaryCache->nextSide ^= 1; - return temporaryRamAddr; - } - - persistentRamAddr = AudioHeap_Alloc(&loadedCache->persistent.pool, size); - loadedCache->persistent.entries[loadedCache->persistent.numEntries].ramAddr = persistentRamAddr; - - if (persistentRamAddr == NULL) { - switch (cache) { - case CACHE_EITHER: - return AudioHeap_AllocCached(tableType, size, CACHE_TEMPORARY, id); - - case CACHE_TEMPORARY: - case CACHE_PERSISTENT: - return NULL; - } - } - - loadedCache->persistent.entries[loadedCache->persistent.numEntries].id = id; - loadedCache->persistent.entries[loadedCache->persistent.numEntries].size = size; - - return loadedCache->persistent.entries[loadedCache->persistent.numEntries++].ramAddr; -} - -void* AudioHeap_SearchCaches(s32 tableType, s32 cache, s32 id) { - void* ramAddr; - - // Always search the permanent cache in addition to the regular ones. - ramAddr = AudioHeap_SearchPermanentCache(tableType, id); - if (ramAddr != NULL) { - return ramAddr; - } - if (cache == CACHE_PERMANENT) { - return NULL; - } - return AudioHeap_SearchRegularCaches(tableType, cache, id); -} - -void* AudioHeap_SearchRegularCaches(s32 tableType, s32 cache, s32 id) { - u32 i; - AudioCache* loadedCache; - AudioTemporaryCache* temporary; - AudioPersistentCache* persistent; - - switch (tableType) { - case SEQUENCE_TABLE: - loadedCache = &gAudioCtx.seqCache; - break; - - case FONT_TABLE: - loadedCache = &gAudioCtx.fontCache; - break; - - case SAMPLE_TABLE: - loadedCache = &gAudioCtx.sampleBankCache; - break; - } - - temporary = &loadedCache->temporary; - if (cache == CACHE_TEMPORARY) { - if (temporary->entries[0].id == id) { - temporary->nextSide = 1; - return temporary->entries[0].ramAddr; - } else if (temporary->entries[1].id == id) { - temporary->nextSide = 0; - return temporary->entries[1].ramAddr; - } else { - return NULL; - } - } - - persistent = &loadedCache->persistent; - for (i = 0; i < persistent->numEntries; i++) { - if (persistent->entries[i].id == id) { - return persistent->entries[i].ramAddr; - } - } - - if (cache == CACHE_EITHER) { - return AudioHeap_SearchCaches(tableType, CACHE_TEMPORARY, id); - } - return NULL; -} - -void func_800DF1D8(f32 p, f32 q, u16* out) { - // With the bug below fixed, this mysterious unused function computes two recurrences - // out[0..7] = a_i, out[8..15] = b_i, where - // a_{-2} = b_{-1} = 262159 = 2^18 + 15 - // a_{-1} = b_{-2} = 0 - // a_i = q * a_{i-1} + p * a_{i-2} - // b_i = q * b_{i-1} + p * b_{i-2} - // These grow exponentially if p < -1 or p + |q| > 1. - s32 i; - f32 tmp[16]; - - tmp[0] = (f32)(q * 262159.0f); - tmp[8] = (f32)(p * 262159.0f); - tmp[1] = (f32)((q * p) * 262159.0f); - tmp[9] = (f32)(((p * p) + q) * 262159.0f); - - for (i = 2; i < 8; i++) { - //! @bug value should be stored to tmp[i] and tmp[8 + i], otherwise we read - //! garbage in later loop iterations. - out[i] = q * tmp[i - 2] + p * tmp[i - 1]; - out[8 + i] = q * tmp[6 + i] + p * tmp[7 + i]; - } - - for (i = 0; i < 16; i++) { - out[i] = tmp[i]; - } -} - -void AudioHeap_ClearFilter(s16* filter) { - s32 i; - - for (i = 0; i < 8; i++) { - filter[i] = 0; - } -} - -void AudioHeap_LoadLowPassFilter(s16* filter, s32 cutoff) { - s32 i; - s16* ptr = &gLowPassFilterData[8 * cutoff]; - - for (i = 0; i < 8; i++) { - filter[i] = ptr[i]; - } -} - -void AudioHeap_LoadHighPassFilter(s16* filter, s32 cutoff) { - s32 i; - s16* ptr = &gHighPassFilterData[8 * (cutoff - 1)]; - - for (i = 0; i < 8; i++) { - filter[i] = ptr[i]; - } -} - -void AudioHeap_LoadFilter(s16* filter, s32 lowPassCutoff, s32 highPassCutoff) { - s32 i; - - if (lowPassCutoff == 0 && highPassCutoff == 0) { - // Identity filter - AudioHeap_LoadLowPassFilter(filter, 0); - } else if (highPassCutoff == 0) { - AudioHeap_LoadLowPassFilter(filter, lowPassCutoff); - } else if (lowPassCutoff == 0) { - AudioHeap_LoadHighPassFilter(filter, highPassCutoff); - } else { - s16* ptr1 = &gLowPassFilterData[8 * lowPassCutoff]; - s16* ptr2 = &gHighPassFilterData[8 * (highPassCutoff - 1)]; - - for (i = 0; i < 8; i++) { - filter[i] = (ptr1[i] + ptr2[i]) / 2; - } - } -} - -void AudioHeap_UpdateReverb(SynthesisReverb* reverb) { -} - -void AudioHeap_UpdateReverbs(void) { - s32 count; - s32 i; - s32 j; - - if (gAudioCtx.audioBufferParameters.specUnk4 == 2) { - count = 2; - } else { - count = 1; - } - - for (i = 0; i < gAudioCtx.numSynthesisReverbs; i++) { - for (j = 0; j < count; j++) { - AudioHeap_UpdateReverb(&gAudioCtx.synthesisReverbs[i]); - } - } -} - -/** - * Clear the current Audio Interface Buffer - */ -void AudioHeap_ClearCurrentAiBuffer(void) { - s32 curAiBufferIndex = gAudioCtx.curAiBufIndex; - s32 i; - - gAudioCtx.aiBufLengths[curAiBufferIndex] = gAudioCtx.audioBufferParameters.minAiBufferLength; - - for (i = 0; i < AIBUF_LEN; i++) { - gAudioCtx.aiBuffers[curAiBufferIndex][i] = 0; - } -} - -s32 AudioHeap_ResetStep(void) { - s32 i; - s32 j; - s32 sp24; - - if (gAudioCtx.audioBufferParameters.specUnk4 == 2) { - sp24 = 2; - } else { - sp24 = 1; - } - - switch (gAudioCtx.resetStatus) { - case 5: - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - AudioSeq_SequencePlayerDisableAsFinished(&gAudioCtx.seqPlayers[i]); - } - gAudioCtx.audioResetFadeOutFramesLeft = 2 / sp24; - gAudioCtx.resetStatus--; - break; - - case 4: - if (gAudioCtx.audioResetFadeOutFramesLeft != 0) { - gAudioCtx.audioResetFadeOutFramesLeft--; - AudioHeap_UpdateReverbs(); - } else { - for (i = 0; i < gAudioCtx.numNotes; i++) { - if (gAudioCtx.notes[i].noteSubEu.bitField0.enabled && - gAudioCtx.notes[i].playbackState.adsr.action.s.state != ADSR_STATE_DISABLED) { - gAudioCtx.notes[i].playbackState.adsr.fadeOutVel = - gAudioCtx.audioBufferParameters.updatesPerFrameInv; - gAudioCtx.notes[i].playbackState.adsr.action.s.release = true; - } - } - gAudioCtx.audioResetFadeOutFramesLeft = 8 / sp24; - gAudioCtx.resetStatus--; - } - break; - - case 3: - if (gAudioCtx.audioResetFadeOutFramesLeft != 0) { - gAudioCtx.audioResetFadeOutFramesLeft--; - AudioHeap_UpdateReverbs(); - } else { - gAudioCtx.audioResetFadeOutFramesLeft = 2 / sp24; - gAudioCtx.resetStatus--; - } - break; - - case 2: - AudioHeap_ClearCurrentAiBuffer(); - if (gAudioCtx.audioResetFadeOutFramesLeft != 0) { - gAudioCtx.audioResetFadeOutFramesLeft--; - } else { - gAudioCtx.resetStatus--; - AudioHeap_DiscardSampleCaches(); - AudioHeap_DiscardSampleBanks(); - } - break; - - case 1: - AudioHeap_Init(); - gAudioCtx.resetStatus = 0; - for (i = 0; i < 3; i++) { - gAudioCtx.aiBufLengths[i] = gAudioCtx.audioBufferParameters.maxAiBufferLength; - for (j = 0; j < AIBUF_LEN; j++) { - gAudioCtx.aiBuffers[i][j] = 0; - } - } - break; - } - - if (gAudioCtx.resetStatus < 3) { - return false; - } - - return true; -} - -void AudioHeap_Init(void) { - s32 pad1[4]; - s16* ramAddr; - s32 persistentSize; - s32 temporarySize; - s32 cachePoolSize; - s32 miscPoolSize; - OSIntMask intMask; - s32 i; - s32 j; - s32 pad2; - AudioSpec* spec = &gAudioSpecs[gAudioCtx.audioResetSpecIdToLoad]; // Audio Specifications - - gAudioCtx.sampleDmaCount = 0; - - // audio buffer parameters - gAudioCtx.audioBufferParameters.samplingFrequency = spec->samplingFrequency; - gAudioCtx.audioBufferParameters.aiSamplingFrequency = - osAiSetFrequency(gAudioCtx.audioBufferParameters.samplingFrequency); - gAudioCtx.audioBufferParameters.samplesPerFrameTarget = - ALIGN16(gAudioCtx.audioBufferParameters.samplingFrequency / gAudioCtx.refreshRate); - gAudioCtx.audioBufferParameters.minAiBufferLength = gAudioCtx.audioBufferParameters.samplesPerFrameTarget - 0x10; - gAudioCtx.audioBufferParameters.maxAiBufferLength = gAudioCtx.audioBufferParameters.samplesPerFrameTarget + 0x10; - gAudioCtx.audioBufferParameters.updatesPerFrame = - ((gAudioCtx.audioBufferParameters.samplesPerFrameTarget + 0x10) / 0xD0) + 1; - gAudioCtx.audioBufferParameters.samplesPerUpdate = - (gAudioCtx.audioBufferParameters.samplesPerFrameTarget / gAudioCtx.audioBufferParameters.updatesPerFrame) & ~7; - gAudioCtx.audioBufferParameters.samplesPerUpdateMax = gAudioCtx.audioBufferParameters.samplesPerUpdate + 8; - gAudioCtx.audioBufferParameters.samplesPerUpdateMin = gAudioCtx.audioBufferParameters.samplesPerUpdate - 8; - gAudioCtx.audioBufferParameters.resampleRate = 32000.0f / (s32)gAudioCtx.audioBufferParameters.samplingFrequency; - gAudioCtx.audioBufferParameters.updatesPerFrameInvScaled = - (1.0f / 256.0f) / gAudioCtx.audioBufferParameters.updatesPerFrame; - gAudioCtx.audioBufferParameters.updatesPerFrameScaled = gAudioCtx.audioBufferParameters.updatesPerFrame / 4.0f; - gAudioCtx.audioBufferParameters.updatesPerFrameInv = 1.0f / gAudioCtx.audioBufferParameters.updatesPerFrame; - - // SampleDma buffer size - gAudioCtx.sampleDmaBufSize1 = spec->sampleDmaBufSize1; - gAudioCtx.sampleDmaBufSize2 = spec->sampleDmaBufSize2; - - gAudioCtx.numNotes = spec->numNotes; - gAudioCtx.audioBufferParameters.numSequencePlayers = spec->numSequencePlayers; - if (gAudioCtx.audioBufferParameters.numSequencePlayers > 4) { - gAudioCtx.audioBufferParameters.numSequencePlayers = 4; - } - gAudioCtx.unk_2 = spec->unk_14; - gAudioCtx.tempoInternalToExternal = - (u32)(gAudioCtx.audioBufferParameters.updatesPerFrame * 2880000.0f / gTatumsPerBeat / gAudioCtx.unk_2960); - - gAudioCtx.unk_2870 = gAudioCtx.refreshRate; - gAudioCtx.unk_2870 *= gAudioCtx.audioBufferParameters.updatesPerFrame; - gAudioCtx.unk_2870 /= gAudioCtx.audioBufferParameters.aiSamplingFrequency; - gAudioCtx.unk_2870 /= gAudioCtx.tempoInternalToExternal; - - gAudioCtx.audioBufferParameters.specUnk4 = spec->unk_04; - gAudioCtx.audioBufferParameters.samplesPerFrameTarget *= gAudioCtx.audioBufferParameters.specUnk4; - gAudioCtx.audioBufferParameters.maxAiBufferLength *= gAudioCtx.audioBufferParameters.specUnk4; - gAudioCtx.audioBufferParameters.minAiBufferLength *= gAudioCtx.audioBufferParameters.specUnk4; - gAudioCtx.audioBufferParameters.updatesPerFrame *= gAudioCtx.audioBufferParameters.specUnk4; - - if (gAudioCtx.audioBufferParameters.specUnk4 >= 2) { - gAudioCtx.audioBufferParameters.maxAiBufferLength -= 0x10; - } - - // Determine the length of the buffer for storing the audio command list passed to the rsp audio microcode - gAudioCtx.maxAudioCmds = - gAudioCtx.numNotes * 0x10 * gAudioCtx.audioBufferParameters.updatesPerFrame + spec->numReverbs * 0x18 + 0x140; - - // Calculate sizes for various caches on the audio heap - persistentSize = - spec->persistentSeqCacheSize + spec->persistentFontCacheSize + spec->persistentSampleBankCacheSize + 0x10; - temporarySize = - spec->temporarySeqCacheSize + spec->temporaryFontCacheSize + spec->temporarySampleBankCacheSize + 0x10; - cachePoolSize = persistentSize + temporarySize; - miscPoolSize = gAudioCtx.sessionPool.size - cachePoolSize - 0x100; - - if (gAudioCtx.externalPool.startRamAddr != NULL) { - gAudioCtx.externalPool.curRamAddr = gAudioCtx.externalPool.startRamAddr; - } - - // Session Pool Split (split into Cache and Misc pools) - gAudioCtx.sessionPoolSplit.miscPoolSize = miscPoolSize; - gAudioCtx.sessionPoolSplit.cachePoolSize = cachePoolSize; - AudioHeap_InitSessionPools(&gAudioCtx.sessionPoolSplit); - - // Cache Pool Split (split into Persistent and Temporary pools) - gAudioCtx.cachePoolSplit.persistentCommonPoolSize = persistentSize; - gAudioCtx.cachePoolSplit.temporaryCommonPoolSize = temporarySize; - AudioHeap_InitCachePools(&gAudioCtx.cachePoolSplit); - - // Persistent Pool Split (split into Sequences, SoundFonts, Samples pools) - gAudioCtx.persistentCommonPoolSplit.seqCacheSize = spec->persistentSeqCacheSize; - gAudioCtx.persistentCommonPoolSplit.fontCacheSize = spec->persistentFontCacheSize; - gAudioCtx.persistentCommonPoolSplit.sampleBankCacheSize = spec->persistentSampleBankCacheSize; - AudioHeap_InitPersistentPoolsAndCaches(&gAudioCtx.persistentCommonPoolSplit); - - // Temporary Pool Split (split into Sequences, SoundFonts, Samples pools) - gAudioCtx.temporaryCommonPoolSplit.seqCacheSize = spec->temporarySeqCacheSize; - gAudioCtx.temporaryCommonPoolSplit.fontCacheSize = spec->temporaryFontCacheSize; - gAudioCtx.temporaryCommonPoolSplit.sampleBankCacheSize = spec->temporarySampleBankCacheSize; - AudioHeap_InitTemporaryPoolsAndCaches(&gAudioCtx.temporaryCommonPoolSplit); - - AudioHeap_ResetLoadStatus(); - - // Initialize notes - gAudioCtx.notes = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, gAudioCtx.numNotes * sizeof(Note)); - Audio_NoteInitAll(); - Audio_InitNoteFreeList(); - gAudioCtx.noteSubsEu = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, gAudioCtx.audioBufferParameters.updatesPerFrame * - gAudioCtx.numNotes * sizeof(NoteSubEu)); - // Initialize audio binary interface command list buffers - for (i = 0; i != 2; i++) { - gAudioCtx.abiCmdBufs[i] = - AudioHeap_AllocDmaMemoryZeroed(&gAudioCtx.miscPool, gAudioCtx.maxAudioCmds * sizeof(Acmd)); - } - - // Initialize the decay rate table for adsr - gAudioCtx.adsrDecayTable = AudioHeap_Alloc(&gAudioCtx.miscPool, 256 * sizeof(f32)); - AudioHeap_InitAdsrDecayTable(); - - // Initialize reverbs - for (i = 0; i < 4; i++) { - gAudioCtx.synthesisReverbs[i].useReverb = 0; - } - - gAudioCtx.numSynthesisReverbs = spec->numReverbs; - for (i = 0; i < gAudioCtx.numSynthesisReverbs; i++) { - ReverbSettings* settings = &spec->reverbSettings[i]; - SynthesisReverb* reverb = &gAudioCtx.synthesisReverbs[i]; - - reverb->downsampleRate = settings->downsampleRate; - reverb->windowSize = settings->windowSize * 64; - reverb->windowSize /= reverb->downsampleRate; - reverb->decayRatio = settings->decayRatio; - reverb->volume = settings->volume; - reverb->unk_14 = settings->unk_6 * 64; - reverb->unk_16 = settings->unk_8; - reverb->unk_18 = 0; - reverb->leakRtl = settings->leakRtl; - reverb->leakLtr = settings->leakLtr; - reverb->unk_05 = settings->unk_10; - reverb->unk_08 = settings->unk_12; - reverb->useReverb = 8; - reverb->leftRingBuf = - AudioHeap_AllocZeroedAttemptExternal(&gAudioCtx.miscPool, reverb->windowSize * SAMPLE_SIZE); - reverb->rightRingBuf = - AudioHeap_AllocZeroedAttemptExternal(&gAudioCtx.miscPool, reverb->windowSize * SAMPLE_SIZE); - reverb->nextRingBufPos = 0; - reverb->unk_20 = 0; - reverb->curFrame = 0; - reverb->bufSizePerChan = reverb->windowSize; - reverb->framesToIgnore = 2; - reverb->resampleFlags = 1; - reverb->tunedSample.sample = &reverb->sample; - reverb->sample.loop = &reverb->loop; - reverb->tunedSample.tuning = 1.0f; - reverb->sample.codec = CODEC_REVERB; - reverb->sample.medium = MEDIUM_RAM; - reverb->sample.size = reverb->windowSize * SAMPLE_SIZE; - reverb->sample.sampleAddr = (u8*)reverb->leftRingBuf; - reverb->loop.start = 0; - reverb->loop.count = 1; - reverb->loop.end = reverb->windowSize; - - if (reverb->downsampleRate != 1) { - reverb->unk_0E = 0x8000 / reverb->downsampleRate; - reverb->unk_30 = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); - reverb->unk_34 = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); - reverb->unk_38 = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); - reverb->unk_3C = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); - for (j = 0; j < gAudioCtx.audioBufferParameters.updatesPerFrame; j++) { - ramAddr = AudioHeap_AllocZeroedAttemptExternal(&gAudioCtx.miscPool, DMEM_2CH_SIZE); - reverb->items[0][j].toDownsampleLeft = ramAddr; - reverb->items[0][j].toDownsampleRight = ramAddr + DMEM_1CH_SIZE / SAMPLE_SIZE; - - ramAddr = AudioHeap_AllocZeroedAttemptExternal(&gAudioCtx.miscPool, DMEM_2CH_SIZE); - reverb->items[1][j].toDownsampleLeft = ramAddr; - reverb->items[1][j].toDownsampleRight = ramAddr + DMEM_1CH_SIZE / SAMPLE_SIZE; - } - } - - if (settings->lowPassFilterCutoffLeft != 0) { - reverb->filterLeftState = - AudioHeap_AllocDmaMemoryZeroed(&gAudioCtx.miscPool, 2 * (FILTER_BUF_PART1 + FILTER_BUF_PART2)); - reverb->filterLeft = AudioHeap_AllocDmaMemory(&gAudioCtx.miscPool, FILTER_SIZE); - AudioHeap_LoadLowPassFilter(reverb->filterLeft, settings->lowPassFilterCutoffLeft); - } else { - reverb->filterLeft = NULL; - } - - if (settings->lowPassFilterCutoffRight != 0) { - reverb->filterRightState = - AudioHeap_AllocDmaMemoryZeroed(&gAudioCtx.miscPool, 2 * (FILTER_BUF_PART1 + FILTER_BUF_PART2)); - reverb->filterRight = AudioHeap_AllocDmaMemory(&gAudioCtx.miscPool, FILTER_SIZE); - AudioHeap_LoadLowPassFilter(reverb->filterRight, settings->lowPassFilterCutoffRight); - } else { - reverb->filterRight = NULL; - } - } - - // Initialize sequence players - AudioSeq_InitSequencePlayers(); - for (j = 0; j < gAudioCtx.audioBufferParameters.numSequencePlayers; j++) { - AudioSeq_InitSequencePlayerChannels(j); - AudioSeq_ResetSequencePlayer(&gAudioCtx.seqPlayers[j]); - } - - // Initialize two additional sample caches for individual samples - AudioHeap_InitSampleCaches(spec->persistentSampleCacheSize, spec->temporarySampleCacheSize); - AudioLoad_InitSampleDmaBuffers(gAudioCtx.numNotes); - - // Initialize Loads - gAudioCtx.preloadSampleStackTop = 0; - AudioLoad_InitSlowLoads(); - AudioLoad_InitScriptLoads(); - AudioLoad_InitAsyncLoads(); - gAudioCtx.unk_4 = 0x1000; - AudioLoad_LoadPermanentSamples(); - - intMask = osSetIntMask(OS_IM_NONE); - osWritebackDCacheAll(); - osSetIntMask(intMask); -} - -void* AudioHeap_SearchPermanentCache(s32 tableType, s32 id) { - s32 i; - - for (i = 0; i < gAudioCtx.permanentPool.numEntries; i++) { - if (gAudioCtx.permanentCache[i].tableType == tableType && gAudioCtx.permanentCache[i].id == id) { - return gAudioCtx.permanentCache[i].ramAddr; - } - } - return NULL; -} - -void* AudioHeap_AllocPermanent(s32 tableType, s32 id, u32 size) { - void* ramAddr; - s32 index = gAudioCtx.permanentPool.numEntries; - - ramAddr = AudioHeap_Alloc(&gAudioCtx.permanentPool, size); - gAudioCtx.permanentCache[index].ramAddr = ramAddr; - if (ramAddr == NULL) { - return NULL; - } - gAudioCtx.permanentCache[index].tableType = tableType; - gAudioCtx.permanentCache[index].id = id; - gAudioCtx.permanentCache[index].size = size; - - //! @bug UB: missing return. "ramAddr" is in v0 at this point, but doing an - //! explicit return uses an additional register. -#ifdef AVOID_UB - return ramAddr; -#endif -} - -void* AudioHeap_AllocSampleCache(u32 size, s32 fontId, void* sampleAddr, s8 medium, s32 cache) { - SampleCacheEntry* entry; - - if (cache == CACHE_TEMPORARY) { - entry = AudioHeap_AllocTemporarySampleCacheEntry(size); - } else { - entry = AudioHeap_AllocPersistentSampleCacheEntry(size); - } - if (entry != NULL) { - //! @bug Should use sampleBankId, not fontId - entry->sampleBankId = fontId; - entry->sampleAddr = sampleAddr; - entry->origMedium = medium; - return entry->allocatedAddr; - } - return NULL; -} - -/** - * Initializes the persistent and temporary caches used for individual samples. Will attempt to use heap space available - * on the external pool. If no external pool is provided, then default to using space on the misc pool. - */ -void AudioHeap_InitSampleCaches(u32 persistentSampleCacheSize, u32 temporarySampleCacheSize) { - void* ramAddr; - - ramAddr = AudioHeap_AllocAttemptExternal(&gAudioCtx.miscPool, persistentSampleCacheSize); - if (ramAddr == NULL) { - gAudioCtx.persistentSampleCache.pool.size = 0; - } else { - AudioHeap_InitPool(&gAudioCtx.persistentSampleCache.pool, ramAddr, persistentSampleCacheSize); - } - ramAddr = AudioHeap_AllocAttemptExternal(&gAudioCtx.miscPool, temporarySampleCacheSize); - if (ramAddr == NULL) { - gAudioCtx.temporarySampleCache.pool.size = 0; - } else { - AudioHeap_InitPool(&gAudioCtx.temporarySampleCache.pool, ramAddr, temporarySampleCacheSize); - } - gAudioCtx.persistentSampleCache.numEntries = 0; - gAudioCtx.temporarySampleCache.numEntries = 0; -} - -SampleCacheEntry* AudioHeap_AllocTemporarySampleCacheEntry(u32 size) { - u8* allocAfter; - u8* allocBefore; - void* ramAddr; - s32 index; - s32 i; - SampleCacheEntry* entry; - AudioPreloadReq* preload; - AudioSampleCache* cache; - u8* startRamAddr; - u8* endRamAddr; - - cache = &gAudioCtx.temporarySampleCache; - allocBefore = cache->pool.curRamAddr; - ramAddr = AudioHeap_Alloc(&cache->pool, size); - if (ramAddr == NULL) { - // Reset the pool and try again. We still keep pointers to within the - // pool, so we have to be careful to discard existing overlapping - // allocations further down. - u8* old = cache->pool.curRamAddr; - - cache->pool.curRamAddr = cache->pool.startRamAddr; - ramAddr = AudioHeap_Alloc(&cache->pool, size); - if (ramAddr == NULL) { - cache->pool.curRamAddr = old; - return NULL; - } - allocBefore = cache->pool.startRamAddr; - } - - allocAfter = cache->pool.curRamAddr; - - index = -1; - for (i = 0; i < gAudioCtx.preloadSampleStackTop; i++) { - preload = &gAudioCtx.preloadSampleStack[i]; - if (!preload->isFree) { - startRamAddr = preload->ramAddr; - endRamAddr = preload->ramAddr + preload->sample->size - 1; - - if (endRamAddr < allocBefore && startRamAddr < allocBefore) { - continue; - } - if (endRamAddr >= allocAfter && startRamAddr >= allocAfter) { - continue; - } - - // Overlap, skip this preload. - preload->isFree = true; - } - } - - for (i = 0; i < cache->numEntries; i++) { - if (!cache->entries[i].inUse) { - continue; - } - - startRamAddr = cache->entries[i].allocatedAddr; - endRamAddr = startRamAddr + cache->entries[i].size - 1; - - if (endRamAddr < allocBefore && startRamAddr < allocBefore) { - continue; - } - if (endRamAddr >= allocAfter && startRamAddr >= allocAfter) { - continue; - } - - // Overlap, discard existing entry. - AudioHeap_DiscardSampleCacheEntry(&cache->entries[i]); - if (index == -1) { - index = i; - } - } - - if (index == -1) { - index = cache->numEntries++; - } - - entry = &cache->entries[index]; - entry->inUse = true; - entry->allocatedAddr = ramAddr; - entry->size = size; - - return entry; -} - -void AudioHeap_UnapplySampleCacheForFont(SampleCacheEntry* entry, s32 fontId) { - Drum* drum; - Instrument* inst; - SoundEffect* soundEffect; - s32 instId; - s32 drumId; - s32 sfxId; - - for (instId = 0; instId < gAudioCtx.soundFontList[fontId].numInstruments; instId++) { - inst = Audio_GetInstrumentInner(fontId, instId); - if (inst != NULL) { - if (inst->normalRangeLo != 0) { - AudioHeap_UnapplySampleCache(entry, inst->lowPitchTunedSample.sample); - } - if (inst->normalRangeHi != 0x7F) { - AudioHeap_UnapplySampleCache(entry, inst->highPitchTunedSample.sample); - } - AudioHeap_UnapplySampleCache(entry, inst->normalPitchTunedSample.sample); - } - } - - for (drumId = 0; drumId < gAudioCtx.soundFontList[fontId].numDrums; drumId++) { - drum = Audio_GetDrum(fontId, drumId); - if (drum != NULL) { - AudioHeap_UnapplySampleCache(entry, drum->tunedSample.sample); - } - } - - for (sfxId = 0; sfxId < gAudioCtx.soundFontList[fontId].numSfx; sfxId++) { - soundEffect = Audio_GetSoundEffect(fontId, sfxId); - if (soundEffect != NULL) { - AudioHeap_UnapplySampleCache(entry, soundEffect->tunedSample.sample); - } - } -} - -void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry) { - s32 numFonts; - s32 sampleBankId1; - s32 sampleBankId2; - s32 fontId; - - numFonts = gAudioCtx.soundFontTable->numEntries; - for (fontId = 0; fontId < numFonts; fontId++) { - sampleBankId1 = gAudioCtx.soundFontList[fontId].sampleBankId1; - sampleBankId2 = gAudioCtx.soundFontList[fontId].sampleBankId2; - if (((sampleBankId1 != 0xFF) && (entry->sampleBankId == sampleBankId1)) || - ((sampleBankId2 != 0xFF) && (entry->sampleBankId == sampleBankId2)) || entry->sampleBankId == 0) { - if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, fontId) != NULL) { - if (AudioLoad_IsFontLoadComplete(fontId) != 0) { - AudioHeap_UnapplySampleCacheForFont(entry, fontId); - } - } - } - } -} - -void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, Sample* sample) { - if (sample != NULL) { - if (sample->sampleAddr == entry->allocatedAddr) { - sample->sampleAddr = entry->sampleAddr; - sample->medium = entry->origMedium; - } - } -} - -SampleCacheEntry* AudioHeap_AllocPersistentSampleCacheEntry(u32 size) { - AudioSampleCache* cache; - SampleCacheEntry* entry; - void* ramAddr; - - cache = &gAudioCtx.persistentSampleCache; - ramAddr = AudioHeap_Alloc(&cache->pool, size); - if (ramAddr == NULL) { - return NULL; - } - entry = &cache->entries[cache->numEntries]; - entry->inUse = true; - entry->allocatedAddr = ramAddr; - entry->size = size; - cache->numEntries++; - - return entry; -} - -void AudioHeap_DiscardSampleCacheForFont(SampleCacheEntry* entry, s32 sampleBankId1, s32 sampleBankId2, s32 fontId) { - if ((entry->sampleBankId == sampleBankId1) || (entry->sampleBankId == sampleBankId2) || - (entry->sampleBankId == 0)) { - AudioHeap_UnapplySampleCacheForFont(entry, fontId); - } -} - -void AudioHeap_DiscardSampleCaches(void) { - s32 numFonts; - s32 sampleBankId1; - s32 sampleBankId2; - s32 fontId; - s32 j; - - numFonts = gAudioCtx.soundFontTable->numEntries; - for (fontId = 0; fontId < numFonts; fontId++) { - sampleBankId1 = gAudioCtx.soundFontList[fontId].sampleBankId1; - sampleBankId2 = gAudioCtx.soundFontList[fontId].sampleBankId2; - if ((sampleBankId1 == 0xFF) && (sampleBankId2 == 0xFF)) { - continue; - } - if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_PERMANENT, fontId) == NULL || - !AudioLoad_IsFontLoadComplete(fontId)) { - continue; - } - - for (j = 0; j < gAudioCtx.persistentSampleCache.numEntries; j++) { - AudioHeap_DiscardSampleCacheForFont(&gAudioCtx.persistentSampleCache.entries[j], sampleBankId1, - sampleBankId2, fontId); - } - for (j = 0; j < gAudioCtx.temporarySampleCache.numEntries; j++) { - AudioHeap_DiscardSampleCacheForFont(&gAudioCtx.temporarySampleCache.entries[j], sampleBankId1, - sampleBankId2, fontId); - } - } -} - -typedef struct { - u32 oldAddr; - u32 newAddr; - u32 size; - u8 newMedium; -} StorageChange; - -void AudioHeap_ChangeStorage(StorageChange* change, Sample* sample) { - if (sample != NULL) { - u32 startAddr = change->oldAddr; - u32 endAddr = change->oldAddr + change->size; - - if (startAddr <= (u32)sample->sampleAddr && (u32)sample->sampleAddr < endAddr) { - sample->sampleAddr = sample->sampleAddr - startAddr + change->newAddr; - sample->medium = change->newMedium; - } - } -} - -void AudioHeap_ApplySampleBankCacheInternal(s32 apply, s32 sampleBankId); - -void AudioHeap_DiscardSampleBank(s32 sampleBankId) { - AudioHeap_ApplySampleBankCacheInternal(false, sampleBankId); -} - -void AudioHeap_ApplySampleBankCache(s32 sampleBankId) { - AudioHeap_ApplySampleBankCacheInternal(true, sampleBankId); -} - -void AudioHeap_ApplySampleBankCacheInternal(s32 apply, s32 sampleBankId) { - AudioTable* sampleBankTable; - AudioTableEntry* entry; - s32 numFonts; - s32 instId; - s32 drumId; - s32 sfxId; - StorageChange change; - s32 sampleBankId1; - s32 sampleBankId2; - s32 fontId; - Drum* drum; - Instrument* inst; - SoundEffect* soundEffect; - u32* fakematch; - s32 pad[4]; - - sampleBankTable = gAudioCtx.sampleBankTable; - numFonts = gAudioCtx.soundFontTable->numEntries; - change.oldAddr = (u32)AudioHeap_SearchCaches(SAMPLE_TABLE, CACHE_EITHER, sampleBankId); - if (change.oldAddr == 0) { - return; - } - - entry = &sampleBankTable->entries[sampleBankId]; - change.size = entry->size; - change.newMedium = entry->medium; - - if ((change.newMedium == MEDIUM_CART) || (change.newMedium == MEDIUM_DISK_DRIVE)) { - change.newAddr = entry->romAddr; - } else { - change.newAddr = 0; - } - - fakematch = &change.oldAddr; - if (apply && (apply == true)) { - u32 temp = change.newAddr; - - change.newAddr = *fakematch; // = change.oldAddr - change.oldAddr = temp; - change.newMedium = MEDIUM_RAM; - } - - for (fontId = 0; fontId < numFonts; fontId++) { - sampleBankId1 = gAudioCtx.soundFontList[fontId].sampleBankId1; - sampleBankId2 = gAudioCtx.soundFontList[fontId].sampleBankId2; - if ((sampleBankId1 != 0xFF) || (sampleBankId2 != 0xFF)) { - if (!AudioLoad_IsFontLoadComplete(fontId) || - AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, fontId) == NULL) { - continue; - } - - if (sampleBankId1 == sampleBankId) { - } else if (sampleBankId2 == sampleBankId) { - } else { - continue; - } - - for (instId = 0; instId < gAudioCtx.soundFontList[fontId].numInstruments; instId++) { - inst = Audio_GetInstrumentInner(fontId, instId); - if (inst != NULL) { - if (inst->normalRangeLo != 0) { - AudioHeap_ChangeStorage(&change, inst->lowPitchTunedSample.sample); - } - if (inst->normalRangeHi != 0x7F) { - AudioHeap_ChangeStorage(&change, inst->highPitchTunedSample.sample); - } - AudioHeap_ChangeStorage(&change, inst->normalPitchTunedSample.sample); - } - } - - for (drumId = 0; drumId < gAudioCtx.soundFontList[fontId].numDrums; drumId++) { - drum = Audio_GetDrum(fontId, drumId); - if (drum != NULL) { - AudioHeap_ChangeStorage(&change, drum->tunedSample.sample); - } - } - - for (sfxId = 0; sfxId < gAudioCtx.soundFontList[fontId].numSfx; sfxId++) { - soundEffect = Audio_GetSoundEffect(fontId, sfxId); - if (soundEffect != NULL) { - AudioHeap_ChangeStorage(&change, soundEffect->tunedSample.sample); - } - } - } - } -} - -void AudioHeap_DiscardSampleBanks(void) { - AudioCache* cache; - AudioPersistentCache* persistent; - AudioTemporaryCache* temporary; - u32 i; - - cache = &gAudioCtx.sampleBankCache; - temporary = &cache->temporary; - - if (temporary->entries[0].id != -1) { - AudioHeap_DiscardSampleBank(temporary->entries[0].id); - } - - if (temporary->entries[1].id != -1) { - AudioHeap_DiscardSampleBank(temporary->entries[1].id); - } - - persistent = &cache->persistent; - for (i = 0; i < persistent->numEntries; i++) { - AudioHeap_DiscardSampleBank(persistent->entries[i].id); - } -} diff --git a/src/code/audio_init_params.c b/src/code/audio_init_params.c deleted file mode 100644 index 56b899993..000000000 --- a/src/code/audio_init_params.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "global.h" - -u8 D_8016F0E0[0xA0]; // unused -AudioContext gAudioCtx; -void (*D_801755D0)(void); -s32 D_801755D8[3]; // unused - -const s16 D_8014A6C0[] = { - 0x1C00, // unused - 0x0030, // gTatumsPerBeat -}; - -// TODO: Extract from table? -#define NUM_SOUNDFONTS 38 -#define SFX_SEQ_SIZE 0x6A90 -#define SFX_SOUNDFONT_1_SIZE 0x3AA0 -#define SFX_SOUNDFONT_2_SIZE 0x17B0 - -// Sizes of everything on the init pool -#define AI_BUFFERS_SIZE (AIBUF_SIZE * ARRAY_COUNT(gAudioCtx.aiBuffers)) -#define SOUNDFONT_LIST_SIZE (NUM_SOUNDFONTS * sizeof(SoundFont)) -#define PERMANENT_POOL_SIZE (SFX_SEQ_SIZE + SFX_SOUNDFONT_1_SIZE + SFX_SOUNDFONT_2_SIZE) - -const AudioHeapInitSizes gAudioHeapInitSizes = { - ALIGN16(sizeof(gAudioHeap) - 0x100), // audio heap size - ALIGN16(PERMANENT_POOL_SIZE + AI_BUFFERS_SIZE + SOUNDFONT_LIST_SIZE), // init pool size - ALIGN16(PERMANENT_POOL_SIZE), // permanent pool size -}; - -#define DEFAULT_REVERB_SETTINGS \ - { 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 } - -ReverbSettings sReverbSettings[][3] = { - { - DEFAULT_REVERB_SETTINGS, - { 1, 0x20, 0x0800, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x0000, 0x0, 0x0 }, - }, - { - DEFAULT_REVERB_SETTINGS, - { 1, 0x30, 0x1800, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x0000, 0xB, 0xB }, - }, - { - DEFAULT_REVERB_SETTINGS, - { 1, 0x38, 0x2800, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x0000, 0x7, 0x7 }, - }, - { - DEFAULT_REVERB_SETTINGS, - { 1, 0x50, 0x5000, 0, 0, 0x7FFF, 0x1000, 0x1000, 0xFF, 0x3000, 0x7, 0x7 }, - }, - { - DEFAULT_REVERB_SETTINGS, - { 1, 0x40, 0x5000, 0, 0, 0x7FFF, 0x1800, 0x1800, 0xFF, 0x3000, 0x7, 0x7 }, - }, - { - DEFAULT_REVERB_SETTINGS, - { 1, 0x40, 0x5C00, 0, 0, 0x7FFF, 0x2000, 0x2000, 0xFF, 0x3000, 0x4, 0x4 }, - }, - { - DEFAULT_REVERB_SETTINGS, - { 1, 0x30, 0x6000, 0, 0, 0x7FFF, 0x1000, 0x1000, 0xFF, 0x3000, 0xA, 0xA }, - }, - { - DEFAULT_REVERB_SETTINGS, - { 1, 0x30, 0x6800, 0, 0, 0x7FFF, 0x1400, 0x1400, 0xFF, 0x3000, 0x6, 0x6 }, - }, - { - DEFAULT_REVERB_SETTINGS, - { 2, 0x50, 0x5000, 0, 0, 0x7FFF, 0xD000, 0x3000, 0xFF, 0x3000, 0x0, 0x0 }, - }, - { - DEFAULT_REVERB_SETTINGS, - { 1, 0x20, 0x0000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x0000, 0x0, 0x0 }, - }, - { - DEFAULT_REVERB_SETTINGS, - { 1, 0x30, 0x1800, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x0000, 0xB, 0xB }, - }, - { - DEFAULT_REVERB_SETTINGS, - }, - { - DEFAULT_REVERB_SETTINGS, - { 1, 0x40, 0x5000, 0, 0, 0x7FFF, 0x0000, 0x0000, 0xFF, 0x3000, 0x0, 0x0 }, - }, -}; - -AudioSpec gAudioSpecs[18] = { - { 32000, 1, 24, 4, 0, 0, 2, sReverbSettings[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, sReverbSettings[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, sReverbSettings[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 23, 4, 0, 0, 2, sReverbSettings[4], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 23, 4, 0, 0, 2, sReverbSettings[5], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, sReverbSettings[6], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, sReverbSettings[7], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 23, 4, 0, 0, 2, sReverbSettings[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, sReverbSettings[9], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 23, 4, 0, 0, 2, sReverbSettings[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 28, 3, 0, 0, 2, sReverbSettings[10], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x2800, 0x2880, 0, 0, 0 }, - { 32000, 1, 28, 3, 0, 0, 1, sReverbSettings[11], 0x300, 0x200, 0x7FFF, 0, 0x4800, 0, 0x4000, 0, 0, 0, 0 }, - { 32000, 1, 28, 3, 0, 0, 1, sReverbSettings[11], 0x300, 0x200, 0x7FFF, 0, 0, 0, 0x4000, 0x4800, 0, 0, 0 }, - { 32000, 1, 22, 4, 0, 0, 2, sReverbSettings[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 22, 4, 0, 0, 2, sReverbSettings[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 16, 4, 0, 0, 2, sReverbSettings[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 22050, 1, 24, 4, 0, 0, 2, sReverbSettings[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, sReverbSettings[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3600, 0x2600, 0, 0, 0 }, -}; diff --git a/src/code/audio_load.c b/src/code/audio_load.c deleted file mode 100644 index f30527d97..000000000 --- a/src/code/audio_load.c +++ /dev/null @@ -1,2127 +0,0 @@ -#include "ultra64.h" -#include "global.h" - -#define MK_ASYNC_MSG(retData, tableType, id, loadStatus) \ - (((retData) << 24) | ((tableType) << 16) | ((id) << 8) | (loadStatus)) -#define ASYNC_TBLTYPE(v) ((u8)(v >> 16)) -#define ASYNC_ID(v) ((u8)(v >> 8)) -#define ASYNC_LOAD_STATUS(v) ((u8)(v >> 0)) - -typedef enum { - /* 0 */ SLOW_LOAD_STATE_WAITING, - /* 1 */ SLOW_LOAD_STATE_START, - /* 2 */ SLOW_LOAD_STATE_LOADING, - /* 3 */ SLOW_LOAD_STATE_DONE -} SlowLoadState; - -typedef struct { - /* 0x00 */ s32 sampleBankId1; - /* 0x04 */ s32 sampleBankId2; - /* 0x08 */ s32 baseAddr1; - /* 0x0C */ s32 baseAddr2; - /* 0x10 */ u32 medium1; - /* 0x14 */ u32 medium2; -} SampleBankRelocInfo; // size = 0x18 - -// opaque type for soundfont data loaded into ram (should maybe get rid of this?) -typedef void SoundFontData; - -/* forward declarations */ -s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2); -SoundFontData* AudioLoad_SyncLoadFont(u32 fontId); -Sample* AudioLoad_GetFontSample(s32 fontId, s32 instId); -void AudioLoad_ProcessAsyncLoads(s32 resetStatus); -void AudioLoad_ProcessAsyncLoadUnkMedium(AudioAsyncLoad* asyncLoad, s32 resetStatus); -void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus); -void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* fontData, SampleBankRelocInfo* sampleBankReloc, - s32 isAsync); -void AudioLoad_RelocateSample(TunedSample* tunedSample, SoundFontData* fontData, SampleBankRelocInfo* sampleBankReloc); -void AudioLoad_DiscardFont(s32 fontId); -u32 AudioLoad_TrySyncLoadSampleBank(u32 sampleBankId, u32* outMedium, s32 noLoad); -void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate); -u32 AudioLoad_GetRealTableIndex(s32 tableType, u32 id); -void* AudioLoad_SearchCaches(s32 tableType, s32 id); -AudioTable* AudioLoad_GetLoadTable(s32 tableType); -void AudioLoad_SyncDma(u32 devAddr, u8* ramAddr, u32 size, s32 medium); -void AudioLoad_SyncDmaUnkMedium(u32 devAddr, u8* addr, u32 size, s32 unkMediumParam); -s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, u32 devAddr, void* ramAddr, u32 size, - OSMesgQueue* reqQueue, s32 medium, const char* dmaFuncType); -void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, OSMesgQueue* retQueue); -AudioAsyncLoad* AudioLoad_StartAsyncLoadUnkMedium(s32 unkMediumParam, u32 devAddr, void* ramAddr, s32 size, s32 medium, - s32 nChunks, OSMesgQueue* retQueue, s32 retMsg); -AudioAsyncLoad* AudioLoad_StartAsyncLoad(u32 devAddr, void* ramAddr, u32 size, s32 medium, s32 nChunks, - OSMesgQueue* retQueue, s32 retMsg); -void AudioLoad_AsyncDma(AudioAsyncLoad* asyncLoad, u32 size); -void AudioLoad_AsyncDmaUnkMedium(u32 devAddr, void* ramAddr, u32 size, s16 arg3); -u8* AudioLoad_SyncLoadSeq(s32 seqId); -s32 AudioLoad_ProcessSamplePreloads(s32 resetStatus); -void AudioLoad_DmaSlowCopy(AudioSlowLoad* slowLoad, s32 size); -void AudioLoad_ProcessSlowLoads(s32 resetStatus); -void AudioLoad_DmaSlowCopyUnkMedium(s32 devAddr, u8* ramAddr, s32 size, s32 arg3); - -OSMesgQueue sScriptLoadQueue; -OSMesg sScriptLoadMsgBuf[16]; -s8* sScriptLoadDonePointers[0x10]; -s32 sAudioLoadPad1[2]; // file padding - -s32 D_8016B780; -s32 sAudioLoadPad2[4]; // double file padding? - -DmaHandler sDmaHandler = osEPiStartDma; -void* sUnusedHandler = NULL; - -s32 gAudioContextInitialized = false; - -void AudioLoad_DecreaseSampleDmaTtls(void) { - u32 i; - - for (i = 0; i < gAudioCtx.sampleDmaListSize1; i++) { - SampleDma* dma = &gAudioCtx.sampleDmas[i]; - - if (dma->ttl != 0) { - dma->ttl--; - if (dma->ttl == 0) { - dma->reuseIndex = gAudioCtx.sampleDmaReuseQueue1WrPos; - gAudioCtx.sampleDmaReuseQueue1[gAudioCtx.sampleDmaReuseQueue1WrPos] = i; - gAudioCtx.sampleDmaReuseQueue1WrPos++; - } - } - } - - for (i = gAudioCtx.sampleDmaListSize1; i < gAudioCtx.sampleDmaCount; i++) { - SampleDma* dma = &gAudioCtx.sampleDmas[i]; - - if (dma->ttl != 0) { - dma->ttl--; - if (dma->ttl == 0) { - dma->reuseIndex = gAudioCtx.sampleDmaReuseQueue2WrPos; - gAudioCtx.sampleDmaReuseQueue2[gAudioCtx.sampleDmaReuseQueue2WrPos] = i; - gAudioCtx.sampleDmaReuseQueue2WrPos++; - } - } - } - - gAudioCtx.unused2628 = 0; -} - -void* AudioLoad_DmaSampleData(u32 devAddr, u32 size, s32 arg2, u8* dmaIndexRef, s32 medium) { - s32 pad1; - SampleDma* dma; - s32 hasDma = false; - u32 dmaDevAddr; - u32 pad2; - u32 dmaIndex; - u32 transfer; - s32 bufferPos; - u32 i; - - if (arg2 != 0 || *dmaIndexRef >= gAudioCtx.sampleDmaListSize1) { - for (i = gAudioCtx.sampleDmaListSize1; i < gAudioCtx.sampleDmaCount; i++) { - dma = &gAudioCtx.sampleDmas[i]; - bufferPos = devAddr - dma->devAddr; - if (0 <= bufferPos && (u32)bufferPos <= dma->size - size) { - // We already have a DMA request for this memory range. - if (dma->ttl == 0 && gAudioCtx.sampleDmaReuseQueue2RdPos != gAudioCtx.sampleDmaReuseQueue2WrPos) { - // Move the DMA out of the reuse queue, by swapping it with the - // read pos, and then incrementing the read pos. - if (dma->reuseIndex != gAudioCtx.sampleDmaReuseQueue2RdPos) { - gAudioCtx.sampleDmaReuseQueue2[dma->reuseIndex] = - gAudioCtx.sampleDmaReuseQueue2[gAudioCtx.sampleDmaReuseQueue2RdPos]; - gAudioCtx.sampleDmas[gAudioCtx.sampleDmaReuseQueue2[gAudioCtx.sampleDmaReuseQueue2RdPos]] - .reuseIndex = dma->reuseIndex; - } - gAudioCtx.sampleDmaReuseQueue2RdPos++; - } - dma->ttl = 32; - *dmaIndexRef = (u8)i; - return &dma->ramAddr[devAddr - dma->devAddr]; - } - } - - if (arg2 == 0) { - goto search_short_lived; - } - - if (gAudioCtx.sampleDmaReuseQueue2RdPos != gAudioCtx.sampleDmaReuseQueue2WrPos && arg2 != 0) { - // Allocate a DMA from reuse queue 2, unless full. - dmaIndex = gAudioCtx.sampleDmaReuseQueue2[gAudioCtx.sampleDmaReuseQueue2RdPos]; - gAudioCtx.sampleDmaReuseQueue2RdPos++; - dma = gAudioCtx.sampleDmas + dmaIndex; - hasDma = true; - } - } else { - search_short_lived: - dma = gAudioCtx.sampleDmas + *dmaIndexRef; - i = 0; - again: - bufferPos = devAddr - dma->devAddr; - if (0 <= bufferPos && (u32)bufferPos <= dma->size - size) { - // We already have DMA for this memory range. - if (dma->ttl == 0) { - // Move the DMA out of the reuse queue, by swapping it with the - // read pos, and then incrementing the read pos. - if (dma->reuseIndex != gAudioCtx.sampleDmaReuseQueue1RdPos) { - gAudioCtx.sampleDmaReuseQueue1[dma->reuseIndex] = - gAudioCtx.sampleDmaReuseQueue1[gAudioCtx.sampleDmaReuseQueue1RdPos]; - gAudioCtx.sampleDmas[gAudioCtx.sampleDmaReuseQueue1[gAudioCtx.sampleDmaReuseQueue1RdPos]] - .reuseIndex = dma->reuseIndex; - } - gAudioCtx.sampleDmaReuseQueue1RdPos++; - } - dma->ttl = 2; - return dma->ramAddr + (devAddr - dma->devAddr); - } - dma = gAudioCtx.sampleDmas + i++; - if (i <= gAudioCtx.sampleDmaListSize1) { - goto again; - } - } - - if (!hasDma) { - if (gAudioCtx.sampleDmaReuseQueue1RdPos == gAudioCtx.sampleDmaReuseQueue1WrPos) { - return NULL; - } - // Allocate a DMA from reuse queue 1. - dmaIndex = gAudioCtx.sampleDmaReuseQueue1[gAudioCtx.sampleDmaReuseQueue1RdPos++]; - dma = gAudioCtx.sampleDmas + dmaIndex; - hasDma = true; - } - - transfer = dma->size; - dmaDevAddr = devAddr & ~0xF; - dma->ttl = 3; - dma->devAddr = dmaDevAddr; - dma->sizeUnused = transfer; - AudioLoad_Dma(&gAudioCtx.curAudioFrameDmaIoMsgBuf[gAudioCtx.curAudioFrameDmaCount++], OS_MESG_PRI_NORMAL, OS_READ, - dmaDevAddr, dma->ramAddr, transfer, &gAudioCtx.curAudioFrameDmaQueue, medium, "SUPERDMA"); - *dmaIndexRef = dmaIndex; - return (devAddr - dmaDevAddr) + dma->ramAddr; -} - -void AudioLoad_InitSampleDmaBuffers(s32 numNotes) { - SampleDma* dma; - s32 i; - s32 t2; - s32 j; - - gAudioCtx.sampleDmaBufSize = gAudioCtx.sampleDmaBufSize1; - gAudioCtx.sampleDmas = AudioHeap_Alloc(&gAudioCtx.miscPool, 4 * gAudioCtx.numNotes * sizeof(SampleDma) * - gAudioCtx.audioBufferParameters.specUnk4); - t2 = 3 * gAudioCtx.numNotes * gAudioCtx.audioBufferParameters.specUnk4; - for (i = 0; i < t2; i++) { - dma = &gAudioCtx.sampleDmas[gAudioCtx.sampleDmaCount]; - dma->ramAddr = AudioHeap_AllocAttemptExternal(&gAudioCtx.miscPool, gAudioCtx.sampleDmaBufSize); - if (dma->ramAddr == NULL) { - break; - } else { - AudioHeap_WritebackDCache(dma->ramAddr, gAudioCtx.sampleDmaBufSize); - dma->size = gAudioCtx.sampleDmaBufSize; - dma->devAddr = 0; - dma->sizeUnused = 0; - dma->unused = 0; - dma->ttl = 0; - gAudioCtx.sampleDmaCount++; - } - } - - for (i = 0; (u32)i < gAudioCtx.sampleDmaCount; i++) { - gAudioCtx.sampleDmaReuseQueue1[i] = i; - gAudioCtx.sampleDmas[i].reuseIndex = i; - } - - for (i = gAudioCtx.sampleDmaCount; i < 0x100; i++) { - gAudioCtx.sampleDmaReuseQueue1[i] = 0; - } - - gAudioCtx.sampleDmaReuseQueue1RdPos = 0; - gAudioCtx.sampleDmaReuseQueue1WrPos = gAudioCtx.sampleDmaCount; - gAudioCtx.sampleDmaListSize1 = gAudioCtx.sampleDmaCount; - gAudioCtx.sampleDmaBufSize = gAudioCtx.sampleDmaBufSize2; - - for (j = 0; j < gAudioCtx.numNotes; j++) { - dma = &gAudioCtx.sampleDmas[gAudioCtx.sampleDmaCount]; - dma->ramAddr = AudioHeap_AllocAttemptExternal(&gAudioCtx.miscPool, gAudioCtx.sampleDmaBufSize); - if (dma->ramAddr == NULL) { - break; - } else { - AudioHeap_WritebackDCache(dma->ramAddr, gAudioCtx.sampleDmaBufSize); - dma->size = gAudioCtx.sampleDmaBufSize; - dma->devAddr = 0U; - dma->sizeUnused = 0; - dma->unused = 0; - dma->ttl = 0; - gAudioCtx.sampleDmaCount++; - } - } - - for (i = gAudioCtx.sampleDmaListSize1; (u32)i < gAudioCtx.sampleDmaCount; i++) { - gAudioCtx.sampleDmaReuseQueue2[i - gAudioCtx.sampleDmaListSize1] = i; - gAudioCtx.sampleDmas[i].reuseIndex = i - gAudioCtx.sampleDmaListSize1; - } - - for (i = gAudioCtx.sampleDmaCount; i < 0x100; i++) { - gAudioCtx.sampleDmaReuseQueue2[i] = gAudioCtx.sampleDmaListSize1; - } - - gAudioCtx.sampleDmaReuseQueue2RdPos = 0; - gAudioCtx.sampleDmaReuseQueue2WrPos = gAudioCtx.sampleDmaCount - gAudioCtx.sampleDmaListSize1; -} - -s32 AudioLoad_IsFontLoadComplete(s32 fontId) { - if (fontId == 0xFF) { - return true; - } else if (gAudioCtx.fontLoadStatus[fontId] >= LOAD_STATUS_COMPLETE) { - return true; - } else if (gAudioCtx.fontLoadStatus[AudioLoad_GetRealTableIndex(FONT_TABLE, fontId)] >= LOAD_STATUS_COMPLETE) { - return true; - } else { - return false; - } -} - -s32 AudioLoad_IsSeqLoadComplete(s32 seqId) { - if (seqId == 0xFF) { - return true; - } else if (gAudioCtx.seqLoadStatus[seqId] >= LOAD_STATUS_COMPLETE) { - return true; - } else if (gAudioCtx.seqLoadStatus[AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId)] >= LOAD_STATUS_COMPLETE) { - return true; - } else { - return false; - } -} - -s32 AudioLoad_IsSampleLoadComplete(s32 sampleBankId) { - if (sampleBankId == 0xFF) { - return true; - } else if (gAudioCtx.sampleFontLoadStatus[sampleBankId] >= LOAD_STATUS_COMPLETE) { - return true; - } else if (gAudioCtx.sampleFontLoadStatus[AudioLoad_GetRealTableIndex(SAMPLE_TABLE, sampleBankId)] >= - LOAD_STATUS_COMPLETE) { - return true; - } else { - return false; - } -} - -void AudioLoad_SetFontLoadStatus(s32 fontId, s32 loadStatus) { - if ((fontId != 0xFF) && (gAudioCtx.fontLoadStatus[fontId] != LOAD_STATUS_PERMANENTLY_LOADED)) { - gAudioCtx.fontLoadStatus[fontId] = loadStatus; - } -} - -void AudioLoad_SetSeqLoadStatus(s32 seqId, s32 loadStatus) { - if ((seqId != 0xFF) && (gAudioCtx.seqLoadStatus[seqId] != LOAD_STATUS_PERMANENTLY_LOADED)) { - gAudioCtx.seqLoadStatus[seqId] = loadStatus; - } -} - -void AudioLoad_SetSampleFontLoadStatusAndApplyCaches(s32 sampleBankId, s32 loadStatus) { - if (sampleBankId != 0xFF) { - if (gAudioCtx.sampleFontLoadStatus[sampleBankId] != LOAD_STATUS_PERMANENTLY_LOADED) { - gAudioCtx.sampleFontLoadStatus[sampleBankId] = loadStatus; - } - - if ((gAudioCtx.sampleFontLoadStatus[sampleBankId] == LOAD_STATUS_PERMANENTLY_LOADED) || - (gAudioCtx.sampleFontLoadStatus[sampleBankId] == LOAD_STATUS_COMPLETE)) { - AudioHeap_ApplySampleBankCache(sampleBankId); - } - } -} - -void AudioLoad_SetSampleFontLoadStatus(s32 sampleBankId, s32 loadStatus) { - if ((sampleBankId != 0xFF) && (gAudioCtx.sampleFontLoadStatus[sampleBankId] != LOAD_STATUS_PERMANENTLY_LOADED)) { - gAudioCtx.sampleFontLoadStatus[sampleBankId] = loadStatus; - } -} - -void AudioLoad_InitTable(AudioTable* table, u32 romAddr, u16 unkMediumParam) { - s32 i; - - table->unkMediumParam = unkMediumParam; - table->romAddr = romAddr; - - for (i = 0; i < table->numEntries; i++) { - if ((table->entries[i].size != 0) && (table->entries[i].medium == MEDIUM_CART)) { - table->entries[i].romAddr += romAddr; - } - } -} - -SoundFontData* AudioLoad_SyncLoadSeqFonts(s32 seqId, u32* outDefaultFontId) { - s32 pad[2]; - s32 index; - SoundFontData* fontData; - s32 numFonts; - s32 fontId; - s32 i; - - if (seqId >= gAudioCtx.numSequences) { - return NULL; - } - - fontId = 0xFF; - index = ((u16*)gAudioCtx.sequenceFontTable)[seqId]; - numFonts = gAudioCtx.sequenceFontTable[index++]; - - while (numFonts > 0) { - fontId = gAudioCtx.sequenceFontTable[index++]; - fontData = AudioLoad_SyncLoadFont(fontId); - numFonts--; - } - - *outDefaultFontId = fontId; - return fontData; -} - -void AudioLoad_SyncLoadSeqParts(s32 seqId, s32 arg1) { - s32 pad; - u32 defaultFontId; - - if (seqId < gAudioCtx.numSequences) { - if (arg1 & 2) { - AudioLoad_SyncLoadSeqFonts(seqId, &defaultFontId); - } - if (arg1 & 1) { - AudioLoad_SyncLoadSeq(seqId); - } - } -} - -s32 AudioLoad_SyncLoadSample(Sample* sample, s32 fontId) { - void* sampleAddr; - - if (sample->isRelocated == true) { - if (sample->medium != MEDIUM_RAM) { - sampleAddr = AudioHeap_AllocSampleCache(sample->size, fontId, (void*)sample->sampleAddr, sample->medium, - CACHE_PERSISTENT); - if (sampleAddr == NULL) { - return -1; - } - - if (sample->medium == MEDIUM_UNK) { - AudioLoad_SyncDmaUnkMedium((u32)sample->sampleAddr, sampleAddr, sample->size, - gAudioCtx.sampleBankTable->unkMediumParam); - } else { - AudioLoad_SyncDma((u32)sample->sampleAddr, sampleAddr, sample->size, sample->medium); - } - sample->medium = MEDIUM_RAM; - sample->sampleAddr = sampleAddr; - } - } -} - -s32 AudioLoad_SyncLoadInstrument(s32 fontId, s32 instId, s32 drumId) { - if (instId < 0x7F) { - Instrument* instrument = Audio_GetInstrumentInner(fontId, instId); - - if (instrument == NULL) { - return -1; - } - if (instrument->normalRangeLo != 0) { - AudioLoad_SyncLoadSample(instrument->lowPitchTunedSample.sample, fontId); - } - AudioLoad_SyncLoadSample(instrument->normalPitchTunedSample.sample, fontId); - if (instrument->normalRangeHi != 0x7F) { - return AudioLoad_SyncLoadSample(instrument->highPitchTunedSample.sample, fontId); - } - } else if (instId == 0x7F) { - Drum* drum = Audio_GetDrum(fontId, drumId); - - if (drum == NULL) { - return -1; - } - AudioLoad_SyncLoadSample(drum->tunedSample.sample, fontId); - return 0; - } -} - -void AudioLoad_AsyncLoad(s32 tableType, s32 id, s32 nChunks, s32 retData, OSMesgQueue* retQueue) { - if (AudioLoad_AsyncLoadInner(tableType, id, nChunks, retData, retQueue) == NULL) { - osSendMesg(retQueue, (OSMesg)0xFFFFFFFF, OS_MESG_NOBLOCK); - } -} - -void AudioLoad_AsyncLoadSeq(s32 seqId, s32 arg1, s32 retData, OSMesgQueue* retQueue) { - AudioLoad_AsyncLoad(SEQUENCE_TABLE, seqId, 0, retData, retQueue); -} - -void AudioLoad_AsyncLoadSampleBank(s32 sampleBankId, s32 arg1, s32 retData, OSMesgQueue* retQueue) { - AudioLoad_AsyncLoad(SAMPLE_TABLE, sampleBankId, 0, retData, retQueue); -} - -void AudioLoad_AsyncLoadFont(s32 fontId, s32 arg1, s32 retData, OSMesgQueue* retQueue) { - AudioLoad_AsyncLoad(FONT_TABLE, fontId, 0, retData, retQueue); -} - -u8* AudioLoad_GetFontsForSequence(s32 seqId, u32* outNumFonts) { - s32 index = ((u16*)gAudioCtx.sequenceFontTable)[seqId]; - - *outNumFonts = gAudioCtx.sequenceFontTable[index++]; - if (*outNumFonts == 0) { - return NULL; - } - return &gAudioCtx.sequenceFontTable[index]; -} - -void AudioLoad_DiscardSeqFonts(s32 seqId) { - s32 fontId; - s32 index = ((u16*)gAudioCtx.sequenceFontTable)[seqId]; - s32 numFonts = gAudioCtx.sequenceFontTable[index++]; - - while (numFonts > 0) { - numFonts--; - fontId = AudioLoad_GetRealTableIndex(FONT_TABLE, gAudioCtx.sequenceFontTable[index++]); - if (AudioHeap_SearchPermanentCache(FONT_TABLE, fontId) == NULL) { - AudioLoad_DiscardFont(fontId); - AudioLoad_SetFontLoadStatus(fontId, LOAD_STATUS_NOT_LOADED); - } - } -} - -void AudioLoad_DiscardFont(s32 fontId) { - u32 i; - AudioCache* pool = &gAudioCtx.fontCache; - AudioPersistentCache* persistent; - - if (fontId == pool->temporary.entries[0].id) { - pool->temporary.entries[0].id = -1; - } else if (fontId == pool->temporary.entries[1].id) { - pool->temporary.entries[1].id = -1; - } - - persistent = &pool->persistent; - for (i = 0; i < persistent->numEntries; i++) { - if (fontId == persistent->entries[i].id) { - persistent->entries[i].id = -1; - } - } - - AudioHeap_DiscardFont(fontId); -} - -s32 AudioLoad_SyncInitSeqPlayer(s32 playerIdx, s32 seqId, s32 arg2) { - if (gAudioCtx.resetTimer != 0) { - return 0; - } - - gAudioCtx.seqPlayers[playerIdx].skipTicks = 0; - AudioLoad_SyncInitSeqPlayerInternal(playerIdx, seqId, arg2); - // Intentionally missing return. Returning the result of the above function - // call matches but is UB because it too is missing a return, and using the - // result of a non-void function that has failed to return a value is UB. - // The callers of this function do not use the return value, so it's fine. -} - -s32 AudioLoad_SyncInitSeqPlayerSkipTicks(s32 playerIdx, s32 seqId, s32 skipTicks) { - if (gAudioCtx.resetTimer != 0) { - return 0; - } - - gAudioCtx.seqPlayers[playerIdx].skipTicks = skipTicks; - AudioLoad_SyncInitSeqPlayerInternal(playerIdx, seqId, 0); - // Missing return, see above. -} - -s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; - u8* seqData; - s32 index; - s32 numFonts; - s32 fontId; - - if (seqId >= gAudioCtx.numSequences) { - return 0; - } - - AudioSeq_SequencePlayerDisable(seqPlayer); - - fontId = 0xFF; - index = ((u16*)gAudioCtx.sequenceFontTable)[seqId]; - numFonts = gAudioCtx.sequenceFontTable[index++]; - - while (numFonts > 0) { - fontId = gAudioCtx.sequenceFontTable[index++]; - AudioLoad_SyncLoadFont(fontId); - numFonts--; - } - - seqData = AudioLoad_SyncLoadSeq(seqId); - if (seqData == NULL) { - return 0; - } - - AudioSeq_ResetSequencePlayer(seqPlayer); - seqPlayer->seqId = seqId; - seqPlayer->defaultFont = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId); - seqPlayer->seqData = seqData; - seqPlayer->enabled = true; - seqPlayer->scriptState.pc = seqData; - seqPlayer->scriptState.depth = 0; - seqPlayer->delay = 0; - seqPlayer->finished = false; - seqPlayer->playerIdx = playerIdx; - AudioSeq_SkipForwardSequence(seqPlayer); - //! @bug missing return (but the return value is not used so it's not UB) -} - -u8* AudioLoad_SyncLoadSeq(s32 seqId) { - s32 pad; - s32 didAllocate; - - if (gAudioCtx.seqLoadStatus[AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId)] == LOAD_STATUS_IN_PROGRESS) { - return NULL; - } - - return AudioLoad_SyncLoad(SEQUENCE_TABLE, seqId, &didAllocate); -} - -u32 AudioLoad_GetSampleBank(u32 sampleBankId, u32* outMedium) { - return AudioLoad_TrySyncLoadSampleBank(sampleBankId, outMedium, true); -} - -u32 AudioLoad_TrySyncLoadSampleBank(u32 sampleBankId, u32* outMedium, s32 noLoad) { - void* ramAddr; - AudioTable* sampleBankTable; - u32 realTableId = AudioLoad_GetRealTableIndex(SAMPLE_TABLE, sampleBankId); - s8 cachePolicy; - - sampleBankTable = AudioLoad_GetLoadTable(SAMPLE_TABLE); - ramAddr = AudioLoad_SearchCaches(SAMPLE_TABLE, realTableId); - if (ramAddr != NULL) { - if (gAudioCtx.sampleFontLoadStatus[realTableId] != LOAD_STATUS_IN_PROGRESS) { - AudioLoad_SetSampleFontLoadStatus(realTableId, LOAD_STATUS_COMPLETE); - } - *outMedium = MEDIUM_RAM; - return (u32)ramAddr; - } - - cachePolicy = sampleBankTable->entries[sampleBankId].cachePolicy; - if (cachePolicy == 4 || noLoad == true) { - *outMedium = sampleBankTable->entries[sampleBankId].medium; - return sampleBankTable->entries[realTableId].romAddr; - } - - ramAddr = AudioLoad_SyncLoad(SAMPLE_TABLE, sampleBankId, &noLoad); - if (ramAddr != NULL) { - *outMedium = MEDIUM_RAM; - return (u32)ramAddr; - } - - *outMedium = sampleBankTable->entries[sampleBankId].medium; - return sampleBankTable->entries[realTableId].romAddr; -} - -SoundFontData* AudioLoad_SyncLoadFont(u32 fontId) { - SoundFontData* fontData; - s32 sampleBankId1; - s32 sampleBankId2; - s32 didAllocate; - SampleBankRelocInfo sampleBankReloc; - s32 realFontId = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId); - - if (gAudioCtx.fontLoadStatus[realFontId] == LOAD_STATUS_IN_PROGRESS) { - return NULL; - } - sampleBankId1 = gAudioCtx.soundFontList[realFontId].sampleBankId1; - sampleBankId2 = gAudioCtx.soundFontList[realFontId].sampleBankId2; - - sampleBankReloc.sampleBankId1 = sampleBankId1; - sampleBankReloc.sampleBankId2 = sampleBankId2; - if (sampleBankId1 != 0xFF) { - sampleBankReloc.baseAddr1 = AudioLoad_TrySyncLoadSampleBank(sampleBankId1, &sampleBankReloc.medium1, false); - } else { - sampleBankReloc.baseAddr1 = 0; - } - - if (sampleBankId2 != 0xFF) { - sampleBankReloc.baseAddr2 = AudioLoad_TrySyncLoadSampleBank(sampleBankId2, &sampleBankReloc.medium2, false); - } else { - sampleBankReloc.baseAddr2 = 0; - } - - fontData = AudioLoad_SyncLoad(FONT_TABLE, fontId, &didAllocate); - if (fontData == NULL) { - return NULL; - } - if (didAllocate == true) { - AudioLoad_RelocateFontAndPreloadSamples(realFontId, fontData, &sampleBankReloc, false); - } - - return fontData; -} - -void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) { - u32 size; - AudioTable* table; - s32 pad; - u32 medium; - s32 loadStatus; - u32 romAddr; - s32 cachePolicy; - void* ramAddr; - u32 realId; - - realId = AudioLoad_GetRealTableIndex(tableType, id); - ramAddr = AudioLoad_SearchCaches(tableType, realId); - if (ramAddr != NULL) { - *didAllocate = false; - loadStatus = LOAD_STATUS_COMPLETE; - } else { - table = AudioLoad_GetLoadTable(tableType); - size = table->entries[realId].size; - size = ALIGN16(size); - medium = table->entries[id].medium; - cachePolicy = table->entries[id].cachePolicy; - romAddr = table->entries[realId].romAddr; - switch (cachePolicy) { - case 0: - ramAddr = AudioHeap_AllocPermanent(tableType, realId, size); - if (ramAddr == NULL) { - return ramAddr; - } - break; - - case 1: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - - case 2: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_TEMPORARY, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - - case 3: - case 4: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_EITHER, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - } - - *didAllocate = true; - if (medium == MEDIUM_UNK) { - AudioLoad_SyncDmaUnkMedium(romAddr, ramAddr, size, (s16)table->unkMediumParam); - } else { - AudioLoad_SyncDma(romAddr, ramAddr, size, medium); - } - - loadStatus = (cachePolicy == 0) ? LOAD_STATUS_PERMANENTLY_LOADED : LOAD_STATUS_COMPLETE; - } - - switch (tableType) { - case SEQUENCE_TABLE: - AudioLoad_SetSeqLoadStatus(realId, loadStatus); - break; - - case FONT_TABLE: - AudioLoad_SetFontLoadStatus(realId, loadStatus); - break; - - case SAMPLE_TABLE: - AudioLoad_SetSampleFontLoadStatusAndApplyCaches(realId, loadStatus); - break; - - default: - break; - } - - return ramAddr; -} - -u32 AudioLoad_GetRealTableIndex(s32 tableType, u32 id) { - AudioTable* table = AudioLoad_GetLoadTable(tableType); - - if (table->entries[id].size == 0) { - id = table->entries[id].romAddr; - } - - return id; -} - -void* AudioLoad_SearchCaches(s32 tableType, s32 id) { - void* ramAddr; - - ramAddr = AudioHeap_SearchPermanentCache(tableType, id); - if (ramAddr != NULL) { - return ramAddr; - } - - ramAddr = AudioHeap_SearchCaches(tableType, CACHE_EITHER, id); - if (ramAddr != NULL) { - return ramAddr; - } - - return NULL; -} - -AudioTable* AudioLoad_GetLoadTable(s32 tableType) { - AudioTable* table; - - switch (tableType) { - case SEQUENCE_TABLE: - table = gAudioCtx.sequenceTable; - break; - - case FONT_TABLE: - table = gAudioCtx.soundFontTable; - break; - - default: - table = NULL; - break; - - case SAMPLE_TABLE: - table = gAudioCtx.sampleBankTable; - break; - } - return table; -} - -/** - * Read and extract information from soundFont binary loaded into ram. - * Also relocate offsets into pointers within this loaded soundFont - * - * @param fontId index of font being processed - * @param fontData ram address of raw soundfont binary loaded into cache - * @param sampleBankReloc information on the sampleBank containing raw audio samples - */ -void AudioLoad_RelocateFont(s32 fontId, SoundFontData* fontDataStartAddr, SampleBankRelocInfo* sampleBankReloc) { - u32 soundOffset; // Relative offset from the beginning of fontData directly to the tunedSample/envelope - u32 soundListOffset; // Relative offset from the beginning of fontData to the list of soundOffsets/sfxs - Instrument* inst; - Drum* drum; - SoundEffect* soundEffect; - s32 i; - s32 numDrums = gAudioCtx.soundFontList[fontId].numDrums; - s32 numInstruments = gAudioCtx.soundFontList[fontId].numInstruments; - s32 numSfx = gAudioCtx.soundFontList[fontId].numSfx; - u32* fontData = (u32*)fontDataStartAddr; - - // Relocate an offset (relative to the start of the font data) to a pointer (a ram address) -#define RELOC_TO_RAM(offset) ((u32)(offset) + (u32)(fontDataStartAddr)) - - // Drums relocation - - // The first u32 in fontData is an offset to a list of offsets to the drums - soundListOffset = fontData[0]; - if (1) {} - - // If the soundFont has drums - if ((soundListOffset != 0) && (numDrums != 0)) { - - fontData[0] = RELOC_TO_RAM(soundListOffset); - - // Loop through the drum offsets - for (i = 0; i < numDrums; i++) { - // Get the i'th drum offset - soundOffset = (u32)((Drum**)fontData[0])[i]; - - // Some drum data entries are empty, represented by an offset of 0 in the list of drum offsets - if (soundOffset != 0) { - soundOffset = RELOC_TO_RAM(soundOffset); - ((Drum**)fontData[0])[i] = drum = (Drum*)soundOffset; - - // The drum may be in the list multiple times and already relocated - if (!drum->isRelocated) { - AudioLoad_RelocateSample(&drum->tunedSample, fontDataStartAddr, sampleBankReloc); - - soundOffset = (u32)drum->envelope; - drum->envelope = (EnvelopePoint*)RELOC_TO_RAM(soundOffset); - - drum->isRelocated = true; - } - } - } - } - - // Sound effects relocation - - // The second u32 in fontData is an offset to the first sound effect entry - soundListOffset = fontData[1]; - if (1) {} - - // If the soundFont has sound effects - if ((soundListOffset != 0) && (numSfx != 0)) { - - fontData[1] = RELOC_TO_RAM(soundListOffset); - - // Loop through the sound effects - for (i = 0; i < numSfx; i++) { - // Get a pointer to the i'th sound effect - soundOffset = (u32)(((SoundEffect*)fontData[1]) + i); - soundEffect = (SoundEffect*)soundOffset; - - // Check for NULL (note: the pointer is guaranteed to be in fontData and can never be NULL) - if ((soundEffect != NULL) && ((u32)soundEffect->tunedSample.sample != 0)) { - AudioLoad_RelocateSample(&soundEffect->tunedSample, fontDataStartAddr, sampleBankReloc); - } - } - } - - // Instruments relocation - - // Instrument Id 126 and above is reserved. - // There can only be 126 instruments, indexed from 0 to 125 - if (numInstruments > 126) { - numInstruments = 126; - } - - // Starting from the 3rd u32 in fontData is the list of offsets to the instruments - // Loop through the instruments - for (i = 2; i <= 2 + numInstruments - 1; i++) { - // Some instrument data entries are empty, represented by an offset of 0 in the list of instrument offsets - if (fontData[i] != 0) { - fontData[i] = RELOC_TO_RAM(fontData[i]); - inst = (Instrument*)fontData[i]; - - // The instrument may be in the list multiple times and already relocated - if (!inst->isRelocated) { - // Some instruments have a different sample for low pitches - if (inst->normalRangeLo != 0) { - AudioLoad_RelocateSample(&inst->lowPitchTunedSample, fontDataStartAddr, sampleBankReloc); - } - - // Every instrument has a sample for the default range - AudioLoad_RelocateSample(&inst->normalPitchTunedSample, fontDataStartAddr, sampleBankReloc); - - // Some instruments have a different sample for high pitches - if (inst->normalRangeHi != 0x7F) { - AudioLoad_RelocateSample(&inst->highPitchTunedSample, fontDataStartAddr, sampleBankReloc); - } - - soundOffset = (u32)inst->envelope; - inst->envelope = (EnvelopePoint*)RELOC_TO_RAM(soundOffset); - - inst->isRelocated = true; - } - } - } - -#undef FONT_DATA_RELOC - - // Store the relocated pointers - gAudioCtx.soundFontList[fontId].drums = (Drum**)fontData[0]; - gAudioCtx.soundFontList[fontId].soundEffects = (SoundEffect*)fontData[1]; - gAudioCtx.soundFontList[fontId].instruments = (Instrument**)(fontData + 2); -} - -void AudioLoad_SyncDma(u32 devAddr, u8* ramAddr, u32 size, s32 medium) { - OSMesgQueue* msgQueue = &gAudioCtx.syncDmaQueue; - OSIoMesg* ioMesg = &gAudioCtx.syncDmaIoMesg; - size = ALIGN16(size); - - Audio_InvalDCache(ramAddr, size); - - while (true) { - if (size < 0x400) { - break; - } - AudioLoad_Dma(ioMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, ramAddr, 0x400, msgQueue, medium, "FastCopy"); - osRecvMesg(msgQueue, NULL, OS_MESG_BLOCK); - size -= 0x400; - devAddr += 0x400; - ramAddr += 0x400; - } - - if (size != 0) { - AudioLoad_Dma(ioMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, ramAddr, size, msgQueue, medium, "FastCopy"); - osRecvMesg(msgQueue, NULL, OS_MESG_BLOCK); - } -} - -void AudioLoad_SyncDmaUnkMedium(u32 devAddr, u8* addr, u32 size, s32 unkMediumParam) { -} - -s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, u32 devAddr, void* ramAddr, u32 size, - OSMesgQueue* reqQueue, s32 medium, const char* dmaFuncType) { - OSPiHandle* handle; - - if (gAudioCtx.resetTimer > 16) { - return -1; - } - - switch (medium) { - case MEDIUM_CART: - handle = gAudioCtx.cartHandle; - break; - - case MEDIUM_DISK_DRIVE: - // driveHandle is uninitialized and corresponds to stubbed-out disk drive support. - // SM64 Shindou called osDriveRomInit here. - handle = gAudioCtx.driveHandle; - break; - - default: - return 0; - } - - if ((size % 0x10) != 0) { - size = ALIGN16(size); - } - - mesg->hdr.pri = priority; - mesg->hdr.retQueue = reqQueue; - mesg->dramAddr = ramAddr; - mesg->devAddr = devAddr; - mesg->size = size; - handle->transferInfo.cmdType = 2; - sDmaHandler(handle, mesg, direction); - return 0; -} - -void AudioLoad_Unused1(void) { -} - -void AudioLoad_SyncLoadSimple(u32 tableType, u32 fontId) { - s32 didAllocate; - - AudioLoad_SyncLoad(tableType, fontId, &didAllocate); -} - -void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, OSMesgQueue* retQueue) { - u32 size; - AudioTable* table; - void* ramAddr; - s32 medium; - s8 cachePolicy; - u32 devAddr; - s32 loadStatus; - s32 pad; - u32 realId = AudioLoad_GetRealTableIndex(tableType, id); - - switch (tableType) { - case SEQUENCE_TABLE: - if (gAudioCtx.seqLoadStatus[realId] == LOAD_STATUS_IN_PROGRESS) { - return NULL; - } - break; - - case FONT_TABLE: - if (gAudioCtx.fontLoadStatus[realId] == LOAD_STATUS_IN_PROGRESS) { - return NULL; - } - break; - - case SAMPLE_TABLE: - if (gAudioCtx.sampleFontLoadStatus[realId] == LOAD_STATUS_IN_PROGRESS) { - return NULL; - } - break; - } - - ramAddr = AudioLoad_SearchCaches(tableType, realId); - if (ramAddr != NULL) { - loadStatus = LOAD_STATUS_COMPLETE; - osSendMesg(retQueue, (OSMesg)MK_ASYNC_MSG(retData, 0, 0, LOAD_STATUS_NOT_LOADED), OS_MESG_NOBLOCK); - } else { - table = AudioLoad_GetLoadTable(tableType); - size = table->entries[realId].size; - size = ALIGN16(size); - medium = table->entries[id].medium; - cachePolicy = table->entries[id].cachePolicy; - devAddr = table->entries[realId].romAddr; - loadStatus = LOAD_STATUS_COMPLETE; - - switch (cachePolicy) { - case 0: - ramAddr = AudioHeap_AllocPermanent(tableType, realId, size); - if (ramAddr == NULL) { - return ramAddr; - } - loadStatus = LOAD_STATUS_PERMANENTLY_LOADED; - break; - - case 1: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - - case 2: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_TEMPORARY, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - - case 3: - case 4: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_EITHER, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - } - - if (medium == MEDIUM_UNK) { - AudioLoad_StartAsyncLoadUnkMedium((s16)table->unkMediumParam, devAddr, ramAddr, size, medium, nChunks, - retQueue, MK_ASYNC_MSG(retData, tableType, id, loadStatus)); - } else { - AudioLoad_StartAsyncLoad(devAddr, ramAddr, size, medium, nChunks, retQueue, - MK_ASYNC_MSG(retData, tableType, realId, loadStatus)); - } - loadStatus = LOAD_STATUS_IN_PROGRESS; - } - - switch (tableType) { - case SEQUENCE_TABLE: - AudioLoad_SetSeqLoadStatus(realId, loadStatus); - break; - - case FONT_TABLE: - AudioLoad_SetFontLoadStatus(realId, loadStatus); - break; - - case SAMPLE_TABLE: - AudioLoad_SetSampleFontLoadStatusAndApplyCaches(realId, loadStatus); - break; - - default: - break; - } - - return ramAddr; -} - -void AudioLoad_ProcessLoads(s32 resetStatus) { - AudioLoad_ProcessSlowLoads(resetStatus); - AudioLoad_ProcessSamplePreloads(resetStatus); - AudioLoad_ProcessAsyncLoads(resetStatus); -} - -void AudioLoad_SetDmaHandler(DmaHandler callback) { - sDmaHandler = callback; -} - -void AudioLoad_SetUnusedHandler(void* callback) { - sUnusedHandler = callback; -} - -void AudioLoad_InitSoundFont(s32 fontId) { - SoundFont* font = &gAudioCtx.soundFontList[fontId]; - AudioTableEntry* entry = &gAudioCtx.soundFontTable->entries[fontId]; - - font->sampleBankId1 = (entry->shortData1 >> 8) & 0xFF; - font->sampleBankId2 = (entry->shortData1) & 0xFF; - font->numInstruments = (entry->shortData2 >> 8) & 0xFF; - font->numDrums = entry->shortData2 & 0xFF; - font->numSfx = entry->shortData3; -} - -void AudioLoad_Init(void* heap, u32 heapSize) { - s32 pad[18]; - s32 numFonts; - void* ramAddr; - s32 i; - - D_801755D0 = NULL; - gAudioCtx.resetTimer = 0; - - { - s32 i; - u8* audioContextPtr = (u8*)&gAudioCtx; - - for (i = sizeof(gAudioCtx); i >= 0; i--) { - *audioContextPtr++ = 0; - } - } - - switch (osTvType) { - case OS_TV_PAL: - gAudioCtx.unk_2960 = 20.03042f; - gAudioCtx.refreshRate = 50; - break; - - case OS_TV_MPAL: - gAudioCtx.unk_2960 = 16.546f; - gAudioCtx.refreshRate = 60; - break; - - case OS_TV_NTSC: - default: - gAudioCtx.unk_2960 = 16.713f; - gAudioCtx.refreshRate = 60; - break; - } - - Audio_InitMesgQueues(); - - for (i = 0; i < 3; i++) { - gAudioCtx.aiBufLengths[i] = 0xA0; - } - - gAudioCtx.totalTaskCount = 0; - gAudioCtx.rspTaskIndex = 0; - gAudioCtx.curAiBufIndex = 0; - gAudioCtx.soundMode = SOUNDMODE_STEREO; - gAudioCtx.curTask = NULL; - gAudioCtx.rspTask[0].task.t.data_size = 0; - gAudioCtx.rspTask[1].task.t.data_size = 0; - osCreateMesgQueue(&gAudioCtx.syncDmaQueue, &gAudioCtx.syncDmaMesg, 1); - osCreateMesgQueue(&gAudioCtx.curAudioFrameDmaQueue, gAudioCtx.curAudioFrameDmaMsgBuf, - ARRAY_COUNT(gAudioCtx.curAudioFrameDmaMsgBuf)); - osCreateMesgQueue(&gAudioCtx.externalLoadQueue, gAudioCtx.externalLoadMsgBuf, - ARRAY_COUNT(gAudioCtx.externalLoadMsgBuf)); - osCreateMesgQueue(&gAudioCtx.preloadSampleQueue, gAudioCtx.preloadSampleMsgBuf, - ARRAY_COUNT(gAudioCtx.preloadSampleMsgBuf)); - gAudioCtx.curAudioFrameDmaCount = 0; - gAudioCtx.sampleDmaCount = 0; - gAudioCtx.cartHandle = osCartRomInit(); - - if (heap == NULL) { - gAudioCtx.audioHeap = gAudioHeap; - gAudioCtx.audioHeapSize = gAudioHeapInitSizes.heapSize; - } else { - void** hp = &heap; - gAudioCtx.audioHeap = *hp; - gAudioCtx.audioHeapSize = heapSize; - } - - for (i = 0; i < (s32)gAudioCtx.audioHeapSize / 8; i++) { - ((u64*)gAudioCtx.audioHeap)[i] = 0; - } - - // Main Pool Split (split entirety of audio heap into initPool and sessionPool) - AudioHeap_InitMainPools(gAudioHeapInitSizes.initPoolSize); - - // Initialize the audio interface buffers - for (i = 0; i < ARRAY_COUNT(gAudioCtx.aiBuffers); i++) { - gAudioCtx.aiBuffers[i] = AudioHeap_AllocZeroed(&gAudioCtx.initPool, AIBUF_SIZE); - } - - // Set audio tables pointers - gAudioCtx.sequenceTable = (AudioTable*)gSequenceTable; - gAudioCtx.soundFontTable = (AudioTable*)gSoundFontTable; - gAudioCtx.sampleBankTable = (AudioTable*)gSampleBankTable; - gAudioCtx.sequenceFontTable = gSequenceFontTable; - - gAudioCtx.numSequences = gAudioCtx.sequenceTable->numEntries; - - gAudioCtx.audioResetSpecIdToLoad = 0; - gAudioCtx.resetStatus = 1; // Set reset to immediately initialize the audio heap - - AudioHeap_ResetStep(); - - // Initialize audio tables - AudioLoad_InitTable(gAudioCtx.sequenceTable, (u32)_AudioseqSegmentRomStart, 0); - AudioLoad_InitTable(gAudioCtx.soundFontTable, (u32)_AudiobankSegmentRomStart, 0); - AudioLoad_InitTable(gAudioCtx.sampleBankTable, (u32)_AudiotableSegmentRomStart, 0); - numFonts = gAudioCtx.soundFontTable->numEntries; - gAudioCtx.soundFontList = AudioHeap_Alloc(&gAudioCtx.initPool, numFonts * sizeof(SoundFont)); - - for (i = 0; i < numFonts; i++) { - AudioLoad_InitSoundFont(i); - } - - ramAddr = AudioHeap_Alloc(&gAudioCtx.initPool, gAudioHeapInitSizes.permanentPoolSize); - if (ramAddr == NULL) { - // cast away const from gAudioHeapInitSizes - *((u32*)&gAudioHeapInitSizes.permanentPoolSize) = 0; - } - - AudioHeap_InitPool(&gAudioCtx.permanentPool, ramAddr, gAudioHeapInitSizes.permanentPoolSize); - gAudioContextInitialized = true; - osSendMesg(gAudioCtx.taskStartQueueP, (OSMesg)gAudioCtx.totalTaskCount, OS_MESG_NOBLOCK); -} - -void AudioLoad_InitSlowLoads(void) { - gAudioCtx.slowLoads[0].state = SLOW_LOAD_STATE_WAITING; - gAudioCtx.slowLoads[1].state = SLOW_LOAD_STATE_WAITING; -} - -s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* status) { - Sample* sample; - AudioSlowLoad* slowLoad; - - sample = AudioLoad_GetFontSample(fontId, instId); - if (sample == NULL) { - *status = 0; - return -1; - } - - if (sample->medium == MEDIUM_RAM) { - *status = 2; - return 0; - } - - slowLoad = &gAudioCtx.slowLoads[gAudioCtx.slowLoadPos]; - if (slowLoad->state == SLOW_LOAD_STATE_DONE) { - slowLoad->state = SLOW_LOAD_STATE_WAITING; - } - - slowLoad->sample = *sample; - slowLoad->status = status; - slowLoad->curRamAddr = - AudioHeap_AllocSampleCache(sample->size, fontId, sample->sampleAddr, sample->medium, CACHE_TEMPORARY); - - if (slowLoad->curRamAddr == NULL) { - if (sample->medium == MEDIUM_UNK || sample->codec == CODEC_S16_INMEMORY) { - *status = 0; - return -1; - } else { - *status = 3; - return -1; - } - } - - slowLoad->state = SLOW_LOAD_STATE_START; - slowLoad->bytesRemaining = ALIGN16(sample->size); - slowLoad->ramAddr = slowLoad->curRamAddr; - slowLoad->curDevAddr = (u32)sample->sampleAddr; - slowLoad->medium = sample->medium; - slowLoad->seqOrFontId = fontId; - slowLoad->instId = instId; - if (slowLoad->medium == MEDIUM_UNK) { - slowLoad->unkMediumParam = gAudioCtx.sampleBankTable->unkMediumParam; - } - - gAudioCtx.slowLoadPos ^= 1; - return 0; -} - -Sample* AudioLoad_GetFontSample(s32 fontId, s32 instId) { - Sample* sample; - - if (instId < 0x80) { - Instrument* instrument = Audio_GetInstrumentInner(fontId, instId); - - if (instrument == NULL) { - return NULL; - } - sample = instrument->normalPitchTunedSample.sample; - } else if (instId < 0x100) { - Drum* drum = Audio_GetDrum(fontId, instId - 0x80); - - if (drum == NULL) { - return NULL; - } - sample = drum->tunedSample.sample; - } else { - SoundEffect* soundEffect = Audio_GetSoundEffect(fontId, instId - 0x100); - - if (soundEffect == NULL) { - return NULL; - } - sample = soundEffect->tunedSample.sample; - } - return sample; -} - -void AudioLoad_Unused2(void) { -} - -void AudioLoad_FinishSlowLoad(AudioSlowLoad* slowLoad) { - Sample* sample; - - if (slowLoad->sample.sampleAddr == NULL) { - return; - } - - sample = AudioLoad_GetFontSample(slowLoad->seqOrFontId, slowLoad->instId); - if (sample == NULL) { - return; - } - - slowLoad->sample = *sample; - sample->sampleAddr = slowLoad->ramAddr; - sample->medium = MEDIUM_RAM; -} - -void AudioLoad_ProcessSlowLoads(s32 resetStatus) { - AudioSlowLoad* slowLoad; - s32 i; - - for (i = 0; i < ARRAY_COUNT(gAudioCtx.slowLoads); i++) { - slowLoad = &gAudioCtx.slowLoads[i]; - switch (gAudioCtx.slowLoads[i].state) { - case SLOW_LOAD_STATE_LOADING: - if (slowLoad->medium != MEDIUM_UNK) { - osRecvMesg(&slowLoad->msgQueue, NULL, OS_MESG_BLOCK); - } - - if (resetStatus != 0) { - slowLoad->state = SLOW_LOAD_STATE_DONE; - continue; - } - FALLTHROUGH; - case SLOW_LOAD_STATE_START: - slowLoad->state = SLOW_LOAD_STATE_LOADING; - if (slowLoad->bytesRemaining == 0) { - AudioLoad_FinishSlowLoad(slowLoad); - slowLoad->state = SLOW_LOAD_STATE_DONE; - *slowLoad->status = 1; - } else if (slowLoad->bytesRemaining < 0x400) { - if (slowLoad->medium == MEDIUM_UNK) { - u32 size = slowLoad->bytesRemaining; - - AudioLoad_DmaSlowCopyUnkMedium(slowLoad->curDevAddr, slowLoad->curRamAddr, size, - slowLoad->unkMediumParam); - } else { - AudioLoad_DmaSlowCopy(slowLoad, slowLoad->bytesRemaining); - } - slowLoad->bytesRemaining = 0; - } else { - if (slowLoad->medium == MEDIUM_UNK) { - AudioLoad_DmaSlowCopyUnkMedium(slowLoad->curDevAddr, slowLoad->curRamAddr, 0x400, - slowLoad->unkMediumParam); - } else { - AudioLoad_DmaSlowCopy(slowLoad, 0x400); - } - slowLoad->bytesRemaining -= 0x400; - slowLoad->curRamAddr += 0x400; - slowLoad->curDevAddr += 0x400; - } - break; - } - } -} - -void AudioLoad_DmaSlowCopy(AudioSlowLoad* slowLoad, s32 size) { - Audio_InvalDCache(slowLoad->curRamAddr, size); - osCreateMesgQueue(&slowLoad->msgQueue, &slowLoad->msg, 1); - AudioLoad_Dma(&slowLoad->ioMesg, OS_MESG_PRI_NORMAL, OS_READ, slowLoad->curDevAddr, slowLoad->curRamAddr, size, - &slowLoad->msgQueue, slowLoad->medium, "SLOWCOPY"); -} - -void AudioLoad_DmaSlowCopyUnkMedium(s32 devAddr, u8* ramAddr, s32 size, s32 arg3) { -} - -s32 AudioLoad_SlowLoadSeq(s32 seqId, u8* ramAddr, s8* status) { - AudioSlowLoad* slowLoad; - AudioTable* seqTable; - u32 size; - - if (seqId >= gAudioCtx.numSequences) { - *status = 0; - return -1; - } - - seqId = AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId); - seqTable = AudioLoad_GetLoadTable(SEQUENCE_TABLE); - slowLoad = &gAudioCtx.slowLoads[gAudioCtx.slowLoadPos]; - if (slowLoad->state == SLOW_LOAD_STATE_DONE) { - slowLoad->state = SLOW_LOAD_STATE_WAITING; - } - - slowLoad->sample.sampleAddr = NULL; - slowLoad->status = status; - size = seqTable->entries[seqId].size; - size = ALIGN16(size); - slowLoad->curRamAddr = ramAddr; - slowLoad->state = SLOW_LOAD_STATE_START; - slowLoad->bytesRemaining = size; - slowLoad->ramAddr = ramAddr; - slowLoad->curDevAddr = seqTable->entries[seqId].romAddr; - slowLoad->medium = seqTable->entries[seqId].medium; - slowLoad->seqOrFontId = seqId; - - if (slowLoad->medium == MEDIUM_UNK) { - slowLoad->unkMediumParam = seqTable->unkMediumParam; - } - - gAudioCtx.slowLoadPos ^= 1; - return 0; -} - -void AudioLoad_InitAsyncLoads(void) { - s32 i; - - for (i = 0; i < ARRAY_COUNT(gAudioCtx.asyncLoads); i++) { - gAudioCtx.asyncLoads[i].status = 0; - } -} - -AudioAsyncLoad* AudioLoad_StartAsyncLoadUnkMedium(s32 unkMediumParam, u32 devAddr, void* ramAddr, s32 size, s32 medium, - s32 nChunks, OSMesgQueue* retQueue, s32 retMsg) { - AudioAsyncLoad* asyncLoad; - - asyncLoad = AudioLoad_StartAsyncLoad(devAddr, ramAddr, size, medium, nChunks, retQueue, retMsg); - - if (asyncLoad == NULL) { - return NULL; - } - - osSendMesg(&gAudioCtx.asyncLoadUnkMediumQueue, (OSMesg)asyncLoad, OS_MESG_NOBLOCK); - asyncLoad->unkMediumParam = unkMediumParam; - return asyncLoad; -} - -AudioAsyncLoad* AudioLoad_StartAsyncLoad(u32 devAddr, void* ramAddr, u32 size, s32 medium, s32 nChunks, - OSMesgQueue* retQueue, s32 retMsg) { - AudioAsyncLoad* asyncLoad; - s32 i; - - for (i = 0; i < ARRAY_COUNT(gAudioCtx.asyncLoads); i++) { - if (gAudioCtx.asyncLoads[i].status == 0) { - asyncLoad = &gAudioCtx.asyncLoads[i]; - break; - } - } - - // no more available async loads - if (i == ARRAY_COUNT(gAudioCtx.asyncLoads)) { - return NULL; - } - - asyncLoad->status = 1; - asyncLoad->curDevAddr = devAddr; - asyncLoad->ramAddr = ramAddr; - asyncLoad->curRamAddr = ramAddr; - asyncLoad->bytesRemaining = size; - - if (nChunks == 0) { - asyncLoad->chunkSize = 0x1000; - } else if (nChunks == 1) { - asyncLoad->chunkSize = size; - } else { - asyncLoad->chunkSize = ALIGN256((s32)size / nChunks); - if (asyncLoad->chunkSize < 0x100) { - asyncLoad->chunkSize = 0x100; - } - } - - asyncLoad->retQueue = retQueue; - asyncLoad->delay = 3; - asyncLoad->medium = medium; - asyncLoad->retMsg = retMsg; - osCreateMesgQueue(&asyncLoad->msgQueue, &asyncLoad->msg, 1); - return asyncLoad; -} - -void AudioLoad_ProcessAsyncLoads(s32 resetStatus) { - AudioAsyncLoad* asyncLoad; - s32 i; - - if (gAudioCtx.resetTimer == 1) { - return; - } - - if (gAudioCtx.curUnkMediumLoad == NULL) { - if (resetStatus != 0) { - // Clear and ignore queue if resetting. - do { - } while (osRecvMesg(&gAudioCtx.asyncLoadUnkMediumQueue, (OSMesg*)&asyncLoad, OS_MESG_NOBLOCK) != -1); - } else if (osRecvMesg(&gAudioCtx.asyncLoadUnkMediumQueue, (OSMesg*)&asyncLoad, OS_MESG_NOBLOCK) == -1) { - gAudioCtx.curUnkMediumLoad = NULL; - } else { - gAudioCtx.curUnkMediumLoad = asyncLoad; - } - } - - if (gAudioCtx.curUnkMediumLoad != NULL) { - AudioLoad_ProcessAsyncLoadUnkMedium(gAudioCtx.curUnkMediumLoad, resetStatus); - } - - for (i = 0; i < ARRAY_COUNT(gAudioCtx.asyncLoads); i++) { - if (gAudioCtx.asyncLoads[i].status == 1) { - asyncLoad = &gAudioCtx.asyncLoads[i]; - if (asyncLoad->medium != MEDIUM_UNK) { - AudioLoad_ProcessAsyncLoad(asyncLoad, resetStatus); - } - } - } -} - -void AudioLoad_ProcessAsyncLoadUnkMedium(AudioAsyncLoad* asyncLoad, s32 resetStatus) { -} - -void AudioLoad_FinishAsyncLoad(AudioAsyncLoad* asyncLoad) { - u32 retMsg = asyncLoad->retMsg; - u32 fontId; - u32 pad; - OSMesg doneMsg; - u32 sampleBankId1; - u32 sampleBankId2; - SampleBankRelocInfo sampleBankReloc; - - if (1) {} - switch (ASYNC_TBLTYPE(retMsg)) { - case SEQUENCE_TABLE: - AudioLoad_SetSeqLoadStatus(ASYNC_ID(retMsg), ASYNC_LOAD_STATUS(retMsg)); - break; - - case SAMPLE_TABLE: - AudioLoad_SetSampleFontLoadStatusAndApplyCaches(ASYNC_ID(retMsg), ASYNC_LOAD_STATUS(retMsg)); - break; - - case FONT_TABLE: - fontId = ASYNC_ID(retMsg); - sampleBankId1 = gAudioCtx.soundFontList[fontId].sampleBankId1; - sampleBankId2 = gAudioCtx.soundFontList[fontId].sampleBankId2; - sampleBankReloc.sampleBankId1 = sampleBankId1; - sampleBankReloc.sampleBankId2 = sampleBankId2; - sampleBankReloc.baseAddr1 = - sampleBankId1 != 0xFF ? AudioLoad_GetSampleBank(sampleBankId1, &sampleBankReloc.medium1) : 0; - sampleBankReloc.baseAddr2 = - sampleBankId2 != 0xFF ? AudioLoad_GetSampleBank(sampleBankId2, &sampleBankReloc.medium2) : 0; - AudioLoad_SetFontLoadStatus(fontId, ASYNC_LOAD_STATUS(retMsg)); - AudioLoad_RelocateFontAndPreloadSamples(fontId, asyncLoad->ramAddr, &sampleBankReloc, true); - break; - } - - doneMsg = (OSMesg)asyncLoad->retMsg; - if (1) {} - asyncLoad->status = 0; - osSendMesg(asyncLoad->retQueue, doneMsg, OS_MESG_NOBLOCK); -} - -void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus) { - AudioTable* sampleBankTable = gAudioCtx.sampleBankTable; - - if (asyncLoad->delay >= 2) { - asyncLoad->delay--; - return; - } - - if (asyncLoad->delay == 1) { - asyncLoad->delay = 0; - } else if (resetStatus != 0) { - // Await the previous DMA response synchronously, then return. - osRecvMesg(&asyncLoad->msgQueue, NULL, OS_MESG_BLOCK); - asyncLoad->status = 0; - return; - } else if (osRecvMesg(&asyncLoad->msgQueue, NULL, OS_MESG_NOBLOCK) == -1) { - // If the previous DMA step isn't done, return. - return; - } - - if (asyncLoad->bytesRemaining == 0) { - AudioLoad_FinishAsyncLoad(asyncLoad); - return; - } - - if (asyncLoad->bytesRemaining < asyncLoad->chunkSize) { - if (asyncLoad->medium == MEDIUM_UNK) { - AudioLoad_AsyncDmaUnkMedium(asyncLoad->curDevAddr, asyncLoad->curRamAddr, asyncLoad->bytesRemaining, - sampleBankTable->unkMediumParam); - } else { - AudioLoad_AsyncDma(asyncLoad, asyncLoad->bytesRemaining); - } - asyncLoad->bytesRemaining = 0; - return; - } - - if (asyncLoad->medium == MEDIUM_UNK) { - AudioLoad_AsyncDmaUnkMedium(asyncLoad->curDevAddr, asyncLoad->curRamAddr, asyncLoad->chunkSize, - sampleBankTable->unkMediumParam); - } else { - AudioLoad_AsyncDma(asyncLoad, asyncLoad->chunkSize); - } - - asyncLoad->bytesRemaining -= asyncLoad->chunkSize; - asyncLoad->curDevAddr += asyncLoad->chunkSize; - asyncLoad->curRamAddr += asyncLoad->chunkSize; -} - -void AudioLoad_AsyncDma(AudioAsyncLoad* asyncLoad, u32 size) { - size = ALIGN16(size); - Audio_InvalDCache(asyncLoad->curRamAddr, size); - osCreateMesgQueue(&asyncLoad->msgQueue, &asyncLoad->msg, 1); - AudioLoad_Dma(&asyncLoad->ioMesg, OS_MESG_PRI_NORMAL, OS_READ, asyncLoad->curDevAddr, asyncLoad->curRamAddr, size, - &asyncLoad->msgQueue, asyncLoad->medium, "BGCOPY"); -} - -void AudioLoad_AsyncDmaUnkMedium(u32 devAddr, void* ramAddr, u32 size, s16 arg3) { -} - -/** - * Read and extract information from TunedSample and its Sample - * contained in the soundFont binary loaded into ram - * TunedSample contains metadata on a sample used by a particular instrument/drum/sfx - * Also relocate offsets into pointers within this loaded TunedSample - * - * @param fontId index of font being processed - * @param fontData ram address of raw soundfont binary loaded into cache - * @param sampleBankReloc information on the sampleBank containing raw audio samples - */ -void AudioLoad_RelocateSample(TunedSample* tunedSample, SoundFontData* fontData, SampleBankRelocInfo* sampleBankReloc) { - Sample* sample; - void* reloc; - - // Relocate an offset (relative to data loaded in ram at `base`) to a pointer (a ram address) -#define AUDIO_RELOC(offset, base) (reloc = (void*)((u32)(offset) + (u32)(base))) - - // If this has not already been relocated - if ((u32)tunedSample->sample <= AUDIO_RELOCATED_ADDRESS_START) { - - sample = tunedSample->sample = AUDIO_RELOC(tunedSample->sample, fontData); - - // If the sample exists and has not already been relocated - // Note: this is important, as the same sample can be used by different drums, sound effects, instruments - if ((sample->size != 0) && (sample->isRelocated != true)) { - sample->loop = AUDIO_RELOC(sample->loop, fontData); - sample->book = AUDIO_RELOC(sample->book, fontData); - - // Resolve the sample medium 2-bit bitfield into a real value based on sampleBankReloc. - // Then relocate the offset sample within the sampleBank (not the fontData) into absolute address. - // sampleAddr can be either rom or ram depending on sampleBank cache policy - // in practice, this is always in rom - switch (sample->medium) { - case 0: - sample->sampleAddr = AUDIO_RELOC(sample->sampleAddr, sampleBankReloc->baseAddr1); - sample->medium = sampleBankReloc->medium1; - break; - - case 1: - sample->sampleAddr = AUDIO_RELOC(sample->sampleAddr, sampleBankReloc->baseAddr2); - sample->medium = sampleBankReloc->medium2; - break; - - case 2: - case 3: - // Invalid? This leaves sample->medium as MEDIUM_CART and MEDIUM_DISK_DRIVE - // respectively, and the sampleAddr unrelocated. - break; - } - - sample->isRelocated = true; - - if (sample->unk_bit26 && (sample->medium != MEDIUM_RAM)) { - gAudioCtx.usedSamples[gAudioCtx.numUsedSamples++] = sample; - } - } - } - -#undef AUDIO_RELOC -} - -/** - * @param fontId index of font being processed - * @param fontData ram address of raw soundfont binary loaded into cache - * @param sampleBankReloc information on the sampleBank containing raw audio samples - * @param isAsync bool for whether this is an asynchronous load or not - */ -void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* fontData, SampleBankRelocInfo* sampleBankReloc, - s32 isAsync) { - AudioPreloadReq* preload; - AudioPreloadReq* topPreload; - Sample* sample; - s32 size; - s32 nChunks; - u8* sampleRamAddr; - s32 preloadInProgress; - s32 i; - - preloadInProgress = false; - if (gAudioCtx.preloadSampleStackTop != 0) { - preloadInProgress = true; - } else { - D_8016B780 = 0; - } - - gAudioCtx.numUsedSamples = 0; - AudioLoad_RelocateFont(fontId, fontData, sampleBankReloc); - - size = 0; - for (i = 0; i < gAudioCtx.numUsedSamples; i++) { - size += ALIGN16(gAudioCtx.usedSamples[i]->size); - } - if (size && size) {} - - for (i = 0; i < gAudioCtx.numUsedSamples; i++) { - if (gAudioCtx.preloadSampleStackTop == 120) { - break; - } - - sample = gAudioCtx.usedSamples[i]; - sampleRamAddr = NULL; - switch (isAsync) { - case false: - if (sample->medium == sampleBankReloc->medium1) { - sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId1, - sample->sampleAddr, sample->medium, CACHE_PERSISTENT); - } else if (sample->medium == sampleBankReloc->medium2) { - sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId2, - sample->sampleAddr, sample->medium, CACHE_PERSISTENT); - } else if (sample->medium == MEDIUM_DISK_DRIVE) { - sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, 0xFE, sample->sampleAddr, sample->medium, - CACHE_PERSISTENT); - } - break; - - case true: - if (sample->medium == sampleBankReloc->medium1) { - sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId1, - sample->sampleAddr, sample->medium, CACHE_TEMPORARY); - } else if (sample->medium == sampleBankReloc->medium2) { - sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId2, - sample->sampleAddr, sample->medium, CACHE_TEMPORARY); - } else if (sample->medium == MEDIUM_DISK_DRIVE) { - sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, 0xFE, sample->sampleAddr, sample->medium, - CACHE_TEMPORARY); - } - break; - } - if (sampleRamAddr == NULL) { - continue; - } - - switch (isAsync) { - case false: - if (sample->medium == MEDIUM_UNK) { - AudioLoad_SyncDmaUnkMedium((u32)sample->sampleAddr, sampleRamAddr, sample->size, - gAudioCtx.sampleBankTable->unkMediumParam); - sample->sampleAddr = sampleRamAddr; - sample->medium = MEDIUM_RAM; - } else { - AudioLoad_SyncDma((u32)sample->sampleAddr, sampleRamAddr, sample->size, sample->medium); - sample->sampleAddr = sampleRamAddr; - sample->medium = MEDIUM_RAM; - } - if (sample->medium == MEDIUM_DISK_DRIVE) {} - break; - - case true: - preload = &gAudioCtx.preloadSampleStack[gAudioCtx.preloadSampleStackTop]; - preload->sample = sample; - preload->ramAddr = sampleRamAddr; - preload->encodedInfo = (gAudioCtx.preloadSampleStackTop << 24) | 0xFFFFFF; - preload->isFree = false; - preload->endAndMediumKey = (u32)sample->sampleAddr + sample->size + sample->medium; - gAudioCtx.preloadSampleStackTop++; - break; - } - } - gAudioCtx.numUsedSamples = 0; - - if (gAudioCtx.preloadSampleStackTop != 0 && !preloadInProgress) { - topPreload = &gAudioCtx.preloadSampleStack[gAudioCtx.preloadSampleStackTop - 1]; - sample = topPreload->sample; - nChunks = (sample->size >> 12) + 1; - AudioLoad_StartAsyncLoad((u32)sample->sampleAddr, topPreload->ramAddr, sample->size, sample->medium, nChunks, - &gAudioCtx.preloadSampleQueue, topPreload->encodedInfo); - } -} - -s32 AudioLoad_ProcessSamplePreloads(s32 resetStatus) { - Sample* sample; - AudioPreloadReq* preload; - u32 preloadIndex; - u32 key; - u32 nChunks; - s32 pad; - - if (gAudioCtx.preloadSampleStackTop > 0) { - if (resetStatus != 0) { - // Clear result queue and preload stack and return. - osRecvMesg(&gAudioCtx.preloadSampleQueue, (OSMesg*)&preloadIndex, OS_MESG_NOBLOCK); - gAudioCtx.preloadSampleStackTop = 0; - return false; - } - if (osRecvMesg(&gAudioCtx.preloadSampleQueue, (OSMesg*)&preloadIndex, OS_MESG_NOBLOCK) == -1) { - // Previous preload is not done yet. - return false; - } - - preloadIndex >>= 24; - preload = &gAudioCtx.preloadSampleStack[preloadIndex]; - - if (!preload->isFree) { - sample = preload->sample; - key = (u32)sample->sampleAddr + sample->size + sample->medium; - if (key == preload->endAndMediumKey) { - // Change storage for sample to the preloaded version. - sample->sampleAddr = preload->ramAddr; - sample->medium = MEDIUM_RAM; - } - preload->isFree = true; - } - - // Pop requests with isFree = true off the stack, as far as possible, - // and dispatch the next DMA. - while (true) { - if (gAudioCtx.preloadSampleStackTop <= 0) { - break; - } - preload = &gAudioCtx.preloadSampleStack[gAudioCtx.preloadSampleStackTop - 1]; - if (preload->isFree == true) { - gAudioCtx.preloadSampleStackTop--; - continue; - } - - sample = preload->sample; - nChunks = (sample->size >> 12) + 1; - key = (u32)sample->sampleAddr + sample->size + sample->medium; - if (key != preload->endAndMediumKey) { - preload->isFree = true; - gAudioCtx.preloadSampleStackTop--; - } else { - AudioLoad_StartAsyncLoad((u32)sample->sampleAddr, preload->ramAddr, sample->size, sample->medium, - nChunks, &gAudioCtx.preloadSampleQueue, preload->encodedInfo); - break; - } - } - } - return true; -} - -s32 AudioLoad_AddToSampleSet(Sample* sample, s32 numSamples, Sample** sampleSet) { - s32 i; - - for (i = 0; i < numSamples; i++) { - if (sample->sampleAddr == sampleSet[i]->sampleAddr) { - break; - } - } - - if (i == numSamples) { - sampleSet[numSamples] = sample; - numSamples++; - } - - return numSamples; -} - -s32 AudioLoad_GetSamplesForFont(s32 fontId, Sample** sampleSet) { - s32 i; - s32 numSamples = 0; - s32 numDrums = gAudioCtx.soundFontList[fontId].numDrums; - s32 numInstruments = gAudioCtx.soundFontList[fontId].numInstruments; - - for (i = 0; i < numDrums; i++) { - Drum* drum = Audio_GetDrum(fontId, i); - - if (1) {} - if (drum != NULL) { - numSamples = AudioLoad_AddToSampleSet(drum->tunedSample.sample, numSamples, sampleSet); - } - } - - for (i = 0; i < numInstruments; i++) { - Instrument* instrument = Audio_GetInstrumentInner(fontId, i); - - if (instrument != NULL) { - if (instrument->normalRangeLo != 0) { - numSamples = AudioLoad_AddToSampleSet(instrument->lowPitchTunedSample.sample, numSamples, sampleSet); - } - if (instrument->normalRangeHi != 0x7F) { - numSamples = AudioLoad_AddToSampleSet(instrument->highPitchTunedSample.sample, numSamples, sampleSet); - } - numSamples = AudioLoad_AddToSampleSet(instrument->normalPitchTunedSample.sample, numSamples, sampleSet); - } - } - - // Should really also process sfx, but this method is never called. - return numSamples; -} - -void AudioLoad_AddUsedSample(TunedSample* tunedSample) { - Sample* sample = tunedSample->sample; - - if ((sample->size != 0) && sample->unk_bit26 && (sample->medium != MEDIUM_RAM)) { - gAudioCtx.usedSamples[gAudioCtx.numUsedSamples++] = sample; - } -} - -void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, SampleBankRelocInfo* sampleBankReloc) { - s32 numDrums; - s32 numInstruments; - s32 numSfx; - Drum* drum; - Instrument* instrument; - SoundEffect* soundEffect; - AudioPreloadReq* preload; - AudioPreloadReq* topPreload; - u8* addr; - s32 size; - s32 i; - Sample* sample; - s32 preloadInProgress; - s32 nChunks; - - preloadInProgress = false; - if (gAudioCtx.preloadSampleStackTop != 0) { - preloadInProgress = true; - } - - gAudioCtx.numUsedSamples = 0; - - numDrums = gAudioCtx.soundFontList[fontId].numDrums; - numInstruments = gAudioCtx.soundFontList[fontId].numInstruments; - numSfx = gAudioCtx.soundFontList[fontId].numSfx; - - for (i = 0; i < numInstruments; i++) { - instrument = Audio_GetInstrumentInner(fontId, i); - if (instrument != NULL) { - if (instrument->normalRangeLo != 0) { - AudioLoad_AddUsedSample(&instrument->lowPitchTunedSample); - } - if (instrument->normalRangeHi != 0x7F) { - AudioLoad_AddUsedSample(&instrument->highPitchTunedSample); - } - AudioLoad_AddUsedSample(&instrument->normalPitchTunedSample); - } - } - - for (i = 0; i < numDrums; i++) { - drum = Audio_GetDrum(fontId, i); - if (drum != NULL) { - AudioLoad_AddUsedSample(&drum->tunedSample); - } - } - - for (i = 0; i < numSfx; i++) { - soundEffect = Audio_GetSoundEffect(fontId, i); - if (soundEffect != NULL) { - AudioLoad_AddUsedSample(&soundEffect->tunedSample); - } - } - - if (gAudioCtx.numUsedSamples == 0) { - return; - } - - size = 0; - for (i = 0; i < gAudioCtx.numUsedSamples; i++) { - size += ALIGN16(gAudioCtx.usedSamples[i]->size); - } - if (size) {} - - for (i = 0; i < gAudioCtx.numUsedSamples; i++) { - if (gAudioCtx.preloadSampleStackTop == 120) { - break; - } - - sample = gAudioCtx.usedSamples[i]; - if (sample->medium == MEDIUM_RAM) { - continue; - } - - switch (async) { - case false: - if (sample->medium == sampleBankReloc->medium1) { - addr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId1, sample->sampleAddr, - sample->medium, CACHE_PERSISTENT); - } else if (sample->medium == sampleBankReloc->medium2) { - addr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId2, sample->sampleAddr, - sample->medium, CACHE_PERSISTENT); - } - break; - - case true: - if (sample->medium == sampleBankReloc->medium1) { - addr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId1, sample->sampleAddr, - sample->medium, CACHE_TEMPORARY); - } else if (sample->medium == sampleBankReloc->medium2) { - addr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId2, sample->sampleAddr, - sample->medium, CACHE_TEMPORARY); - } - break; - } - if (addr == NULL) { - continue; - } - - switch (async) { - case false: - if (sample->medium == MEDIUM_UNK) { - AudioLoad_SyncDmaUnkMedium((u32)sample->sampleAddr, addr, sample->size, - gAudioCtx.sampleBankTable->unkMediumParam); - sample->sampleAddr = addr; - sample->medium = MEDIUM_RAM; - } else { - AudioLoad_SyncDma((u32)sample->sampleAddr, addr, sample->size, sample->medium); - sample->sampleAddr = addr; - sample->medium = MEDIUM_RAM; - } - break; - - case true: - preload = &gAudioCtx.preloadSampleStack[gAudioCtx.preloadSampleStackTop]; - preload->sample = sample; - preload->ramAddr = addr; - preload->encodedInfo = (gAudioCtx.preloadSampleStackTop << 24) | 0xFFFFFF; - preload->isFree = false; - preload->endAndMediumKey = (u32)sample->sampleAddr + sample->size + sample->medium; - gAudioCtx.preloadSampleStackTop++; - break; - } - } - gAudioCtx.numUsedSamples = 0; - - if (gAudioCtx.preloadSampleStackTop != 0 && !preloadInProgress) { - topPreload = &gAudioCtx.preloadSampleStack[gAudioCtx.preloadSampleStackTop - 1]; - sample = topPreload->sample; - nChunks = (sample->size >> 12) + 1; - AudioLoad_StartAsyncLoad((u32)sample->sampleAddr, topPreload->ramAddr, sample->size, sample->medium, nChunks, - &gAudioCtx.preloadSampleQueue, topPreload->encodedInfo); - } -} - -void AudioLoad_LoadPermanentSamples(void) { - s32 pad; - u32 fontId; - AudioTable* sampleBankTable; - s32 pad2; - s32 i; - - sampleBankTable = AudioLoad_GetLoadTable(SAMPLE_TABLE); - for (i = 0; i < gAudioCtx.permanentPool.numEntries; i++) { - SampleBankRelocInfo sampleBankReloc; - - if (gAudioCtx.permanentCache[i].tableType == FONT_TABLE) { - fontId = AudioLoad_GetRealTableIndex(FONT_TABLE, gAudioCtx.permanentCache[i].id); - sampleBankReloc.sampleBankId1 = gAudioCtx.soundFontList[fontId].sampleBankId1; - sampleBankReloc.sampleBankId2 = gAudioCtx.soundFontList[fontId].sampleBankId2; - - if (sampleBankReloc.sampleBankId1 != 0xFF) { - sampleBankReloc.sampleBankId1 = - AudioLoad_GetRealTableIndex(SAMPLE_TABLE, sampleBankReloc.sampleBankId1); - sampleBankReloc.medium1 = sampleBankTable->entries[sampleBankReloc.sampleBankId1].medium; - } - - if (sampleBankReloc.sampleBankId2 != 0xFF) { - sampleBankReloc.sampleBankId2 = - AudioLoad_GetRealTableIndex(SAMPLE_TABLE, sampleBankReloc.sampleBankId2); - sampleBankReloc.medium2 = sampleBankTable->entries[sampleBankReloc.sampleBankId2].medium; - } - AudioLoad_PreloadSamplesForFont(fontId, false, &sampleBankReloc); - } - } -} - -void AudioLoad_Unused3(void) { -} - -void AudioLoad_Unused4(void) { -} - -void AudioLoad_Unused5(void) { -} - -void AudioLoad_ScriptLoad(s32 tableType, s32 id, s8* status) { - static u32 sLoadIndex = 0; - - sScriptLoadDonePointers[sLoadIndex] = status; - AudioLoad_AsyncLoad(tableType, id, 0, sLoadIndex, &sScriptLoadQueue); - sLoadIndex++; - if (sLoadIndex == 0x10) { - sLoadIndex = 0; - } -} - -void AudioLoad_ProcessScriptLoads(void) { - u32 temp; - u32 sp20; - s8* status; - - if (osRecvMesg(&sScriptLoadQueue, (OSMesg*)&sp20, OS_MESG_NOBLOCK) != -1) { - temp = sp20 >> 24; - status = sScriptLoadDonePointers[temp]; - if (status != NULL) { - *status = 0; - } - } -} - -void AudioLoad_InitScriptLoads(void) { - osCreateMesgQueue(&sScriptLoadQueue, sScriptLoadMsgBuf, ARRAY_COUNT(sScriptLoadMsgBuf)); -} diff --git a/src/code/audio_playback.c b/src/code/audio_playback.c deleted file mode 100644 index 87e2f792c..000000000 --- a/src/code/audio_playback.c +++ /dev/null @@ -1,952 +0,0 @@ -#include "global.h" - -void Audio_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) { - f32 volLeft; - f32 volRight; - s32 halfPanIndex; - u64 pad; - u8 strongLeft; - u8 strongRight; - f32 vel; - u8 pan; - u8 reverbVol; - StereoData stereoData; - s32 stereoHeadsetEffects = note->playbackState.stereoHeadsetEffects; - - vel = attrs->velocity; - pan = attrs->pan; - reverbVol = attrs->reverbVol; - stereoData = attrs->stereo.s; - - sub->bitField0 = note->noteSubEu.bitField0; - sub->bitField1 = note->noteSubEu.bitField1; - sub->waveSampleAddr = note->noteSubEu.waveSampleAddr; - sub->harmonicIndexCurAndPrev = note->noteSubEu.harmonicIndexCurAndPrev; - - Audio_NoteSetResamplingRate(sub, attrs->frequency); - - pan &= 0x7F; - - sub->bitField0.stereoStrongRight = false; - sub->bitField0.stereoStrongLeft = false; - sub->bitField0.stereoHeadsetEffects = stereoData.stereoHeadsetEffects; - sub->bitField0.usesHeadsetPanEffects = stereoData.usesHeadsetPanEffects; - if (stereoHeadsetEffects && (gAudioCtx.soundMode == SOUNDMODE_HEADSET)) { - halfPanIndex = pan >> 1; - if (halfPanIndex > 0x3F) { - halfPanIndex = 0x3F; - } - - sub->haasEffectRightDelaySize = gHaasEffectDelaySizes[halfPanIndex]; - sub->haasEffectLeftDelaySize = gHaasEffectDelaySizes[0x3F - halfPanIndex]; - sub->bitField1.useHaasEffect = true; - - volLeft = gHeadsetPanVolume[pan]; - volRight = gHeadsetPanVolume[0x7F - pan]; - } else if (stereoHeadsetEffects && (gAudioCtx.soundMode == SOUNDMODE_STEREO)) { - strongLeft = strongRight = 0; - sub->haasEffectLeftDelaySize = 0; - sub->haasEffectRightDelaySize = 0; - sub->bitField1.useHaasEffect = false; - - volLeft = gStereoPanVolume[pan]; - volRight = gStereoPanVolume[0x7F - pan]; - if (pan < 0x20) { - strongLeft = 1; - } else if (pan > 0x60) { - strongRight = 1; - } - - sub->bitField0.stereoStrongRight = strongRight; - sub->bitField0.stereoStrongLeft = strongLeft; - - switch (stereoData.bit2) { - case 0: - break; - - case 1: - sub->bitField0.stereoStrongRight = stereoData.strongRight; - sub->bitField0.stereoStrongLeft = stereoData.strongLeft; - break; - - case 2: - sub->bitField0.stereoStrongRight = stereoData.strongRight | strongRight; - sub->bitField0.stereoStrongLeft = stereoData.strongLeft | strongLeft; - break; - - case 3: - sub->bitField0.stereoStrongRight = stereoData.strongRight ^ strongRight; - sub->bitField0.stereoStrongLeft = stereoData.strongLeft ^ strongLeft; - break; - } - - } else if (gAudioCtx.soundMode == SOUNDMODE_MONO) { - sub->bitField0.stereoHeadsetEffects = false; - sub->bitField0.usesHeadsetPanEffects = false; - volLeft = 0.707f; // approx 1/sqrt(2) - volRight = 0.707f; - } else { - sub->bitField0.stereoStrongRight = stereoData.strongRight; - sub->bitField0.stereoStrongLeft = stereoData.strongLeft; - volLeft = gDefaultPanVolume[pan]; - volRight = gDefaultPanVolume[0x7F - pan]; - } - - vel = 0.0f > vel ? 0.0f : vel; - vel = 1.0f < vel ? 1.0f : vel; - - sub->targetVolLeft = (s32)((vel * volLeft) * (0x1000 - 0.001f)); - sub->targetVolRight = (s32)((vel * volRight) * (0x1000 - 0.001f)); - - sub->gain = attrs->gain; - sub->filter = attrs->filter; - sub->unk_07 = attrs->unk_14; - sub->unk_0E = attrs->unk_16; - sub->reverbVol = reverbVol; -} - -void Audio_NoteSetResamplingRate(NoteSubEu* noteSubEu, f32 resamplingRateInput) { - f32 resamplingRate = 0.0f; - - if (resamplingRateInput < 2.0f) { - noteSubEu->bitField1.hasTwoParts = false; - resamplingRate = CLAMP_MAX(resamplingRateInput, 1.99998f); - - } else { - noteSubEu->bitField1.hasTwoParts = true; - if (resamplingRateInput > 3.99996f) { - resamplingRate = 1.99998f; - } else { - resamplingRate = resamplingRateInput * 0.5f; - } - } - noteSubEu->resamplingRateFixedPoint = (s32)(resamplingRate * 32768.0f); -} - -void Audio_NoteInit(Note* note) { - if (note->playbackState.parentLayer->adsr.decayIndex == 0) { - Audio_AdsrInit(¬e->playbackState.adsr, note->playbackState.parentLayer->channel->adsr.envelope, - ¬e->playbackState.adsrVolScaleUnused); - } else { - Audio_AdsrInit(¬e->playbackState.adsr, note->playbackState.parentLayer->adsr.envelope, - ¬e->playbackState.adsrVolScaleUnused); - } - - note->playbackState.unk_04 = 0; - note->playbackState.adsr.action.s.state = ADSR_STATE_INITIAL; - note->noteSubEu = gDefaultNoteSub; -} - -void Audio_NoteDisable(Note* note) { - if (note->noteSubEu.bitField0.needsInit == true) { - note->noteSubEu.bitField0.needsInit = false; - } - note->playbackState.priority = 0; - note->noteSubEu.bitField0.enabled = false; - note->playbackState.unk_04 = 0; - note->noteSubEu.bitField0.finished = false; - note->playbackState.parentLayer = NO_LAYER; - note->playbackState.prevParentLayer = NO_LAYER; - note->playbackState.adsr.action.s.state = ADSR_STATE_DISABLED; - note->playbackState.adsr.current = 0; -} - -void Audio_ProcessNotes(void) { - s32 pad[2]; - NoteAttributes* attrs; - NoteSubEu* noteSubEu2; - NoteSubEu* noteSubEu; - Note* note; - NotePlaybackState* playbackState; - NoteSubAttributes subAttrs; - u8 bookOffset; - f32 scale; - s32 i; - - for (i = 0; i < gAudioCtx.numNotes; i++) { - note = &gAudioCtx.notes[i]; - noteSubEu2 = &gAudioCtx.noteSubsEu[gAudioCtx.noteSubEuOffset + i]; - playbackState = ¬e->playbackState; - if (playbackState->parentLayer != NO_LAYER) { - if ((u32)playbackState->parentLayer < 0x7FFFFFFF) { - continue; - } - - if (note != playbackState->parentLayer->note && playbackState->unk_04 == 0) { - playbackState->adsr.action.s.release = true; - playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; - playbackState->priority = 1; - playbackState->unk_04 = 2; - goto out; - } else if (!playbackState->parentLayer->enabled && playbackState->unk_04 == 0 && - playbackState->priority >= 1) { - // do nothing - } else if (playbackState->parentLayer->channel->seqPlayer == NULL) { - AudioSeq_SequenceChannelDisable(playbackState->parentLayer->channel); - playbackState->priority = 1; - playbackState->unk_04 = 1; - continue; - } else if (playbackState->parentLayer->channel->seqPlayer->muted && - (playbackState->parentLayer->channel->muteBehavior & MUTE_BEHAVIOR_STOP_NOTES)) { - // do nothing - } else { - goto out; - } - - Audio_SeqLayerNoteRelease(playbackState->parentLayer); - Audio_AudioListRemove(¬e->listItem); - Audio_AudioListPushFront(¬e->listItem.pool->decaying, ¬e->listItem); - playbackState->priority = 1; - playbackState->unk_04 = 2; - } else if (playbackState->unk_04 == 0 && playbackState->priority >= 1) { - continue; - } - - out: - if (playbackState->priority != 0) { - if (1) {} - noteSubEu = ¬e->noteSubEu; - if (playbackState->unk_04 >= 1 || noteSubEu->bitField0.finished) { - if (playbackState->adsr.action.s.state == ADSR_STATE_DISABLED || noteSubEu->bitField0.finished) { - if (playbackState->wantedParentLayer != NO_LAYER) { - Audio_NoteDisable(note); - if (playbackState->wantedParentLayer->channel != NULL) { - Audio_NoteInitForLayer(note, playbackState->wantedParentLayer); - Audio_NoteVibratoInit(note); - Audio_NotePortamentoInit(note); - Audio_AudioListRemove(¬e->listItem); - AudioSeq_AudioListPushBack(¬e->listItem.pool->active, ¬e->listItem); - playbackState->wantedParentLayer = NO_LAYER; - // don't skip - } else { - Audio_NoteDisable(note); - Audio_AudioListRemove(¬e->listItem); - AudioSeq_AudioListPushBack(¬e->listItem.pool->disabled, ¬e->listItem); - playbackState->wantedParentLayer = NO_LAYER; - goto skip; - } - } else { - if (playbackState->parentLayer != NO_LAYER) { - playbackState->parentLayer->bit1 = true; - } - Audio_NoteDisable(note); - Audio_AudioListRemove(¬e->listItem); - AudioSeq_AudioListPushBack(¬e->listItem.pool->disabled, ¬e->listItem); - continue; - } - } - } else if (playbackState->adsr.action.s.state == ADSR_STATE_DISABLED) { - if (playbackState->parentLayer != NO_LAYER) { - playbackState->parentLayer->bit1 = true; - } - Audio_NoteDisable(note); - Audio_AudioListRemove(¬e->listItem); - AudioSeq_AudioListPushBack(¬e->listItem.pool->disabled, ¬e->listItem); - continue; - } - - scale = Audio_AdsrUpdate(&playbackState->adsr); - Audio_NoteVibratoUpdate(note); - attrs = &playbackState->attributes; - if (playbackState->unk_04 == 1 || playbackState->unk_04 == 2) { - subAttrs.frequency = attrs->freqScale; - subAttrs.velocity = attrs->velocity; - subAttrs.pan = attrs->pan; - subAttrs.reverbVol = attrs->reverb; - subAttrs.stereo = attrs->stereo; - subAttrs.gain = attrs->gain; - subAttrs.filter = attrs->filter; - subAttrs.unk_14 = attrs->unk_4; - subAttrs.unk_16 = attrs->unk_6; - bookOffset = noteSubEu->bitField1.bookOffset; - } else { - SequenceLayer* layer = playbackState->parentLayer; - SequenceChannel* channel = layer->channel; - - subAttrs.frequency = layer->noteFreqScale; - subAttrs.velocity = layer->noteVelocity; - subAttrs.pan = layer->notePan; - if (layer->stereo.asByte == 0) { - subAttrs.stereo = channel->stereo; - } else { - subAttrs.stereo = layer->stereo; - } - subAttrs.reverbVol = channel->reverb; - subAttrs.gain = channel->gain; - subAttrs.filter = channel->filter; - subAttrs.unk_14 = channel->unk_0F; - subAttrs.unk_16 = channel->unk_20; - bookOffset = channel->bookOffset & 0x7; - - if (channel->seqPlayer->muted && (channel->muteBehavior & MUTE_BEHAVIOR_3)) { - subAttrs.frequency = 0.0f; - subAttrs.velocity = 0.0f; - } - } - - subAttrs.frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale; - subAttrs.frequency *= gAudioCtx.audioBufferParameters.resampleRate; - subAttrs.velocity *= scale; - Audio_InitNoteSub(note, noteSubEu2, &subAttrs); - noteSubEu->bitField1.bookOffset = bookOffset; - skip:; - } - } -} - -TunedSample* Audio_GetInstrumentTunedSample(Instrument* instrument, s32 semitone) { - TunedSample* tunedSample; - - if (semitone < instrument->normalRangeLo) { - tunedSample = &instrument->lowPitchTunedSample; - } else if (semitone <= instrument->normalRangeHi) { - tunedSample = &instrument->normalPitchTunedSample; - } else { - tunedSample = &instrument->highPitchTunedSample; - } - return tunedSample; -} - -Instrument* Audio_GetInstrumentInner(s32 fontId, s32 instId) { - Instrument* inst; - - if (fontId == 0xFF) { - return NULL; - } - - if (!AudioLoad_IsFontLoadComplete(fontId)) { - gAudioCtx.audioErrorFlags = fontId + 0x10000000; - return NULL; - } - - if (instId >= gAudioCtx.soundFontList[fontId].numInstruments) { - gAudioCtx.audioErrorFlags = ((fontId << 8) + instId) + 0x3000000; - return NULL; - } - - inst = gAudioCtx.soundFontList[fontId].instruments[instId]; - if (inst == NULL) { - gAudioCtx.audioErrorFlags = ((fontId << 8) + instId) + 0x1000000; - return inst; - } - - return inst; -} - -Drum* Audio_GetDrum(s32 fontId, s32 drumId) { - Drum* drum; - - if (fontId == 0xFF) { - return NULL; - } - - if (!AudioLoad_IsFontLoadComplete(fontId)) { - gAudioCtx.audioErrorFlags = fontId + 0x10000000; - return NULL; - } - - if (drumId >= gAudioCtx.soundFontList[fontId].numDrums) { - gAudioCtx.audioErrorFlags = ((fontId << 8) + drumId) + 0x4000000; - return NULL; - } - if ((u32)gAudioCtx.soundFontList[fontId].drums < AUDIO_RELOCATED_ADDRESS_START) { - return NULL; - } - drum = gAudioCtx.soundFontList[fontId].drums[drumId]; - - if (drum == NULL) { - gAudioCtx.audioErrorFlags = ((fontId << 8) + drumId) + 0x5000000; - } - - return drum; -} - -SoundEffect* Audio_GetSoundEffect(s32 fontId, s32 sfxId) { - SoundEffect* soundEffect; - - if (fontId == 0xFF) { - return NULL; - } - - if (!AudioLoad_IsFontLoadComplete(fontId)) { - gAudioCtx.audioErrorFlags = fontId + 0x10000000; - return NULL; - } - - if (sfxId >= gAudioCtx.soundFontList[fontId].numSfx) { - gAudioCtx.audioErrorFlags = ((fontId << 8) + sfxId) + 0x4000000; - return NULL; - } - - if ((u32)gAudioCtx.soundFontList[fontId].soundEffects < AUDIO_RELOCATED_ADDRESS_START) { - return NULL; - } - - soundEffect = &gAudioCtx.soundFontList[fontId].soundEffects[sfxId]; - - if (soundEffect == NULL) { - gAudioCtx.audioErrorFlags = ((fontId << 8) + sfxId) + 0x5000000; - } - - if (soundEffect->tunedSample.sample == NULL) { - return NULL; - } - - return soundEffect; -} - -s32 Audio_SetFontInstrument(s32 instrumentType, s32 fontId, s32 index, void* value) { - if (fontId == 0xFF) { - return -1; - } - - if (!AudioLoad_IsFontLoadComplete(fontId)) { - return -2; - } - - switch (instrumentType) { - case 0: - if (index >= gAudioCtx.soundFontList[fontId].numDrums) { - return -3; - } - gAudioCtx.soundFontList[fontId].drums[index] = value; - break; - - case 1: - if (index >= gAudioCtx.soundFontList[fontId].numSfx) { - return -3; - } - gAudioCtx.soundFontList[fontId].soundEffects[index] = *(SoundEffect*)value; - break; - - default: - if (index >= gAudioCtx.soundFontList[fontId].numInstruments) { - return -3; - } - gAudioCtx.soundFontList[fontId].instruments[index] = value; - break; - } - - return 0; -} - -void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) { - Note* note; - NoteAttributes* attrs; - SequenceChannel* chan; - s32 i; - - if (layer == NO_LAYER) { - return; - } - - layer->bit3 = false; - - if (layer->note == NULL) { - return; - } - - note = layer->note; - attrs = ¬e->playbackState.attributes; - - if (note->playbackState.wantedParentLayer == layer) { - note->playbackState.wantedParentLayer = NO_LAYER; - } - - if (note->playbackState.parentLayer != layer) { - if (note->playbackState.parentLayer == NO_LAYER && note->playbackState.wantedParentLayer == NO_LAYER && - note->playbackState.prevParentLayer == layer && target != ADSR_STATE_DECAY) { - note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; - note->playbackState.adsr.action.s.release = true; - } - return; - } - - if (note->playbackState.adsr.action.s.state != ADSR_STATE_DECAY) { - attrs->freqScale = layer->noteFreqScale; - attrs->velocity = layer->noteVelocity; - attrs->pan = layer->notePan; - - if (layer->channel != NULL) { - chan = layer->channel; - attrs->reverb = chan->reverb; - attrs->gain = chan->gain; - attrs->filter = chan->filter; - - if (attrs->filter != NULL) { - for (i = 0; i < 8; i++) { - attrs->filterBuf[i] = attrs->filter[i]; - } - attrs->filter = attrs->filterBuf; - } - - attrs->unk_6 = chan->unk_20; - attrs->unk_4 = chan->unk_0F; - if (chan->seqPlayer->muted && (chan->muteBehavior & MUTE_BEHAVIOR_3)) { - note->noteSubEu.bitField0.finished = true; - } - - if (layer->stereo.asByte == 0) { - attrs->stereo = chan->stereo; - } else { - attrs->stereo = layer->stereo; - } - note->playbackState.priority = chan->someOtherPriority; - } else { - attrs->stereo = layer->stereo; - note->playbackState.priority = 1; - } - - note->playbackState.prevParentLayer = note->playbackState.parentLayer; - note->playbackState.parentLayer = NO_LAYER; - if (target == ADSR_STATE_RELEASE) { - note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; - note->playbackState.adsr.action.s.release = true; - note->playbackState.unk_04 = 2; - } else { - note->playbackState.unk_04 = 1; - note->playbackState.adsr.action.s.decay = true; - if (layer->adsr.decayIndex == 0) { - note->playbackState.adsr.fadeOutVel = gAudioCtx.adsrDecayTable[layer->channel->adsr.decayIndex]; - } else { - note->playbackState.adsr.fadeOutVel = gAudioCtx.adsrDecayTable[layer->adsr.decayIndex]; - } - note->playbackState.adsr.sustain = - ((f32)(s32)(layer->channel->adsr.sustain) * note->playbackState.adsr.current) / 256.0f; - } - } - - if (target == ADSR_STATE_DECAY) { - Audio_AudioListRemove(¬e->listItem); - Audio_AudioListPushFront(¬e->listItem.pool->decaying, ¬e->listItem); - } -} - -void Audio_SeqLayerNoteDecay(SequenceLayer* layer) { - Audio_SeqLayerDecayRelease(layer, ADSR_STATE_DECAY); -} - -void Audio_SeqLayerNoteRelease(SequenceLayer* layer) { - Audio_SeqLayerDecayRelease(layer, ADSR_STATE_RELEASE); -} - -/** - * Extract the synthetic wave to use from gWaveSamples and update corresponding frequencies - * - * @param note - * @param layer - * @param waveId the index of the type of synthetic wave to use, offset by 128 - * @return harmonicIndex, the index of the harmonic for the synthetic wave contained in gWaveSamples - */ -s32 Audio_BuildSyntheticWave(Note* note, SequenceLayer* layer, s32 waveId) { - f32 freqScale; - f32 freqRatio; - u8 harmonicIndex; - - if (waveId < 128) { - waveId = 128; - } - - freqScale = layer->freqScale; - if (layer->portamento.mode != 0 && 0.0f < layer->portamento.extent) { - freqScale *= (layer->portamento.extent + 1.0f); - } - - // Map frequency to the harmonic to use from gWaveSamples - if (freqScale < 0.99999f) { - harmonicIndex = 0; - freqRatio = 1.0465f; - } else if (freqScale < 1.99999f) { - harmonicIndex = 1; - freqRatio = 1.0465f / 2; - } else if (freqScale < 3.99999f) { - harmonicIndex = 2; - freqRatio = 1.0465f / 4 + 1.005E-3; - } else { - harmonicIndex = 3; - freqRatio = 1.0465f / 8 - 2.5E-6; - } - - // Update results - layer->freqScale *= freqRatio; - note->playbackState.waveId = waveId; - note->playbackState.harmonicIndex = harmonicIndex; - - // Save the pointer to the synthethic wave - // waveId index starts at 128, there are WAVE_SAMPLE_COUNT samples to read from - note->noteSubEu.waveSampleAddr = &gWaveSamples[waveId - 128][harmonicIndex * WAVE_SAMPLE_COUNT]; - - return harmonicIndex; -} - -void Audio_InitSyntheticWave(Note* note, SequenceLayer* layer) { - s32 prevHarmonicIndex; - s32 curHarmonicIndex; - s32 waveId = layer->instOrWave; - - if (waveId == 0xFF) { - waveId = layer->channel->instOrWave; - } - - prevHarmonicIndex = note->playbackState.harmonicIndex; - curHarmonicIndex = Audio_BuildSyntheticWave(note, layer, waveId); - - if (curHarmonicIndex != prevHarmonicIndex) { - note->noteSubEu.harmonicIndexCurAndPrev = (curHarmonicIndex << 2) + prevHarmonicIndex; - } -} - -void Audio_InitNoteList(AudioListItem* list) { - list->prev = list; - list->next = list; - list->u.count = 0; -} - -void Audio_InitNoteLists(NotePool* pool) { - Audio_InitNoteList(&pool->disabled); - Audio_InitNoteList(&pool->decaying); - Audio_InitNoteList(&pool->releasing); - Audio_InitNoteList(&pool->active); - pool->disabled.pool = pool; - pool->decaying.pool = pool; - pool->releasing.pool = pool; - pool->active.pool = pool; -} - -void Audio_InitNoteFreeList(void) { - s32 i; - - Audio_InitNoteLists(&gAudioCtx.noteFreeLists); - for (i = 0; i < gAudioCtx.numNotes; i++) { - gAudioCtx.notes[i].listItem.u.value = &gAudioCtx.notes[i]; - gAudioCtx.notes[i].listItem.prev = NULL; - AudioSeq_AudioListPushBack(&gAudioCtx.noteFreeLists.disabled, &gAudioCtx.notes[i].listItem); - } -} - -void Audio_NotePoolClear(NotePool* pool) { - s32 i; - AudioListItem* source; - AudioListItem* cur; - AudioListItem* dest; - - for (i = 0; i < 4; i++) { - switch (i) { - case 0: - source = &pool->disabled; - dest = &gAudioCtx.noteFreeLists.disabled; - break; - - case 1: - source = &pool->decaying; - dest = &gAudioCtx.noteFreeLists.decaying; - break; - - case 2: - source = &pool->releasing; - dest = &gAudioCtx.noteFreeLists.releasing; - break; - - case 3: - source = &pool->active; - dest = &gAudioCtx.noteFreeLists.active; - break; - } - - while (true) { - cur = source->next; - if (cur == source || cur == NULL) { - break; - } - Audio_AudioListRemove(cur); - AudioSeq_AudioListPushBack(dest, cur); - } - } -} - -void Audio_NotePoolFill(NotePool* pool, s32 count) { - s32 i; - s32 j; - Note* note; - AudioListItem* source; - AudioListItem* dest; - - Audio_NotePoolClear(pool); - - for (i = 0, j = 0; j < count; i++) { - if (i == 4) { - return; - } - - switch (i) { - case 0: - source = &gAudioCtx.noteFreeLists.disabled; - dest = &pool->disabled; - break; - - case 1: - source = &gAudioCtx.noteFreeLists.decaying; - dest = &pool->decaying; - break; - - case 2: - source = &gAudioCtx.noteFreeLists.releasing; - dest = &pool->releasing; - break; - - case 3: - source = &gAudioCtx.noteFreeLists.active; - dest = &pool->active; - break; - } - - while (j < count) { - note = AudioSeq_AudioListPopBack(source); - if (note == NULL) { - break; - } - AudioSeq_AudioListPushBack(dest, ¬e->listItem); - j++; - } - } -} - -void Audio_AudioListPushFront(AudioListItem* list, AudioListItem* item) { - // add 'item' to the front of the list given by 'list', if it's not in any list - if (item->prev == NULL) { - item->prev = list; - item->next = list->next; - list->next->prev = item; - list->next = item; - list->u.count++; - item->pool = list->pool; - } -} - -void Audio_AudioListRemove(AudioListItem* item) { - // remove 'item' from the list it's in, if any - if (item->prev != NULL) { - item->prev->next = item->next; - item->next->prev = item->prev; - item->prev = NULL; - } -} - -Note* Audio_FindNodeWithPrioLessThan(AudioListItem* list, s32 limit) { - AudioListItem* cur = list->next; - AudioListItem* best; - - if (cur == list) { - return NULL; - } - - for (best = cur; cur != list; cur = cur->next) { - if (((Note*)best->u.value)->playbackState.priority >= ((Note*)cur->u.value)->playbackState.priority) { - best = cur; - } - } - - if (best == NULL) { - return NULL; - } - - if (limit <= ((Note*)best->u.value)->playbackState.priority) { - return NULL; - } - - return best->u.value; -} - -void Audio_NoteInitForLayer(Note* note, SequenceLayer* layer) { - s32 pad[3]; - s16 instId; - NotePlaybackState* playbackState = ¬e->playbackState; - NoteSubEu* sub = ¬e->noteSubEu; - - note->playbackState.prevParentLayer = NO_LAYER; - note->playbackState.parentLayer = layer; - playbackState->priority = layer->channel->notePriority; - layer->notePropertiesNeedInit = true; - layer->bit3 = true; - layer->note = note; - layer->channel->noteUnused = note; - layer->channel->layerUnused = layer; - layer->noteVelocity = 0.0f; - Audio_NoteInit(note); - instId = layer->instOrWave; - - if (instId == 0xFF) { - instId = layer->channel->instOrWave; - } - sub->tunedSample = layer->tunedSample; - - if (instId >= 0x80 && instId < 0xC0) { - sub->bitField1.isSyntheticWave = true; - } else { - sub->bitField1.isSyntheticWave = false; - } - - if (sub->bitField1.isSyntheticWave) { - Audio_BuildSyntheticWave(note, layer, instId); - } - - playbackState->fontId = layer->channel->fontId; - playbackState->stereoHeadsetEffects = layer->channel->stereoHeadsetEffects; - sub->bitField1.reverbIndex = layer->channel->reverbIndex & 3; -} - -void func_800E82C0(Note* note, SequenceLayer* layer) { - // similar to Audio_NoteReleaseAndTakeOwnership, hard to say what the difference is - Audio_SeqLayerNoteRelease(note->playbackState.parentLayer); - note->playbackState.wantedParentLayer = layer; -} - -void Audio_NoteReleaseAndTakeOwnership(Note* note, SequenceLayer* layer) { - note->playbackState.wantedParentLayer = layer; - note->playbackState.priority = layer->channel->notePriority; - - note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; - note->playbackState.adsr.action.s.release = true; -} - -Note* Audio_AllocNoteFromDisabled(NotePool* pool, SequenceLayer* layer) { - Note* note = AudioSeq_AudioListPopBack(&pool->disabled); - if (note != NULL) { - Audio_NoteInitForLayer(note, layer); - Audio_AudioListPushFront(&pool->active, ¬e->listItem); - } - return note; -} - -Note* Audio_AllocNoteFromDecaying(NotePool* pool, SequenceLayer* layer) { - Note* note = AudioSeq_AudioListPopBack(&pool->decaying); - if (note != NULL) { - Audio_NoteReleaseAndTakeOwnership(note, layer); - AudioSeq_AudioListPushBack(&pool->releasing, ¬e->listItem); - } - return note; -} - -Note* Audio_AllocNoteFromActive(NotePool* pool, SequenceLayer* layer) { - Note* rNote; - Note* aNote; - s32 rPriority; - s32 aPriority; - - rPriority = aPriority = 0x10; - rNote = Audio_FindNodeWithPrioLessThan(&pool->releasing, layer->channel->notePriority); - - if (rNote != NULL) { - rPriority = rNote->playbackState.priority; - } - - aNote = Audio_FindNodeWithPrioLessThan(&pool->active, layer->channel->notePriority); - - if (aNote != NULL) { - aPriority = aNote->playbackState.priority; - } - - if (rNote == NULL && aNote == NULL) { - return NULL; - } - - if (aPriority < rPriority) { - Audio_AudioListRemove(&aNote->listItem); - func_800E82C0(aNote, layer); - AudioSeq_AudioListPushBack(&pool->releasing, &aNote->listItem); - aNote->playbackState.priority = layer->channel->notePriority; - return aNote; - } - rNote->playbackState.wantedParentLayer = layer; - rNote->playbackState.priority = layer->channel->notePriority; - return rNote; -} - -Note* Audio_AllocNote(SequenceLayer* layer) { - Note* note; - u32 policy = layer->channel->noteAllocPolicy; - - if (policy & 1) { - note = layer->note; - if (note != NULL && note->playbackState.prevParentLayer == layer && - note->playbackState.wantedParentLayer == NO_LAYER) { - Audio_NoteReleaseAndTakeOwnership(note, layer); - Audio_AudioListRemove(¬e->listItem); - AudioSeq_AudioListPushBack(¬e->listItem.pool->releasing, ¬e->listItem); - return note; - } - } - - if (policy & 2) { - if (!(note = Audio_AllocNoteFromDisabled(&layer->channel->notePool, layer)) && - !(note = Audio_AllocNoteFromDecaying(&layer->channel->notePool, layer)) && - !(note = Audio_AllocNoteFromActive(&layer->channel->notePool, layer))) { - goto null_return; - } - return note; - } - - if (policy & 4) { - if (!(note = Audio_AllocNoteFromDisabled(&layer->channel->notePool, layer)) && - !(note = Audio_AllocNoteFromDisabled(&layer->channel->seqPlayer->notePool, layer)) && - !(note = Audio_AllocNoteFromDecaying(&layer->channel->notePool, layer)) && - !(note = Audio_AllocNoteFromDecaying(&layer->channel->seqPlayer->notePool, layer)) && - !(note = Audio_AllocNoteFromActive(&layer->channel->notePool, layer)) && - !(note = Audio_AllocNoteFromActive(&layer->channel->seqPlayer->notePool, layer))) { - goto null_return; - } - return note; - } - - if (policy & 8) { - if (!(note = Audio_AllocNoteFromDisabled(&gAudioCtx.noteFreeLists, layer)) && - !(note = Audio_AllocNoteFromDecaying(&gAudioCtx.noteFreeLists, layer)) && - !(note = Audio_AllocNoteFromActive(&gAudioCtx.noteFreeLists, layer))) { - goto null_return; - } - return note; - } - - if (!(note = Audio_AllocNoteFromDisabled(&layer->channel->notePool, layer)) && - !(note = Audio_AllocNoteFromDisabled(&layer->channel->seqPlayer->notePool, layer)) && - !(note = Audio_AllocNoteFromDisabled(&gAudioCtx.noteFreeLists, layer)) && - !(note = Audio_AllocNoteFromDecaying(&layer->channel->notePool, layer)) && - !(note = Audio_AllocNoteFromDecaying(&layer->channel->seqPlayer->notePool, layer)) && - !(note = Audio_AllocNoteFromDecaying(&gAudioCtx.noteFreeLists, layer)) && - !(note = Audio_AllocNoteFromActive(&layer->channel->notePool, layer)) && - !(note = Audio_AllocNoteFromActive(&layer->channel->seqPlayer->notePool, layer)) && - !(note = Audio_AllocNoteFromActive(&gAudioCtx.noteFreeLists, layer))) { - goto null_return; - } - return note; - -null_return: - layer->bit3 = true; - return NULL; -} - -void Audio_NoteInitAll(void) { - Note* note; - s32 i; - - for (i = 0; i < gAudioCtx.numNotes; i++) { - note = &gAudioCtx.notes[i]; - note->noteSubEu = gZeroNoteSub; - note->playbackState.priority = 0; - note->playbackState.unk_04 = 0; - note->playbackState.parentLayer = NO_LAYER; - note->playbackState.wantedParentLayer = NO_LAYER; - note->playbackState.prevParentLayer = NO_LAYER; - note->playbackState.waveId = 0; - note->playbackState.attributes.velocity = 0.0f; - note->playbackState.adsrVolScaleUnused = 0; - note->playbackState.adsr.action.asByte = 0; - note->playbackState.vibratoState.active = 0; - note->playbackState.portamento.cur = 0; - note->playbackState.portamento.speed = 0; - note->playbackState.stereoHeadsetEffects = false; - note->startSamplePos = 0; - note->synthesisState.synthesisBuffers = - AudioHeap_AllocDmaMemory(&gAudioCtx.miscPool, sizeof(NoteSynthesisBuffers)); - } -} diff --git a/src/code/audio_seqplayer.c b/src/code/audio_seqplayer.c deleted file mode 100644 index 008bedea6..000000000 --- a/src/code/audio_seqplayer.c +++ /dev/null @@ -1,2149 +0,0 @@ -/** - * @file audio_seqplayer.c - * - * Manages audio sequence players, interprets and executes sequence instructions used to write .seq files - * - * Sequence Instructions: - * - A customized assembly language based on MIDI - * - All sequences are written using these instructions - * - There are 3 different sets of instructions - * 1) Sequence Instructions - * 2) Channel Instructions - * 3) Layer Instruction - * - All three sets share a common pool of control flow instructions (>= 0xF2). - * Otherwise, each set of instructions has its own command interpreter - */ -#include "ultra64.h" -#include "global.h" - -#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80) -#define PORTAMENTO_MODE(x) ((x).mode & ~0x80) - -#define PROCESS_SCRIPT_END -1 - -typedef enum { - /* 0 */ PORTAMENTO_MODE_OFF, - /* 1 */ PORTAMENTO_MODE_1, - /* 2 */ PORTAMENTO_MODE_2, - /* 3 */ PORTAMENTO_MODE_3, - /* 4 */ PORTAMENTO_MODE_4, - /* 5 */ PORTAMENTO_MODE_5 -} PortamentoMode; - -u8 AudioSeq_ScriptReadU8(SeqScriptState* state); -s16 AudioSeq_ScriptReadS16(SeqScriptState* state); -u16 AudioSeq_ScriptReadCompressedU16(SeqScriptState* state); - -void AudioSeq_SeqLayerProcessScriptStep1(SequenceLayer* layer); -s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer); -s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd); -s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd); -s32 AudioSeq_SeqLayerProcessScriptStep5(SequenceLayer* layer, s32 sameTunedSample); - -u8 AudioSeq_GetInstrument(SequenceChannel* channel, u8 instId, Instrument** instOut, AdsrSettings* adsr); - -/** - * sSeqInstructionArgsTable is a table for each sequence instruction - * that contains both how many arguments an instruction takes, as well - * as the type of each argument - * - * sSeqInstructionArgsTable is bitpacked as follows: - * abcUUUnn - * - * n - number of arguments that the sequence instruction takes - * - * a - bitFlag for the type of arg0 if it exists - * b - bitFlag for the type of arg1 if it exists - * c - bitFlag for the type of arg2 if it exists - * - * bitFlag on - argument is s16 - * bitFlag off - argument is u8 - * - * U - Unused - */ - -// CMD_ARGS_(NUMBER_OF_ARGS) -#define CMD_ARGS_0() 0 -#define CMD_ARGS_1(arg0Type) (((sizeof(arg0Type) - 1) << 7) | 1) -#define CMD_ARGS_2(arg0Type, arg1Type) (((sizeof(arg0Type) - 1) << 7) | ((sizeof(arg1Type) - 1) << 6) | 2) -#define CMD_ARGS_3(arg0Type, arg1Type, arg2Type) \ - (((sizeof(arg0Type) - 1) << 7) | ((sizeof(arg1Type) - 1) << 6) | ((sizeof(arg2Type) - 1) << 5) | 3) - -u8 sSeqInstructionArgsTable[] = { - CMD_ARGS_1(s16), // 0xB0 - CMD_ARGS_0(), // 0xB1 - CMD_ARGS_1(s16), // 0xB2 - CMD_ARGS_1(u8), // 0xB3 - CMD_ARGS_0(), // 0xB4 - CMD_ARGS_0(), // 0xB5 - CMD_ARGS_0(), // 0xB6 - CMD_ARGS_1(s16), // 0xB7 - CMD_ARGS_1(u8), // 0xB8 - CMD_ARGS_1(u8), // 0xB9 - CMD_ARGS_1(u8), // 0xBA - CMD_ARGS_2(u8, s16), // 0xBB - CMD_ARGS_1(s16), // 0xBC - CMD_ARGS_2(s16, s16), // 0xBD - CMD_ARGS_0(), // 0xBE - CMD_ARGS_0(), // 0xBF - CMD_ARGS_0(), // 0xC0 - CMD_ARGS_1(u8), // 0xC1 - CMD_ARGS_1(s16), // 0xC2 - CMD_ARGS_0(), // 0xC3 - CMD_ARGS_0(), // 0xC4 - CMD_ARGS_0(), // 0xC5 - CMD_ARGS_1(u8), // 0xC6 - CMD_ARGS_2(u8, s16), // 0xC7 - CMD_ARGS_1(u8), // 0xC8 - CMD_ARGS_1(u8), // 0xC9 - CMD_ARGS_1(u8), // 0xCA - CMD_ARGS_1(s16), // 0xCB - CMD_ARGS_1(u8), // 0xCC - CMD_ARGS_1(u8), // 0xCD - CMD_ARGS_1(s16), // 0xCE - CMD_ARGS_1(s16), // 0xCF - CMD_ARGS_1(u8), // 0xD0 - CMD_ARGS_1(u8), // 0xD1 - CMD_ARGS_1(u8), // 0xD2 - CMD_ARGS_1(u8), // 0xD3 - CMD_ARGS_1(u8), // 0xD4 - CMD_ARGS_1(u8), // 0xD5 - CMD_ARGS_1(u8), // 0xD6 - CMD_ARGS_1(u8), // 0xD7 - CMD_ARGS_1(u8), // 0xD8 - CMD_ARGS_1(u8), // 0xD9 - CMD_ARGS_1(s16), // 0xDA - CMD_ARGS_1(u8), // 0xDB - CMD_ARGS_1(u8), // 0xDC - CMD_ARGS_1(u8), // 0xDD - CMD_ARGS_1(s16), // 0xDE - CMD_ARGS_1(u8), // 0xDF - CMD_ARGS_1(u8), // 0xE0 - CMD_ARGS_3(u8, u8, u8), // 0xE1 - CMD_ARGS_3(u8, u8, u8), // 0xE2 - CMD_ARGS_1(u8), // 0xE3 - CMD_ARGS_0(), // 0xE4 - CMD_ARGS_1(u8), // 0xE5 - CMD_ARGS_1(u8), // 0xE6 - CMD_ARGS_1(s16), // 0xE7 - CMD_ARGS_3(u8, u8, u8), // 0xE8 - CMD_ARGS_1(u8), // 0xE9 - CMD_ARGS_0(), // 0xEA - CMD_ARGS_2(u8, u8), // 0xEB - CMD_ARGS_0(), // 0xEC - CMD_ARGS_1(u8), // 0xED - CMD_ARGS_1(u8), // 0xEE - CMD_ARGS_2(s16, u8), // 0xEF - CMD_ARGS_0(), // 0xF0 - CMD_ARGS_1(u8), // 0xF1 - // Control flow instructions (>= 0xF2) can only have 0 or 1 args - CMD_ARGS_1(u8), // 0xF2 - CMD_ARGS_1(u8), // 0xF3 - CMD_ARGS_1(u8), // 0xF4 - CMD_ARGS_1(s16), // 0xF5 - CMD_ARGS_0(), // 0xF6 - CMD_ARGS_0(), // 0xF7 - CMD_ARGS_1(u8), // 0xF8 - CMD_ARGS_1(s16), // 0xF9 - CMD_ARGS_1(s16), // 0xFA - CMD_ARGS_1(s16), // 0xFB - CMD_ARGS_1(s16), // 0xFC - CMD_ARGS_0(), // 0xFD - CMD_ARGS_0(), // 0xFE - CMD_ARGS_0(), // 0xFF -}; - -/** - * Read and return the argument from the sequence script for a control flow instruction. - * Control flow instructions (>= 0xF2) can only have 0 or 1 args. - * @return the argument value for a control flow instruction, or 0 if there is no argument - */ -u16 AudioSeq_GetScriptControlFlowArgument(SeqScriptState* state, u8 cmd) { - u8 highBits = sSeqInstructionArgsTable[cmd - 0xB0]; - u8 lowBits = highBits & 3; - u16 cmdArg = 0; - - // only 1 argument - if (lowBits == 1) { - if (!(highBits & 0x80)) { - cmdArg = AudioSeq_ScriptReadU8(state); - } else { - cmdArg = AudioSeq_ScriptReadS16(state); - } - } - - return cmdArg; -} - -/** - * Read and execute the control flow sequence instructions - * @return number of frames until next instruction. -1 signals termination - */ -s32 AudioSeq_HandleScriptFlowControl(SequencePlayer* seqPlayer, SeqScriptState* state, s32 cmd, s32 cmdArg) { - switch (cmd) { - case 0xFF: - if (state->depth == 0) { - return PROCESS_SCRIPT_END; - } - state->pc = state->stack[--state->depth]; - break; - - case 0xFD: - return AudioSeq_ScriptReadCompressedU16(state); - - case 0xFE: - return 1; - - case 0xFC: - state->stack[state->depth++] = state->pc; - state->pc = seqPlayer->seqData + (u16)cmdArg; - break; - - case 0xF8: - state->remLoopIters[state->depth] = cmdArg; - state->stack[state->depth++] = state->pc; - break; - - case 0xF7: - state->remLoopIters[state->depth - 1]--; - if (state->remLoopIters[state->depth - 1] != 0) { - state->pc = state->stack[state->depth - 1]; - } else { - state->depth--; - } - break; - - case 0xF6: - state->depth--; - break; - - case 0xF5: - case 0xF9: - case 0xFA: - case 0xFB: - if (cmd == 0xFA && state->value != 0) { - break; - } - if (cmd == 0xF9 && state->value >= 0) { - break; - } - if (cmd == 0xF5 && state->value < 0) { - break; - } - state->pc = seqPlayer->seqData + (u16)cmdArg; - break; - - case 0xF2: - case 0xF3: - case 0xF4: - if (cmd == 0xF3 && state->value != 0) { - break; - } - if (cmd == 0xF2 && state->value >= 0) { - break; - } - state->pc += (s8)(cmdArg & 0xFF); - break; - } - - return 0; -} - -void AudioSeq_InitSequenceChannel(SequenceChannel* channel) { - s32 i; - - if (channel == &gAudioCtx.sequenceChannelNone) { - return; - } - - channel->enabled = false; - channel->finished = false; - channel->stopScript = false; - channel->stopSomething2 = false; - channel->hasInstrument = false; - channel->stereoHeadsetEffects = false; - channel->transposition = 0; - channel->largeNotes = false; - channel->bookOffset = 0; - channel->stereo.asByte = 0; - channel->changes.asByte = 0xFF; - channel->scriptState.depth = 0; - channel->newPan = 0x40; - channel->panChannelWeight = 0x80; - channel->velocityRandomVariance = 0; - channel->gateTimeRandomVariance = 0; - channel->noteUnused = NULL; - channel->reverbIndex = 0; - channel->reverb = 0; - channel->gain = 0; - channel->notePriority = 3; - channel->someOtherPriority = 1; - channel->delay = 0; - channel->adsr.envelope = gDefaultEnvelope; - channel->adsr.decayIndex = 0xF0; - channel->adsr.sustain = 0; - channel->vibratoRateTarget = 0x800; - channel->vibratoRateStart = 0x800; - channel->vibratoExtentTarget = 0; - channel->vibratoExtentStart = 0; - channel->vibratoRateChangeDelay = 0; - channel->vibratoExtentChangeDelay = 0; - channel->vibratoDelay = 0; - channel->filter = NULL; - channel->unk_20 = 0; - channel->unk_0F = 0; - channel->volume = 1.0f; - channel->volumeScale = 1.0f; - channel->freqScale = 1.0f; - - for (i = 0; i < ARRAY_COUNT(channel->soundScriptIO); i++) { - channel->soundScriptIO[i] = SEQ_IO_VAL_NONE; - } - - channel->unused = false; - Audio_InitNoteLists(&channel->notePool); -} - -s32 AudioSeq_SeqChannelSetLayer(SequenceChannel* channel, s32 layerIndex) { - SequenceLayer* layer; - s32 pad; - - if (channel->layers[layerIndex] == NULL) { - layer = AudioSeq_AudioListPopBack(&gAudioCtx.layerFreeList); - channel->layers[layerIndex] = layer; - if (layer == NULL) { - channel->layers[layerIndex] = NULL; - return -1; - } - } else { - Audio_SeqLayerNoteDecay(channel->layers[layerIndex]); - } - - layer = channel->layers[layerIndex]; - - layer->channel = channel; - layer->adsr = channel->adsr; - layer->adsr.decayIndex = 0; - layer->enabled = true; - layer->finished = false; - layer->stopSomething = false; - layer->continuousNotes = false; - layer->bit3 = false; - layer->ignoreDrumPan = false; - layer->bit1 = false; - layer->notePropertiesNeedInit = false; - layer->stereo.asByte = 0; - layer->portamento.mode = PORTAMENTO_MODE_OFF; - layer->scriptState.depth = 0; - layer->gateTime = 0x80; - layer->pan = 0x40; - layer->transposition = 0; - layer->delay = 0; - layer->gateDelay = 0; - layer->delay2 = 0; - layer->note = NULL; - layer->instrument = NULL; - layer->freqScale = 1.0f; - layer->bend = 1.0f; - layer->velocitySquare2 = 0.0f; - layer->instOrWave = 0xFF; - - return 0; -} - -void AudioSeq_SeqLayerDisable(SequenceLayer* layer) { - if (layer != NULL) { - if (layer->channel != &gAudioCtx.sequenceChannelNone && layer->channel->seqPlayer->finished == 1) { - Audio_SeqLayerNoteRelease(layer); - } else { - Audio_SeqLayerNoteDecay(layer); - } - layer->enabled = false; - layer->finished = true; - } -} - -void AudioSeq_SeqLayerFree(SequenceChannel* channel, s32 layerIndex) { - SequenceLayer* layer = channel->layers[layerIndex]; - - if (layer != NULL) { - AudioSeq_AudioListPushBack(&gAudioCtx.layerFreeList, &layer->listItem); - AudioSeq_SeqLayerDisable(layer); - channel->layers[layerIndex] = NULL; - } -} - -void AudioSeq_SequenceChannelDisable(SequenceChannel* channel) { - s32 i; - - for (i = 0; i < 4; i++) { - AudioSeq_SeqLayerFree(channel, i); - } - - Audio_NotePoolClear(&channel->notePool); - channel->enabled = false; - channel->finished = true; -} - -void AudioSeq_SequencePlayerSetupChannels(SequencePlayer* seqPlayer, u16 channelBits) { - SequenceChannel* channel; - s32 i; - - for (i = 0; i < SEQ_NUM_CHANNELS; i++) { - if (channelBits & 1) { - channel = seqPlayer->channels[i]; - channel->fontId = seqPlayer->defaultFont; - channel->muteBehavior = seqPlayer->muteBehavior; - channel->noteAllocPolicy = seqPlayer->noteAllocPolicy; - } - channelBits = channelBits >> 1; - } -} - -void AudioSeq_SequencePlayerDisableChannels(SequencePlayer* seqPlayer, u16 channelBitsUnused) { - SequenceChannel* channel; - s32 i; - - for (i = 0; i < SEQ_NUM_CHANNELS; i++) { - channel = seqPlayer->channels[i]; - if (IS_SEQUENCE_CHANNEL_VALID(channel) == 1) { - AudioSeq_SequenceChannelDisable(channel); - } - } -} - -void AudioSeq_SequenceChannelEnable(SequencePlayer* seqPlayer, u8 channelIndex, void* script) { - SequenceChannel* channel = seqPlayer->channels[channelIndex]; - s32 i; - - channel->enabled = true; - channel->finished = false; - channel->scriptState.depth = 0; - channel->scriptState.pc = script; - channel->delay = 0; - - for (i = 0; i < ARRAY_COUNT(channel->layers); i++) { - if (channel->layers[i] != NULL) { - AudioSeq_SeqLayerFree(channel, i); - } - } -} - -void AudioSeq_SequencePlayerDisableAsFinished(SequencePlayer* seqPlayer) { - seqPlayer->finished = true; - AudioSeq_SequencePlayerDisable(seqPlayer); -} - -void AudioSeq_SequencePlayerDisable(SequencePlayer* seqPlayer) { - AudioSeq_SequencePlayerDisableChannels(seqPlayer, 0xFFFF); - Audio_NotePoolClear(&seqPlayer->notePool); - if (!seqPlayer->enabled) { - return; - } - - seqPlayer->enabled = false; - seqPlayer->finished = true; - - if (AudioLoad_IsSeqLoadComplete(seqPlayer->seqId)) { - AudioLoad_SetSeqLoadStatus(seqPlayer->seqId, LOAD_STATUS_DISCARDABLE); - } - - if (AudioLoad_IsFontLoadComplete(seqPlayer->defaultFont)) { - AudioLoad_SetFontLoadStatus(seqPlayer->defaultFont, LOAD_STATUS_MAYBE_DISCARDABLE); - } - - if (seqPlayer->defaultFont == gAudioCtx.fontCache.temporary.entries[0].id) { - gAudioCtx.fontCache.temporary.nextSide = 0; - } else if (seqPlayer->defaultFont == gAudioCtx.fontCache.temporary.entries[1].id) { - gAudioCtx.fontCache.temporary.nextSide = 1; - } -} - -void AudioSeq_AudioListPushBack(AudioListItem* list, AudioListItem* item) { - if (item->prev == NULL) { - list->prev->next = item; - item->prev = list->prev; - item->next = list; - list->prev = item; - list->u.count++; - item->pool = list->pool; - } -} - -void* AudioSeq_AudioListPopBack(AudioListItem* list) { - AudioListItem* item = list->prev; - - if (item == list) { - return NULL; - } - - item->prev->next = list; - list->prev = item->prev; - item->prev = NULL; - list->u.count--; - - return item->u.value; -} - -void AudioSeq_InitLayerFreelist(void) { - s32 i; - - gAudioCtx.layerFreeList.prev = &gAudioCtx.layerFreeList; - gAudioCtx.layerFreeList.next = &gAudioCtx.layerFreeList; - gAudioCtx.layerFreeList.u.count = 0; - gAudioCtx.layerFreeList.pool = NULL; - - for (i = 0; i < ARRAY_COUNT(gAudioCtx.sequenceLayers); i++) { - gAudioCtx.sequenceLayers[i].listItem.u.value = &gAudioCtx.sequenceLayers[i]; - gAudioCtx.sequenceLayers[i].listItem.prev = NULL; - AudioSeq_AudioListPushBack(&gAudioCtx.layerFreeList, &gAudioCtx.sequenceLayers[i].listItem); - } -} - -u8 AudioSeq_ScriptReadU8(SeqScriptState* state) { - return *(state->pc++); -} - -s16 AudioSeq_ScriptReadS16(SeqScriptState* state) { - s16 ret = *(state->pc++) << 8; - - ret = *(state->pc++) | ret; - return ret; -} - -u16 AudioSeq_ScriptReadCompressedU16(SeqScriptState* state) { - u16 ret = *(state->pc++); - - if (ret & 0x80) { - ret = (ret << 8) & 0x7F00; - ret = *(state->pc++) | ret; - } - return ret; -} - -void AudioSeq_SeqLayerProcessScript(SequenceLayer* layer) { - s32 cmd; - - if (!layer->enabled) { - return; - } - - if (layer->delay > 1) { - layer->delay--; - if (!layer->stopSomething && layer->delay <= layer->gateDelay) { - Audio_SeqLayerNoteDecay(layer); - layer->stopSomething = true; - } - return; - } - - AudioSeq_SeqLayerProcessScriptStep1(layer); - - cmd = AudioSeq_SeqLayerProcessScriptStep2(layer); - if (cmd == PROCESS_SCRIPT_END) { - return; - } - - cmd = AudioSeq_SeqLayerProcessScriptStep3(layer, cmd); - - if (cmd != PROCESS_SCRIPT_END) { - // returns `sameSound` instead of a command - cmd = AudioSeq_SeqLayerProcessScriptStep4(layer, cmd); - } - - if (cmd != PROCESS_SCRIPT_END) { - AudioSeq_SeqLayerProcessScriptStep5(layer, cmd); - } - - if (layer->stopSomething == true) { - if ((layer->note != NULL) || layer->continuousNotes) { - Audio_SeqLayerNoteDecay(layer); - } - } -} - -void AudioSeq_SeqLayerProcessScriptStep1(SequenceLayer* layer) { - if (!layer->continuousNotes) { - Audio_SeqLayerNoteDecay(layer); - } else if (layer->note != NULL && layer->note->playbackState.wantedParentLayer == layer) { - Audio_SeqLayerNoteDecay(layer); - } - - if (PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_1 || - PORTAMENTO_MODE(layer->portamento) == PORTAMENTO_MODE_2) { - layer->portamento.mode = PORTAMENTO_MODE_OFF; - } - layer->notePropertiesNeedInit = true; -} - -s32 AudioSeq_SeqLayerProcessScriptStep5(SequenceLayer* layer, s32 sameTunedSample) { - Note* note; - - if (!layer->stopSomething && layer->tunedSample != NULL && - layer->tunedSample->sample->codec == CODEC_S16_INMEMORY && layer->tunedSample->sample->medium != MEDIUM_RAM) { - layer->stopSomething = true; - return PROCESS_SCRIPT_END; - } - - if (layer->continuousNotes == true && layer->bit1 == 1) { - return 0; - } - - if (layer->continuousNotes == true && layer->note != NULL && layer->bit3 && sameTunedSample == true && - layer->note->playbackState.parentLayer == layer) { - if (layer->tunedSample == NULL) { - Audio_InitSyntheticWave(layer->note, layer); - } - } else { - if (!sameTunedSample) { - Audio_SeqLayerNoteDecay(layer); - } - - layer->note = Audio_AllocNote(layer); - if (layer->note != NULL && layer->note->playbackState.parentLayer == layer) { - Audio_NoteVibratoInit(layer->note); - } - } - - if (layer->note != NULL && layer->note->playbackState.parentLayer == layer) { - note = layer->note; - - Audio_NotePortamentoInit(note); - } - - return 0; -} - -s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) { - SequenceChannel* channel = layer->channel; - SeqScriptState* state = &layer->scriptState; - SequencePlayer* seqPlayer = channel->seqPlayer; - u8 cmd; - u8 cmdArg8; - u16 cmdArg16; - u16 velocity; - - while (true) { - cmd = AudioSeq_ScriptReadU8(state); - - // To be processed in AudioSeq_SeqLayerProcessScriptStep3 - if (cmd <= 0xC0) { - return cmd; - } - - // Control Flow Commands - if (cmd >= 0xF2) { - cmdArg16 = AudioSeq_GetScriptControlFlowArgument(state, cmd); - - if (AudioSeq_HandleScriptFlowControl(seqPlayer, state, cmd, cmdArg16) == 0) { - continue; - } - AudioSeq_SeqLayerDisable(layer); - return PROCESS_SCRIPT_END; - } - - switch (cmd) { - case 0xC1: // layer_setshortnotevelocity - case 0xCA: // layer_setpan - cmdArg8 = *(state->pc++); - if (cmd == 0xC1) { - layer->velocitySquare = SQ(cmdArg8) / SQ(127.0f); - } else { - layer->pan = cmdArg8; - } - break; - - case 0xC9: // layer_setshortnotegatetime - case 0xC2: // layer_transpose; set transposition in semitones - cmdArg8 = *(state->pc++); - if (cmd == 0xC9) { - layer->gateTime = cmdArg8; - } else { - layer->transposition = cmdArg8; - } - break; - - case 0xC4: // layer_continuousnoteson - case 0xC5: // layer_continuousnotesoff - if (cmd == 0xC4) { - layer->continuousNotes = true; - } else { - layer->continuousNotes = false; - } - layer->bit1 = false; - Audio_SeqLayerNoteDecay(layer); - break; - - case 0xC3: // layer_setshortnotedefaultdelay - cmdArg16 = AudioSeq_ScriptReadCompressedU16(state); - layer->shortNoteDefaultDelay = cmdArg16; - break; - - case 0xC6: // layer_setinstr - cmd = AudioSeq_ScriptReadU8(state); - if (cmd >= 0x7E) { - if (cmd == 0x7E) { - // Sfxs - layer->instOrWave = 1; - } else if (cmd == 0x7F) { - // Drums - layer->instOrWave = 0; - } else { - // Synthetic Wave - layer->instOrWave = cmd; - layer->instrument = NULL; - } - - if (cmd == 0xFF) { - layer->adsr.decayIndex = 0; - } - } else { - // Instrument - if ((layer->instOrWave = AudioSeq_GetInstrument(channel, cmd, &layer->instrument, &layer->adsr)) == - 0) { - layer->instOrWave = 0xFF; - } - } - break; - - case 0xC7: // layer_portamento - layer->portamento.mode = AudioSeq_ScriptReadU8(state); - - cmd = AudioSeq_ScriptReadU8(state); - cmd += channel->transposition; - cmd += layer->transposition; - cmd += seqPlayer->transposition; - - if (cmd >= 0x80) { - cmd = 0; - } - - layer->portamentoTargetNote = cmd; - - // If special, the next param is u8 instead of var - if (PORTAMENTO_IS_SPECIAL(layer->portamento)) { - layer->portamentoTime = *(state->pc++); - break; - } - - cmdArg16 = AudioSeq_ScriptReadCompressedU16(state); - layer->portamentoTime = cmdArg16; - break; - - case 0xC8: // layer_disableportamento - layer->portamento.mode = PORTAMENTO_MODE_OFF; - break; - - case 0xCB: - cmdArg16 = AudioSeq_ScriptReadS16(state); - layer->adsr.envelope = (EnvelopePoint*)(seqPlayer->seqData + cmdArg16); - FALLTHROUGH; - case 0xCF: - layer->adsr.decayIndex = AudioSeq_ScriptReadU8(state); - break; - - case 0xCC: - layer->ignoreDrumPan = true; - break; - - case 0xCD: - layer->stereo.asByte = AudioSeq_ScriptReadU8(state); - break; - - case 0xCE: - cmdArg8 = AudioSeq_ScriptReadU8(state); - layer->bend = gBendPitchTwoSemitonesFrequencies[(u8)(cmdArg8 + 0x80)]; - break; - - default: - switch (cmd & 0xF0) { - case 0xD0: // layer_setshortnotevelocityfromtable - velocity = seqPlayer->shortNoteVelocityTable[cmd & 0xF]; - layer->velocitySquare = SQ(velocity) / SQ(127.0f); - break; - - case 0xE0: // layer_setshortnotegatetimefromtable - layer->gateTime = seqPlayer->shortNoteGateTimeTable[cmd & 0xF]; - break; - } - } - } -} - -s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) { - s32 sameTunedSample = true; - s32 instOrWave; - s32 speed; - f32 temp_f14; - f32 temp_f2; - Portamento* portamento; - f32 freqScale; - f32 freqScale2; - TunedSample* tunedSample; - Instrument* instrument; - Drum* drum; - SoundEffect* soundEffect; - SequenceChannel* channel; - SequencePlayer* seqPlayer; - u8 semitone = cmd; - u16 sfxId; - s32 semitone2; - s32 vel; - f32 time; - f32 tuning; - s32 speed2; - - instOrWave = layer->instOrWave; - channel = layer->channel; - seqPlayer = channel->seqPlayer; - - if (instOrWave == 0xFF) { - if (!channel->hasInstrument) { - return PROCESS_SCRIPT_END; - } - instOrWave = channel->instOrWave; - } - - switch (instOrWave) { - case 0: - // Drums - semitone += channel->transposition + layer->transposition; - layer->semitone = semitone; - - drum = Audio_GetDrum(channel->fontId, semitone); - if (drum == NULL) { - layer->stopSomething = true; - layer->delay2 = layer->delay; - return PROCESS_SCRIPT_END; - } - - tunedSample = &drum->tunedSample; - layer->adsr.envelope = drum->envelope; - layer->adsr.decayIndex = drum->adsrDecayIndex; - if (!layer->ignoreDrumPan) { - layer->pan = drum->pan; - } - layer->tunedSample = tunedSample; - layer->freqScale = tunedSample->tuning; - break; - - case 1: - // Sfxs - layer->semitone = semitone; - sfxId = (layer->transposition << 6) + semitone; - - soundEffect = Audio_GetSoundEffect(channel->fontId, sfxId); - if (soundEffect == NULL) { - layer->stopSomething = true; - layer->delay2 = layer->delay + 1; - return PROCESS_SCRIPT_END; - } - - tunedSample = &soundEffect->tunedSample; - layer->tunedSample = tunedSample; - layer->freqScale = tunedSample->tuning; - break; - - default: - semitone += seqPlayer->transposition + channel->transposition + layer->transposition; - semitone2 = semitone; - - layer->semitone = semitone; - if (semitone >= 0x80) { - layer->stopSomething = true; - return PROCESS_SCRIPT_END; - } - - if (layer->instOrWave == 0xFF) { - instrument = channel->instrument; - } else { - instrument = layer->instrument; - } - - if (layer->portamento.mode != PORTAMENTO_MODE_OFF) { - portamento = &layer->portamento; - vel = (semitone > layer->portamentoTargetNote) ? semitone : layer->portamentoTargetNote; - - if (instrument != NULL) { - tunedSample = Audio_GetInstrumentTunedSample(instrument, vel); - sameTunedSample = (layer->tunedSample == tunedSample); - layer->tunedSample = tunedSample; - tuning = tunedSample->tuning; - } else { - layer->tunedSample = NULL; - tuning = 1.0f; - if (instOrWave >= 0xC0) { - layer->tunedSample = &gAudioCtx.synthesisReverbs[instOrWave - 0xC0].tunedSample; - } - } - - temp_f2 = gPitchFrequencies[semitone2] * tuning; - temp_f14 = gPitchFrequencies[layer->portamentoTargetNote] * tuning; - - switch (PORTAMENTO_MODE(*portamento)) { - case PORTAMENTO_MODE_1: - case PORTAMENTO_MODE_3: - case PORTAMENTO_MODE_5: - freqScale2 = temp_f2; - freqScale = temp_f14; - break; - - case PORTAMENTO_MODE_2: - case PORTAMENTO_MODE_4: - freqScale = temp_f2; - freqScale2 = temp_f14; - break; - - default: - freqScale = temp_f2; - freqScale2 = temp_f2; - break; - } - - portamento->extent = (freqScale2 / freqScale) - 1.0f; - - if (PORTAMENTO_IS_SPECIAL(*portamento)) { - speed = seqPlayer->tempo * 0x8000 / gAudioCtx.tempoInternalToExternal; - if (layer->delay != 0) { - speed = speed * 0x100 / (layer->delay * layer->portamentoTime); - } - } else { - speed = 0x20000 / (layer->portamentoTime * gAudioCtx.audioBufferParameters.updatesPerFrame); - } - - if (speed >= 0x7FFF) { - speed = 0x7FFF; - } else if (speed < 1) { - speed = 1; - } - - portamento->speed = speed; - portamento->cur = 0; - layer->freqScale = freqScale; - if (PORTAMENTO_MODE(*portamento) == PORTAMENTO_MODE_5) { - layer->portamentoTargetNote = semitone; - } - break; - } - - if (instrument != NULL) { - tunedSample = Audio_GetInstrumentTunedSample(instrument, semitone); - sameTunedSample = (tunedSample == layer->tunedSample); - layer->tunedSample = tunedSample; - layer->freqScale = gPitchFrequencies[semitone2] * tunedSample->tuning; - } else { - layer->tunedSample = NULL; - layer->freqScale = gPitchFrequencies[semitone2]; - if (instOrWave >= 0xC0) { - layer->tunedSample = &gAudioCtx.synthesisReverbs[instOrWave - 0xC0].tunedSample; - } - } - break; - } - - layer->delay2 = layer->delay; - layer->freqScale *= layer->bend; - - if (layer->delay == 0) { - if (layer->tunedSample != NULL) { - time = layer->tunedSample->sample->loop->end; - } else { - time = 0.0f; - } - time *= seqPlayer->tempo; - time *= gAudioCtx.unk_2870; - time /= layer->freqScale; - if (time > 0x7FFE) { - time = 0x7FFE; - } - - layer->gateDelay = 0; - layer->delay = (u16)(s32)time + 1; - - if (layer->portamento.mode != PORTAMENTO_MODE_OFF) { - // (It's a bit unclear if 'portamento' has actually always been - // set when this is reached...) - if (PORTAMENTO_IS_SPECIAL(*portamento)) { - speed2 = seqPlayer->tempo * 0x8000 / gAudioCtx.tempoInternalToExternal; - speed2 = speed2 * 0x100 / (layer->delay * layer->portamentoTime); - if (speed2 >= 0x7FFF) { - speed2 = 0x7FFF; - } else if (speed2 < 1) { - speed2 = 1; - } - portamento->speed = speed2; - } - } - } - return sameTunedSample; -} - -s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd) { - SeqScriptState* state = &layer->scriptState; - u16 delay; - s32 velocity; - SequenceChannel* channel = layer->channel; - SequencePlayer* seqPlayer = channel->seqPlayer; - s32 intDelta; - f32 floatDelta; - - if (cmd == 0xC0) { - layer->delay = AudioSeq_ScriptReadCompressedU16(state); - layer->stopSomething = true; - layer->bit1 = false; - return PROCESS_SCRIPT_END; - } - - layer->stopSomething = false; - - if (channel->largeNotes == true) { - switch (cmd & 0xC0) { - case 0x00: - delay = AudioSeq_ScriptReadCompressedU16(state); - velocity = *(state->pc++); - layer->gateTime = *(state->pc++); - layer->lastDelay = delay; - break; - - case 0x40: - delay = AudioSeq_ScriptReadCompressedU16(state); - velocity = *(state->pc++); - layer->gateTime = 0; - layer->lastDelay = delay; - break; - - case 0x80: - delay = layer->lastDelay; - velocity = *(state->pc++); - layer->gateTime = *(state->pc++); - break; - } - - if (velocity > 0x7F || velocity < 0) { - velocity = 0x7F; - } - layer->velocitySquare = SQ((f32)velocity) / SQ(127.0f); - cmd -= (cmd & 0xC0); - } else { - switch (cmd & 0xC0) { - case 0x00: - delay = AudioSeq_ScriptReadCompressedU16(state); - layer->lastDelay = delay; - break; - - case 0x40: - delay = layer->shortNoteDefaultDelay; - break; - - case 0x80: - delay = layer->lastDelay; - break; - } - cmd -= (cmd & 0xC0); - } - - if (channel->velocityRandomVariance != 0) { - floatDelta = layer->velocitySquare * (gAudioCtx.audioRandom % channel->velocityRandomVariance) / 100.0f; - if ((gAudioCtx.audioRandom & 0x8000) != 0) { - floatDelta = -floatDelta; - } - - layer->velocitySquare2 = layer->velocitySquare + floatDelta; - - if (layer->velocitySquare2 < 0.0f) { - layer->velocitySquare2 = 0.0f; - } else if (layer->velocitySquare2 > 1.0f) { - layer->velocitySquare2 = 1.0f; - } - } else { - layer->velocitySquare2 = layer->velocitySquare; - } - - layer->delay = delay; - layer->gateDelay = (layer->gateTime * delay) >> 8; - - if (channel->gateTimeRandomVariance != 0) { - //! @bug should probably be gateTimeRandomVariance - intDelta = (layer->gateDelay * (gAudioCtx.audioRandom % channel->velocityRandomVariance)) / 100; - if ((gAudioCtx.audioRandom & 0x4000) != 0) { - intDelta = -intDelta; - } - - layer->gateDelay += intDelta; - if (layer->gateDelay < 0) { - layer->gateDelay = 0; - } else if (layer->gateDelay > layer->delay) { - layer->gateDelay = layer->delay; - } - } - - if ((seqPlayer->muted && (channel->muteBehavior & (MUTE_BEHAVIOR_STOP_NOTES | MUTE_BEHAVIOR_4))) || - channel->stopSomething2) { - layer->stopSomething = true; - return PROCESS_SCRIPT_END; - } - - if (seqPlayer->skipTicks != 0) { - layer->stopSomething = true; - return PROCESS_SCRIPT_END; - } - - return cmd; -} - -void AudioSeq_SetChannelPriorities(SequenceChannel* channel, u8 priority) { - if ((priority & 0xF) != 0) { - channel->notePriority = priority & 0xF; - } - - priority = priority >> 4; - if (priority != 0) { - channel->someOtherPriority = priority; - } -} - -u8 AudioSeq_GetInstrument(SequenceChannel* channel, u8 instId, Instrument** instOut, AdsrSettings* adsr) { - Instrument* inst = Audio_GetInstrumentInner(channel->fontId, instId); - - if (inst == NULL) { - *instOut = NULL; - return 0; - } - - adsr->envelope = inst->envelope; - adsr->decayIndex = inst->adsrDecayIndex; - *instOut = inst; - - // temporarily offset instrument id by 2 so that instId 0, 1 - // can be reserved by drums and sfxs respectively. - instId += 2; - - return instId; -} - -void AudioSeq_SetInstrument(SequenceChannel* channel, u8 instId) { - if (instId >= 0x80) { - // Synthetic Waves - channel->instOrWave = instId; - channel->instrument = NULL; - } else if (instId == 0x7F) { - // Drums - channel->instOrWave = 0; - channel->instrument = (Instrument*)1; // invalid pointer, never dereferenced - } else if (instId == 0x7E) { - // Sfxs - channel->instOrWave = 1; - channel->instrument = (Instrument*)2; // invalid pointer, never dereferenced - } else { - // Instruments - if ((channel->instOrWave = AudioSeq_GetInstrument(channel, instId, &channel->instrument, &channel->adsr)) == - 0) { - channel->hasInstrument = false; - return; - } - } - - channel->hasInstrument = true; -} - -void AudioSeq_SequenceChannelSetVolume(SequenceChannel* channel, u8 volume) { - channel->volume = (s32)volume / 127.0f; -} - -void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { - s32 i; - u8* data; - u8* seqData; - SequencePlayer* seqPlayer; - - if (channel->stopScript) { - goto exit_loop; - } - - seqPlayer = channel->seqPlayer; - if (seqPlayer->muted && (channel->muteBehavior & MUTE_BEHAVIOR_STOP_SCRIPT)) { - return; - } - - if (channel->delay >= 2) { - channel->delay--; - goto exit_loop; - } - - while (true) { - SeqScriptState* scriptState = &channel->scriptState; - s32 param; - s16 temp1; - u16 cmdArgU16; - u32 cmdArgs[3]; - s8 cmdArgS8; - u8 cmd = AudioSeq_ScriptReadU8(scriptState); - u8 lowBits; - u8 highBits; - s32 delay; - s32 temp2; - - if (cmd >= 0xB0) { - highBits = sSeqInstructionArgsTable[cmd - 0xB0]; - lowBits = highBits & 3; - - // read in arguments for the instruction - for (i = 0; i < lowBits; i++, highBits <<= 1) { - if (!(highBits & 0x80)) { - cmdArgs[i] = AudioSeq_ScriptReadU8(scriptState); - } else { - cmdArgs[i] = AudioSeq_ScriptReadS16(scriptState); - } - } - - // Control Flow Commands - if (cmd >= 0xF2) { - delay = AudioSeq_HandleScriptFlowControl(seqPlayer, scriptState, cmd, cmdArgs[0]); - - if (delay != 0) { - if (delay == PROCESS_SCRIPT_END) { - AudioSeq_SequenceChannelDisable(channel); - } else { - channel->delay = delay; - } - break; - } - continue; - } - - switch (cmd) { - case 0xEA: - channel->stopScript = true; - goto exit_loop; - - case 0xF1: - Audio_NotePoolClear(&channel->notePool); - cmd = (u8)cmdArgs[0]; - Audio_NotePoolFill(&channel->notePool, cmd); - break; - - case 0xF0: - Audio_NotePoolClear(&channel->notePool); - break; - - case 0xC2: - cmdArgU16 = (u16)cmdArgs[0]; - channel->dynTable = (void*)&seqPlayer->seqData[cmdArgU16]; - break; - - case 0xC5: - if (scriptState->value != -1) { - data = (*channel->dynTable)[scriptState->value]; - cmdArgU16 = (u16)((data[0] << 8) + data[1]); - - channel->dynTable = (void*)&seqPlayer->seqData[cmdArgU16]; - } - break; - - case 0xEB: - cmd = (u8)cmdArgs[0]; - - if (seqPlayer->defaultFont != 0xFF) { - cmdArgU16 = ((u16*)gAudioCtx.sequenceFontTable)[seqPlayer->seqId]; - lowBits = gAudioCtx.sequenceFontTable[cmdArgU16]; - cmd = gAudioCtx.sequenceFontTable[cmdArgU16 + lowBits - cmd]; - } - - if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, cmd)) { - channel->fontId = cmd; - } - - cmdArgs[0] = cmdArgs[1]; - FALLTHROUGH; - case 0xC1: - cmd = (u8)cmdArgs[0]; - AudioSeq_SetInstrument(channel, cmd); - break; - - case 0xC3: - channel->largeNotes = false; - break; - - case 0xC4: - channel->largeNotes = true; - break; - - case 0xDF: - cmd = (u8)cmdArgs[0]; - AudioSeq_SequenceChannelSetVolume(channel, cmd); - channel->changes.s.volume = true; - break; - - case 0xE0: - cmd = (u8)cmdArgs[0]; - channel->volumeScale = (s32)cmd / 128.0f; - channel->changes.s.volume = true; - break; - - case 0xDE: - cmdArgU16 = (u16)cmdArgs[0]; - channel->freqScale = (s32)cmdArgU16 / 32768.0f; - channel->changes.s.freqScale = true; - break; - - case 0xD3: - cmd = (u8)cmdArgs[0]; - cmd += 0x80; - channel->freqScale = gBendPitchOneOctaveFrequencies[cmd]; - channel->changes.s.freqScale = true; - break; - - case 0xEE: - cmd = (u8)cmdArgs[0]; - cmd += 0x80; - channel->freqScale = gBendPitchTwoSemitonesFrequencies[cmd]; - channel->changes.s.freqScale = true; - break; - - case 0xDD: - cmd = (u8)cmdArgs[0]; - channel->newPan = cmd; - channel->changes.s.pan = true; - break; - - case 0xDC: - cmd = (u8)cmdArgs[0]; - channel->panChannelWeight = cmd; - channel->changes.s.pan = true; - break; - - case 0xDB: - cmdArgS8 = (s8)cmdArgs[0]; - channel->transposition = cmdArgS8; - break; - - case 0xDA: - cmdArgU16 = (u16)cmdArgs[0]; - channel->adsr.envelope = (EnvelopePoint*)&seqPlayer->seqData[cmdArgU16]; - break; - - case 0xD9: - cmd = (u8)cmdArgs[0]; - channel->adsr.decayIndex = cmd; - break; - - case 0xD8: - cmd = (u8)cmdArgs[0]; - channel->vibratoExtentTarget = cmd * 8; - channel->vibratoExtentStart = 0; - channel->vibratoExtentChangeDelay = 0; - break; - - case 0xD7: - cmd = (u8)cmdArgs[0]; - channel->vibratoRateChangeDelay = 0; - channel->vibratoRateTarget = cmd * 32; - channel->vibratoRateStart = cmd * 32; - break; - - case 0xE2: - cmd = (u8)cmdArgs[0]; - channel->vibratoExtentStart = cmd * 8; - cmd = (u8)cmdArgs[1]; - channel->vibratoExtentTarget = cmd * 8; - cmd = (u8)cmdArgs[2]; - channel->vibratoExtentChangeDelay = cmd * 16; - break; - - case 0xE1: - cmd = (u8)cmdArgs[0]; - channel->vibratoRateStart = cmd * 32; - cmd = (u8)cmdArgs[1]; - channel->vibratoRateTarget = cmd * 32; - cmd = (u8)cmdArgs[2]; - channel->vibratoRateChangeDelay = cmd * 16; - break; - - case 0xE3: - cmd = (u8)cmdArgs[0]; - channel->vibratoDelay = cmd * 16; - break; - - case 0xD4: - cmd = (u8)cmdArgs[0]; - channel->reverb = cmd; - break; - - case 0xC6: - cmd = (u8)cmdArgs[0]; - - if (seqPlayer->defaultFont != 0xFF) { - cmdArgU16 = ((u16*)gAudioCtx.sequenceFontTable)[seqPlayer->seqId]; - lowBits = gAudioCtx.sequenceFontTable[cmdArgU16]; - cmd = gAudioCtx.sequenceFontTable[cmdArgU16 + lowBits - cmd]; - } - - if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, cmd)) { - channel->fontId = cmd; - } - break; - - case 0xC7: - cmd = (u8)cmdArgs[0]; - cmdArgU16 = (u16)cmdArgs[1]; - seqData = &seqPlayer->seqData[cmdArgU16]; - seqData[0] = (u8)scriptState->value + cmd; - break; - - case 0xC8: - case 0xCC: - case 0xC9: - cmdArgS8 = (s8)cmdArgs[0]; - - if (cmd == 0xC8) { - scriptState->value -= cmdArgS8; - } else if (cmd == 0xCC) { - scriptState->value = cmdArgS8; - } else { - scriptState->value &= cmdArgS8; - } - break; - - case 0xCD: - cmd = (u8)cmdArgs[0]; - AudioSeq_SequenceChannelDisable(seqPlayer->channels[cmd]); - break; - - case 0xCA: - cmd = (u8)cmdArgs[0]; - channel->muteBehavior = cmd; - channel->changes.s.volume = true; - break; - - case 0xCB: - cmdArgU16 = (u16)cmdArgs[0]; - scriptState->value = *(seqPlayer->seqData + (u32)(cmdArgU16 + scriptState->value)); - break; - - case 0xCE: - cmdArgU16 = (u16)cmdArgs[0]; - channel->unk_22 = cmdArgU16; - break; - - case 0xCF: - cmdArgU16 = (u16)cmdArgs[0]; - seqData = &seqPlayer->seqData[cmdArgU16]; - seqData[0] = (channel->unk_22 >> 8) & 0xFF; - seqData[1] = channel->unk_22 & 0xFF; - break; - - case 0xD0: - cmd = (u8)cmdArgs[0]; - if (cmd & 0x80) { - channel->stereoHeadsetEffects = true; - } else { - channel->stereoHeadsetEffects = false; - } - channel->stereo.asByte = cmd & 0x7F; - break; - - case 0xD1: - cmd = (u8)cmdArgs[0]; - channel->noteAllocPolicy = cmd; - break; - - case 0xD2: - cmd = (u8)cmdArgs[0]; - channel->adsr.sustain = cmd; - break; - - case 0xE5: - cmd = (u8)cmdArgs[0]; - channel->reverbIndex = cmd; - break; - - case 0xE4: - if (scriptState->value != -1) { - data = (*channel->dynTable)[scriptState->value]; - //! @bug: Missing a stack depth check here - scriptState->stack[scriptState->depth++] = scriptState->pc; - cmdArgU16 = (u16)((data[0] << 8) + data[1]); - scriptState->pc = seqPlayer->seqData + cmdArgU16; - } - break; - - case 0xE6: - cmd = (u8)cmdArgs[0]; - channel->bookOffset = cmd; - break; - - case 0xE7: - cmdArgU16 = (u16)cmdArgs[0]; - data = &seqPlayer->seqData[cmdArgU16]; - channel->muteBehavior = data[0]; - data += 3; - channel->noteAllocPolicy = data[-2]; - AudioSeq_SetChannelPriorities(channel, data[-1]); - channel->transposition = (s8)data[0]; - data += 4; - channel->newPan = data[-3]; - channel->panChannelWeight = data[-2]; - channel->reverb = data[-1]; - channel->reverbIndex = data[0]; - //! @bug: Not marking reverb state as changed - channel->changes.s.pan = true; - break; - - case 0xE8: - channel->muteBehavior = cmdArgs[0]; - channel->noteAllocPolicy = cmdArgs[1]; - cmd = (u8)cmdArgs[2]; - AudioSeq_SetChannelPriorities(channel, cmd); - channel->transposition = (s8)AudioSeq_ScriptReadU8(scriptState); - channel->newPan = AudioSeq_ScriptReadU8(scriptState); - channel->panChannelWeight = AudioSeq_ScriptReadU8(scriptState); - channel->reverb = AudioSeq_ScriptReadU8(scriptState); - channel->reverbIndex = AudioSeq_ScriptReadU8(scriptState); - //! @bug: Not marking reverb state as changed - channel->changes.s.pan = true; - break; - - case 0xEC: - channel->vibratoExtentTarget = 0; - channel->vibratoExtentStart = 0; - channel->vibratoExtentChangeDelay = 0; - channel->vibratoRateTarget = 0; - channel->vibratoRateStart = 0; - channel->vibratoRateChangeDelay = 0; - channel->filter = NULL; - channel->gain = 0; - channel->adsr.sustain = 0; - channel->velocityRandomVariance = 0; - channel->gateTimeRandomVariance = 0; - channel->unk_0F = 0; - channel->unk_20 = 0; - channel->bookOffset = 0; - channel->freqScale = 1.0f; - break; - - case 0xE9: - AudioSeq_SetChannelPriorities(channel, (u8)cmdArgs[0]); - break; - - case 0xED: - cmd = (u8)cmdArgs[0]; - channel->gain = cmd; - break; - - case 0xB0: - cmdArgU16 = (u16)cmdArgs[0]; - data = seqPlayer->seqData + cmdArgU16; - channel->filter = (s16*)data; - break; - - case 0xB1: - channel->filter = NULL; - break; - - case 0xB3: - cmd = cmdArgs[0]; - - if (channel->filter != NULL) { - lowBits = (cmd >> 4) & 0xF; // LowPassCutoff - cmd &= 0xF; // HighPassCutoff - AudioHeap_LoadFilter(channel->filter, lowBits, cmd); - } - break; - - case 0xB2: - cmdArgU16 = (u16)cmdArgs[0]; - channel->unk_22 = *(u16*)(seqPlayer->seqData + (u32)(cmdArgU16 + scriptState->value * 2)); - break; - - case 0xB4: - channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22]; - break; - - case 0xB5: - channel->unk_22 = ((u16*)(channel->dynTable))[scriptState->value]; - break; - - case 0xB6: - scriptState->value = (*channel->dynTable)[0][scriptState->value]; - break; - - case 0xB7: - channel->unk_22 = - (cmdArgs[0] == 0) ? gAudioCtx.audioRandom & 0xFFFF : gAudioCtx.audioRandom % cmdArgs[0]; - break; - - case 0xB8: - scriptState->value = - (cmdArgs[0] == 0) ? gAudioCtx.audioRandom & 0xFFFF : gAudioCtx.audioRandom % cmdArgs[0]; - break; - - case 0xBD: - temp2 = Audio_NextRandom(); - channel->unk_22 = (cmdArgs[0] == 0) ? (temp2 & 0xFFFF) : (temp2 % cmdArgs[0]); - channel->unk_22 += cmdArgs[1]; - temp2 = (channel->unk_22 / 0x100) + 0x80; - param = channel->unk_22 % 0x100; - channel->unk_22 = (temp2 << 8) | param; - break; - - case 0xB9: - channel->velocityRandomVariance = cmdArgs[0]; - break; - - case 0xBA: - channel->gateTimeRandomVariance = cmdArgs[0]; - break; - - case 0xBB: - channel->unk_0F = cmdArgs[0]; - channel->unk_20 = cmdArgs[1]; - break; - - case 0xBC: - channel->unk_22 += cmdArgs[0]; - break; - } - continue; - } - - if (cmd >= 0x70) { - lowBits = cmd & 0x7; - - if ((cmd & 0xF8) != 0x70 && lowBits >= 4) { - lowBits = 0; - } - - switch (cmd & 0xF8) { - case 0x80: - if (channel->layers[lowBits] != NULL) { - scriptState->value = channel->layers[lowBits]->finished; - } else { - scriptState->value = -1; - } - break; - - case 0x88: - cmdArgU16 = AudioSeq_ScriptReadS16(scriptState); - if (!AudioSeq_SeqChannelSetLayer(channel, lowBits)) { - channel->layers[lowBits]->scriptState.pc = &seqPlayer->seqData[cmdArgU16]; - } - break; - - case 0x90: - AudioSeq_SeqLayerFree(channel, lowBits); - break; - - case 0x98: - if (scriptState->value != -1 && AudioSeq_SeqChannelSetLayer(channel, lowBits) != -1) { - data = (*channel->dynTable)[scriptState->value]; - cmdArgU16 = (data[0] << 8) + data[1]; - channel->layers[lowBits]->scriptState.pc = &seqPlayer->seqData[cmdArgU16]; - } - break; - - case 0x70: - channel->soundScriptIO[lowBits] = scriptState->value; - break; - - case 0x78: - temp1 = AudioSeq_ScriptReadS16(scriptState); - if (!AudioSeq_SeqChannelSetLayer(channel, lowBits)) { - channel->layers[lowBits]->scriptState.pc = &scriptState->pc[temp1]; - } - break; - } - continue; - } - - lowBits = cmd & 0xF; - - switch (cmd & 0xF0) { - case 0x00: - channel->delay = lowBits; - goto exit_loop; - - case 0x10: - if (lowBits < 8) { - channel->soundScriptIO[lowBits] = SEQ_IO_VAL_NONE; - if (AudioLoad_SlowLoadSample(channel->fontId, scriptState->value, - &channel->soundScriptIO[lowBits]) == -1) {} - } else { - lowBits -= 8; - channel->soundScriptIO[lowBits] = SEQ_IO_VAL_NONE; - if (AudioLoad_SlowLoadSample(channel->fontId, channel->unk_22 + 0x100, - &channel->soundScriptIO[lowBits]) == -1) {} - } - break; - - case 0x60: - scriptState->value = channel->soundScriptIO[lowBits]; - if (lowBits < 2) { - channel->soundScriptIO[lowBits] = SEQ_IO_VAL_NONE; - } - break; - - case 0x50: - scriptState->value -= channel->soundScriptIO[lowBits]; - break; - - case 0x20: - cmdArgU16 = AudioSeq_ScriptReadS16(scriptState); - AudioSeq_SequenceChannelEnable(seqPlayer, lowBits, &seqPlayer->seqData[cmdArgU16]); - break; - - case 0x30: - cmd = AudioSeq_ScriptReadU8(scriptState); - seqPlayer->channels[lowBits]->soundScriptIO[cmd] = scriptState->value; - break; - - case 0x40: - cmd = AudioSeq_ScriptReadU8(scriptState); - scriptState->value = seqPlayer->channels[lowBits]->soundScriptIO[cmd]; - break; - } - } -exit_loop: - - for (i = 0; i < ARRAY_COUNT(channel->layers); i++) { - if (channel->layers[i] != NULL) { - AudioSeq_SeqLayerProcessScript(channel->layers[i]); - } - } -} - -void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) { - u8 cmd; - u8 cmdLowBits; - SeqScriptState* seqScript = &seqPlayer->scriptState; - s16 tempS; - u16 temp; - s32 i; - s32 value; - u8* data; - u8* data2; - u8* data3; - s32 pad; - s32 dummy; - s32 delay; - - if (!seqPlayer->enabled) { - return; - } - - if (!AudioLoad_IsSeqLoadComplete(seqPlayer->seqId) || !AudioLoad_IsFontLoadComplete(seqPlayer->defaultFont)) { - AudioSeq_SequencePlayerDisable(seqPlayer); - return; - } - - AudioLoad_SetSeqLoadStatus(seqPlayer->seqId, LOAD_STATUS_COMPLETE); - AudioLoad_SetFontLoadStatus(seqPlayer->defaultFont, LOAD_STATUS_COMPLETE); - - if (seqPlayer->muted && (seqPlayer->muteBehavior & MUTE_BEHAVIOR_STOP_SCRIPT)) { - return; - } - - seqPlayer->scriptCounter++; - seqPlayer->tempoAcc += seqPlayer->tempo; - seqPlayer->tempoAcc += (s16)seqPlayer->unk_0C; - - if (seqPlayer->tempoAcc < gAudioCtx.tempoInternalToExternal) { - return; - } - - seqPlayer->tempoAcc -= (u16)gAudioCtx.tempoInternalToExternal; - - if (seqPlayer->stopScript == true) { - return; - } - - if (seqPlayer->delay > 1) { - seqPlayer->delay--; - } else { - seqPlayer->recalculateVolume = true; - - while (true) { - cmd = AudioSeq_ScriptReadU8(seqScript); - - // 0xF2 and above are "flow control" commands, including termination. - if (cmd >= 0xF2) { - delay = AudioSeq_HandleScriptFlowControl( - seqPlayer, seqScript, cmd, AudioSeq_GetScriptControlFlowArgument(&seqPlayer->scriptState, cmd)); - - if (delay != 0) { - if (delay == -1) { - AudioSeq_SequencePlayerDisable(seqPlayer); - } else { - seqPlayer->delay = delay; - } - break; - } - continue; - } - - if (cmd >= 0xC0) { - switch (cmd) { - case 0xF1: - Audio_NotePoolClear(&seqPlayer->notePool); - cmd = AudioSeq_ScriptReadU8(seqScript); - Audio_NotePoolFill(&seqPlayer->notePool, cmd); - // Fake-match: the asm has two breaks in a row here, - // which the compiler normally optimizes out. - dummy = -1; - if (dummy < 0) { - dummy = 0; - } - if (dummy > 1) { - dummy = 1; - } - if (dummy) {} - break; - - case 0xF0: - Audio_NotePoolClear(&seqPlayer->notePool); - break; - - case 0xDF: - seqPlayer->transposition = 0; - FALLTHROUGH; - case 0xDE: - seqPlayer->transposition += (s8)AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xDD: - seqPlayer->tempo = AudioSeq_ScriptReadU8(seqScript) * TATUMS_PER_BEAT; - if (seqPlayer->tempo > gAudioCtx.tempoInternalToExternal) { - seqPlayer->tempo = (u16)gAudioCtx.tempoInternalToExternal; - } - - if ((s16)seqPlayer->tempo <= 0) { - seqPlayer->tempo = 1; - } - break; - - case 0xDC: - seqPlayer->unk_0C = (s8)AudioSeq_ScriptReadU8(seqScript) * TATUMS_PER_BEAT; - break; - - case 0xDA: - cmd = AudioSeq_ScriptReadU8(seqScript); - temp = AudioSeq_ScriptReadS16(seqScript); - switch (cmd) { - case 0: - case 1: - if (seqPlayer->state != 2) { - seqPlayer->fadeTimerUnkEu = temp; - seqPlayer->state = cmd; - } - break; - - case 2: - seqPlayer->fadeTimer = temp; - seqPlayer->state = cmd; - seqPlayer->fadeVelocity = (0.0f - seqPlayer->fadeVolume) / (s32)seqPlayer->fadeTimer; - break; - } - break; - - case 0xDB: - value = AudioSeq_ScriptReadU8(seqScript); - switch (seqPlayer->state) { - case 1: - seqPlayer->state = 0; - seqPlayer->fadeVolume = 0.0f; - FALLTHROUGH; - case 0: - seqPlayer->fadeTimer = seqPlayer->fadeTimerUnkEu; - if (seqPlayer->fadeTimerUnkEu != 0) { - seqPlayer->fadeVelocity = - ((value / 127.0f) - seqPlayer->fadeVolume) / (s32)seqPlayer->fadeTimer; - } else { - seqPlayer->fadeVolume = value / 127.0f; - } - break; - - case 2: - break; - } - break; - - case 0xD9: - seqPlayer->fadeVolumeScale = (s8)AudioSeq_ScriptReadU8(seqScript) / 127.0f; - break; - - case 0xD7: - temp = AudioSeq_ScriptReadS16(seqScript); - AudioSeq_SequencePlayerSetupChannels(seqPlayer, temp); - break; - - case 0xD6: - AudioSeq_ScriptReadS16(seqScript); - break; - - case 0xD5: - seqPlayer->muteVolumeScale = (s8)AudioSeq_ScriptReadU8(seqScript) / 127.0f; - break; - - case 0xD4: - seqPlayer->muted = true; - break; - - case 0xD3: - seqPlayer->muteBehavior = AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xD1: - case 0xD2: - temp = AudioSeq_ScriptReadS16(seqScript); - data3 = &seqPlayer->seqData[temp]; - if (cmd == 0xD2) { - seqPlayer->shortNoteVelocityTable = data3; - } else { - seqPlayer->shortNoteGateTimeTable = data3; - } - break; - - case 0xD0: - seqPlayer->noteAllocPolicy = AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xCE: - cmd = AudioSeq_ScriptReadU8(seqScript); - if (cmd == 0) { - seqScript->value = (gAudioCtx.audioRandom >> 2) & 0xFF; - } else { - seqScript->value = (gAudioCtx.audioRandom >> 2) % cmd; - } - break; - - case 0xCD: - temp = AudioSeq_ScriptReadS16(seqScript); - if ((seqScript->value != -1) && (seqScript->depth != 3)) { - data = seqPlayer->seqData + (u32)(temp + (seqScript->value << 1)); - seqScript->stack[seqScript->depth] = seqScript->pc; - seqScript->depth++; - - temp = (data[0] << 8) + data[1]; - seqScript->pc = &seqPlayer->seqData[temp]; - } - break; - - case 0xCC: - seqScript->value = AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xC9: - seqScript->value &= AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xC8: - seqScript->value -= AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xC7: - cmd = AudioSeq_ScriptReadU8(seqScript); - temp = AudioSeq_ScriptReadS16(seqScript); - data2 = &seqPlayer->seqData[temp]; - *data2 = (u8)seqScript->value + cmd; - break; - - case 0xC6: - seqPlayer->stopScript = true; - return; - - case 0xC5: - seqPlayer->scriptCounter = (u16)AudioSeq_ScriptReadS16(seqScript); - break; - - case 0xEF: - AudioSeq_ScriptReadS16(seqScript); - AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xC4: - cmd = AudioSeq_ScriptReadU8(seqScript); - if (cmd == 0xFF) { - cmd = seqPlayer->playerIdx; - } - cmdLowBits = AudioSeq_ScriptReadU8(seqScript); - AudioLoad_SyncInitSeqPlayer(cmd, cmdLowBits, 0); - if (cmd == (u8)seqPlayer->playerIdx) { - return; - } - break; - } - continue; - } - - cmdLowBits = cmd & 0x0F; - - switch (cmd & 0xF0) { - case 0x00: - seqScript->value = seqPlayer->channels[cmdLowBits]->enabled ^ 1; - break; - - case 0x50: - seqScript->value -= seqPlayer->soundScriptIO[cmdLowBits]; - break; - - case 0x70: - seqPlayer->soundScriptIO[cmdLowBits] = seqScript->value; - break; - - case 0x80: - seqScript->value = seqPlayer->soundScriptIO[cmdLowBits]; - if (cmdLowBits < 2) { - seqPlayer->soundScriptIO[cmdLowBits] = SEQ_IO_VAL_NONE; - } - break; - - case 0x40: - AudioSeq_SequenceChannelDisable(seqPlayer->channels[cmdLowBits]); - break; - - case 0x90: - temp = AudioSeq_ScriptReadS16(seqScript); - AudioSeq_SequenceChannelEnable(seqPlayer, cmdLowBits, (void*)&seqPlayer->seqData[temp]); - break; - - case 0xA0: - tempS = AudioSeq_ScriptReadS16(seqScript); - AudioSeq_SequenceChannelEnable(seqPlayer, cmdLowBits, (void*)&seqScript->pc[tempS]); - break; - - case 0xB0: - cmd = AudioSeq_ScriptReadU8(seqScript); - temp = AudioSeq_ScriptReadS16(seqScript); - data2 = &seqPlayer->seqData[temp]; - AudioLoad_SlowLoadSeq(cmd, data2, &seqPlayer->soundScriptIO[cmdLowBits]); - break; - - case 0x60: - cmd = AudioSeq_ScriptReadU8(seqScript); - value = cmd; - temp = AudioSeq_ScriptReadU8(seqScript); - AudioLoad_ScriptLoad(value, temp, &seqPlayer->soundScriptIO[cmdLowBits]); - break; - } - } - } - - for (i = 0; i < SEQ_NUM_CHANNELS; i++) { - if (seqPlayer->channels[i]->enabled) { - AudioSeq_SequenceChannelProcessScript(seqPlayer->channels[i]); - } - } -} - -void AudioSeq_ProcessSequences(s32 arg0) { - SequencePlayer* seqPlayer; - u32 i; - - gAudioCtx.noteSubEuOffset = (gAudioCtx.audioBufferParameters.updatesPerFrame - arg0 - 1) * gAudioCtx.numNotes; - - for (i = 0; i < (u32)gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - seqPlayer = &gAudioCtx.seqPlayers[i]; - if (seqPlayer->enabled == true) { - AudioSeq_SequencePlayerProcessSequence(seqPlayer); - Audio_SequencePlayerProcessSound(seqPlayer); - } - } - - Audio_ProcessNotes(); -} - -void AudioSeq_SkipForwardSequence(SequencePlayer* seqPlayer) { - while (seqPlayer->skipTicks > 0) { - AudioSeq_SequencePlayerProcessSequence(seqPlayer); - Audio_SequencePlayerProcessSound(seqPlayer); - seqPlayer->skipTicks--; - } -} - -void AudioSeq_ResetSequencePlayer(SequencePlayer* seqPlayer) { - s32 i; - - AudioSeq_SequencePlayerDisable(seqPlayer); - seqPlayer->stopScript = false; - seqPlayer->delay = 0; - seqPlayer->state = 1; - seqPlayer->fadeTimer = 0; - seqPlayer->fadeTimerUnkEu = 0; - seqPlayer->tempoAcc = 0; - seqPlayer->tempo = 120 * TATUMS_PER_BEAT; // 120 BPM - seqPlayer->unk_0C = 0; - seqPlayer->transposition = 0; - seqPlayer->noteAllocPolicy = 0; - seqPlayer->shortNoteVelocityTable = gDefaultShortNoteVelocityTable; - seqPlayer->shortNoteGateTimeTable = gDefaultShortNoteGateTimeTable; - seqPlayer->scriptCounter = 0; - seqPlayer->fadeVolume = 1.0f; - seqPlayer->fadeVelocity = 0.0f; - seqPlayer->volume = 0.0f; - seqPlayer->muteVolumeScale = 0.5f; - - for (i = 0; i < SEQ_NUM_CHANNELS; i++) { - AudioSeq_InitSequenceChannel(seqPlayer->channels[i]); - } -} - -void AudioSeq_InitSequencePlayerChannels(s32 playerIdx) { - SequenceChannel* channel; - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; - s32 i; - s32 j; - - for (i = 0; i < SEQ_NUM_CHANNELS; i++) { - seqPlayer->channels[i] = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(SequenceChannel)); - if (seqPlayer->channels[i] == NULL) { - seqPlayer->channels[i] = &gAudioCtx.sequenceChannelNone; - } else { - channel = seqPlayer->channels[i]; - channel->seqPlayer = seqPlayer; - channel->enabled = false; - for (j = 0; j < ARRAY_COUNT(channel->layers); j++) { - channel->layers[j] = NULL; - } - } - AudioSeq_InitSequenceChannel(seqPlayer->channels[i]); - } -} - -void AudioSeq_InitSequencePlayer(SequencePlayer* seqPlayer) { - s32 i; - s32 j; - - for (i = 0; i < SEQ_NUM_CHANNELS; i++) { - seqPlayer->channels[i] = &gAudioCtx.sequenceChannelNone; - } - - seqPlayer->enabled = false; - seqPlayer->muted = false; - seqPlayer->fontDmaInProgress = false; - seqPlayer->seqDmaInProgress = false; - seqPlayer->applyBend = false; - - for (j = 0; j < ARRAY_COUNT(seqPlayer->soundScriptIO); j++) { - seqPlayer->soundScriptIO[j] = SEQ_IO_VAL_NONE; - } - - seqPlayer->muteBehavior = MUTE_BEHAVIOR_SOFTEN | MUTE_BEHAVIOR_STOP_NOTES; - seqPlayer->fadeVolumeScale = 1.0f; - seqPlayer->bend = 1.0f; - Audio_InitNoteLists(&seqPlayer->notePool); - AudioSeq_ResetSequencePlayer(seqPlayer); -} - -void AudioSeq_InitSequencePlayers(void) { - s32 i; - - AudioSeq_InitLayerFreelist(); - - for (i = 0; i < ARRAY_COUNT(gAudioCtx.sequenceLayers); i++) { - gAudioCtx.sequenceLayers[i].channel = NULL; - gAudioCtx.sequenceLayers[i].enabled = false; - } - - for (i = 0; i < ARRAY_COUNT(gAudioCtx.seqPlayers); i++) { - AudioSeq_InitSequencePlayer(&gAudioCtx.seqPlayers[i]); - } -} diff --git a/src/code/audio_sfx_params.c b/src/code/audio_sfx_params.c deleted file mode 100644 index 6269dffa4..000000000 --- a/src/code/audio_sfx_params.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "ultra64.h" -#include "global.h" - -#define DEFINE_SFX(_0, importance, distParam, randParam, flags) \ - { importance, ((((distParam) << SFX_PARAM_01_SHIFT) & SFX_PARAM_01_MASK) | \ - (((randParam) << SFX_PARAM_67_SHIFT) & SFX_PARAM_67_MASK) | (flags)) }, - -SfxParams sEnemyBankParams[] = { -#include "tables/sfx/enemybank_table.h" -}; - -SfxParams sPlayerBankParams[] = { -#include "tables/sfx/playerbank_table.h" -}; - -SfxParams sItemBankParams[] = { -#include "tables/sfx/itembank_table.h" -}; - -SfxParams sEnvBankParams[] = { -#include "tables/sfx/environmentbank_table.h" -}; - -SfxParams sSystemBankParams[] = { -#include "tables/sfx/systembank_table.h" -}; - -SfxParams sOcarinaBankParams[] = { -#include "tables/sfx/ocarinabank_table.h" -}; - -SfxParams sVoiceBankParams[] = { -#include "tables/sfx/voicebank_table.h" -}; - -#undef DEFINE_SFX - -SfxParams* gSfxParams[7] = { - sPlayerBankParams, sItemBankParams, sEnvBankParams, sEnemyBankParams, - sSystemBankParams, sOcarinaBankParams, sVoiceBankParams, -}; diff --git a/src/code/code_800C3C20.c b/src/code/audio_stop_all_sfx.c index ef84cd6ff..ef84cd6ff 100644 --- a/src/code/code_800C3C20.c +++ b/src/code/audio_stop_all_sfx.c diff --git a/src/code/audio_synthesis.c b/src/code/audio_synthesis.c deleted file mode 100644 index 51b2c2e5a..000000000 --- a/src/code/audio_synthesis.c +++ /dev/null @@ -1,1338 +0,0 @@ -#include "ultra64.h" -#include "global.h" - -// DMEM Addresses for the RSP -#define DMEM_TEMP 0x3C0 -#define DMEM_UNCOMPRESSED_NOTE 0x580 -#define DMEM_HAAS_TEMP 0x5C0 -#define DMEM_SCRATCH2 0x760 // = DMEM_TEMP + DMEM_2CH_SIZE + a bit more -#define DMEM_COMPRESSED_ADPCM_DATA 0x940 // = DMEM_LEFT_CH -#define DMEM_LEFT_CH 0x940 -#define DMEM_RIGHT_CH 0xAE0 -#define DMEM_WET_TEMP 0x3E0 -#define DMEM_WET_SCRATCH 0x720 // = DMEM_WET_TEMP + DMEM_2CH_SIZE -#define DMEM_WET_LEFT_CH 0xC80 -#define DMEM_WET_RIGHT_CH 0xE20 // = DMEM_WET_LEFT_CH + DMEM_1CH_SIZE - -typedef enum { - /* 0 */ HAAS_EFFECT_DELAY_NONE, - /* 1 */ HAAS_EFFECT_DELAY_LEFT, // Delay left channel so that right channel is heard first - /* 2 */ HAAS_EFFECT_DELAY_RIGHT // Delay right channel so that left channel is heard first -} HaasEffectDelaySide; - -Acmd* AudioSynth_LoadRingBufferPart(Acmd* cmd, u16 dmem, u16 startPos, s32 size, SynthesisReverb* reverb); -Acmd* AudioSynth_SaveBufferOffset(Acmd* cmd, u16 dmem, u16 offset, s32 size, s16* buf); -Acmd* AudioSynth_SaveRingBufferPart(Acmd* cmd, u16 dmem, u16 startPos, s32 size, SynthesisReverb* reverb); -Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updateIndex); -Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s16* aiBuf, - s32 aiBufLen, Acmd* cmd, s32 updateIndex); -Acmd* AudioSynth_LoadWaveSamples(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 numSamplesToLoad); -Acmd* AudioSynth_ApplyHaasEffect(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 size, s32 flags, - s32 haasEffectDelaySide); -Acmd* AudioSynth_ProcessEnvelope(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 aiBufLen, - u16 dmemSrc, s32 haasEffectDelaySide, s32 flags); -Acmd* AudioSynth_FinalResample(Acmd* cmd, NoteSynthesisState* synthState, s32 size, u16 pitch, u16 inpDmem, - s32 resampleFlags); - -u32 sEnvMixerOp = _SHIFTL(A_ENVMIXER, 24, 8); - -// Store the left dry channel in a temp space to be delayed to produce the haas effect -u32 sEnvMixerLeftHaasDmemDests = - MK_CMD(DMEM_HAAS_TEMP >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); - -// Store the right dry channel in a temp space to be delayed to produce the haas effect -u32 sEnvMixerRightHaasDmemDests = - MK_CMD(DMEM_LEFT_CH >> 4, DMEM_HAAS_TEMP >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); - -u32 sEnvMixerDefaultDmemDests = - MK_CMD(DMEM_LEFT_CH >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); - -u16 D_801304B0[] = { - 0x7FFF, 0xD001, 0x3FFF, 0xF001, 0x5FFF, 0x9001, 0x7FFF, 0x8001, -}; - -u8 sNumSamplesPerWavePeriod[] = { - WAVE_SAMPLE_COUNT, // 1st harmonic - WAVE_SAMPLE_COUNT / 2, // 2nd harmonic - WAVE_SAMPLE_COUNT / 4, // 4th harmonic - WAVE_SAMPLE_COUNT / 8, // 8th harmonic -}; - -void AudioSynth_InitNextRingBuf(s32 chunkLen, s32 updateIndex, s32 reverbIndex) { - ReverbRingBufferItem* bufItem; - s32 pad[3]; - SynthesisReverb* reverb = &gAudioCtx.synthesisReverbs[reverbIndex]; - s32 temp_a0_2; - s32 temp_a0_4; - s32 numSamples; - s32 extraSamples; - s32 i; - s32 j; - - if (reverb->downsampleRate >= 2) { - if (reverb->framesToIgnore == 0) { - bufItem = &reverb->items[reverb->curFrame][updateIndex]; - Audio_InvalDCache(bufItem->toDownsampleLeft, DMEM_2CH_SIZE); - - for (j = 0, i = 0; i < bufItem->lengthA / (s32)SAMPLE_SIZE; j += reverb->downsampleRate, i++) { - reverb->leftRingBuf[bufItem->startPos + i] = bufItem->toDownsampleLeft[j]; - reverb->rightRingBuf[bufItem->startPos + i] = bufItem->toDownsampleRight[j]; - } - - for (i = 0; i < bufItem->lengthB / (s32)SAMPLE_SIZE; j += reverb->downsampleRate, i++) { - reverb->leftRingBuf[i] = bufItem->toDownsampleLeft[j]; - reverb->rightRingBuf[i] = bufItem->toDownsampleRight[j]; - } - } - } - - bufItem = &reverb->items[reverb->curFrame][updateIndex]; - numSamples = chunkLen / reverb->downsampleRate; - extraSamples = (numSamples + reverb->nextRingBufPos) - reverb->bufSizePerChan; - temp_a0_2 = reverb->nextRingBufPos; - if (extraSamples < 0) { - bufItem->lengthA = numSamples * SAMPLE_SIZE; - bufItem->lengthB = 0; - bufItem->startPos = reverb->nextRingBufPos; - reverb->nextRingBufPos += numSamples; - } else { - // End of the buffer is reached. Loop back around - bufItem->lengthA = (numSamples - extraSamples) * SAMPLE_SIZE; - bufItem->lengthB = extraSamples * SAMPLE_SIZE; - bufItem->startPos = reverb->nextRingBufPos; - reverb->nextRingBufPos = extraSamples; - } - - bufItem->numSamplesAfterDownsampling = numSamples; - bufItem->chunkLen = chunkLen; - - if (reverb->unk_14 != 0) { - temp_a0_4 = reverb->unk_14 + temp_a0_2; - if (temp_a0_4 >= reverb->bufSizePerChan) { - temp_a0_4 -= reverb->bufSizePerChan; - } - bufItem = &reverb->items2[reverb->curFrame][updateIndex]; - numSamples = chunkLen / reverb->downsampleRate; - extraSamples = (temp_a0_4 + numSamples) - reverb->bufSizePerChan; - if (extraSamples < 0) { - bufItem->lengthA = numSamples * SAMPLE_SIZE; - bufItem->lengthB = 0; - bufItem->startPos = temp_a0_4; - } else { - // End of the buffer is reached. Loop back around - bufItem->lengthA = (numSamples - extraSamples) * SAMPLE_SIZE; - bufItem->lengthB = extraSamples * SAMPLE_SIZE; - bufItem->startPos = temp_a0_4; - } - bufItem->numSamplesAfterDownsampling = numSamples; - bufItem->chunkLen = chunkLen; - } -} - -void func_800DB03C(s32 updateIndex) { - NoteSubEu* subEu; - NoteSubEu* subEu2; - s32 baseIndex; - s32 i; - - baseIndex = gAudioCtx.numNotes * updateIndex; - for (i = 0; i < gAudioCtx.numNotes; i++) { - subEu = &gAudioCtx.notes[i].noteSubEu; - subEu2 = &gAudioCtx.noteSubsEu[baseIndex + i]; - if (subEu->bitField0.enabled) { - subEu->bitField0.needsInit = false; - } else { - subEu2->bitField0.enabled = false; - } - - subEu->harmonicIndexCurAndPrev = 0; - } -} - -Acmd* AudioSynth_Update(Acmd* cmdStart, s32* cmdCnt, s16* aiStart, s32 aiBufLen) { - s32 chunkLen; - s16* aiBufP; - Acmd* cmdP; - s32 i; - s32 j; - SynthesisReverb* reverb; - - cmdP = cmdStart; - for (i = gAudioCtx.audioBufferParameters.updatesPerFrame; i > 0; i--) { - AudioSeq_ProcessSequences(i - 1); - func_800DB03C(gAudioCtx.audioBufferParameters.updatesPerFrame - i); - } - - aiBufP = aiStart; - gAudioCtx.curLoadedBook = NULL; - - for (i = gAudioCtx.audioBufferParameters.updatesPerFrame; i > 0; i--) { - if (i == 1) { - chunkLen = aiBufLen; - } else if ((aiBufLen / i) >= gAudioCtx.audioBufferParameters.samplesPerUpdateMax) { - chunkLen = gAudioCtx.audioBufferParameters.samplesPerUpdateMax; - } else if (gAudioCtx.audioBufferParameters.samplesPerUpdateMin >= (aiBufLen / i)) { - chunkLen = gAudioCtx.audioBufferParameters.samplesPerUpdateMin; - } else { - chunkLen = gAudioCtx.audioBufferParameters.samplesPerUpdate; - } - - for (j = 0; j < gAudioCtx.numSynthesisReverbs; j++) { - if (gAudioCtx.synthesisReverbs[j].useReverb) { - AudioSynth_InitNextRingBuf(chunkLen, gAudioCtx.audioBufferParameters.updatesPerFrame - i, j); - } - } - - cmdP = AudioSynth_DoOneAudioUpdate(aiBufP, chunkLen, cmdP, gAudioCtx.audioBufferParameters.updatesPerFrame - i); - aiBufLen -= chunkLen; - aiBufP += 2 * chunkLen; - } - - for (j = 0; j < gAudioCtx.numSynthesisReverbs; j++) { - if (gAudioCtx.synthesisReverbs[j].framesToIgnore != 0) { - gAudioCtx.synthesisReverbs[j].framesToIgnore--; - } - gAudioCtx.synthesisReverbs[j].curFrame ^= 1; - } - - *cmdCnt = cmdP - cmdStart; - return cmdP; -} - -void func_800DB2C0(s32 updateIndex, s32 noteIndex) { - NoteSubEu* noteSubEu; - s32 i; - - for (i = updateIndex + 1; i < gAudioCtx.audioBufferParameters.updatesPerFrame; i++) { - noteSubEu = &gAudioCtx.noteSubsEu[(gAudioCtx.numNotes * i) + noteIndex]; - if (!noteSubEu->bitField0.needsInit) { - noteSubEu->bitField0.enabled = false; - } else { - break; - } - } -} - -Acmd* AudioSynth_LoadRingBuffer1AtTemp(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) { - ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][updateIndex]; - - cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_TEMP, bufItem->startPos, bufItem->lengthA, reverb); - if (bufItem->lengthB != 0) { - // Ring buffer wrapped - cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_TEMP + bufItem->lengthA, 0, bufItem->lengthB, reverb); - } - return cmd; -} - -Acmd* AudioSynth_SaveRingBuffer1AtTemp(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) { - ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][updateIndex]; - - cmd = AudioSynth_SaveRingBufferPart(cmd, DMEM_WET_TEMP, bufItem->startPos, bufItem->lengthA, reverb); - if (bufItem->lengthB != 0) { - // Ring buffer wrapped - cmd = AudioSynth_SaveRingBufferPart(cmd, DMEM_WET_TEMP + bufItem->lengthA, 0, bufItem->lengthB, reverb); - } - return cmd; -} - -/** - * Leak some audio from the left reverb channel into the right reverb channel and vice versa (pan) - */ -Acmd* AudioSynth_LeakReverb(Acmd* cmd, SynthesisReverb* reverb) { - aDMEMMove(cmd++, DMEM_WET_LEFT_CH, DMEM_WET_SCRATCH, DMEM_1CH_SIZE); - aMix(cmd++, DMEM_1CH_SIZE >> 4, reverb->leakRtl, DMEM_WET_RIGHT_CH, DMEM_WET_LEFT_CH); - aMix(cmd++, DMEM_1CH_SIZE >> 4, reverb->leakLtr, DMEM_WET_SCRATCH, DMEM_WET_RIGHT_CH); - return cmd; -} - -Acmd* func_800DB4E4(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) { - ReverbRingBufferItem* item = &reverb->items[reverb->curFrame][updateIndex]; - s16 offsetA; - s16 offsetB; - - offsetA = (item->startPos & 7) * SAMPLE_SIZE; - offsetB = ALIGN16(offsetA + item->lengthA); - cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_TEMP, item->startPos - (offsetA / (s32)SAMPLE_SIZE), - DMEM_1CH_SIZE, reverb); - if (item->lengthB != 0) { - // Ring buffer wrapped - cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_TEMP + offsetB, 0, DMEM_1CH_SIZE - offsetB, reverb); - } - aSetBuffer(cmd++, 0, DMEM_WET_TEMP + offsetA, DMEM_WET_LEFT_CH, aiBufLen * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, reverb->unk_0E, reverb->unk_30); - aSetBuffer(cmd++, 0, DMEM_WET_TEMP + DMEM_1CH_SIZE + offsetA, DMEM_WET_RIGHT_CH, aiBufLen * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, reverb->unk_0E, reverb->unk_34); - return cmd; -} - -Acmd* func_800DB680(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) { - ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][updateIndex]; - - aSetBuffer(cmd++, 0, DMEM_WET_LEFT_CH, DMEM_WET_SCRATCH, bufItem->unk_18 * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, bufItem->unk_16, reverb->unk_38); - - cmd = AudioSynth_SaveBufferOffset(cmd, DMEM_WET_SCRATCH, bufItem->startPos, bufItem->lengthA, reverb->leftRingBuf); - if (bufItem->lengthB != 0) { - // Ring buffer wrapped - cmd = AudioSynth_SaveBufferOffset(cmd, DMEM_WET_SCRATCH + bufItem->lengthA, 0, bufItem->lengthB, - reverb->leftRingBuf); - } - aSetBuffer(cmd++, 0, DMEM_WET_RIGHT_CH, DMEM_WET_SCRATCH, bufItem->unk_18 * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, bufItem->unk_16, reverb->unk_3C); - cmd = AudioSynth_SaveBufferOffset(cmd, DMEM_WET_SCRATCH, bufItem->startPos, bufItem->lengthA, reverb->rightRingBuf); - - if (bufItem->lengthB != 0) { - // Ring buffer wrapped - cmd = AudioSynth_SaveBufferOffset(cmd, DMEM_WET_SCRATCH + bufItem->lengthA, 0, bufItem->lengthB, - reverb->rightRingBuf); - } - - return cmd; -} - -Acmd* func_800DB828(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) { - ReverbRingBufferItem* item = &reverb->items[reverb->curFrame][updateIndex]; - s16 offsetA; - s16 offsetB; - - item->unk_14 = (item->unk_18 << 0xF) / aiBufLen; - offsetA = (item->startPos & 7) * SAMPLE_SIZE; - item->unk_16 = (aiBufLen << 0xF) / item->unk_18; - offsetB = ALIGN16(offsetA + item->lengthA); - cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_TEMP, item->startPos - (offsetA / (s32)SAMPLE_SIZE), - DMEM_1CH_SIZE, reverb); - if (item->lengthB != 0) { - // Ring buffer wrapped - cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_TEMP + offsetB, 0, DMEM_1CH_SIZE - offsetB, reverb); - } - aSetBuffer(cmd++, 0, DMEM_WET_TEMP + offsetA, DMEM_WET_LEFT_CH, aiBufLen * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, item->unk_14, reverb->unk_30); - aSetBuffer(cmd++, 0, DMEM_WET_TEMP + DMEM_1CH_SIZE + offsetA, DMEM_WET_RIGHT_CH, aiBufLen * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, item->unk_14, reverb->unk_34); - return cmd; -} - -/** - * Apply a filter (convolution) to each reverb channel. - */ -Acmd* AudioSynth_FilterReverb(Acmd* cmd, s32 size, SynthesisReverb* reverb) { - if (reverb->filterLeft != NULL) { - aFilter(cmd++, 2, size, reverb->filterLeft); - aFilter(cmd++, reverb->resampleFlags, DMEM_WET_LEFT_CH, reverb->filterLeftState); - } - - if (reverb->filterRight != NULL) { - aFilter(cmd++, 2, size, reverb->filterRight); - aFilter(cmd++, reverb->resampleFlags, DMEM_WET_RIGHT_CH, reverb->filterRightState); - } - return cmd; -} - -Acmd* AudioSynth_MaybeMixRingBuffer1(Acmd* cmd, SynthesisReverb* reverb, s32 updateIndex) { - SynthesisReverb* temp_a3; - - temp_a3 = &gAudioCtx.synthesisReverbs[reverb->unk_05]; - if (temp_a3->downsampleRate == 1) { - cmd = AudioSynth_LoadRingBuffer1AtTemp(cmd, temp_a3, updateIndex); - aMix(cmd++, DMEM_2CH_SIZE >> 4, reverb->unk_08, DMEM_WET_LEFT_CH, DMEM_WET_TEMP); - cmd = AudioSynth_SaveRingBuffer1AtTemp(cmd, temp_a3, updateIndex); - } - return cmd; -} - -void func_800DBB94(void) { -} - -void AudioSynth_ClearBuffer(Acmd* cmd, s32 dmem, s32 size) { - aClearBuffer(cmd, dmem, size); -} - -void func_800DBBBC(void) { -} - -void func_800DBBC4(void) { -} - -void func_800DBBCC(void) { -} - -void AudioSynth_Mix(Acmd* cmd, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { - aMix(cmd, arg1, arg2, arg3, arg4); -} - -void func_800DBC08(void) { -} - -void func_800DBC10(void) { -} - -void func_800DBC18(void) { -} - -void AudioSynth_SetBuffer(Acmd* cmd, s32 flags, s32 dmemIn, s32 dmemOut, u32 size) { - aSetBuffer(cmd, flags, dmemIn, dmemOut, size); -} - -void func_800DBC54(void) { -} - -void func_800DBC5C(void) { -} - -// possible fake match? -void AudioSynth_DMemMove(Acmd* cmd, s32 dmemIn, s32 dmemOut, u32 size) { - cmd->words.w0 = _SHIFTL(A_DMEMMOVE, 24, 8) | _SHIFTL(dmemIn, 0, 24); - cmd->words.w1 = _SHIFTL(dmemOut, 16, 16) | _SHIFTL(size, 0, 16); -} - -void func_800DBC90(void) { -} - -void func_800DBC98(void) { -} - -void func_800DBCA0(void) { -} - -void func_800DBCA8(void) { -} - -void AudioSynth_InterL(Acmd* cmd, s32 dmemIn, s32 dmemOut, s32 numSamples) { - cmd->words.w0 = _SHIFTL(A_INTERL, 24, 8) | _SHIFTL(numSamples, 0, 16); - cmd->words.w1 = _SHIFTL(dmemIn, 16, 16) | _SHIFTL(dmemOut, 0, 16); -} - -void AudioSynth_EnvSetup1(Acmd* cmd, s32 arg1, s32 arg2, s32 arg3, s32 arg4) { - aEnvSetup1(cmd, arg1, arg2, arg3, arg4); -} - -void func_800DBD08(void) { -} - -void AudioSynth_LoadBuffer(Acmd* cmd, s32 dmemDest, s32 size, void* addrSrc) { - aLoadBuffer(cmd, addrSrc, dmemDest, size); -} - -void AudioSynth_SaveBuffer(Acmd* cmd, s32 dmemSrc, s32 size, void* addrDest) { - aSaveBuffer(cmd, dmemSrc, addrDest, size); -} - -void AudioSynth_EnvSetup2(Acmd* cmd, s32 volLeft, s32 volRight) { - cmd->words.w0 = _SHIFTL(A_ENVSETUP2, 24, 8); - cmd->words.w1 = _SHIFTL(volLeft, 16, 16) | _SHIFTL(volRight, 0, 16); -} - -void func_800DBD7C(void) { -} - -void func_800DBD84(void) { -} - -void func_800DBD8C(void) { -} - -void AudioSynth_S8Dec(Acmd* cmd, s32 flags, s16* state) { - aS8Dec(cmd, flags, state); -} - -void AudioSynth_HiLoGain(Acmd* cmd, s32 gain, s32 dmemIn, s32 dmemOut, s32 size) { - cmd->words.w0 = _SHIFTL(A_HILOGAIN, 24, 8) | _SHIFTL(gain, 16, 8) | _SHIFTL(size, 0, 16); - cmd->words.w1 = _SHIFTL(dmemIn, 16, 16) | _SHIFTL(dmemOut, 0, 16); -} - -void AudioSynth_UnkCmd19(Acmd* cmd, s32 arg1, s32 arg2, s32 size, s32 arg4) { - cmd->words.w0 = _SHIFTL(A_UNK19, 24, 8) | _SHIFTL(arg4, 16, 8) | _SHIFTL(size, 0, 16); - cmd->words.w1 = _SHIFTL(arg1, 16, 16) | _SHIFTL(arg2, 0, 16); -} - -void func_800DBE18(void) { -} - -void func_800DBE20(void) { -} - -void func_800DBE28(void) { -} - -void func_800DBE30(void) { -} - -void AudioSynth_UnkCmd3(Acmd* cmd, s32 arg1, s32 arg2, s32 size) { - cmd->words.w0 = _SHIFTL(A_UNK3, 24, 8) | _SHIFTL(size, 0, 16); - cmd->words.w1 = _SHIFTL(arg1, 16, 16) | _SHIFTL(arg2, 0, 16); -} - -void func_800DBE5C(void) { -} - -void func_800DBE64(void) { -} - -void func_800DBE6C(void) { -} - -void AudioSynth_LoadFilterBuffer(Acmd* cmd, s32 flags, s32 buf, void* addr) { - aFilter(cmd, flags, buf, addr); -} - -void AudioSynth_LoadFilterSize(Acmd* cmd, s32 size, void* addr) { - aFilter(cmd, 2, size, addr); -} - -Acmd* AudioSynth_LoadRingBuffer1(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) { - ReverbRingBufferItem* ringBufferItem = &reverb->items[reverb->curFrame][updateIndex]; - - cmd = - AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_LEFT_CH, ringBufferItem->startPos, ringBufferItem->lengthA, reverb); - if (ringBufferItem->lengthB != 0) { - // Ring buffer wrapped - cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_LEFT_CH + ringBufferItem->lengthA, 0, ringBufferItem->lengthB, - reverb); - } - - return cmd; -} - -Acmd* AudioSynth_LoadRingBuffer2(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) { - ReverbRingBufferItem* bufItem = &reverb->items2[reverb->curFrame][updateIndex]; - - cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_LEFT_CH, bufItem->startPos, bufItem->lengthA, reverb); - if (bufItem->lengthB != 0) { - // Ring buffer wrapped - cmd = AudioSynth_LoadRingBufferPart(cmd, DMEM_WET_LEFT_CH + bufItem->lengthA, 0, bufItem->lengthB, reverb); - } - return cmd; -} - -Acmd* AudioSynth_LoadRingBufferPart(Acmd* cmd, u16 dmem, u16 startPos, s32 size, SynthesisReverb* reverb) { - aLoadBuffer(cmd++, &reverb->leftRingBuf[startPos], dmem, size); - aLoadBuffer(cmd++, &reverb->rightRingBuf[startPos], dmem + DMEM_1CH_SIZE, size); - return cmd; -} - -Acmd* AudioSynth_SaveRingBufferPart(Acmd* cmd, u16 dmem, u16 startPos, s32 size, SynthesisReverb* reverb) { - aSaveBuffer(cmd++, dmem, &reverb->leftRingBuf[startPos], size); - aSaveBuffer(cmd++, dmem + DMEM_1CH_SIZE, &reverb->rightRingBuf[startPos], size); - return cmd; -} - -Acmd* AudioSynth_SaveBufferOffset(Acmd* cmd, u16 dmem, u16 offset, s32 size, s16* buf) { - aSaveBuffer(cmd++, dmem, &buf[offset], size); - return cmd; -} - -Acmd* AudioSynth_MaybeLoadRingBuffer2(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) { - if (reverb->downsampleRate == 1) { - cmd = AudioSynth_LoadRingBuffer2(cmd, aiBufLen, reverb, updateIndex); - } - - return cmd; -} - -Acmd* AudioSynth_LoadReverbSamples(Acmd* cmd, s32 aiBufLen, SynthesisReverb* reverb, s16 updateIndex) { - // Sets DMEM_WET_{LEFT,RIGHT}_CH, clobbers DMEM_TEMP - if (reverb->downsampleRate == 1) { - if (reverb->unk_18 != 0) { - cmd = func_800DB828(cmd, aiBufLen, reverb, updateIndex); - } else { - cmd = AudioSynth_LoadRingBuffer1(cmd, aiBufLen, reverb, updateIndex); - } - } else { - cmd = func_800DB4E4(cmd, aiBufLen, reverb, updateIndex); - } - return cmd; -} - -Acmd* AudioSynth_SaveReverbSamples(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) { - ReverbRingBufferItem* bufItem = &reverb->items[reverb->curFrame][updateIndex]; - - if (reverb->downsampleRate == 1) { - if (reverb->unk_18 != 0) { - cmd = func_800DB680(cmd, reverb, updateIndex); - } else { - // Put the oldest samples in the ring buffer into the wet channels - cmd = AudioSynth_SaveRingBufferPart(cmd, DMEM_WET_LEFT_CH, bufItem->startPos, bufItem->lengthA, reverb); - if (bufItem->lengthB != 0) { - // Ring buffer wrapped - cmd = AudioSynth_SaveRingBufferPart(cmd, DMEM_WET_LEFT_CH + bufItem->lengthA, 0, bufItem->lengthB, - reverb); - } - } - } else { - // Downsampling is done later by CPU when RSP is done, therefore we need to have - // double buffering. Left and right buffers are adjacent in memory. - AudioSynth_SaveBuffer(cmd++, DMEM_WET_LEFT_CH, DMEM_2CH_SIZE, - reverb->items[reverb->curFrame][updateIndex].toDownsampleLeft); - } - - reverb->resampleFlags = 0; - return cmd; -} - -Acmd* AudioSynth_SaveRingBuffer2(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) { - ReverbRingBufferItem* bufItem = &reverb->items2[reverb->curFrame][updateIndex]; - - cmd = AudioSynth_SaveRingBufferPart(cmd, DMEM_WET_LEFT_CH, bufItem->startPos, bufItem->lengthA, reverb); - if (bufItem->lengthB != 0) { - // Ring buffer wrapped - cmd = AudioSynth_SaveRingBufferPart(cmd, DMEM_WET_LEFT_CH + bufItem->lengthA, 0, bufItem->lengthB, reverb); - } - return cmd; -} - -Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updateIndex) { - u8 noteIndices[0x5C]; - s16 count; - s16 reverbIndex; - SynthesisReverb* reverb; - s32 useReverb; - s32 t; - s32 i; - NoteSubEu* noteSubEu; - NoteSubEu* noteSubEu2; - s32 unk14; - - t = gAudioCtx.numNotes * updateIndex; - count = 0; - if (gAudioCtx.numSynthesisReverbs == 0) { - for (i = 0; i < gAudioCtx.numNotes; i++) { - if (gAudioCtx.noteSubsEu[t + i].bitField0.enabled) { - noteIndices[count++] = i; - } - } - } else { - for (reverbIndex = 0; reverbIndex < gAudioCtx.numSynthesisReverbs; reverbIndex++) { - for (i = 0; i < gAudioCtx.numNotes; i++) { - noteSubEu = &gAudioCtx.noteSubsEu[t + i]; - if (noteSubEu->bitField0.enabled && noteSubEu->bitField1.reverbIndex == reverbIndex) { - noteIndices[count++] = i; - } - } - } - - for (i = 0; i < gAudioCtx.numNotes; i++) { - noteSubEu = &gAudioCtx.noteSubsEu[t + i]; - if (noteSubEu->bitField0.enabled && noteSubEu->bitField1.reverbIndex >= gAudioCtx.numSynthesisReverbs) { - noteIndices[count++] = i; - } - } - } - - aClearBuffer(cmd++, DMEM_LEFT_CH, DMEM_2CH_SIZE); - - i = 0; - for (reverbIndex = 0; reverbIndex < gAudioCtx.numSynthesisReverbs; reverbIndex++) { - reverb = &gAudioCtx.synthesisReverbs[reverbIndex]; - useReverb = reverb->useReverb; - if (useReverb) { - - // Loads reverb samples from RDRAM (ringBuffer) into DMEM (DMEM_WET_LEFT_CH) - cmd = AudioSynth_LoadReverbSamples(cmd, aiBufLen, reverb, updateIndex); - - // Mixes reverb sample into the main dry channel - // reverb->volume is always set to 0x7FFF (audio spec), and DMEM_LEFT_CH is cleared before the loop. - // So for the first iteration, this is essentially a DMEMmove from DMEM_WET_LEFT_CH to DMEM_LEFT_CH - aMix(cmd++, DMEM_2CH_SIZE >> 4, reverb->volume, DMEM_WET_LEFT_CH, DMEM_LEFT_CH); - - unk14 = reverb->unk_14; - if (unk14) { - aDMEMMove(cmd++, DMEM_WET_LEFT_CH, DMEM_WET_TEMP, DMEM_2CH_SIZE); - } - - // Decays reverb over time. The (+ 0x8000) here is -100% - aMix(cmd++, DMEM_2CH_SIZE >> 4, reverb->decayRatio + 0x8000, DMEM_WET_LEFT_CH, DMEM_WET_LEFT_CH); - - // Leak reverb between the left and right channels - if (reverb->leakRtl != 0 || reverb->leakLtr != 0) { - cmd = AudioSynth_LeakReverb(cmd, reverb); - } - - if (unk14) { - // Saves the wet channel sample from DMEM (DMEM_WET_LEFT_CH) into RDRAM (ringBuffer) for future use - cmd = AudioSynth_SaveReverbSamples(cmd, reverb, updateIndex); - if (reverb->unk_05 != -1) { - cmd = AudioSynth_MaybeMixRingBuffer1(cmd, reverb, updateIndex); - } - cmd = AudioSynth_MaybeLoadRingBuffer2(cmd, aiBufLen, reverb, updateIndex); - aMix(cmd++, DMEM_2CH_SIZE >> 4, reverb->unk_16, DMEM_WET_TEMP, DMEM_WET_LEFT_CH); - } - } - - while (i < count) { - noteSubEu2 = &gAudioCtx.noteSubsEu[noteIndices[i] + t]; - if (noteSubEu2->bitField1.reverbIndex == reverbIndex) { - cmd = - AudioSynth_ProcessNote(noteIndices[i], noteSubEu2, &gAudioCtx.notes[noteIndices[i]].synthesisState, - aiBuf, aiBufLen, cmd, updateIndex); - } else { - break; - } - i++; - } - - if (useReverb) { - if (reverb->filterLeft != NULL || reverb->filterRight != NULL) { - cmd = AudioSynth_FilterReverb(cmd, aiBufLen * SAMPLE_SIZE, reverb); - } - - // Saves the wet channel sample from DMEM (DMEM_WET_LEFT_CH) into RDRAM (ringBuffer) for future use - if (unk14) { - cmd = AudioSynth_SaveRingBuffer2(cmd, reverb, updateIndex); - } else { - cmd = AudioSynth_SaveReverbSamples(cmd, reverb, updateIndex); - if (reverb->unk_05 != -1) { - cmd = AudioSynth_MaybeMixRingBuffer1(cmd, reverb, updateIndex); - } - } - } - } - - while (i < count) { - cmd = - AudioSynth_ProcessNote(noteIndices[i], &gAudioCtx.noteSubsEu[t + noteIndices[i]], - &gAudioCtx.notes[noteIndices[i]].synthesisState, aiBuf, aiBufLen, cmd, updateIndex); - i++; - } - - aInterleave(cmd++, DMEM_TEMP, DMEM_LEFT_CH, DMEM_RIGHT_CH, 2 * aiBufLen); - aSaveBuffer(cmd++, DMEM_TEMP, aiBuf, 2 * (aiBufLen * (s32)SAMPLE_SIZE)); - - return cmd; -} - -Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s16* aiBuf, - s32 aiBufLen, Acmd* cmd, s32 updateIndex) { - s32 pad1[3]; - Sample* sample; - AdpcmLoop* loopInfo; - s32 nSamplesUntilLoopEnd; - s32 nSamplesInThisIteration; - s32 noteFinished; - s32 restart; - s32 flags; - u16 resamplingRateFixedPoint; - s32 nSamplesInFirstFrame; - s32 nTrailingSamplesToIgnore; - s32 gain; - s32 frameIndex; - s32 skipBytes; - s32 temp_v1_6; - void* buf; - s32 nSamplesToDecode; - u32 sampleAddr; - u32 samplesLenFixedPoint; - s32 samplesLenAdjusted; // seems to be used as both bytes and numSamples? - s32 nSamplesProcessed; - s32 loopEndPos; - s32 nSamplesToProcess; - s32 phi_s4; - s32 nFirstFrameSamplesToIgnore; - s32 pad2[7]; - s32 frameSize; - s32 nFramesToDecode; - s32 skipInitialSamples; - s32 sampleDataStart; - u8* sampleData; - s32 nParts; - s32 curPart; - s32 sampleDataStartPad; - s32 haasEffectDelaySide; - s32 resampledTempLen; - u16 sampleDmemBeforeResampling; - s32 sampleDataOffset; - s32 thing; - s32 s5; - Note* note; - u32 numSamplesToLoad; - u16 unk7; - u16 unkE; - s16* filter; - s32 bookOffset; - s32 finished; - s32 aligned; - s16 addr; - u16 unused; - - bookOffset = noteSubEu->bitField1.bookOffset; - finished = noteSubEu->bitField0.finished; - note = &gAudioCtx.notes[noteIndex]; - flags = A_CONTINUE; - - if (noteSubEu->bitField0.needsInit == true) { - flags = A_INIT; - synthState->restart = 0; - synthState->samplePosInt = note->startSamplePos; - synthState->samplePosFrac = 0; - synthState->curVolLeft = 0; - synthState->curVolRight = 0; - synthState->prevHaasEffectLeftDelaySize = 0; - synthState->prevHaasEffectRightDelaySize = 0; - synthState->reverbVol = noteSubEu->reverbVol; - synthState->numParts = 0; - synthState->unk_1A = 1; - note->noteSubEu.bitField0.finished = false; - finished = false; - } - - resamplingRateFixedPoint = noteSubEu->resamplingRateFixedPoint; - nParts = noteSubEu->bitField1.hasTwoParts + 1; - samplesLenFixedPoint = (resamplingRateFixedPoint * aiBufLen * 2) + synthState->samplePosFrac; - numSamplesToLoad = samplesLenFixedPoint >> 16; - synthState->samplePosFrac = samplesLenFixedPoint & 0xFFFF; - - // Partially-optimized out no-op ifs required for matching. SM64 decomp - // makes it clear that this is how it should look. - if (synthState->numParts == 1 && nParts == 2) { - } else if (synthState->numParts == 2 && nParts == 1) { - } else { - } - - synthState->numParts = nParts; - - if (noteSubEu->bitField1.isSyntheticWave) { - cmd = AudioSynth_LoadWaveSamples(cmd, noteSubEu, synthState, numSamplesToLoad); - sampleDmemBeforeResampling = DMEM_UNCOMPRESSED_NOTE + (synthState->samplePosInt * (s32)SAMPLE_SIZE); - synthState->samplePosInt += numSamplesToLoad; - } else { - sample = noteSubEu->tunedSample->sample; - loopInfo = sample->loop; - loopEndPos = loopInfo->end; - sampleAddr = (u32)sample->sampleAddr; - resampledTempLen = 0; - - for (curPart = 0; curPart < nParts; curPart++) { - nSamplesProcessed = 0; - s5 = 0; - - if (nParts == 1) { - samplesLenAdjusted = numSamplesToLoad; - } else if (numSamplesToLoad & 1) { - samplesLenAdjusted = (numSamplesToLoad & ~1) + (curPart * 2); - } else { - samplesLenAdjusted = numSamplesToLoad; - } - - if (sample->codec == CODEC_ADPCM || sample->codec == CODEC_SMALL_ADPCM) { - if (gAudioCtx.curLoadedBook != sample->book->book) { - u32 nEntries; - - switch (bookOffset) { - case 1: - gAudioCtx.curLoadedBook = &D_8012FBA8[1]; - break; - case 2: - case 3: - default: - gAudioCtx.curLoadedBook = sample->book->book; - break; - } - if (1) {} - if (1) {} - if (1) {} - nEntries = SAMPLES_PER_FRAME * sample->book->order * sample->book->numPredictors; - aLoadADPCM(cmd++, nEntries, gAudioCtx.curLoadedBook); - } - } - - while (nSamplesProcessed != samplesLenAdjusted) { - noteFinished = false; - restart = false; - phi_s4 = 0; - - nFirstFrameSamplesToIgnore = synthState->samplePosInt & 0xF; - nSamplesUntilLoopEnd = loopEndPos - synthState->samplePosInt; - nSamplesToProcess = samplesLenAdjusted - nSamplesProcessed; - - if (nFirstFrameSamplesToIgnore == 0 && !synthState->restart) { - nFirstFrameSamplesToIgnore = SAMPLES_PER_FRAME; - } - nSamplesInFirstFrame = SAMPLES_PER_FRAME - nFirstFrameSamplesToIgnore; - - if (nSamplesToProcess < nSamplesUntilLoopEnd) { - nFramesToDecode = - (s32)(nSamplesToProcess - nSamplesInFirstFrame + SAMPLES_PER_FRAME - 1) / SAMPLES_PER_FRAME; - nSamplesToDecode = nFramesToDecode * SAMPLES_PER_FRAME; - nTrailingSamplesToIgnore = nSamplesInFirstFrame + nSamplesToDecode - nSamplesToProcess; - } else { - nSamplesToDecode = nSamplesUntilLoopEnd - nSamplesInFirstFrame; - nTrailingSamplesToIgnore = 0; - if (nSamplesToDecode <= 0) { - nSamplesToDecode = 0; - nSamplesInFirstFrame = nSamplesUntilLoopEnd; - } - nFramesToDecode = (nSamplesToDecode + SAMPLES_PER_FRAME - 1) / SAMPLES_PER_FRAME; - if (loopInfo->count != 0) { - // Loop around and restart - restart = true; - } else { - noteFinished = true; - } - } - - switch (sample->codec) { - case CODEC_ADPCM: - // 16 2-byte samples (32 bytes) compressed into 4-bit samples (8 bytes) + 1 header byte - frameSize = 9; - skipInitialSamples = SAMPLES_PER_FRAME; - sampleDataStart = 0; - break; - - case CODEC_SMALL_ADPCM: - // 16 2-byte samples (32 bytes) compressed into 2-bit samples (4 bytes) + 1 header byte - frameSize = 5; - skipInitialSamples = SAMPLES_PER_FRAME; - sampleDataStart = 0; - break; - - case CODEC_S8: - // 16 2-byte samples (32 bytes) compressed into 8-bit samples (16 bytes) - frameSize = 16; - skipInitialSamples = SAMPLES_PER_FRAME; - sampleDataStart = 0; - break; - - case CODEC_S16_INMEMORY: - AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, - (samplesLenAdjusted + SAMPLES_PER_FRAME) * SAMPLE_SIZE); - flags = A_CONTINUE; - skipBytes = 0; - nSamplesProcessed = samplesLenAdjusted; - s5 = samplesLenAdjusted; - goto skip; - - case CODEC_S16: - AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, - (samplesLenAdjusted + SAMPLES_PER_FRAME) * SAMPLE_SIZE); - flags = A_CONTINUE; - skipBytes = 0; - nSamplesProcessed = samplesLenAdjusted; - s5 = samplesLenAdjusted; - goto skip; - - case CODEC_REVERB: - break; - } - - if (nFramesToDecode != 0) { - frameIndex = (synthState->samplePosInt + skipInitialSamples - nFirstFrameSamplesToIgnore) / - SAMPLES_PER_FRAME; - sampleDataOffset = frameIndex * frameSize; - if (sample->medium == MEDIUM_RAM) { - sampleData = (u8*)(sampleDataStart + sampleDataOffset + sampleAddr); - } else if (sample->medium == MEDIUM_UNK) { - return cmd; - } else { - sampleData = AudioLoad_DmaSampleData(sampleDataStart + sampleDataOffset + sampleAddr, - ALIGN16((nFramesToDecode * frameSize) + SAMPLES_PER_FRAME), - flags, &synthState->sampleDmaIndex, sample->medium); - } - - if (sampleData == NULL) { - return cmd; - } - - sampleDataStartPad = (u32)sampleData & 0xF; - aligned = ALIGN16((nFramesToDecode * frameSize) + SAMPLES_PER_FRAME); - addr = DMEM_COMPRESSED_ADPCM_DATA - aligned; - aLoadBuffer(cmd++, sampleData - sampleDataStartPad, addr, aligned); - } else { - nSamplesToDecode = 0; - sampleDataStartPad = 0; - } - - if (synthState->restart) { - aSetLoop(cmd++, sample->loop->predictorState); - flags = A_LOOP; - synthState->restart = false; - } - - nSamplesInThisIteration = nSamplesToDecode + nSamplesInFirstFrame - nTrailingSamplesToIgnore; - if (nSamplesProcessed == 0) { - if (1) {} - skipBytes = nFirstFrameSamplesToIgnore * SAMPLE_SIZE; - } else { - phi_s4 = ALIGN16(s5 + 8 * SAMPLE_SIZE); - } - - switch (sample->codec) { - case CODEC_ADPCM: - aligned = ALIGN16((nFramesToDecode * frameSize) + SAMPLES_PER_FRAME); - addr = DMEM_COMPRESSED_ADPCM_DATA - aligned; - aSetBuffer(cmd++, 0, addr + sampleDataStartPad, DMEM_UNCOMPRESSED_NOTE + phi_s4, - nSamplesToDecode * SAMPLE_SIZE); - aADPCMdec(cmd++, flags, synthState->synthesisBuffers->adpcmdecState); - break; - - case CODEC_SMALL_ADPCM: - aligned = ALIGN16((nFramesToDecode * frameSize) + SAMPLES_PER_FRAME); - addr = DMEM_COMPRESSED_ADPCM_DATA - aligned; - aSetBuffer(cmd++, 0, addr + sampleDataStartPad, DMEM_UNCOMPRESSED_NOTE + phi_s4, - nSamplesToDecode * SAMPLE_SIZE); - aADPCMdec(cmd++, flags | 4, synthState->synthesisBuffers->adpcmdecState); - break; - - case CODEC_S8: - aligned = ALIGN16((nFramesToDecode * frameSize) + SAMPLES_PER_FRAME); - addr = DMEM_COMPRESSED_ADPCM_DATA - aligned; - AudioSynth_SetBuffer(cmd++, 0, addr + sampleDataStartPad, DMEM_UNCOMPRESSED_NOTE + phi_s4, - nSamplesToDecode * SAMPLE_SIZE); - AudioSynth_S8Dec(cmd++, flags, synthState->synthesisBuffers->adpcmdecState); - break; - } - - if (nSamplesProcessed != 0) { - aDMEMMove(cmd++, DMEM_UNCOMPRESSED_NOTE + phi_s4 + (nFirstFrameSamplesToIgnore * SAMPLE_SIZE), - DMEM_UNCOMPRESSED_NOTE + s5, nSamplesInThisIteration * SAMPLE_SIZE); - } - - nSamplesProcessed += nSamplesInThisIteration; - - switch (flags) { - case A_INIT: - skipBytes = SAMPLES_PER_FRAME * SAMPLE_SIZE; - s5 = (nSamplesToDecode + SAMPLES_PER_FRAME) * SAMPLE_SIZE; - break; - - case A_LOOP: - s5 = nSamplesInThisIteration * SAMPLE_SIZE + s5; - break; - - default: - if (s5 != 0) { - s5 = nSamplesInThisIteration * SAMPLE_SIZE + s5; - } else { - s5 = (nFirstFrameSamplesToIgnore + nSamplesInThisIteration) * SAMPLE_SIZE; - } - break; - } - - flags = A_CONTINUE; - - skip: - if (noteFinished) { - AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE + s5, - (samplesLenAdjusted - nSamplesProcessed) * SAMPLE_SIZE); - finished = true; - note->noteSubEu.bitField0.finished = true; - func_800DB2C0(updateIndex, noteIndex); - break; - } else { - if (restart) { - synthState->restart = true; - synthState->samplePosInt = loopInfo->start; - } else { - synthState->samplePosInt += nSamplesToProcess; - } - } - } - - switch (nParts) { - case 1: - sampleDmemBeforeResampling = DMEM_UNCOMPRESSED_NOTE + skipBytes; - break; - - case 2: - switch (curPart) { - case 0: - AudioSynth_InterL(cmd++, DMEM_UNCOMPRESSED_NOTE + skipBytes, - DMEM_TEMP + (SAMPLES_PER_FRAME * SAMPLE_SIZE), - ALIGN8(samplesLenAdjusted / 2)); - resampledTempLen = samplesLenAdjusted; - sampleDmemBeforeResampling = DMEM_TEMP + (SAMPLES_PER_FRAME * SAMPLE_SIZE); - if (finished) { - AudioSynth_ClearBuffer(cmd++, sampleDmemBeforeResampling + resampledTempLen, - samplesLenAdjusted + SAMPLES_PER_FRAME); - } - break; - - case 1: - AudioSynth_InterL(cmd++, DMEM_UNCOMPRESSED_NOTE + skipBytes, - DMEM_TEMP + (SAMPLES_PER_FRAME * SAMPLE_SIZE) + resampledTempLen, - ALIGN8(samplesLenAdjusted / 2)); - break; - } - } - if (finished) { - break; - } - } - } - - flags = A_CONTINUE; - if (noteSubEu->bitField0.needsInit == true) { - noteSubEu->bitField0.needsInit = false; - flags = A_INIT; - } - - cmd = AudioSynth_FinalResample(cmd, synthState, aiBufLen * (s32)SAMPLE_SIZE, resamplingRateFixedPoint, - sampleDmemBeforeResampling, flags); - if (bookOffset == 3) { - AudioSynth_UnkCmd19(cmd++, DMEM_TEMP, DMEM_TEMP, aiBufLen * SAMPLE_SIZE, 0); - } - - if (bookOffset == 2) { - AudioSynth_UnkCmd3(cmd++, DMEM_TEMP, DMEM_TEMP, aiBufLen * SAMPLE_SIZE); - } - - gain = noteSubEu->gain; - if (gain != 0) { - // A gain of 0x10 (a UQ4.4 number) is equivalent to 1.0 and represents no volume change - if (gain < 0x10) { - gain = 0x10; - } - AudioSynth_HiLoGain(cmd++, gain, DMEM_TEMP, 0, (aiBufLen + SAMPLES_PER_FRAME) * SAMPLE_SIZE); - } - - filter = noteSubEu->filter; - if (filter != NULL) { - AudioSynth_LoadFilterSize(cmd++, aiBufLen * SAMPLE_SIZE, filter); - AudioSynth_LoadFilterBuffer(cmd++, flags, DMEM_TEMP, synthState->synthesisBuffers->mixEnvelopeState); - } - - unk7 = noteSubEu->unk_07; - unkE = noteSubEu->unk_0E; - buf = synthState->synthesisBuffers->unkState; - if (unk7 != 0 && noteSubEu->unk_0E != 0) { - AudioSynth_DMemMove(cmd++, DMEM_TEMP, DMEM_SCRATCH2, aiBufLen * SAMPLE_SIZE); - thing = DMEM_SCRATCH2 - unk7; - if (synthState->unk_1A != 0) { - AudioSynth_ClearBuffer(cmd++, thing, unk7); - synthState->unk_1A = 0; - } else { - AudioSynth_LoadBuffer(cmd++, thing, unk7, buf); - } - AudioSynth_SaveBuffer(cmd++, DMEM_TEMP + (aiBufLen * SAMPLE_SIZE) - unk7, unk7, buf); - AudioSynth_Mix(cmd++, (aiBufLen * (s32)SAMPLE_SIZE) >> 4, unkE, DMEM_SCRATCH2, thing); - AudioSynth_DMemMove(cmd++, thing, DMEM_TEMP, aiBufLen * SAMPLE_SIZE); - } else { - synthState->unk_1A = 1; - } - - if ((noteSubEu->haasEffectLeftDelaySize != 0) || (synthState->prevHaasEffectLeftDelaySize != 0)) { - haasEffectDelaySide = HAAS_EFFECT_DELAY_LEFT; - } else if ((noteSubEu->haasEffectRightDelaySize != 0) || (synthState->prevHaasEffectRightDelaySize != 0)) { - haasEffectDelaySide = HAAS_EFFECT_DELAY_RIGHT; - } else { - haasEffectDelaySide = HAAS_EFFECT_DELAY_NONE; - } - - cmd = AudioSynth_ProcessEnvelope(cmd, noteSubEu, synthState, aiBufLen, DMEM_TEMP, haasEffectDelaySide, flags); - - if (noteSubEu->bitField1.useHaasEffect) { - if (!(flags & A_INIT)) { - flags = A_CONTINUE; - } - cmd = AudioSynth_ApplyHaasEffect(cmd, noteSubEu, synthState, aiBufLen * (s32)SAMPLE_SIZE, flags, - haasEffectDelaySide); - } - - return cmd; -} - -Acmd* AudioSynth_FinalResample(Acmd* cmd, NoteSynthesisState* synthState, s32 size, u16 pitch, u16 inpDmem, - s32 resampleFlags) { - if (pitch == 0) { - AudioSynth_ClearBuffer(cmd++, DMEM_TEMP, size); - } else { - aSetBuffer(cmd++, 0, inpDmem, DMEM_TEMP, size); - aResample(cmd++, resampleFlags, pitch, synthState->synthesisBuffers->finalResampleState); - } - return cmd; -} - -Acmd* AudioSynth_ProcessEnvelope(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 aiBufLen, - u16 dmemSrc, s32 haasEffectDelaySide, s32 flags) { - u32 dmemDests; - u16 curVolLeft; - u16 targetVolLeft; - s32 phi_t1; - s16 reverbVol; - u16 curVolRight; - s16 rampLeft; - s16 rampRight; - s16 rampReverb; - s16 sourceReverbVol; - u16 targetVolRight; - s32 pad; - - curVolLeft = synthState->curVolLeft; - targetVolLeft = noteSubEu->targetVolLeft; - targetVolLeft <<= 4; - reverbVol = noteSubEu->reverbVol; - curVolRight = synthState->curVolRight; - targetVolRight = noteSubEu->targetVolRight; - targetVolRight <<= 4; - - if (targetVolLeft != curVolLeft) { - rampLeft = (targetVolLeft - curVolLeft) / (aiBufLen >> 3); - } else { - rampLeft = 0; - } - if (targetVolRight != curVolRight) { - rampRight = (targetVolRight - curVolRight) / (aiBufLen >> 3); - } else { - rampRight = 0; - } - - sourceReverbVol = synthState->reverbVol; - phi_t1 = sourceReverbVol & 0x7F; - - if (sourceReverbVol != reverbVol) { - rampReverb = (((reverbVol & 0x7F) - phi_t1) << 9) / (aiBufLen >> 3); - synthState->reverbVol = reverbVol; - } else { - rampReverb = 0; - } - - synthState->curVolLeft = curVolLeft + (rampLeft * (aiBufLen >> 3)); - synthState->curVolRight = curVolRight + (rampRight * (aiBufLen >> 3)); - - if (noteSubEu->bitField1.useHaasEffect) { - AudioSynth_ClearBuffer(cmd++, DMEM_HAAS_TEMP, DMEM_1CH_SIZE); - AudioSynth_EnvSetup1(cmd++, phi_t1 * 2, rampReverb, rampLeft, rampRight); - AudioSynth_EnvSetup2(cmd++, curVolLeft, curVolRight); - - switch (haasEffectDelaySide) { - case HAAS_EFFECT_DELAY_LEFT: - // Store the left dry channel in a temp space to be delayed to produce the haas effect - dmemDests = sEnvMixerLeftHaasDmemDests; - break; - - case HAAS_EFFECT_DELAY_RIGHT: - // Store the right dry channel in a temp space to be delayed to produce the haas effect - dmemDests = sEnvMixerRightHaasDmemDests; - break; - - default: // HAAS_EFFECT_DELAY_NONE - dmemDests = sEnvMixerDefaultDmemDests; - break; - } - } else { - aEnvSetup1(cmd++, phi_t1 * 2, rampReverb, rampLeft, rampRight); - aEnvSetup2(cmd++, curVolLeft, curVolRight); - dmemDests = sEnvMixerDefaultDmemDests; - } - - aEnvMixer(cmd++, dmemSrc, aiBufLen, (sourceReverbVol & 0x80) >> 7, noteSubEu->bitField0.stereoHeadsetEffects, - noteSubEu->bitField0.usesHeadsetPanEffects, noteSubEu->bitField0.stereoStrongRight, - noteSubEu->bitField0.stereoStrongLeft, dmemDests, sEnvMixerOp); - - return cmd; -} - -Acmd* AudioSynth_LoadWaveSamples(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, - s32 numSamplesToLoad) { - s32 numSamplesAvail; - s32 harmonicIndexCurAndPrev = noteSubEu->harmonicIndexCurAndPrev; - s32 samplePosInt = synthState->samplePosInt; - s32 numDuplicates; - - if (noteSubEu->bitField1.bookOffset != 0) { - // Move the noise wave (that reads compiled assembly as samples) from ram to dmem - AudioSynth_LoadBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, ALIGN16(numSamplesToLoad * SAMPLE_SIZE), gWaveSamples[8]); - // Offset the address for the samples read by gWaveSamples[8] to the next set of samples - gWaveSamples[8] += numSamplesToLoad * SAMPLE_SIZE; - return cmd; - } else { - // Move the synthetic wave from ram to dmem - aLoadBuffer(cmd++, noteSubEu->waveSampleAddr, DMEM_UNCOMPRESSED_NOTE, WAVE_SAMPLE_COUNT * SAMPLE_SIZE); - - // If the harmonic changes, map the offset in the wave from one harmonic to another for continuity - if (harmonicIndexCurAndPrev != 0) { - samplePosInt = samplePosInt * sNumSamplesPerWavePeriod[harmonicIndexCurAndPrev >> 2] / - sNumSamplesPerWavePeriod[harmonicIndexCurAndPrev & 3]; - } - - // Offset in the WAVE_SAMPLE_COUNT samples of gWaveSamples to start processing the wave for continuity - samplePosInt = (u32)samplePosInt % WAVE_SAMPLE_COUNT; - // Number of samples in the initial WAVE_SAMPLE_COUNT samples available to be used to process - numSamplesAvail = WAVE_SAMPLE_COUNT - samplePosInt; - - // Require duplicates if there are more samples to load than available - if (numSamplesToLoad > numSamplesAvail) { - // Duplicate (copy) the WAVE_SAMPLE_COUNT samples as many times as needed to reach numSamplesToLoad. - // (numSamplesToLoad - numSamplesAvail) is the number of samples missing. - // Divide by WAVE_SAMPLE_COUNT, rounding up, to get the amount of duplicates - numDuplicates = ((numSamplesToLoad - numSamplesAvail + WAVE_SAMPLE_COUNT - 1) / WAVE_SAMPLE_COUNT); - if (numDuplicates != 0) { - aDuplicate(cmd++, numDuplicates, DMEM_UNCOMPRESSED_NOTE, - DMEM_UNCOMPRESSED_NOTE + (WAVE_SAMPLE_COUNT * SAMPLE_SIZE)); - } - } - synthState->samplePosInt = samplePosInt; - } - return cmd; -} - -/** - * The Haas Effect gives directionality to sound by applying a small (< 35ms) delay to either the left or right channel. - * The delay is small enough that the sound is still perceived as one sound, but the channel that is not delayed will - * reach our ear first and give a sense of directionality. The sound is directed towards the opposite side of the delay. - */ -Acmd* AudioSynth_ApplyHaasEffect(Acmd* cmd, NoteSubEu* noteSubEu, NoteSynthesisState* synthState, s32 size, s32 flags, - s32 haasEffectDelaySide) { - u16 dmemDest; - u16 pitch; - u8 prevHaasEffectDelaySize; - u8 haasEffectDelaySize; - - switch (haasEffectDelaySide) { - case HAAS_EFFECT_DELAY_LEFT: - // Delay the sample on the left channel - // This allows the right channel to be heard first - dmemDest = DMEM_LEFT_CH; - haasEffectDelaySize = noteSubEu->haasEffectLeftDelaySize; - prevHaasEffectDelaySize = synthState->prevHaasEffectLeftDelaySize; - synthState->prevHaasEffectRightDelaySize = 0; - synthState->prevHaasEffectLeftDelaySize = haasEffectDelaySize; - break; - - case HAAS_EFFECT_DELAY_RIGHT: - // Delay the sample on the right channel - // This allows the left channel to be heard first - dmemDest = DMEM_RIGHT_CH; - haasEffectDelaySize = noteSubEu->haasEffectRightDelaySize; - prevHaasEffectDelaySize = synthState->prevHaasEffectRightDelaySize; - synthState->prevHaasEffectRightDelaySize = haasEffectDelaySize; - synthState->prevHaasEffectLeftDelaySize = 0; - break; - - default: // HAAS_EFFECT_DELAY_NONE - return cmd; - } - - if (flags != A_INIT) { - // Slightly adjust the sample rate in order to fit a change in sample delay - if (haasEffectDelaySize != prevHaasEffectDelaySize) { - pitch = (((size << 0xF) / 2) - 1) / ((size + haasEffectDelaySize - prevHaasEffectDelaySize - 2) / 2); - aSetBuffer(cmd++, 0, DMEM_HAAS_TEMP, DMEM_TEMP, size + haasEffectDelaySize - prevHaasEffectDelaySize); - aResampleZoh(cmd++, pitch, 0); - } else { - aDMEMMove(cmd++, DMEM_HAAS_TEMP, DMEM_TEMP, size); - } - - if (prevHaasEffectDelaySize != 0) { - aLoadBuffer(cmd++, synthState->synthesisBuffers->haasEffectDelayState, DMEM_HAAS_TEMP, - ALIGN16(prevHaasEffectDelaySize)); - aDMEMMove(cmd++, DMEM_TEMP, DMEM_HAAS_TEMP + prevHaasEffectDelaySize, - size + haasEffectDelaySize - prevHaasEffectDelaySize); - } else { - aDMEMMove(cmd++, DMEM_TEMP, DMEM_HAAS_TEMP, size + haasEffectDelaySize); - } - } else { - // Just apply a delay directly - aDMEMMove(cmd++, DMEM_HAAS_TEMP, DMEM_TEMP, size); - aClearBuffer(cmd++, DMEM_HAAS_TEMP, haasEffectDelaySize); - aDMEMMove(cmd++, DMEM_TEMP, DMEM_HAAS_TEMP + haasEffectDelaySize, size); - } - - if ((u32)haasEffectDelaySize != 0) { - // Save excessive samples for next iteration - aSaveBuffer(cmd++, DMEM_HAAS_TEMP + size, synthState->synthesisBuffers->haasEffectDelayState, - ALIGN16(haasEffectDelaySize)); - } - - aAddMixer(cmd++, ALIGN64(size), DMEM_HAAS_TEMP, dmemDest, 0x7FFF); - - return cmd; -} diff --git a/src/code/audioMgr.c b/src/code/audio_thread_manager.c index 01bf54397..01bf54397 100644 --- a/src/code/audioMgr.c +++ b/src/code/audio_thread_manager.c diff --git a/src/code/code_800E4FE0.c b/src/code/code_800E4FE0.c deleted file mode 100644 index 53cd7d246..000000000 --- a/src/code/code_800E4FE0.c +++ /dev/null @@ -1,875 +0,0 @@ -#include "global.h" - -#define SAMPLES_TO_OVERPRODUCE 0x10 -#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x80 - -typedef enum { - CHAN_UPD_UNK_0, // 0 - CHAN_UPD_VOL_SCALE, // 1 - CHAN_UPD_VOL, // 2 - CHAN_UPD_PAN_SIGNED, // 3 - CHAN_UPD_FREQ_SCALE, // 4 - CHAN_UPD_REVERB, // 5 - CHAN_UPD_SCRIPT_IO, // 6 - CHAN_UPD_PAN_UNSIGNED, // 7 - CHAN_UPD_STOP_SOMETHING2, // 8 - CHAN_UPD_MUTE_BEHAVE, // 9 - CHAN_UPD_VIBE_X8, // 10 - CHAN_UPD_VIBE_X32, // 11 - CHAN_UPD_UNK_0F, // 12 - CHAN_UPD_UNK_20, // 13 - CHAN_UPD_STEREO // 14 -} ChannelUpdateType; - -void func_800E6300(SequenceChannel* channel, AudioCmd* cmd); -void func_800E59AC(s32 playerIdx, s32 fadeTimer); -void Audio_InitMesgQueues(void); -AudioTask* func_800E5000(void); -void Audio_ProcessCmds(u32); -void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd); -void func_800E5958(s32 playerIdx, s32 fadeTimer); -s32 func_800E66C0(s32 arg0); - -// AudioMgr_Retrace -AudioTask* func_800E4FE0(void) { - return func_800E5000(); -} - -/** - * This is Audio_Update for the audio thread - */ -AudioTask* func_800E5000(void) { - static s32 sMaxAbiCmdCnt = 0x80; - static AudioTask* sWaitingAudioTask = NULL; - u32 samplesRemainingInAi; - s32 abiCmdCnt; - s32 pad; - s32 j; - s32 sp5C; - s16* curAiBuffer; - OSTask_t* task; - s32 index; - u32 sp4C; - s32 sp48; - s32 i; - - gAudioCtx.totalTaskCount++; - if (gAudioCtx.totalTaskCount % (gAudioCtx.audioBufferParameters.specUnk4) != 0) { - if (D_801755D0 != NULL) { - D_801755D0(); - } - - if ((gAudioCtx.totalTaskCount % gAudioCtx.audioBufferParameters.specUnk4) + 1 == - gAudioCtx.audioBufferParameters.specUnk4) { - return sWaitingAudioTask; - } else { - return NULL; - } - } - - osSendMesg(gAudioCtx.taskStartQueueP, (OSMesg)gAudioCtx.totalTaskCount, OS_MESG_NOBLOCK); - gAudioCtx.rspTaskIndex ^= 1; - gAudioCtx.curAiBufIndex++; - gAudioCtx.curAiBufIndex %= 3; - index = (gAudioCtx.curAiBufIndex - 2 + 3) % 3; - samplesRemainingInAi = osAiGetLength() / 4; - - if (gAudioCtx.resetTimer < 16) { - if (gAudioCtx.aiBufLengths[index] != 0) { - osAiSetNextBuffer(gAudioCtx.aiBuffers[index], gAudioCtx.aiBufLengths[index] * 4); - if (gAudioCtx.aiBuffers[index]) {} - if (gAudioCtx.aiBufLengths[index]) {} - } - } - - if (D_801755D0 != NULL) { - D_801755D0(); - } - - sp5C = gAudioCtx.curAudioFrameDmaCount; - for (i = 0; i < gAudioCtx.curAudioFrameDmaCount; i++) { - if (osRecvMesg(&gAudioCtx.curAudioFrameDmaQueue, NULL, OS_MESG_NOBLOCK) == 0) { - sp5C--; - } - } - - if (sp5C != 0) { - for (i = 0; i < sp5C; i++) { - osRecvMesg(&gAudioCtx.curAudioFrameDmaQueue, NULL, OS_MESG_BLOCK); - } - } - - sp48 = MQ_GET_COUNT(&gAudioCtx.curAudioFrameDmaQueue); - if (sp48 != 0) { - for (i = 0; i < sp48; i++) { - osRecvMesg(&gAudioCtx.curAudioFrameDmaQueue, NULL, OS_MESG_NOBLOCK); - } - } - - gAudioCtx.curAudioFrameDmaCount = 0; - AudioLoad_DecreaseSampleDmaTtls(); - AudioLoad_ProcessLoads(gAudioCtx.resetStatus); - AudioLoad_ProcessScriptLoads(); - - if (gAudioCtx.resetStatus != 0) { - if (AudioHeap_ResetStep() == 0) { - if (gAudioCtx.resetStatus == 0) { - osSendMesg(gAudioCtx.audioResetQueueP, (OSMesg)(u32)gAudioCtx.audioResetSpecIdToLoad, OS_MESG_NOBLOCK); - } - - sWaitingAudioTask = NULL; - return NULL; - } - } - - if (gAudioCtx.resetTimer > 16) { - return NULL; - } - if (gAudioCtx.resetTimer != 0) { - gAudioCtx.resetTimer++; - } - - gAudioCtx.curTask = &gAudioCtx.rspTask[gAudioCtx.rspTaskIndex]; - gAudioCtx.curAbiCmdBuf = gAudioCtx.abiCmdBufs[gAudioCtx.rspTaskIndex]; - - index = gAudioCtx.curAiBufIndex; - curAiBuffer = gAudioCtx.aiBuffers[index]; - - gAudioCtx.aiBufLengths[index] = - (s16)((((gAudioCtx.audioBufferParameters.samplesPerFrameTarget - samplesRemainingInAi) + - EXTRA_BUFFERED_AI_SAMPLES_TARGET) & - ~0xF) + - SAMPLES_TO_OVERPRODUCE); - if (gAudioCtx.aiBufLengths[index] < gAudioCtx.audioBufferParameters.minAiBufferLength) { - gAudioCtx.aiBufLengths[index] = gAudioCtx.audioBufferParameters.minAiBufferLength; - } - - if (gAudioCtx.aiBufLengths[index] > gAudioCtx.audioBufferParameters.maxAiBufferLength) { - gAudioCtx.aiBufLengths[index] = gAudioCtx.audioBufferParameters.maxAiBufferLength; - } - - j = 0; - if (gAudioCtx.resetStatus == 0) { - // msg = 0000RREE R = read pos, E = End Pos - while (osRecvMesg(gAudioCtx.cmdProcQueueP, (OSMesg*)&sp4C, OS_MESG_NOBLOCK) != -1) { - if (1) {} - Audio_ProcessCmds(sp4C); - j++; - } - if ((j == 0) && (gAudioCtx.cmdQueueFinished)) { - Audio_ScheduleProcessCmds(); - } - } - - gAudioCtx.curAbiCmdBuf = - AudioSynth_Update(gAudioCtx.curAbiCmdBuf, &abiCmdCnt, curAiBuffer, gAudioCtx.aiBufLengths[index]); - - // Update audioRandom to the next random number - gAudioCtx.audioRandom = (gAudioCtx.audioRandom + gAudioCtx.totalTaskCount) * osGetCount(); - gAudioCtx.audioRandom = gAudioCtx.audioRandom + gAudioCtx.aiBuffers[index][gAudioCtx.totalTaskCount & 0xFF]; - - // gWaveSamples[8] interprets compiled assembly code as s16 samples as a way to generate sound with noise. - // Start with the address of func_800E4FE0, and offset it by a random number between 0 - 0xFFF0 - // Use the resulting address as the starting address to interpret an array of samples i.e. `s16 samples[]` - gWaveSamples[8] = (s16*)(((u8*)func_800E4FE0) + (gAudioCtx.audioRandom & 0xFFF0)); - - index = gAudioCtx.rspTaskIndex; - gAudioCtx.curTask->msgQueue = NULL; - gAudioCtx.curTask->unk_44 = NULL; - - task = &gAudioCtx.curTask->task.t; - task->type = M_AUDTASK; - task->flags = 0; - task->ucode_boot = aspMainTextStart; - task->ucode_boot_size = SP_UCODE_SIZE; - task->ucode_data_size = (size_t)(aspMainDataEnd - aspMainDataStart) * sizeof(u64) - 1; - task->ucode = aspMainTextStart; - task->ucode_data = aspMainDataStart; - task->ucode_size = SP_UCODE_SIZE; - task->dram_stack = NULL; - task->dram_stack_size = 0; - task->output_buff = NULL; - task->output_buff_size = NULL; - if (1) {} - task->data_ptr = (u64*)gAudioCtx.abiCmdBufs[index]; - task->data_size = abiCmdCnt * sizeof(Acmd); - task->yield_data_ptr = NULL; - task->yield_data_size = 0; - - if (sMaxAbiCmdCnt < abiCmdCnt) { - sMaxAbiCmdCnt = abiCmdCnt; - } - - if (gAudioCtx.audioBufferParameters.specUnk4 == 1) { - return gAudioCtx.curTask; - } else { - sWaitingAudioTask = gAudioCtx.curTask; - return NULL; - } -} - -#define ACMD_SND_MDE ((u32)0xF0000000) -#define ACMD_MUTE ((u32)0xF1000000) - -void func_800E5584(AudioCmd* cmd) { - s32 i; - s32 pad; - s32 pad2; - u32 temp_a1_5; - u32 temp_t7; - - switch (cmd->op) { - case 0x81: - AudioLoad_SyncLoadSeqParts(cmd->arg1, cmd->arg2); - break; - - case 0x82: - AudioLoad_SyncInitSeqPlayer(cmd->arg0, cmd->arg1, cmd->arg2); - func_800E59AC(cmd->arg0, cmd->asInt); - break; - - case 0x85: - AudioLoad_SyncInitSeqPlayerSkipTicks(cmd->arg0, cmd->arg1, cmd->asInt); - break; - - case 0x83: - if (gAudioCtx.seqPlayers[cmd->arg0].enabled) { - if (cmd->asInt == 0) { - AudioSeq_SequencePlayerDisableAsFinished(&gAudioCtx.seqPlayers[cmd->arg0]); - } else { - func_800E5958(cmd->arg0, cmd->asInt); - } - } - break; - - case 0xF0: - gAudioCtx.soundMode = cmd->asUInt; - break; - - case 0xF1: - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i]; - - seqPlayer->muted = 1; - seqPlayer->recalculateVolume = 1; - } - break; - - case 0xF2: - if (cmd->asUInt == 1) { - for (i = 0; i < gAudioCtx.numNotes; i++) { - Note* note = &gAudioCtx.notes[i]; - NoteSubEu* subEu = ¬e->noteSubEu; - - if (subEu->bitField0.enabled && note->playbackState.unk_04 == 0) { - if (note->playbackState.parentLayer->channel->muteBehavior & MUTE_BEHAVIOR_3) { - subEu->bitField0.finished = true; - } - } - } - } - - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i]; - - seqPlayer->muted = 0; - seqPlayer->recalculateVolume = 1; - } - break; - - case 0xF3: - AudioLoad_SyncLoadInstrument(cmd->arg0, cmd->arg1, cmd->arg2); - break; - - case 0xF4: - AudioLoad_AsyncLoadSampleBank(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); - break; - - case 0xF5: - AudioLoad_AsyncLoadFont(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); - break; - - case 0xFC: - AudioLoad_AsyncLoadSeq(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); - break; - - case 0xF6: - AudioLoad_DiscardSeqFonts(cmd->arg1); - break; - - case 0x90: - gAudioCtx.unk_5BDC[cmd->arg0] = cmd->asUShort; - break; - - case 0xF9: - gAudioCtx.resetStatus = 5; - gAudioCtx.audioResetSpecIdToLoad = cmd->asUInt; - break; - - case 0xFB: - D_801755D0 = (void (*)(void))cmd->asUInt; - break; - - case 0xE0: - case 0xE1: - case 0xE2: - Audio_SetFontInstrument(cmd->op - 0xE0, cmd->arg0, cmd->arg1, cmd->data); - break; - - case 0xFE: - temp_t7 = cmd->asUInt; - if (temp_t7 == 1) { - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i]; - - if (seqPlayer->enabled) { - AudioSeq_SequencePlayerDisableAsFinished(seqPlayer); - } - } - } - func_800E66C0(temp_t7); - break; - - case 0xE3: - AudioHeap_PopPersistentCache(cmd->asInt); - break; - - default: - break; - } -} - -// SetFadeOutTimer -void func_800E5958(s32 playerIdx, s32 fadeTimer) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; - - if (fadeTimer == 0) { - fadeTimer = 1; - } - - seqPlayer->fadeVelocity = -(seqPlayer->fadeVolume / fadeTimer); - seqPlayer->state = 2; - seqPlayer->fadeTimer = fadeTimer; -} - -// SetFadeInTimer -void func_800E59AC(s32 playerIdx, s32 fadeTimer) { - SequencePlayer* seqPlayer; - - if (fadeTimer != 0) { - seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; - seqPlayer->state = 1; - seqPlayer->fadeTimerUnkEu = fadeTimer; - seqPlayer->fadeTimer = fadeTimer; - seqPlayer->fadeVolume = 0.0f; - seqPlayer->fadeVelocity = 0.0f; - } -} - -void Audio_InitMesgQueuesInternal(void) { - gAudioCtx.cmdWrPos = 0; - gAudioCtx.cmdRdPos = 0; - gAudioCtx.cmdQueueFinished = 0; - gAudioCtx.taskStartQueueP = &gAudioCtx.taskStartQueue; - gAudioCtx.cmdProcQueueP = &gAudioCtx.cmdProcQueue; - gAudioCtx.audioResetQueueP = &gAudioCtx.audioResetQueue; - osCreateMesgQueue(gAudioCtx.taskStartQueueP, gAudioCtx.taskStartMsgBuf, ARRAY_COUNT(gAudioCtx.taskStartMsgBuf)); - osCreateMesgQueue(gAudioCtx.cmdProcQueueP, gAudioCtx.cmdProcMsgBuf, ARRAY_COUNT(gAudioCtx.cmdProcMsgBuf)); - osCreateMesgQueue(gAudioCtx.audioResetQueueP, gAudioCtx.audioResetMsgBuf, ARRAY_COUNT(gAudioCtx.audioResetMsgBuf)); -} - -void Audio_QueueCmd(u32 opArgs, void** data) { - AudioCmd* cmd = &gAudioCtx.cmdBuf[gAudioCtx.cmdWrPos & 0xFF]; - - cmd->opArgs = opArgs; - cmd->data = *data; - - gAudioCtx.cmdWrPos++; - - if (gAudioCtx.cmdWrPos == gAudioCtx.cmdRdPos) { - gAudioCtx.cmdWrPos--; - } -} - -void Audio_QueueCmdF32(u32 opArgs, f32 data) { - Audio_QueueCmd(opArgs, (void**)&data); -} - -void Audio_QueueCmdS32(u32 opArgs, s32 data) { - Audio_QueueCmd(opArgs, (void**)&data); -} - -void Audio_QueueCmdS8(u32 opArgs, s8 data) { - u32 uData = data << 0x18; - - Audio_QueueCmd(opArgs, (void**)&uData); -} - -void Audio_QueueCmdU16(u32 opArgs, u16 data) { - u32 uData = data << 0x10; - - Audio_QueueCmd(opArgs, (void**)&uData); -} - -s32 Audio_ScheduleProcessCmds(void) { - static s32 D_801304E8 = 0; - s32 ret; - - if (D_801304E8 < (u8)((gAudioCtx.cmdWrPos - gAudioCtx.cmdRdPos) + 0x100)) { - D_801304E8 = (u8)((gAudioCtx.cmdWrPos - gAudioCtx.cmdRdPos) + 0x100); - } - - ret = osSendMesg(gAudioCtx.cmdProcQueueP, - (OSMesg)(((gAudioCtx.cmdRdPos & 0xFF) << 8) | (gAudioCtx.cmdWrPos & 0xFF)), OS_MESG_NOBLOCK); - if (ret != -1) { - gAudioCtx.cmdRdPos = gAudioCtx.cmdWrPos; - ret = 0; - } else { - return -1; - } - - return ret; -} - -void Audio_ResetCmdQueue(void) { - gAudioCtx.cmdQueueFinished = 0; - gAudioCtx.cmdRdPos = gAudioCtx.cmdWrPos; -} - -void Audio_ProcessCmd(AudioCmd* cmd) { - SequencePlayer* seqPlayer; - u16 phi_v0; - s32 i; - - if ((cmd->op & 0xF0) == 0xF0) { - func_800E5584(cmd); - return; - } - - if (cmd->arg0 < gAudioCtx.audioBufferParameters.numSequencePlayers) { - seqPlayer = &gAudioCtx.seqPlayers[cmd->arg0]; - if (cmd->op & 0x80) { - func_800E5584(cmd); - return; - } - if (cmd->op & 0x40) { - func_800E6128(seqPlayer, cmd); - return; - } - - if (cmd->arg1 < 0x10) { - func_800E6300(seqPlayer->channels[cmd->arg1], cmd); - return; - } - if (cmd->arg1 == 0xFF) { - phi_v0 = gAudioCtx.unk_5BDC[cmd->arg0]; - for (i = 0; i < 16; i++) { - if (phi_v0 & 1) { - func_800E6300(seqPlayer->channels[i], cmd); - } - phi_v0 = phi_v0 >> 1; - } - } - } -} - -void Audio_ProcessCmds(u32 msg) { - static u8 curCmdRdPos = 0; - AudioCmd* cmd; - u8 endPos; - - if (!gAudioCtx.cmdQueueFinished) { - curCmdRdPos = msg >> 8; - } - - while (true) { - endPos = msg & 0xFF; - if (curCmdRdPos == endPos) { - gAudioCtx.cmdQueueFinished = 0; - return; - } - - cmd = &gAudioCtx.cmdBuf[curCmdRdPos++ & 0xFF]; - if (cmd->op == 0xF8) { - gAudioCtx.cmdQueueFinished = 1; - return; - } - - Audio_ProcessCmd(cmd); - cmd->op = 0; - } -} - -u32 func_800E5E20(u32* out) { - u32 sp1C; - - if (osRecvMesg(&gAudioCtx.externalLoadQueue, (OSMesg*)&sp1C, OS_MESG_NOBLOCK) == -1) { - *out = 0; - return 0; - } - *out = sp1C & 0xFFFFFF; - return sp1C >> 0x18; -} - -u8* func_800E5E84(s32 arg0, u32* arg1) { - return AudioLoad_GetFontsForSequence(arg0, arg1); -} - -void Audio_GetSampleBankIdsOfFont(s32 fontId, u32* sampleBankId1, u32* sampleBankId2) { - *sampleBankId1 = gAudioCtx.soundFontList[fontId].sampleBankId1; - *sampleBankId2 = gAudioCtx.soundFontList[fontId].sampleBankId2; -} - -s32 func_800E5EDC(void) { - s32 pad; - s32 sp18; - - if (osRecvMesg(gAudioCtx.audioResetQueueP, (OSMesg*)&sp18, OS_MESG_NOBLOCK) == -1) { - return 0; - } else if (gAudioCtx.audioResetSpecIdToLoad != sp18) { - return -1; - } else { - return 1; - } -} - -void func_800E5F34(void) { - // macro? - // clang-format off - s32 chk = -1; OSMesg msg; do {} while (osRecvMesg(gAudioCtx.audioResetQueueP, &msg, OS_MESG_NOBLOCK) != chk); - // clang-format on -} - -s32 func_800E5F88(s32 resetPreloadID) { - s32 resetStatus; - OSMesg msg; - s32 pad; - - func_800E5F34(); - resetStatus = gAudioCtx.resetStatus; - if (resetStatus != 0) { - Audio_ResetCmdQueue(); - if (gAudioCtx.audioResetSpecIdToLoad == resetPreloadID) { - return -2; - } else if (resetStatus > 2) { - gAudioCtx.audioResetSpecIdToLoad = resetPreloadID; - return -3; - } else { - osRecvMesg(gAudioCtx.audioResetQueueP, &msg, OS_MESG_BLOCK); - } - } - - func_800E5F34(); - Audio_QueueCmdS32(0xF9000000, resetPreloadID); - - return Audio_ScheduleProcessCmds(); -} - -void Audio_PreNMIInternal(void) { - gAudioCtx.resetTimer = 1; - if (gAudioContextInitialized) { - func_800E5F88(0); - gAudioCtx.resetStatus = 0; - } -} - -s8 func_800E6070(s32 playerIdx, s32 channelIdx, s32 scriptIdx) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; - SequenceChannel* channel; - - if (seqPlayer->enabled) { - channel = seqPlayer->channels[channelIdx]; - return channel->soundScriptIO[scriptIdx]; - } else { - return -1; - } -} - -s8 func_800E60C4(s32 playerIdx, s32 port) { - return gAudioCtx.seqPlayers[playerIdx].soundScriptIO[port]; -} - -void Audio_InitExternalPool(void* ramAddr, u32 size) { - AudioHeap_InitPool(&gAudioCtx.externalPool, ramAddr, size); -} - -void Audio_DestroyExternalPool(void) { - gAudioCtx.externalPool.startRamAddr = NULL; -} - -void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd) { - f32 fadeVolume; - - switch (cmd->op) { - case 0x41: - if (seqPlayer->fadeVolumeScale != cmd->asFloat) { - seqPlayer->fadeVolumeScale = cmd->asFloat; - seqPlayer->recalculateVolume = 1; - } - break; - - case 0x47: - seqPlayer->tempo = cmd->asInt * 0x30; - break; - - case 0x49: - seqPlayer->unk_0C = cmd->asInt * 0x30; - break; - - case 0x4E: - seqPlayer->unk_0C = cmd->asInt; - break; - - case 0x48: - seqPlayer->transposition = cmd->asSbyte; - break; - - case 0x46: - seqPlayer->soundScriptIO[cmd->arg2] = cmd->asSbyte; - break; - - case 0x4A: - fadeVolume = (s32)cmd->arg1 / 127.0f; - goto block_11; - - case 0x4B: - fadeVolume = ((s32)cmd->arg1 / 100.0f) * seqPlayer->fadeVolume; - block_11: - if (seqPlayer->state != 2) { - seqPlayer->volume = seqPlayer->fadeVolume; - if (cmd->asInt == 0) { - seqPlayer->fadeVolume = fadeVolume; - } else { - s32 fadeTimer = cmd->asInt; - - seqPlayer->state = 0; - seqPlayer->fadeTimer = fadeTimer; - seqPlayer->fadeVelocity = (fadeVolume - seqPlayer->fadeVolume) / fadeTimer; - } - } - break; - - case 0x4C: - if (seqPlayer->state != 2) { - if (cmd->asInt == 0) { - seqPlayer->fadeVolume = seqPlayer->volume; - } else { - s32 fadeTimer = cmd->asInt; - - seqPlayer->state = 0; - seqPlayer->fadeTimer = fadeTimer; - seqPlayer->fadeVelocity = (seqPlayer->volume - seqPlayer->fadeVolume) / fadeTimer; - } - } - break; - - case 0x4D: - seqPlayer->bend = cmd->asFloat; - if (seqPlayer->bend == 1.0f) { - seqPlayer->applyBend = false; - } else { - seqPlayer->applyBend = true; - } - break; - - default: - break; - } -} - -void func_800E6300(SequenceChannel* channel, AudioCmd* cmd) { - switch (cmd->op) { - case CHAN_UPD_VOL_SCALE: - if (channel->volumeScale != cmd->asFloat) { - channel->volumeScale = cmd->asFloat; - channel->changes.s.volume = 1; - } - break; - - case CHAN_UPD_VOL: - if (channel->volume != cmd->asFloat) { - channel->volume = cmd->asFloat; - channel->changes.s.volume = 1; - } - break; - - case CHAN_UPD_PAN_SIGNED: - if (channel->newPan != cmd->asSbyte) { - channel->newPan = cmd->asSbyte; - channel->changes.s.pan = 1; - } - break; - - case CHAN_UPD_PAN_UNSIGNED: - if (channel->newPan != cmd->asSbyte) { - channel->panChannelWeight = cmd->asSbyte; - channel->changes.s.pan = 1; - } - break; - - case CHAN_UPD_FREQ_SCALE: - if (channel->freqScale != cmd->asFloat) { - channel->freqScale = cmd->asFloat; - channel->changes.s.freqScale = 1; - } - break; - - case CHAN_UPD_REVERB: - if (channel->reverb != cmd->asSbyte) { - channel->reverb = cmd->asSbyte; - } - break; - - case CHAN_UPD_SCRIPT_IO: - if (cmd->arg2 < 8) { - channel->soundScriptIO[cmd->arg2] = cmd->asSbyte; - } - break; - - case CHAN_UPD_STOP_SOMETHING2: - channel->stopSomething2 = cmd->asSbyte; - break; - - case CHAN_UPD_MUTE_BEHAVE: - channel->muteBehavior = cmd->asSbyte; - break; - - case CHAN_UPD_VIBE_X8: - channel->vibratoExtentTarget = cmd->asUbyte * 8; - channel->vibratoExtentChangeDelay = 1; - break; - - case CHAN_UPD_VIBE_X32: - channel->vibratoRateTarget = cmd->asUbyte * 32; - channel->vibratoRateChangeDelay = 1; - break; - - case CHAN_UPD_UNK_0F: - channel->unk_0F = cmd->asUbyte; - break; - - case CHAN_UPD_UNK_20: - channel->unk_20 = cmd->asUShort; - break; - - case CHAN_UPD_STEREO: - channel->stereo.asByte = cmd->asUbyte; - break; - - default: - break; - } -} - -void func_800E64B0(s32 arg0, s32 arg1, s32 arg2) { - Audio_QueueCmdS32(((arg0 & 0xFF) << 0x10) | 0xFA000000 | ((arg1 & 0xFF) << 8) | (arg2 & 0xFF), 1); -} - -void func_800E64F8(void) { - Audio_QueueCmdS32(0xFA000000, 0); -} - -void func_800E651C(u32 arg0, s32 arg1) { - Audio_QueueCmdS32((arg1 & 0xFF) | 0xFD000000, arg0); -} - -void Audio_WaitForAudioTask(void) { - osRecvMesg(gAudioCtx.taskStartQueueP, NULL, OS_MESG_NOBLOCK); - osRecvMesg(gAudioCtx.taskStartQueueP, NULL, OS_MESG_BLOCK); -} - -s32 func_800E6590(s32 playerIdx, s32 arg1, s32 arg2) { - SequencePlayer* seqPlayer; - SequenceLayer* layer; - Note* note; - TunedSample* tunedSample; - s32 loopEnd; - s32 samplePos; - - seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; - if (seqPlayer->enabled && seqPlayer->channels[arg1]->enabled) { - layer = seqPlayer->channels[arg1]->layers[arg2]; - if (layer == NULL) { - return 0; - } - - if (layer->enabled) { - if (layer->note == NULL) { - return 0; - } - - if (!layer->bit3) { - return 0; - } - - note = layer->note; - if (layer == note->playbackState.parentLayer) { - tunedSample = note->noteSubEu.tunedSample; - if (tunedSample == NULL) { - return 0; - } - loopEnd = tunedSample->sample->loop->end; - samplePos = note->synthesisState.samplePosInt; - return loopEnd - samplePos; - } - return 0; - } - } - return 0; -} - -s32 func_800E6680(void) { - return func_800E66C0(0); -} - -void func_800E66A0(void) { - func_800E66C0(2); -} - -s32 func_800E66C0(s32 arg0) { - s32 phi_v1; - NotePlaybackState* playbackState; - NoteSubEu* noteSubEu; - s32 i; - Note* note; - TunedSample* tunedSample; - - phi_v1 = 0; - for (i = 0; i < gAudioCtx.numNotes; i++) { - note = &gAudioCtx.notes[i]; - playbackState = ¬e->playbackState; - if (note->noteSubEu.bitField0.enabled) { - noteSubEu = ¬e->noteSubEu; - if (playbackState->adsr.action.s.state != 0) { - if (arg0 >= 2) { - tunedSample = noteSubEu->tunedSample; - if (tunedSample == NULL || noteSubEu->bitField1.isSyntheticWave) { - continue; - } - if (tunedSample->sample->medium == MEDIUM_RAM) { - continue; - } - } - - phi_v1++; - if ((arg0 & 1) == 1) { - playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; - playbackState->adsr.action.s.release = 1; - } - } - } - } - return phi_v1; -} - -u32 Audio_NextRandom(void) { - static u32 audRand = 0x12345678; - - audRand = ((osGetCount() + 0x1234567) * (audRand + gAudioCtx.totalTaskCount)); - audRand += gAudioCtx.audioRandom; - return audRand; -} - -void Audio_InitMesgQueues(void) { - Audio_InitMesgQueuesInternal(); -} diff --git a/src/code/code_800E6840.c b/src/code/code_800E6840.c deleted file mode 100644 index caaaea332..000000000 --- a/src/code/code_800E6840.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "global.h" - -void Audio_InvalDCache(void* buf, s32 size) { - OSIntMask prevMask = osSetIntMask(OS_IM_NONE); - - osInvalDCache(buf, size); - osSetIntMask(prevMask); -} - -void Audio_WritebackDCache(void* buf, s32 size) { - OSIntMask prevMask = osSetIntMask(OS_IM_NONE); - - osWritebackDCache(buf, size); - osSetIntMask(prevMask); -} diff --git a/src/code/code_800EC960.c b/src/code/code_800EC960.c deleted file mode 100644 index a5a76016b..000000000 --- a/src/code/code_800EC960.c +++ /dev/null @@ -1,5355 +0,0 @@ -#include "ultra64.h" -#include "global.h" - -#define Audio_DisableSeq(seqPlayerIndex, fadeOut) Audio_QueueCmdS32(0x83000000 | ((u8)seqPlayerIndex << 16), fadeOut) - -#define ABS_ALT(x) ((x) < 0 ? -(x) : (x)) - -typedef struct { - /* 0x0 */ f32 vol; - /* 0x4 */ f32 freqScale; - /* 0x8 */ s8 reverb; - /* 0x9 */ s8 panSigned; - /* 0xA */ s8 stereoBits; - /* 0xB */ u8 filter; - /* 0xC */ u8 unk_0C; -} SfxPlayerState; - -typedef enum { - /* 0x0 */ SFX_CHANNEL_PLAYER0, // SfxPlayerBank - /* 0x1 */ SFX_CHANNEL_PLAYER1, - /* 0x2 */ SFX_CHANNEL_PLAYER2, - /* 0x3 */ SFX_CHANNEL_ITEM0, // SfxItemBank - /* 0x4 */ SFX_CHANNEL_ITEM1, - /* 0x5 */ SFX_CHANNEL_ENV0, // SfxEnvironmentBank - /* 0x6 */ SFX_CHANNEL_ENV1, - /* 0x7 */ SFX_CHANNEL_ENV2, - /* 0x8 */ SFX_CHANNEL_ENEMY0, // SfxEnemyBank - /* 0x9 */ SFX_CHANNEL_ENEMY1, - /* 0xA */ SFX_CHANNEL_ENEMY2, - /* 0xB */ SFX_CHANNEL_SYSTEM0, // SfxSystemBank - /* 0xC */ SFX_CHANNEL_SYSTEM1, - /* 0xD */ SFX_CHANNEL_OCARINA, // SfxOcarinaBank - /* 0xE */ SFX_CHANNEL_VOICE0, // SfxVoiceBank - /* 0xF */ SFX_CHANNEL_VOICE1 -} SfxChannelIndex; // playerIdx = 2 - -typedef struct { - /* 0x0 */ f32 value; - /* 0x4 */ f32 target; - /* 0x8 */ f32 step; - /* 0xC */ s32 remainingFrames; -} FreqLerp; - -typedef struct { - /* 0x0 */ u16 playerIO; - /* 0x2 */ u16 channelMask; - /* 0x4 */ u8 channelIO[3 * 33 + 1]; -} NatureAmbienceDataIO; // size = 0x68 - -typedef enum { - /* 0x0 */ PAGE_NON, - /* 0x1 */ PAGE_SOUND_CONTROL, - /* 0x2 */ PAGE_SPEC_INFO, // unused - /* 0x3 */ PAGE_HEAP_INFO, - /* 0x4 */ PAGE_GROUP_TRACK_INFO, // unused - /* 0x5 */ PAGE_SUB_TRACK_INFO, - /* 0x6 */ PAGE_CHANNEL_INFO, // unused - /* 0x7 */ PAGE_INTERFACE_INFO, - /* 0x8 */ PAGE_SFX_SWAP, - /* 0x9 */ PAGE_BLOCK_CHANGE_BGM, - /* 0xA */ PAGE_NATURAL_SOUND_CONTROL, // unused - /* 0xB */ PAGE_OCARINA_TEST, - /* 0xC */ PAGE_SFX_PARAMETER_CHANGE, - /* 0xD */ PAGE_SCROLL_PRINT, - /* 0xE */ PAGE_FREE_AREA, - /* 0xF */ PAGE_MAX -} AudioDebugPage; - -#define SCROLL_PRINT_BUF_SIZE 25 - -typedef struct { - s8 x; - s8 y; -} OcarinaStick; - -u8 gIsLargeSfxBank[7] = { 0, 0, 0, 1, 0, 0, 0 }; - -// Only the first row of these is supported by sequence 0. (gSfxChannelLayout is always 0.) -u8 gChannelsPerBank[4][7] = { - { 3, 2, 3, 3, 2, 1, 2 }, - { 3, 2, 2, 2, 2, 2, 2 }, - { 3, 2, 2, 2, 2, 2, 2 }, - { 4, 1, 0, 0, 2, 2, 2 }, -}; -u8 gUsedChannelsPerBank[4][7] = { - { 3, 2, 3, 2, 2, 1, 1 }, - { 3, 1, 1, 1, 2, 1, 1 }, - { 3, 1, 1, 1, 2, 1, 1 }, - { 2, 1, 0, 0, 1, 1, 1 }, -}; - -f32 D_801305B0 = 0.7950898f; -s8 D_801305B4 = 35; -s8 D_801305B8 = 20; -s8 D_801305BC = 30; -s8 D_801305C0 = 20; -f32 sBehindScreenZ[2] = { -15.0f, -65.0f }; -u8 sAudioIncreasingTranspose = 0; -u8 gMorphaTransposeTable[16] = { 0, 0, 0, 1, 1, 2, 4, 6, 8, 8, 8, 8, 8, 8, 8, 8 }; -u8 sPrevChargeLevel = 0; -f32 D_801305E4[4] = { 1.0f, 1.12246f, 1.33484f, 1.33484f }; // 2**({0, 2, 5, 5}/12) -f32 D_801305F4 = 1.0f; -u8 sGanonsTowerLevelsVol[8] = { 127, 80, 75, 73, 70, 68, 65, 60 }; -u8 sEnterGanonsTowerTimer = 0; -s8 sSoundMode = SOUNDMODE_SURROUND; -s8 D_80130608 = 0; -s8 sAudioCutsceneFlag = 0; -s8 sSpecReverb = 0; -s8 sAudioEnvReverb = 0; -s8 sAudioCodeReverb = 0; -u8 sPrevSeqMode = 0; -f32 sAudioEnemyDist = 0.0f; -s8 sAudioEnemyVol = 127; -u16 sPrevMainBgmSeqId = NA_BGM_DISABLED; - -#define SEQ_RESUME_POINT_NONE 0xC0 -u8 sSeqResumePoint = 0; -u8 sPrevSceneSeqId = NA_BGM_GENERAL_SFX; - -u32 sNumFramesStill = 0; -u32 sNumFramesMoving = 0; -u8 sAudioBaseFilter = 0; -u8 sAudioExtraFilter = 0; -u8 sAudioBaseFilter2 = 0; -u8 sAudioExtraFilter2 = 0; -Vec3f* sSariaBgmPtr = NULL; -f32 D_80130650 = 2000.0f; -u8 sSeqModeInput = 0; - -#define SEQ_FLAG_ENEMY (1 << 0) // Allows enemy bgm -#define SEQ_FLAG_FANFARE (1 << 1) -#define SEQ_FLAG_FANFARE_GANON (1 << 2) -#define SEQ_FLAG_RESTORE (1 << 3) // required for func_800F5B58 to restore a sequence after func_800F5ACC - -/** - * These two sequence flags work together to implement a “resume playing from where you left off” system for scene - * sequences when leaving and returning to a scene. For a scene to resume playing from the point where it left off, it - * must have `SEQ_FLAG_RESUME` attached to it. Then, if the scene changes and the new scene sequence contain - * `SEQ_FLAG_RESUME_PREV`, the point from the previous scene sequence will be stored. Then, when returning to the - * scene with the sequence `SEQ_FLAG_RESUME`, then the sequence will resume playing from where it left off. - * - * There are only 5 sequences with `SEQ_FLAG_RESUME`, and all 5 of those sequences have special sequence - * instructions in their .seq files to read io port 7 and branch to different starting points along the sequence - * i.e. this system will only work for: kokiri forest, kakariko child, kakariko adult, zoras domain, gerudo valley - */ -#define SEQ_FLAG_RESUME (1 << 4) -#define SEQ_FLAG_RESUME_PREV (1 << 5) - -/** - * Will write a value of 1 to ioPort 7 when called through the scene. How it's used depends on the sequence: - * NA_BGM_CHAMBER_OF_SAGES - ioPort 7 is never read from - * NA_BGM_FILE_SELECT - ioPort 7 skips the harp intro when a value of 1 is written to it. - * Note: NA_BGM_FILE_SELECT is not called through the scene. So this flag serves no purpose - */ -#define SEQ_FLAG_SKIP_HARP_INTRO (1 << 6) -#define SEQ_FLAG_NO_AMBIENCE (1 << 7) - -u8 sSeqFlags[] = { - SEQ_FLAG_FANFARE, // NA_BGM_GENERAL_SFX - SEQ_FLAG_ENEMY, // NA_BGM_NATURE_BACKGROUND - 0, // NA_BGM_FIELD_LOGIC - 0, // NA_BGM_FIELD_INIT - 0, // NA_BGM_FIELD_DEFAULT_1 - 0, // NA_BGM_FIELD_DEFAULT_2 - 0, // NA_BGM_FIELD_DEFAULT_3 - 0, // NA_BGM_FIELD_DEFAULT_4 - 0, // NA_BGM_FIELD_DEFAULT_5 - 0, // NA_BGM_FIELD_DEFAULT_6 - 0, // NA_BGM_FIELD_DEFAULT_7 - 0, // NA_BGM_FIELD_DEFAULT_8 - 0, // NA_BGM_FIELD_DEFAULT_9 - 0, // NA_BGM_FIELD_DEFAULT_A - 0, // NA_BGM_FIELD_DEFAULT_B - 0, // NA_BGM_FIELD_ENEMY_INIT - 0, // NA_BGM_FIELD_ENEMY_1 - 0, // NA_BGM_FIELD_ENEMY_2 - 0, // NA_BGM_FIELD_ENEMY_3 - 0, // NA_BGM_FIELD_ENEMY_4 - 0, // NA_BGM_FIELD_STILL_1 - 0, // NA_BGM_FIELD_STILL_2 - 0, // NA_BGM_FIELD_STILL_3 - 0, // NA_BGM_FIELD_STILL_4 - SEQ_FLAG_RESUME_PREV | SEQ_FLAG_ENEMY, // NA_BGM_DUNGEON - SEQ_FLAG_RESUME, // NA_BGM_KAKARIKO_ADULT - 0, // NA_BGM_ENEMY - SEQ_FLAG_NO_AMBIENCE | SEQ_FLAG_RESTORE, // NA_BGM_BOSS - SEQ_FLAG_ENEMY, // NA_BGM_INSIDE_DEKU_TREE - 0, // NA_BGM_MARKET - 0, // NA_BGM_TITLE - SEQ_FLAG_RESUME_PREV, // NA_BGM_LINK_HOUSE - 0, // NA_BGM_GAME_OVER - 0, // NA_BGM_BOSS_CLEAR - SEQ_FLAG_FANFARE, // NA_BGM_ITEM_GET - SEQ_FLAG_FANFARE_GANON, // NA_BGM_OPENING_GANON - SEQ_FLAG_FANFARE, // NA_BGM_HEART_GET - SEQ_FLAG_FANFARE, // NA_BGM_OCA_LIGHT - SEQ_FLAG_ENEMY, // NA_BGM_JABU_JABU - SEQ_FLAG_RESUME, // NA_BGM_KAKARIKO_KID - 0, // NA_BGM_GREAT_FAIRY - 0, // NA_BGM_ZELDA_THEME - SEQ_FLAG_ENEMY, // NA_BGM_FIRE_TEMPLE - SEQ_FLAG_FANFARE, // NA_BGM_OPEN_TRE_BOX - SEQ_FLAG_ENEMY, // NA_BGM_FOREST_TEMPLE - 0, // NA_BGM_COURTYARD - SEQ_FLAG_NO_AMBIENCE, // NA_BGM_GANON_TOWER - 0, // NA_BGM_LONLON - SEQ_FLAG_NO_AMBIENCE, // NA_BGM_GORON_CITY - 0, // NA_BGM_FIELD_MORNING - SEQ_FLAG_FANFARE, // NA_BGM_SPIRITUAL_STONE - SEQ_FLAG_FANFARE, // NA_BGM_OCA_BOLERO - SEQ_FLAG_FANFARE, // NA_BGM_OCA_MINUET - SEQ_FLAG_FANFARE, // NA_BGM_OCA_SERENADE - SEQ_FLAG_FANFARE, // NA_BGM_OCA_REQUIEM - SEQ_FLAG_FANFARE, // NA_BGM_OCA_NOCTURNE - SEQ_FLAG_NO_AMBIENCE | SEQ_FLAG_RESTORE, // NA_BGM_MINI_BOSS - SEQ_FLAG_FANFARE, // NA_BGM_SMALL_ITEM_GET - 0, // NA_BGM_TEMPLE_OF_TIME - SEQ_FLAG_FANFARE, // NA_BGM_EVENT_CLEAR - SEQ_FLAG_RESUME | SEQ_FLAG_ENEMY, // NA_BGM_KOKIRI - SEQ_FLAG_FANFARE, // NA_BGM_OCA_FAIRY_GET - SEQ_FLAG_ENEMY, // NA_BGM_SARIA_THEME - SEQ_FLAG_ENEMY, // NA_BGM_SPIRIT_TEMPLE - 0, // NA_BGM_HORSE - 0, // NA_BGM_HORSE_GOAL - 0, // NA_BGM_INGO - SEQ_FLAG_FANFARE, // NA_BGM_MEDALLION_GET - SEQ_FLAG_FANFARE, // NA_BGM_OCA_SARIA - SEQ_FLAG_FANFARE, // NA_BGM_OCA_EPONA - SEQ_FLAG_FANFARE, // NA_BGM_OCA_ZELDA - SEQ_FLAG_FANFARE, // NA_BGM_OCA_SUNS - SEQ_FLAG_FANFARE, // NA_BGM_OCA_TIME - SEQ_FLAG_FANFARE, // NA_BGM_OCA_STORM - 0, // NA_BGM_NAVI_OPENING - 0, // NA_BGM_DEKU_TREE_CS - 0, // NA_BGM_WINDMILL - 0, // NA_BGM_HYRULE_CS - SEQ_FLAG_RESUME_PREV, // NA_BGM_MINI_GAME - 0, // NA_BGM_SHEIK - SEQ_FLAG_RESUME, // NA_BGM_ZORA_DOMAIN - SEQ_FLAG_FANFARE, // NA_BGM_APPEAR - 0, // NA_BGM_ADULT_LINK - 0, // NA_BGM_MASTER_SWORD - SEQ_FLAG_FANFARE_GANON, // NA_BGM_INTRO_GANON - SEQ_FLAG_RESUME_PREV, // NA_BGM_SHOP - SEQ_FLAG_SKIP_HARP_INTRO, // NA_BGM_CHAMBER_OF_SAGES - SEQ_FLAG_SKIP_HARP_INTRO, // NA_BGM_FILE_SELECT - SEQ_FLAG_ENEMY, // NA_BGM_ICE_CAVERN - SEQ_FLAG_FANFARE, // NA_BGM_DOOR_OF_TIME - SEQ_FLAG_FANFARE, // NA_BGM_OWL - SEQ_FLAG_ENEMY, // NA_BGM_SHADOW_TEMPLE - SEQ_FLAG_ENEMY, // NA_BGM_WATER_TEMPLE - SEQ_FLAG_FANFARE, // NA_BGM_BRIDGE_TO_GANONS - 0, // NA_BGM_OCARINA_OF_TIME - SEQ_FLAG_RESUME | SEQ_FLAG_ENEMY, // NA_BGM_GERUDO_VALLEY - 0, // NA_BGM_POTION_SHOP - 0, // NA_BGM_KOTAKE_KOUME - SEQ_FLAG_NO_AMBIENCE, // NA_BGM_ESCAPE - 0, // NA_BGM_UNDERGROUND - SEQ_FLAG_NO_AMBIENCE, // NA_BGM_GANON_BATTLE_1 - SEQ_FLAG_NO_AMBIENCE, // NA_BGM_GANON_BATTLE_2 - 0, // NA_BGM_END_DEMO - 0, // NA_BGM_STAFF_1 - 0, // NA_BGM_STAFF_2 - 0, // NA_BGM_STAFF_3 - 0, // NA_BGM_STAFF_4 - 0, // NA_BGM_FIRE_BOSS - SEQ_FLAG_RESTORE, // NA_BGM_TIMED_MINI_GAME - 0, // NA_BGM_CUTSCENE_EFFECTS -}; - -s8 sSpecReverbs[20] = { 0, 0, 0, 0, 0, 0, 0, 40, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -NatureAmbienceDataIO sNatureAmbienceDataIO[20] = { - // NATURE_ID_GENERAL_NIGHT - { - 0xC0FF, // PlayerIO Data - 0xC0FE, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CROWS_CAWS), - NATURE_IO_CRITTER_0_BEND_PITCH(64), - NATURE_IO_CRITTER_0_NUM_LAYERS(0), - NATURE_IO_CRITTER_0_PORT5(32), - - // Channel 2 - NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_1_BEND_PITCH(0), - NATURE_IO_CRITTER_1_NUM_LAYERS(1), - NATURE_IO_CRITTER_1_PORT5(16), - - // Channel 3 - NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_SMALL_BIRD_CHIRPS), - NATURE_IO_CRITTER_2_BEND_PITCH(112), - NATURE_IO_CRITTER_2_NUM_LAYERS(1), - NATURE_IO_CRITTER_2_PORT5(48), - - // Channel 4 - NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_HAWK_SCREECH), - NATURE_IO_CRITTER_3_BEND_PITCH(127), - NATURE_IO_CRITTER_3_NUM_LAYERS(0), - NATURE_IO_CRITTER_3_PORT5(16), - - // Channel 5 - NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_BIRD_CHIRP_1), - NATURE_IO_CRITTER_4_BEND_PITCH(127), - NATURE_IO_CRITTER_4_NUM_LAYERS(1), - NATURE_IO_CRITTER_4_PORT5(16), - - // Channel 6 - NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_TAP), - NATURE_IO_CRITTER_5_BEND_PITCH(127), - NATURE_IO_CRITTER_5_NUM_LAYERS(3), - NATURE_IO_CRITTER_5_PORT5(16), - - // Channel 7 - NATURE_IO_CRITTER_6_TYPE(NATURE_CRITTER_CUCCO_CROWS), - NATURE_IO_CRITTER_6_BEND_PITCH(127), - NATURE_IO_CRITTER_6_NUM_LAYERS(1), - NATURE_IO_CRITTER_6_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_MARKET_ENTRANCE - { - 0xC0FB, // PlayerIO Data - 0xC0FA, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // Channel 3 - NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_BIRD_SCREECH), - NATURE_IO_CRITTER_2_BEND_PITCH(112), - NATURE_IO_CRITTER_2_NUM_LAYERS(1), - NATURE_IO_CRITTER_2_PORT5(48), - - // Channel 4 - NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_HAWK_SCREECH), - NATURE_IO_CRITTER_3_BEND_PITCH(127), - NATURE_IO_CRITTER_3_NUM_LAYERS(0), - NATURE_IO_CRITTER_3_PORT5(16), - - // Channel 5 - NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_BIRD_CHIRP_1), - NATURE_IO_CRITTER_4_BEND_PITCH(127), - NATURE_IO_CRITTER_4_NUM_LAYERS(1), - NATURE_IO_CRITTER_4_PORT5(16), - - // Channel 6 - NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_TAP), - NATURE_IO_CRITTER_5_BEND_PITCH(127), - NATURE_IO_CRITTER_5_NUM_LAYERS(3), - NATURE_IO_CRITTER_5_PORT5(16), - - // Channel 7 - NATURE_IO_CRITTER_6_TYPE(NATURE_CRITTER_CUCCO_CROWS), - NATURE_IO_CRITTER_6_BEND_PITCH(127), - NATURE_IO_CRITTER_6_NUM_LAYERS(1), - NATURE_IO_CRITTER_6_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_KAKARIKO_REGION - { - 0xC001, // PlayerIO Data - 0x4000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 2 - NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_BIRD_SCREECH), - NATURE_IO_CRITTER_1_BEND_PITCH(48), - NATURE_IO_CRITTER_1_NUM_LAYERS(1), - NATURE_IO_CRITTER_1_PORT5(32), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_MARKET_RUINS - { - 0xC005, // PlayerIO Data - 0x4000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_HOWLING_WIND), - NATURE_IO_STREAM_0_PORT3(32), - - // Channel 2 - NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_BIRD_SCREECH), - NATURE_IO_CRITTER_1_BEND_PITCH(48), - NATURE_IO_CRITTER_1_NUM_LAYERS(1), - NATURE_IO_CRITTER_1_PORT5(32), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_KOKIRI_REGION - { - 0xC01F, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(47), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_OWL_HOOT), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // Channel 2 - NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_CAWING_BIRD), - NATURE_IO_CRITTER_1_BEND_PITCH(0), - NATURE_IO_CRITTER_1_NUM_LAYERS(1), - NATURE_IO_CRITTER_1_PORT5(32), - - // Channel 3 - NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_HAWK_SCREECH), - NATURE_IO_CRITTER_2_BEND_PITCH(0), - NATURE_IO_CRITTER_2_NUM_LAYERS(0), - NATURE_IO_CRITTER_2_PORT5(44), - - // Channel 4 - NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_BIRD_SCREECH), - NATURE_IO_CRITTER_3_BEND_PITCH(63), - NATURE_IO_CRITTER_3_NUM_LAYERS(1), - NATURE_IO_CRITTER_3_PORT5(44), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_MARKET_NIGHT - { - 0xC003, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_06 - { - 0xC0FB, // PlayerIO Data - 0xC0FA, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // Channel 3 - NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_BIRD_SCREECH), - NATURE_IO_CRITTER_2_BEND_PITCH(112), - NATURE_IO_CRITTER_2_NUM_LAYERS(1), - NATURE_IO_CRITTER_2_PORT5(48), - - // Channel 4 - NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_HAWK_SCREECH), - NATURE_IO_CRITTER_3_BEND_PITCH(127), - NATURE_IO_CRITTER_3_NUM_LAYERS(0), - NATURE_IO_CRITTER_3_PORT5(16), - - // Channel 5 - NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_BIRD_CHIRP_1), - NATURE_IO_CRITTER_4_BEND_PITCH(127), - NATURE_IO_CRITTER_4_NUM_LAYERS(1), - NATURE_IO_CRITTER_4_PORT5(16), - - // Channel 6 - NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_TAP), - NATURE_IO_CRITTER_5_BEND_PITCH(127), - NATURE_IO_CRITTER_5_NUM_LAYERS(3), - NATURE_IO_CRITTER_5_PORT5(16), - - // Channel 7 - NATURE_IO_CRITTER_6_TYPE(NATURE_CRITTER_CUCCO_CROWS), - NATURE_IO_CRITTER_6_BEND_PITCH(127), - NATURE_IO_CRITTER_6_NUM_LAYERS(1), - NATURE_IO_CRITTER_6_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_GANONS_LAIR - { - 0x8001, // PlayerIO Data - 0x0, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_HOWLING_WIND), - NATURE_IO_STREAM_0_PORT3(32), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_08 - { - 0xC003, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_09 - { - 0xC003, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_WASTELAND - { - 0xC001, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_SCREECHING_WIND), - NATURE_IO_STREAM_0_PORT3(0), - NATURE_IO_STREAM_0_PORT4(0), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_COLOSSUS - { - 0xC02F, // PlayerIO Data - 0xC02E, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_SCREECHING_WIND), - NATURE_IO_STREAM_0_PORT3(0), - NATURE_IO_STREAM_0_PORT4(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_SMALL_BIRD_CHIRPS), - NATURE_IO_CRITTER_0_BEND_PITCH(64), - NATURE_IO_CRITTER_0_NUM_LAYERS(0), - NATURE_IO_CRITTER_0_PORT5(32), - - // Channel 2 - NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_BIRD_CALL), - NATURE_IO_CRITTER_1_BEND_PITCH(112), - NATURE_IO_CRITTER_1_NUM_LAYERS(1), - NATURE_IO_CRITTER_1_PORT5(48), - - // Channel 3 - NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_HAWK_SCREECH), - NATURE_IO_CRITTER_2_BEND_PITCH(127), - NATURE_IO_CRITTER_2_NUM_LAYERS(0), - NATURE_IO_CRITTER_2_PORT5(16), - - // Channel 5 - NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_4_BEND_PITCH(127), - NATURE_IO_CRITTER_4_NUM_LAYERS(0), - NATURE_IO_CRITTER_4_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_DEATH_MOUNTAIN_TRAIL - { - 0xC07F, // PlayerIO Data - 0xC07E, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - NATURE_IO_STREAM_0_PORT4(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_SMALL_BIRD_CHIRPS), - NATURE_IO_CRITTER_0_BEND_PITCH(64), - NATURE_IO_CRITTER_0_NUM_LAYERS(0), - NATURE_IO_CRITTER_0_PORT5(32), - - // Channel 2 - NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_BIRD_SCREECH), - NATURE_IO_CRITTER_1_BEND_PITCH(112), - NATURE_IO_CRITTER_1_NUM_LAYERS(1), - NATURE_IO_CRITTER_1_PORT5(48), - - // Channel 3 - NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_BIRD_SONG), - NATURE_IO_CRITTER_2_BEND_PITCH(127), - NATURE_IO_CRITTER_2_NUM_LAYERS(0), - NATURE_IO_CRITTER_2_PORT5(16), - - // Channel 4 - NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_LOUD_CHIRPING), - NATURE_IO_CRITTER_3_BEND_PITCH(0), - NATURE_IO_CRITTER_3_NUM_LAYERS(0), - NATURE_IO_CRITTER_3_PORT5(16), - - // Channel 5 - NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_BIRD_CHIRP_1), - NATURE_IO_CRITTER_4_BEND_PITCH(0), - NATURE_IO_CRITTER_4_NUM_LAYERS(0), - NATURE_IO_CRITTER_4_PORT5(16), - - // Channel 6 - NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_TAP), - NATURE_IO_CRITTER_5_BEND_PITCH(0), - NATURE_IO_CRITTER_5_NUM_LAYERS(0), - NATURE_IO_CRITTER_5_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_0D - { - 0xC003, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_0E - { - 0xC003, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_0F - { - 0xC01F, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_BIRD_CHIRP_1), - NATURE_IO_CRITTER_0_BEND_PITCH(80), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(8), - - // Channel 2 - NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_SMALL_BIRD_CHIRPS), - NATURE_IO_CRITTER_1_BEND_PITCH(80), - NATURE_IO_CRITTER_1_NUM_LAYERS(1), - NATURE_IO_CRITTER_1_PORT5(48), - - // Channel 3 - NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_LOUD_CHIRPING), - NATURE_IO_CRITTER_2_BEND_PITCH(0), - NATURE_IO_CRITTER_2_NUM_LAYERS(0), - NATURE_IO_CRITTER_2_PORT5(0), - - // Channel 4 - NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_BIRD_SCREECH), - NATURE_IO_CRITTER_3_BEND_PITCH(96), - NATURE_IO_CRITTER_3_NUM_LAYERS(0), - NATURE_IO_CRITTER_3_PORT5(32), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_10 - { - 0xC003, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_11 - { - 0xC003, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_12 - { - 0xC003, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, - - // NATURE_ID_NONE - // While there is data for this natureAmbienceId, it is identical to previous entries - // and the game treats it as no nature ambience - { - 0xC003, // PlayerIO Data - 0xC000, // Channel Mask - { - // Channel 0 - NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_RUSHING_WATER), - NATURE_IO_STREAM_0_PORT3(0), - - // Channel 1 - NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_CRICKETS), - NATURE_IO_CRITTER_0_BEND_PITCH(0), - NATURE_IO_CRITTER_0_NUM_LAYERS(1), - NATURE_IO_CRITTER_0_PORT5(16), - - // End - NATURE_IO_ENTRIES_END, - }, - }, -}; - -u32 sOcarinaAllowedButtonMask = (BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP); -s32 sOcarinaAButtonMap = BTN_A; -s32 sOcarinaCUpButtonMap = BTN_CUP; -s32 sOcarinaCDownButtonMap = BTN_CDOWN; -u8 sIsOcarinaInputEnabled = false; -s8 sOcarinaInstrumentId = OCARINA_INSTRUMENT_OFF; -u8 sCurOcarinaPitch = OCARINA_PITCH_NONE; -u8 sPrevOcarinaPitch = OCARINA_PITCH_C4; -u8 sCurOcarinaButtonIndex = OCARINA_BTN_A; -u8 sMusicStaffPrevPitch = OCARINA_PITCH_C4; -f32 sCurOcarinaBendFreq = 1.0f; -f32 sRelativeOcarinaVolume = 87.0f / 127.0f; -s8 sCurOcarinaBendIndex = 0; -s8 sCurOcarinaVolume = 87; -s8 sCurOcarinaVibrato = 0; -u8 sPlaybackState = 0; -u32 sOcarinaFlags = 0; -u32 sPlaybackNoteTimer = 0; -u16 sPlaybackNotePos = 0; -u16 sPlaybackStaffPos = 0; -u16 sPrevOcarinaWithMusicStaffFlags = 0; -u8 sPlaybackPitch = OCARINA_PITCH_NONE; // Pitch + PitchFlags -u8 sNotePlaybackVolume = 0; -u8 sNotePlaybackVibrato = 0; -s8 sNotePlaybackBend = 0; -f32 sRelativeNotePlaybackBend = 1.0f; -f32 sRelativeNotePlaybackVolume = 1.0f; -s32 sOcarinaPlaybackTaskStart = 0; - -u8 sButtonToPitchMap[5] = { - OCARINA_PITCH_D4, // OCARINA_BTN_A - OCARINA_PITCH_F4, // OCARINA_BTN_C_DOWN - OCARINA_PITCH_A4, // OCARINA_BTN_C_RIGHT - OCARINA_PITCH_B4, // OCARINA_BTN_C_LEFT - OCARINA_PITCH_D5, // OCARINA_BTN_C_UP -}; - -u8 sOcaMemoryGameAppendPos = 0; -u8 sOcaMemoryGameEndPos = 0; -u8 sOcaMemoryGameNumNotes[] = { 5, 6, 8 }; - -OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { - // OCARINA_SONG_MINUET - { - { OCARINA_PITCH_D4, 18, 86, 0, 0, 0 }, - { OCARINA_PITCH_D5, 18, 92, 0, 0, 0 }, - { OCARINA_PITCH_B4, 72, 86, 0, 0, 0 }, - { OCARINA_PITCH_A4, 18, 80, 0, 0, 0 }, - { OCARINA_PITCH_B4, 18, 88, 0, 0, 0 }, - { OCARINA_PITCH_A4, 144, 86, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 86, 0, 0, 0 }, - }, - - // OCARINA_SONG_BOLERO - { - { OCARINA_PITCH_F4, 15, 80, 0, 0, 0 }, - { OCARINA_PITCH_D4, 15, 72, 0, 0, 0 }, - { OCARINA_PITCH_F4, 15, 84, 0, 0, 0 }, - { OCARINA_PITCH_D4, 15, 76, 0, 0, 0 }, - { OCARINA_PITCH_A4, 15, 84, 0, 0, 0 }, - { OCARINA_PITCH_F4, 15, 74, 0, 0, 0 }, - { OCARINA_PITCH_A4, 15, 78, 0, 0, 0 }, - { OCARINA_PITCH_F4, 135, 66, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, - }, - - // OCARINA_SONG_SERENADE - { - { OCARINA_PITCH_D4, 36, 60, 0, 0, 0 }, - { OCARINA_PITCH_F4, 36, 78, 0, 0, 0 }, - { OCARINA_PITCH_A4, 33, 82, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 82, 0, 0, 0 }, - { OCARINA_PITCH_A4, 36, 84, 0, 0, 0 }, - { OCARINA_PITCH_B4, 144, 90, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, - }, - - // OCARINA_SONG_REQUIEM - { - { OCARINA_PITCH_D4, 45, 88, 0, 0, 0 }, - { OCARINA_PITCH_F4, 23, 86, 0, 0, 0 }, - { OCARINA_PITCH_D4, 22, 84, 0, 0, 0 }, - { OCARINA_PITCH_A4, 45, 86, 0, 0, 0 }, - { OCARINA_PITCH_F4, 45, 94, 0, 0, 0 }, - { OCARINA_PITCH_D4, 180, 94, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 94, 0, 0, 0 }, - }, - - // OCARINA_SONG_NOCTURNE - { - { OCARINA_PITCH_B4, 36, 88, 0, 0, 0 }, - { OCARINA_PITCH_A4, 33, 84, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, - { OCARINA_PITCH_A4, 18, 82, 0, 0, 0 }, - { OCARINA_PITCH_D4, 18, 60, 0, 0, 0 }, - { OCARINA_PITCH_B4, 18, 90, 0, 0, 0 }, - { OCARINA_PITCH_A4, 18, 88, 0, 0, 0 }, - { OCARINA_PITCH_F4, 144, 96, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 96, 0, 0, 0 }, - }, - - // OCARINA_SONG_PRELUDE - { - { OCARINA_PITCH_D5, 15, 84, 0, 0, 0 }, - { OCARINA_PITCH_A4, 45, 88, 0, 0, 0 }, - { OCARINA_PITCH_D5, 15, 88, 0, 0, 0 }, - { OCARINA_PITCH_A4, 15, 82, 0, 0, 0 }, - { OCARINA_PITCH_B4, 15, 86, 0, 0, 0 }, - { OCARINA_PITCH_D5, 60, 90, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 75, 90, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, - }, - - // OCARINA_SONG_SARIAS - { - { OCARINA_PITCH_F4, 17, 84, 0, 0, 0 }, - { OCARINA_PITCH_A4, 17, 88, 0, 0, 0 }, - { OCARINA_PITCH_B4, 34, 80, 0, 0, 0 }, - { OCARINA_PITCH_F4, 17, 84, 0, 0, 0 }, - { OCARINA_PITCH_A4, 17, 88, 0, 0, 0 }, - { OCARINA_PITCH_B4, 136, 80, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, - }, - - // OCARINA_SONG_EPONAS - { - { OCARINA_PITCH_D5, 18, 84, 0, 0, 0 }, - { OCARINA_PITCH_B4, 18, 88, 0, 0, 0 }, - { OCARINA_PITCH_A4, 72, 80, 0, 0, 0 }, - { OCARINA_PITCH_D5, 18, 84, 0, 0, 0 }, - { OCARINA_PITCH_B4, 18, 88, 0, 0, 0 }, - { OCARINA_PITCH_A4, 144, 80, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, - }, - - // OCARINA_SONG_LULLABY - { - { OCARINA_PITCH_B4, 51, 84, 0, 0, 0 }, - { OCARINA_PITCH_D5, 25, 88, 0, 0, 0 }, - { OCARINA_PITCH_A4, 78, 80, 0, 0, 0 }, - { OCARINA_PITCH_B4, 51, 84, 0, 0, 0 }, - { OCARINA_PITCH_D5, 25, 88, 0, 0, 0 }, - { OCARINA_PITCH_A4, 100, 80, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, - }, - - // OCARINA_SONG_SUNS - { - { OCARINA_PITCH_A4, 12, 84, 0, 0, 0 }, - { OCARINA_PITCH_F4, 13, 88, 0, 0, 0 }, - { OCARINA_PITCH_D5, 29, 80, 2, 0, 0 }, - { OCARINA_PITCH_NONE, 9, 84, 0, 0, 0 }, - { OCARINA_PITCH_A4, 12, 84, 0, 0, 0 }, - { OCARINA_PITCH_F4, 13, 88, 0, 0, 0 }, - { OCARINA_PITCH_D5, 120, 80, 3, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, - }, - - // OCARINA_SONG_TIME - { - { OCARINA_PITCH_A4, 32, 84, 0, 0, 0 }, - { OCARINA_PITCH_D4, 65, 88, 0, 0, 0 }, - { OCARINA_PITCH_F4, 33, 80, 0, 0, 0 }, - { OCARINA_PITCH_A4, 32, 84, 0, 0, 0 }, - { OCARINA_PITCH_D4, 65, 88, 0, 0, 0 }, - { OCARINA_PITCH_F4, 99, 80, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, - }, - - // OCARINA_SONG_STORMS - { - { OCARINA_PITCH_D4, 11, 84, 0, 0, 0 }, - { OCARINA_PITCH_F4, 11, 88, 0, 0, 0 }, - { OCARINA_PITCH_D5, 45, 80, 0, 0, 0 }, - { OCARINA_PITCH_D4, 11, 84, 0, 0, 0 }, - { OCARINA_PITCH_F4, 11, 88, 0, 0, 0 }, - { OCARINA_PITCH_D5, 90, 80, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, - }, - - // OCARINA_SONG_SCARECROW_SPAWN - { - { OCARINA_PITCH_D4, 3, 0, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 255, 0, 0, 0 }, - }, - - // OCARINA_SONG_MEMORY_GAME - { - { OCARINA_PITCH_D4, 3, 0, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 }, - }, -}; - -OcarinaNote* sPlaybackSong = sOcarinaSongNotes[0]; -u8 sFrogsSongNotes[14] = { - OCARINA_BTN_A, OCARINA_BTN_C_LEFT, OCARINA_BTN_C_RIGHT, OCARINA_BTN_C_DOWN, OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, OCARINA_BTN_C_DOWN, OCARINA_BTN_A, OCARINA_BTN_C_DOWN, OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, OCARINA_BTN_C_RIGHT, OCARINA_BTN_C_LEFT, OCARINA_BTN_A, -}; -u8* gFrogsSongPtr = sFrogsSongNotes; -u8 sRecordingState = OCARINA_RECORD_OFF; -u8 sRecordSongPos = 0; -u32 sOcarinaRecordTaskStart = 0; -u8 sRecordOcarinaPitch = 0; -u8 sRecordOcarinaVolume = 0; -u8 sRecordOcarinaVibrato = 0; -s8 sRecordOcarinaBendIndex = 0; -u8 sRecordOcarinaButtonIndex = 0; -u8 sPlayedOcarinaSongIndexPlusOne = 0; -u8 sMusicStaffNumNotesPerTest = 0; -u8 sOcarinaDropInputTimer = 0; - -OcarinaNote sScarecrowsLongSongNotes[108] = { - { OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 }, -}; -OcarinaNote* gScarecrowLongSongPtr = sScarecrowsLongSongNotes; - -u8* gScarecrowSpawnSongPtr = (u8*)&sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN]; -OcarinaNote* sMemoryGameSongPtr = sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME]; - -u8 sPitchToButtonMap[16] = { - OCARINA_BTN_A, // OCARINA_PITCH_C4 - OCARINA_BTN_A, // OCARINA_PITCH_DFLAT4 - OCARINA_BTN_A, // OCARINA_PITCH_D4 - OCARINA_BTN_A, // OCARINA_PITCH_EFLAT4 - OCARINA_BTN_C_DOWN, // OCARINA_PITCH_E4 - OCARINA_BTN_C_DOWN, // OCARINA_PITCH_F4 - OCARINA_BTN_C_DOWN, // OCARINA_PITCH_GFLAT4 - OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_G4 - OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_AFLAT4 - OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_A4 - OCARINA_BTN_C_RIGHT_OR_C_LEFT, // OCARINA_PITCH_BFLAT4: Interface/Overlap between C_RIGHT and C_LEFT - OCARINA_BTN_C_LEFT, // OCARINA_PITCH_B4 - OCARINA_BTN_C_LEFT, // OCARINA_PITCH_C5 - OCARINA_BTN_C_UP, // OCARINA_PITCH_DFLAT5 - OCARINA_BTN_C_UP, // OCARINA_PITCH_D5 - OCARINA_BTN_C_UP, // OCARINA_PITCH_EFLAT5 -}; - -OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { - // OCARINA_SONG_MINUET - { 6, - { - OCARINA_BTN_A, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - } }, - // OCARINA_SONG_BOLERO - { 8, - { - OCARINA_BTN_C_DOWN, - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_A, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - } }, - // OCARINA_SONG_SERENADE - { 5, - { - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - } }, - // OCARINA_SONG_REQUIEM - { 6, - { - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_A, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_A, - } }, - // OCARINA_SONG_NOCTURNE - { 7, - { - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_A, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - } }, - // OCARINA_SONG_PRELUDE - { 6, - { - OCARINA_BTN_C_UP, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_UP, - } }, - // OCARINA_SONG_SARIAS - { 6, - { - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - } }, - // OCARINA_SONG_EPONAS - { 6, - { - OCARINA_BTN_C_UP, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - } }, - // OCARINA_SONG_LULLABY - { 6, - { - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_RIGHT, - } }, - // OCARINA_SONG_SUNS - { 6, - { - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_UP, - } }, - // OCARINA_SONG_TIME - { 6, - { - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - } }, - // OCARINA_SONG_STORMS - { 6, - { - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_UP, - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_UP, - } }, - // OCARINA_SONG_SCARECROW_SPAWN - { 8, { 0 } }, - // OCARINA_SONG_MEMORY_GAME - { 0, { 0 } }, -}; - -u32 sAudioUpdateStartTime; -u32 sAudioUpdateEndTime; -f32 D_8016B7A8; -f32 D_8016B7AC; -f32 D_8016B7B0; -f32 D_8016B7B4; -FreqLerp sRiverFreqScaleLerp; -FreqLerp sWaterfallFreqScaleLerp; -f32 D_8016B7D8; -s8 D_8016B7DC; -f32 D_8016B7E0; -u16 D_8016B7E4; -struct { - char str[5]; - u16 num; -} sAudioScrPrtBuf[SCROLL_PRINT_BUF_SIZE]; -u8 sRiverSoundMainBgmVol; -u8 sRiverSoundMainBgmCurrentVol; -u8 sRiverSoundMainBgmLower; -u8 sRiverSoundMainBgmRestore; -u8 sGanonsTowerVol; -SfxPlayerState sSfxChannelState[0x10]; -char sBinToStrBuf[0x20]; -u8 sMalonSingingTimer; -u8 sAudioSpecPeakNumNotes[0x12]; -u8 sMalonSingingDisabled; -u8 D_8016B9F3; -u8 sFanfareStartTimer; -u16 sFanfareSeqId; - -OcarinaStaff sPlayingStaff; -OcarinaStaff sPlaybackStaff; -OcarinaStaff sRecordingStaff; -u32 sOcarinaUpdateTaskStart; -OcarinaStick sOcarinaInputStickAdj; -u32 sOcarinaInputButtonCur; -u32 sOcarinaInputButtonStart; -u32 sOcarinaInputButtonPrev; -s32 sOcarinaInputButtonPress; -s32 sOcarinaUnused; -u8 sCurOcarinaSongWithoutMusicStaff[8]; -u8 sOcarinaWithoutMusicStaffPos; -u8 sOcarinaHasStartedSong; -u8 sFirstOcarinaSongIndex; -u8 sLastOcarinaSongIndex; -u16 sAvailOcarinaSongFlags; -u8 sStaffOcarinaPlayingPos; -u16 sMusicStaffPos[OCARINA_SONG_MAX]; -u16 sMusicStaffCurHeldLength[OCARINA_SONG_MAX]; -u16 sMusicStaffExpectedLength[OCARINA_SONG_MAX]; -u8 sMusicStaffExpectedPitch[OCARINA_SONG_MAX]; -OcarinaNote sScarecrowsLongSongSecondNote; -u8 sIsMalonSinging; -f32 sMalonSingingDist; - -void PadMgr_RequestPadData(PadMgr* padMgr, Input* inputs, s32 gameRequest); - -void Audio_StepFreqLerp(FreqLerp* lerp); -void Audio_UpdateSceneSequenceResumePoint(void); -void Audio_PlayNatureAmbienceSequence(u8 natureAmbienceId); -s32 Audio_SetGanonsTowerBgmVolume(u8 targetVol); - -// =========== Audio Ocarina =========== - -void AudioOcarina_SetCustomButtonMapping(u8 useCustom) { - if (!useCustom) { - osSyncPrintf("AUDIO : Ocarina Control Assign Normal\n"); - sOcarinaAllowedButtonMask = (BTN_A | BTN_CUP | BTN_CDOWN | BTN_CLEFT | BTN_CRIGHT); - sOcarinaAButtonMap = BTN_A; - sOcarinaCUpButtonMap = BTN_CUP; - sOcarinaCDownButtonMap = BTN_CDOWN; - } else { - osSyncPrintf("AUDIO : Ocarina Control Assign Custom\n"); - sOcarinaAllowedButtonMask = (BTN_A | BTN_B | BTN_CDOWN | BTN_CLEFT | BTN_CRIGHT); - sOcarinaAButtonMap = BTN_B; - sOcarinaCUpButtonMap = BTN_CDOWN; - sOcarinaCDownButtonMap = BTN_A; - } -} - -void AudioOcarina_ReadControllerInput(void) { - Input inputs[MAXCONTROLLERS]; - Input* input = &inputs[0]; - u32 ocarinaInputButtonPrev = sOcarinaInputButtonCur; - - PadMgr_RequestPadData(&gPadMgr, inputs, false); - sOcarinaInputButtonCur = input->cur.button; - sOcarinaInputButtonPrev = ocarinaInputButtonPrev; - sOcarinaInputStickAdj.x = input->rel.stick_x; - sOcarinaInputStickAdj.y = input->rel.stick_y; -} - -/** - * Looks up the frequency to bend the pitch by. - * The pitch will bend up to a maximum of 2 semitones - * in each direction giving a total range of 4 semitones - */ -f32 AudioOcarina_BendPitchTwoSemitones(s8 bendIndex) { - s8 adjBendIndex; - f32 bendFreq; - - if (bendIndex > 64) { - adjBendIndex = 127; - } else if (bendIndex < -64) { - adjBendIndex = -128; - } else if (bendIndex >= 0) { - adjBendIndex = (bendIndex * 127) / 64; - } else { - adjBendIndex = (bendIndex * 128) / 64; - } - - /** - * index 128 is in the middle of the table and - * contains the value 1.0f i.e. no bend - * absolute indices above 128 will bend the pitch 2 semitones upwards - * absolute indices below 128 will bend the pitch 2 semitones downwards - */ - bendFreq = gBendPitchTwoSemitonesFrequencies[adjBendIndex + 128]; - return bendFreq; -} - -/** - * If an available song has been played, then return that song index - * If the ocarina is on, but no song has been played then return 0xFE - * If the ocarina is off, return 0xFF - */ -u8 AudioOcarina_GetPlayingState(void) { - u8 playedOcarinaSongIndex; - - if (sPlayedOcarinaSongIndexPlusOne != 0) { - playedOcarinaSongIndex = sPlayedOcarinaSongIndexPlusOne - 1; - sPlayedOcarinaSongIndexPlusOne = 0; - } else if (sOcarinaFlags != 0) { - playedOcarinaSongIndex = 0xFE; - } else { - playedOcarinaSongIndex = 0xFF; - } - - return playedOcarinaSongIndex; -} - -u8 AudioOcarina_MapNoteToButton(u8 pitchAndBFlatFlag) { - u8 buttonIndex = sPitchToButtonMap[pitchAndBFlatFlag & 0x3F]; - - /** - * Special case for bFlat4: - * CRIGHT and CLEFT are the only two pitches that are 2 semitones apart - * which are pitches A4 and B4 respectively - * bFlat4 is in the middle of those two and is the only pitches that can not - * be resolved between the two buttons without external information. - * That information is stored as flags in pitch with the mask: - * (pitchAndBFlatFlag & 0xC0) - */ - if (buttonIndex == OCARINA_BTN_C_RIGHT_OR_C_LEFT) { - if (pitchAndBFlatFlag & 0x80) { - return OCARINA_BTN_C_RIGHT; - } - return OCARINA_BTN_C_LEFT; - } - - return buttonIndex; -} - -void AudioOcarina_MapNotesToScarecrowButtons(u8 noteSongIndex) { - u8 buttonSongPos = 0; - u8 noteSongPos = 0; - u8 pitch; - - while (buttonSongPos < 8 && noteSongPos < 16) { - pitch = sOcarinaSongNotes[noteSongIndex][noteSongPos++].pitch; - - if (pitch != OCARINA_PITCH_NONE) { - gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonsIndex[buttonSongPos++] = sPitchToButtonMap[pitch]; - } - } -} - -/** - * Ocarina flags: - * bitmask 0x3FFF: - * - Ocarina song id - * bitmask 0xC000: - * - 0x0000: Limits the notes to 8 notes at a time. Not playing a correct song after 8 notes will cause an ocarina - * error - * - 0x4000: (Identical to 0xC000) - * - 0x8000: Limits the notes to 1 note at a time. A single incorrect note will cause an ocarina error - * - 0xC000: Free-play, no limitations to the number of notes to play - * bitmask 0x7FFF0000: - * - ocarina action (only used to make flags != 0) - * bitmask 0x80000000: - * - unused (only used to make flags != 0) - */ -void AudioOcarina_Start(u16 ocarinaFlags) { - u8 i; - - if ((sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF) && ((ocarinaFlags & 0xFFF) == 0xFFF)) { - ocarinaFlags |= 0x1000; - } - - if ((ocarinaFlags == 0xCFFF) && (sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF)) { - ocarinaFlags = 0xDFFF; - } - - if ((ocarinaFlags == 0xFFF) && (sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF)) { - ocarinaFlags = 0x1FFF; - } - - if (ocarinaFlags != 0xFFFF) { - sOcarinaFlags = 0x80000000 + (u32)ocarinaFlags; - sFirstOcarinaSongIndex = 0; - sLastOcarinaSongIndex = OCARINA_SONG_MAX; - if (ocarinaFlags != 0xA000) { - sLastOcarinaSongIndex--; - } - sAvailOcarinaSongFlags = ocarinaFlags & 0x3FFF; - sMusicStaffNumNotesPerTest = 8; // Ocarina Check - sOcarinaHasStartedSong = false; - sPlayedOcarinaSongIndexPlusOne = 0; - sStaffOcarinaPlayingPos = 0; - sPlayingStaff.state = AudioOcarina_GetPlayingState(); - sIsOcarinaInputEnabled = true; - sPrevOcarinaWithMusicStaffFlags = 0; - - // Reset music staff song check - for (i = 0; i < OCARINA_SONG_MAX; i++) { - sMusicStaffPos[i] = 0; - sMusicStaffCurHeldLength[i] = 0; - sMusicStaffExpectedLength[i] = 0; - sMusicStaffExpectedPitch[i] = 0; - } - - if (ocarinaFlags & 0x8000) { - sMusicStaffNumNotesPerTest = 0; // Ocarina Playback - } - - if (ocarinaFlags & 0x4000) { - sOcarinaWithoutMusicStaffPos = 0; - } - - if (ocarinaFlags & 0xD000) { - AudioOcarina_MapNotesToScarecrowButtons(OCARINA_SONG_SCARECROW_SPAWN); - } - } else { - sOcarinaFlags = 0; - sIsOcarinaInputEnabled = false; - } -} - -void AudioOcarina_CheckIfStartedSong(void) { - if (sCurOcarinaPitch != OCARINA_PITCH_NONE && !sOcarinaHasStartedSong) { - sOcarinaHasStartedSong = true; - sMusicStaffPrevPitch = OCARINA_PITCH_NONE; - } -} - -/** - * Checks for ocarina songs from user input with a music staff prompt - * Type 1) Playback: tests note-by-note (ocarinaFlag & 0xC000 == 0x8000) eg: - * - learning a new song - * - playing the ocarina memory game - * Type 2) Check: tests in 8-note chunks (ocarinaFlag & 0xC000 == 0x0000) eg: - * - validating scarecrow spawn song as adult - * - ocarina prompt for zelda's lullaby, saria's song, Storms, Song of Time, etc... - */ -void AudioOcarina_CheckSongsWithMusicStaff(void) { - u16 curOcarinaSongFlag; - u16 pad; - u8 noNewValidInput = false; - u16 pad2; - s8 staffOcarinaPlayingPosOffset = 0; - u8 songIndex; - OcarinaNote* curNote; - OcarinaNote* nextNote; - - AudioOcarina_CheckIfStartedSong(); - - if (!sOcarinaHasStartedSong) { - return; - } - - if (ABS_ALT(sCurOcarinaBendIndex) > 20) { - sOcarinaFlags = 0; - return; - } - - // clang-format off - if (sPrevOcarinaPitch == sCurOcarinaPitch || sCurOcarinaPitch == OCARINA_PITCH_NONE) { noNewValidInput = true; } - // clang-format on - - for (songIndex = sFirstOcarinaSongIndex; songIndex < sLastOcarinaSongIndex; songIndex++) { - curOcarinaSongFlag = 1 << songIndex; - - if (sAvailOcarinaSongFlags & curOcarinaSongFlag) { - sMusicStaffCurHeldLength[songIndex] = sMusicStaffExpectedLength[songIndex] + 18; - - if (noNewValidInput) { - if ((sMusicStaffCurHeldLength[songIndex] >= sMusicStaffExpectedLength[songIndex] - 18) && - (sMusicStaffCurHeldLength[songIndex] >= sMusicStaffExpectedLength[songIndex] + 18) && - (sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]].length == 0) && - (sMusicStaffPrevPitch == sMusicStaffExpectedPitch[songIndex])) { - // This case is taken if the song is finished and successfully played - // (i.e. .length == 0 indicates that the song is at the end) - sPlayedOcarinaSongIndexPlusOne = songIndex + 1; - sIsOcarinaInputEnabled = false; - sOcarinaFlags = 0; - } - } else if (sMusicStaffCurHeldLength[songIndex] >= (sMusicStaffExpectedLength[songIndex] - 18)) { - // This else-if statement always holds true, taken if a new note is played - if (sMusicStaffPrevPitch != OCARINA_PITCH_NONE) { - // New note is played - if (sMusicStaffPrevPitch == sMusicStaffExpectedPitch[songIndex]) { - // Note is part of expected song - if (songIndex == OCARINA_SONG_SCARECROW_SPAWN) { - sMusicStaffCurHeldLength[songIndex] = 0; - } - } else { - // Note is not part of expected song, so this song is no longer available as an option in this - // playback - sAvailOcarinaSongFlags ^= curOcarinaSongFlag; - } - } - - curNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]]; - nextNote = &sOcarinaSongNotes[songIndex][++sMusicStaffPos[songIndex]]; - sMusicStaffExpectedLength[songIndex] = curNote->length; - sMusicStaffExpectedPitch[songIndex] = curNote->pitch; - - // The current note is not the expected note. - if (sCurOcarinaPitch != sMusicStaffExpectedPitch[songIndex]) { - sAvailOcarinaSongFlags ^= curOcarinaSongFlag; - } - - while (curNote->pitch == nextNote->pitch || - (nextNote->pitch == OCARINA_BTN_INVALID && nextNote->length != 0)) { - sMusicStaffExpectedLength[songIndex] += nextNote->length; - curNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]]; - nextNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex] + 1]; - sMusicStaffPos[songIndex]++; - } - } else if (sMusicStaffCurHeldLength[songIndex] < 10) { - // case never taken - staffOcarinaPlayingPosOffset = -1; - sMusicStaffCurHeldLength[songIndex] = 0; - sMusicStaffPrevPitch = sCurOcarinaPitch; - } else { - // case never taken - sAvailOcarinaSongFlags ^= curOcarinaSongFlag; - } - } - - // if a note is played that doesn't match a song, the song bit in sAvailOcarinaSongFlags is turned off - // if there are no more songs remaining that it could be and the maximum position has been exceeded, then - if (sAvailOcarinaSongFlags == 0 && sStaffOcarinaPlayingPos >= sMusicStaffNumNotesPerTest) { - sIsOcarinaInputEnabled = false; - if ((sOcarinaFlags & 0x4000) && sCurOcarinaPitch == sOcarinaSongNotes[songIndex][0].pitch) { - // case never taken, this function is not called if (sOcarinaFlags & 0x4000) is set - sPrevOcarinaWithMusicStaffFlags = sOcarinaFlags; - } - sOcarinaFlags = 0; - return; - } - } - - if (!noNewValidInput) { - sMusicStaffPrevPitch = sCurOcarinaPitch; - sStaffOcarinaPlayingPos += staffOcarinaPlayingPosOffset + 1; - } -} - -/** - * Checks for ocarina songs from user input with no music staff prompt. - * Includes ocarina actions such as free play, no warp - */ -void AudioOcarina_CheckSongsWithoutMusicStaff(void) { - u32 pitch; - u8 i; - u8 j; - u8 k; - - if (CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_L) && - CHECK_BTN_ANY(sOcarinaInputButtonCur, sOcarinaAllowedButtonMask)) { - AudioOcarina_Start((u16)sOcarinaFlags); - return; - } - - AudioOcarina_CheckIfStartedSong(); - - if (!sOcarinaHasStartedSong) { - return; - } - - if ((sPrevOcarinaPitch != sCurOcarinaPitch) && (sCurOcarinaPitch != OCARINA_PITCH_NONE)) { - sStaffOcarinaPlayingPos++; - if (sStaffOcarinaPlayingPos > ARRAY_COUNT(sCurOcarinaSongWithoutMusicStaff)) { - sStaffOcarinaPlayingPos = 1; - } - - if (sOcarinaWithoutMusicStaffPos == 8) { - for (i = 0; i < 7; i++) { - sCurOcarinaSongWithoutMusicStaff[i] = sCurOcarinaSongWithoutMusicStaff[i + 1]; - } - } else { - sOcarinaWithoutMusicStaffPos++; - } - - if (ABS_ALT(sCurOcarinaBendIndex) > 20) { - sCurOcarinaSongWithoutMusicStaff[sOcarinaWithoutMusicStaffPos - 1] = OCARINA_PITCH_NONE; - } else { - sCurOcarinaSongWithoutMusicStaff[sOcarinaWithoutMusicStaffPos - 1] = sCurOcarinaPitch; - } - - // This nested for-loop tests to see if the notes from the ocarina are identical - // to any of the songIndex from sFirstOcarinaSongIndex to sLastOcarinaSongIndex - - // Loop through each of the songs - for (i = sFirstOcarinaSongIndex; i < sLastOcarinaSongIndex; i++) { - // Checks to see if the song is available to be played - if (sAvailOcarinaSongFlags & (u16)(1 << i)) { - for (j = 0, k = 0; j < gOcarinaSongButtons[i].numButtons && k == 0 && - sOcarinaWithoutMusicStaffPos >= gOcarinaSongButtons[i].numButtons;) { - pitch = sCurOcarinaSongWithoutMusicStaff[sOcarinaWithoutMusicStaffPos - - gOcarinaSongButtons[i].numButtons + j]; - if (pitch == sButtonToPitchMap[gOcarinaSongButtons[i].buttonsIndex[j]]) { - j++; - } else { - k++; - } - } - - // This conditional is true if songIndex = i is detected - if (j == gOcarinaSongButtons[i].numButtons) { - sPlayedOcarinaSongIndexPlusOne = i + 1; - sIsOcarinaInputEnabled = false; - sOcarinaFlags = 0; - } - } - } - } -} - -// This unused argument is used in Majora's Mask as a u8 -void AudioOcarina_PlayControllerInput(u8 unused) { - u32 ocarinaBtnsHeld; - - // Prevents two different ocarina notes from being played on two consecutive frames - if ((sOcarinaFlags != 0) && (sOcarinaDropInputTimer != 0)) { - sOcarinaDropInputTimer--; - return; - } - - // Ensures the button pressed to start the ocarina does not also play an ocarina note - if ((sOcarinaInputButtonStart == 0) || ((sOcarinaInputButtonStart & sOcarinaAllowedButtonMask) != - (sOcarinaInputButtonCur & sOcarinaAllowedButtonMask))) { - sOcarinaInputButtonStart = 0; - if (1) {} - sCurOcarinaPitch = OCARINA_PITCH_NONE; - sCurOcarinaButtonIndex = OCARINA_BTN_INVALID; - ocarinaBtnsHeld = (sOcarinaInputButtonCur & sOcarinaAllowedButtonMask) & - (sOcarinaInputButtonPrev & sOcarinaAllowedButtonMask); - if (!(sOcarinaInputButtonPress & ocarinaBtnsHeld) && (sOcarinaInputButtonCur != 0)) { - sOcarinaInputButtonPress = sOcarinaInputButtonCur; - } else { - sOcarinaInputButtonPress &= ocarinaBtnsHeld; - } - - // Interprets and transforms controller input into ocarina buttons and notes - if (CHECK_BTN_ANY(sOcarinaInputButtonPress, sOcarinaAButtonMap)) { - osSyncPrintf("Presss NA_KEY_D4 %08x\n", sOcarinaAButtonMap); - sCurOcarinaPitch = OCARINA_PITCH_D4; - sCurOcarinaButtonIndex = OCARINA_BTN_A; - - } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, sOcarinaCDownButtonMap)) { - osSyncPrintf("Presss NA_KEY_F4 %08x\n", sOcarinaCDownButtonMap); - sCurOcarinaPitch = OCARINA_PITCH_F4; - sCurOcarinaButtonIndex = OCARINA_BTN_C_DOWN; - - } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CRIGHT)) { - osSyncPrintf("Presss NA_KEY_A4 %08x\n", BTN_CRIGHT); - sCurOcarinaPitch = OCARINA_PITCH_A4; - sCurOcarinaButtonIndex = OCARINA_BTN_C_RIGHT; - - } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CLEFT)) { - osSyncPrintf("Presss NA_KEY_B4 %08x\n", BTN_CLEFT); - sCurOcarinaPitch = OCARINA_PITCH_B4; - sCurOcarinaButtonIndex = OCARINA_BTN_C_LEFT; - - } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, sOcarinaCUpButtonMap)) { - osSyncPrintf("Presss NA_KEY_D5 %08x\n", sOcarinaCUpButtonMap); - sCurOcarinaPitch = OCARINA_PITCH_D5; - sCurOcarinaButtonIndex = OCARINA_BTN_C_UP; - } - - // Pressing the R Button will raise the pitch by 1 semitone - if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_R) && - (sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN)) { - sCurOcarinaButtonIndex += 0x80; // Flag to resolve B Flat 4 - sCurOcarinaPitch++; // Raise the pitch by 1 semitone - } - - // Pressing the Z Button will lower the pitch by 1 semitone - if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_Z) && - (sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN)) { - sCurOcarinaButtonIndex += 0x40; // Flag to resolve B Flat 4 - sCurOcarinaPitch--; // Lower the pitch by 1 semitone - } - - if (sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN) { - // Bend the pitch of the note based on y control stick - sCurOcarinaBendIndex = sOcarinaInputStickAdj.y; - sCurOcarinaBendFreq = AudioOcarina_BendPitchTwoSemitones(sCurOcarinaBendIndex); - - // Add vibrato of the ocarina note based on the x control stick - sCurOcarinaVibrato = ABS_ALT(sOcarinaInputStickAdj.x) >> 2; - // Sets vibrato to io port 6 - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 6, sCurOcarinaVibrato); - } else { - // no bending or vibrato for recording state OCARINA_RECORD_SCARECROW_SPAWN - sCurOcarinaBendIndex = 0; - sCurOcarinaBendFreq = 1.0f; // No bend - } - - // Processes new and valid notes - if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && (sPrevOcarinaPitch != sCurOcarinaPitch)) { - // Sets ocarina instrument Id to channelIdx io port 7, which is used - // as an index in seq 0 to get the true instrument Id - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 7, sOcarinaInstrumentId - 1); - // Sets pitch to io port 5 - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5, sCurOcarinaPitch); - Audio_PlaySfxGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sCurOcarinaBendFreq, &sRelativeOcarinaVolume, - &gSfxDefaultReverb); - } else if ((sPrevOcarinaPitch != OCARINA_PITCH_NONE) && (sCurOcarinaPitch == OCARINA_PITCH_NONE)) { - // Stops ocarina sound when transitioning from playing to not playing a note - Audio_StopSfxById(NA_SE_OC_OCARINA); - } - } -} - -/** - * Directly enable the ocarina to receive input without - * properly resetting it based on an ocarina instrument id - * Unused. - */ -void AudioOcarina_EnableInput(u8 inputEnabled) { - sIsOcarinaInputEnabled = inputEnabled; -} - -/** - * Resets ocarina properties based on the ocarina instrument id - * If ocarina instrument id is "OCARINA_INSTRUMENT_OFF", turn off the ocarina - * For all ocarina instrument ids, turn the ocarina on with the instrument id - */ -void AudioOcarina_SetInstrument(u8 ocarinaInstrumentId) { - if (sOcarinaInstrumentId == ocarinaInstrumentId) { - return; - } - - SEQCMD_SET_CHANNEL_IO(SEQ_PLAYER_SFX, SFX_CHANNEL_OCARINA, 1, ocarinaInstrumentId); - sOcarinaInstrumentId = ocarinaInstrumentId; - if (ocarinaInstrumentId == OCARINA_INSTRUMENT_OFF) { - sOcarinaInputButtonCur = 0; - sOcarinaInputButtonPrev = 0; - sOcarinaInputButtonPress = 0; - - sOcarinaInputButtonStart = 0xFFFF; - - AudioOcarina_PlayControllerInput(false); - Audio_StopSfxById(NA_SE_OC_OCARINA); - Audio_SetSfxBanksMute(0); - sPlaybackState = 0; - sPlaybackStaffPos = 0; - sIsOcarinaInputEnabled = false; - sOcarinaFlags = 0; - // return to full volume for players 0 and 3 (background bgm) after ocarina is finished - Audio_ClearBGMMute(SFX_CHANNEL_OCARINA); - } else { - sOcarinaInputButtonCur = 0; - AudioOcarina_ReadControllerInput(); - // Store button used to turn on ocarina - sOcarinaInputButtonStart = sOcarinaInputButtonCur; - // lowers volumes of players 0 and 3 (background bgm) while playing ocarina - Audio_QueueSeqCmdMute(SFX_CHANNEL_OCARINA); - } -} - -void AudioOcarina_SetPlaybackSong(s8 songIndexPlusOne, s8 playbackState) { - if (songIndexPlusOne == 0) { - sPlaybackState = 0; - Audio_StopSfxById(NA_SE_OC_OCARINA); - return; - } - - if (songIndexPlusOne < (OCARINA_SONG_SCARECROW_LONG + 1)) { - sPlaybackSong = sOcarinaSongNotes[songIndexPlusOne - 1]; - } else { - sPlaybackSong = sScarecrowsLongSongNotes; - } - - sPlaybackState = playbackState; - sPlaybackNoteTimer = 0; - sPlaybackPitch = OCARINA_PITCH_NONE; - sPlaybackNotePos = 0; - sPlaybackStaffPos = 0; - - while (sPlaybackSong[sPlaybackNotePos].pitch == OCARINA_PITCH_NONE) { - sPlaybackNotePos++; - } -} - -/** - * Play a song with the ocarina to the user that is - * based on OcarinaNote data and not user input - */ -void AudioOcarina_PlaybackSong(void) { - u32 noteTimerStep; - u32 nextNoteTimerStep; - - if (sPlaybackState == 0) { - return; - } - - if (sPlaybackStaffPos == 0) { - noteTimerStep = 3; - } else { - noteTimerStep = sOcarinaUpdateTaskStart - sOcarinaPlaybackTaskStart; - } - - if (noteTimerStep < sPlaybackNoteTimer) { - sPlaybackNoteTimer -= noteTimerStep; - } else { - nextNoteTimerStep = noteTimerStep - sPlaybackNoteTimer; - sPlaybackNoteTimer = 0; - } - - if (sPlaybackNoteTimer == 0) { - - sPlaybackNoteTimer = sPlaybackSong[sPlaybackNotePos].length; - - if (sPlaybackNotePos == 1) { - sPlaybackNoteTimer++; - } - - if (sPlaybackNoteTimer == 0) { - sPlaybackState--; - if (sPlaybackState != 0) { - sPlaybackNotePos = 0; - sPlaybackStaffPos = 0; - sPlaybackPitch = OCARINA_PITCH_NONE; - } else { - Audio_StopSfxById(NA_SE_OC_OCARINA); - } - return; - } else { - sPlaybackNoteTimer -= nextNoteTimerStep; - } - - // Update volume - if (sNotePlaybackVolume != sPlaybackSong[sPlaybackNotePos].volume) { - sNotePlaybackVolume = sPlaybackSong[sPlaybackNotePos].volume; - sRelativeNotePlaybackVolume = sNotePlaybackVolume / 127.0f; - } - - // Update vibrato - if (sNotePlaybackVibrato != sPlaybackSong[sPlaybackNotePos].vibrato) { - sNotePlaybackVibrato = sPlaybackSong[sPlaybackNotePos].vibrato; - // Sets vibrato to io port 6 - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 6, sNotePlaybackVibrato); - } - - // Update bend - if (sNotePlaybackBend != sPlaybackSong[sPlaybackNotePos].bend) { - sNotePlaybackBend = sPlaybackSong[sPlaybackNotePos].bend; - sRelativeNotePlaybackBend = AudioOcarina_BendPitchTwoSemitones(sNotePlaybackBend); - } - - // No changes in volume, vibrato, or bend between notes - if ((sPlaybackSong[sPlaybackNotePos].volume == sPlaybackSong[sPlaybackNotePos - 1].volume && - (sPlaybackSong[sPlaybackNotePos].vibrato == sPlaybackSong[sPlaybackNotePos - 1].vibrato) && - (sPlaybackSong[sPlaybackNotePos].bend == sPlaybackSong[sPlaybackNotePos - 1].bend))) { - sPlaybackPitch = 0xFE; - } - - if (sPlaybackPitch != sPlaybackSong[sPlaybackNotePos].pitch) { - u8 pitch = sPlaybackSong[sPlaybackNotePos].pitch; - - // As bFlat4 is exactly in the middle of notes B & A, a flag is - // added to the pitch to resolve which button to map Bflat4 to - if (pitch == OCARINA_PITCH_BFLAT4) { - sPlaybackPitch = pitch + sPlaybackSong[sPlaybackNotePos].bFlat4Flag; - } else { - sPlaybackPitch = pitch; - } - - if (sPlaybackPitch != OCARINA_PITCH_NONE) { - sPlaybackStaffPos++; - // Sets ocarina instrument Id to channelIdx io port 7, which is used - // as an index in seq 0 to get the true instrument Id - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 7, - sOcarinaInstrumentId - 1); - // Sets sPlaybackPitch to channelIdx io port 5 - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | SFX_CHANNEL_OCARINA << 8 | 5, - sPlaybackPitch & 0x3F); - Audio_PlaySfxGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sRelativeNotePlaybackBend, - &sRelativeNotePlaybackVolume, &gSfxDefaultReverb); - } else { - Audio_StopSfxById(NA_SE_OC_OCARINA); - } - } - sPlaybackNotePos++; - } -} - -void AudioOcarina_SetRecordingSong(u8 isRecordingComplete) { - u16 i; - u16 i2; - u16 pad; - u8 pitch; - OcarinaNote* note; - u8 j; - u8 k; - s32 t; - OcarinaNote* recordedSong; - - if (sRecordingState == OCARINA_RECORD_SCARECROW_LONG) { - recordedSong = gScarecrowLongSongPtr; - } else { - /** - * OCARINA_RECORD_SCARECROW_SPAWN - * - * The notes for scarecrows spawn song are first recorded into the ocarina memory - * game address to act as a buffer. That way, if a new scarecrow spawn song is - * rejected, the previous scarecrow spawn song is not overwritten. If the scarecrow - * spawn song is accepted, then the notes are copied over to the scarecrow spawn - * song address - */ - recordedSong = sMemoryGameSongPtr; - } - - recordedSong[sRecordSongPos].pitch = sRecordOcarinaPitch; - recordedSong[sRecordSongPos].length = sOcarinaUpdateTaskStart - sOcarinaRecordTaskStart; - recordedSong[sRecordSongPos].volume = sRecordOcarinaVolume; - recordedSong[sRecordSongPos].vibrato = sRecordOcarinaVibrato; - recordedSong[sRecordSongPos].bend = sRecordOcarinaBendIndex; - recordedSong[sRecordSongPos].bFlat4Flag = sRecordOcarinaButtonIndex & 0xC0; - - sRecordOcarinaPitch = sCurOcarinaPitch; - sRecordOcarinaVolume = sCurOcarinaVolume; - sRecordOcarinaVibrato = sCurOcarinaVibrato; - sRecordOcarinaBendIndex = sCurOcarinaBendIndex; - sRecordOcarinaButtonIndex = sCurOcarinaButtonIndex; - - sRecordSongPos++; - - if ((sRecordSongPos != (ARRAY_COUNT(sScarecrowsLongSongNotes) - 1)) && !isRecordingComplete) { - // Continue recording - return; - } - - // Recording is complete - - i = sRecordSongPos; - pitch = OCARINA_PITCH_NONE; - while (i != 0 && pitch == OCARINA_PITCH_NONE) { - i--; - pitch = recordedSong[i].pitch; - } - - if (1) {} - - if (sRecordSongPos != (i + 1)) { - sRecordSongPos = i + 2; - recordedSong[sRecordSongPos - 1].length = 0; - } - - recordedSong[sRecordSongPos].length = 0; - - if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) { - if (sStaffOcarinaPlayingPos >= 8) { - for (i = 0; i < sRecordSongPos; i++) { - recordedSong[i] = recordedSong[i + 1]; - } - - // Copies Notes from buffer into scarecrows spawn buttons to be tested for acceptance or rejection - AudioOcarina_MapNotesToScarecrowButtons(OCARINA_SONG_MEMORY_GAME); - - // Loop through each of the songs - for (i = 0; i < OCARINA_SONG_SCARECROW_SPAWN; i++) { - // Loops through all possible starting indices - for (j = 0; j < 9 - gOcarinaSongButtons[i].numButtons; j++) { - // Loops through the notes of song i - for (k = 0; k < gOcarinaSongButtons[i].numButtons && k + j < 8 && - gOcarinaSongButtons[i].buttonsIndex[k] == - gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonsIndex[k + j]; - k++) { - ; - } - - // This conditional is true if the recorded song contains a reserved song - if (k == gOcarinaSongButtons[i].numButtons) { - sRecordingState = OCARINA_RECORD_REJECTED; - sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume = 0xFF; - return; - } - } - } - - // Counts how many times a note is repeated - i = 1; - while (i < 8) { - if (gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonsIndex[0] != - gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonsIndex[i]) { - i = 9; // break - } else { - i++; - } - } - - // This condition is true if all 8 notes are the same pitch - if (i == 8) { - sRecordingState = OCARINA_RECORD_REJECTED; - sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume = 0xFF; - return; - } - - // The scarecrow spawn song is accepted and copied from the buffer to the scarecrow spawn notes - for (i = 0; i < sRecordSongPos; i++) { - sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][i] = sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][i]; - } - - sIsOcarinaInputEnabled = false; - } else { - sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume = 0xFF; - } - } - - sRecordingState = OCARINA_RECORD_OFF; -} - -/** - * recordingState = OCARINA_RECORD_OFF, end - * recordingState = OCARINA_RECORD_SCARECROW_LONG, start long scarecrows song - * recordingState = OCARINA_RECORD_SCARECROW_SPAWN, start spawn scarecrows song - */ -void AudioOcarina_SetRecordingState(u8 recordingState) { - if ((u32)recordingState == sRecordingState) { - return; - } - - if (recordingState != OCARINA_RECORD_OFF) { - sOcarinaRecordTaskStart = sOcarinaUpdateTaskStart; - sRecordOcarinaPitch = OCARINA_PITCH_NONE; - sRecordOcarinaVolume = 0x57; - sRecordOcarinaVibrato = 0; - sRecordOcarinaBendIndex = 0; - sRecordOcarinaButtonIndex = 0; - sRecordSongPos = 0; - sIsOcarinaInputEnabled = true; - sStaffOcarinaPlayingPos = 0; - sScarecrowsLongSongSecondNote = sScarecrowsLongSongNotes[1]; - } else { - if (sRecordSongPos == 0) { - sScarecrowsLongSongNotes[1] = sScarecrowsLongSongSecondNote; - } else { - if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) { - sStaffOcarinaPlayingPos = 1; - } - - AudioOcarina_SetRecordingSong(true); - } - - sIsOcarinaInputEnabled = false; - sStaffOcarinaPlayingPos = 0; - } - - sRecordingState = recordingState; -} - -void AudioOcarina_UpdateRecordingStaff(void) { - sRecordingStaff.state = sRecordingState; - sRecordingStaff.pos = sStaffOcarinaPlayingPos; - if (sRecordingState == OCARINA_RECORD_REJECTED) { - sRecordingState = OCARINA_RECORD_OFF; - } -} - -void AudioOcarina_UpdatePlayingStaff(void) { - sPlayingStaff.buttonIndex = sCurOcarinaButtonIndex & 0x3F; - sPlayingStaff.state = AudioOcarina_GetPlayingState(); - sPlayingStaff.pos = sStaffOcarinaPlayingPos; -} - -void AudioOcarina_UpdatePlaybackStaff(void) { - if ((sPlaybackPitch & 0x3F) <= OCARINA_PITCH_EFLAT5) { - sPlaybackStaff.buttonIndex = AudioOcarina_MapNoteToButton(sPlaybackPitch); - } - - sPlaybackStaff.state = sPlaybackState; - - if (sPlaybackSong != sScarecrowsLongSongNotes) { - sPlaybackStaff.pos = sPlaybackStaffPos; - } else if (sPlaybackStaffPos == 0) { - sPlaybackStaff.pos = 0; - } else { - sPlaybackStaff.pos = ((sPlaybackStaffPos - 1) % 8) + 1; - } -} - -OcarinaStaff* AudioOcarina_GetRecordingStaff(void) { - return &sRecordingStaff; -} - -OcarinaStaff* AudioOcarina_GetPlayingStaff(void) { - if (sPlayingStaff.state < 0xFE) { - sOcarinaFlags = 0; - } - - return &sPlayingStaff; -} - -OcarinaStaff* AudioOcarina_GetPlaybackStaff(void) { - return &sPlaybackStaff; -} - -void AudioOcarina_RecordSong(void) { - s32 noteChanged; - - if ((sRecordingState != OCARINA_RECORD_OFF) && ((sOcarinaUpdateTaskStart - sOcarinaRecordTaskStart) >= 3)) { - noteChanged = false; - if (sRecordOcarinaPitch != sCurOcarinaPitch) { - if (sCurOcarinaPitch != OCARINA_PITCH_NONE) { - sRecordingStaff.buttonIndex = sCurOcarinaButtonIndex & 0x3F; - sStaffOcarinaPlayingPos++; - } else if ((sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) && (sStaffOcarinaPlayingPos == 8)) { - AudioOcarina_SetRecordingSong(true); - return; - } - - if (sStaffOcarinaPlayingPos > 8) { - if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) { - // notes played are over 8 and in recording mode. - AudioOcarina_SetRecordingSong(true); - return; - } - sStaffOcarinaPlayingPos = 1; - } - - noteChanged = true; - } else if (sRecordOcarinaVolume != sCurOcarinaVolume) { - noteChanged = true; - } else if (sRecordOcarinaVibrato != sCurOcarinaVibrato) { - noteChanged = true; - } else if (sRecordOcarinaBendIndex != sCurOcarinaBendIndex) { - noteChanged = true; - } - - if (noteChanged) { - AudioOcarina_SetRecordingSong(false); - sOcarinaRecordTaskStart = sOcarinaUpdateTaskStart; - } - } -} - -void AudioOcarina_MemoryGameInit(u8 minigameRound) { - u8 i; - - if (minigameRound > 2) { - minigameRound = 2; - } - - sOcaMemoryGameAppendPos = 0; - sOcaMemoryGameEndPos = sOcaMemoryGameNumNotes[minigameRound]; - - for (i = 0; i < 3; i++) { - AudioOcarina_MemoryGameNextNote(); - } -} - -s32 AudioOcarina_MemoryGameNextNote(void) { - u32 randomButtonIndex; - u8 randomPitch; - - if (sOcaMemoryGameAppendPos == sOcaMemoryGameEndPos) { - return 1; - } - - randomButtonIndex = Audio_NextRandom(); - randomPitch = sButtonToPitchMap[randomButtonIndex % 5]; - - if (sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos - 1].pitch == randomPitch) { - randomPitch = sButtonToPitchMap[(randomButtonIndex + 1) % 5]; - } - - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].pitch = randomPitch; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].length = 45; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].volume = 0x50; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].vibrato = 0; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].bend = 0; - - sOcaMemoryGameAppendPos++; - - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].pitch = OCARINA_PITCH_NONE; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos].length = 0; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos + 1].pitch = OCARINA_PITCH_NONE; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcaMemoryGameAppendPos + 1].length = 0; - if (1) {} - return 0; -} - -void AudioOcarina_Update(void) { - sOcarinaUpdateTaskStart = gAudioCtx.totalTaskCount; - if (sOcarinaInstrumentId != OCARINA_INSTRUMENT_OFF) { - if (sIsOcarinaInputEnabled == true) { - AudioOcarina_ReadControllerInput(); - } - - if ((sPlaybackState == 0) && (sIsOcarinaInputEnabled == true)) { - AudioOcarina_PlayControllerInput(false); - } - - if (sOcarinaFlags != 0) { - if (sOcarinaFlags & 0x4000) { - AudioOcarina_CheckSongsWithoutMusicStaff(); - } else { - AudioOcarina_CheckSongsWithMusicStaff(); - } - } - - AudioOcarina_PlaybackSong(); - sOcarinaPlaybackTaskStart = sOcarinaUpdateTaskStart; - - if (sPlaybackState == 0) { - AudioOcarina_RecordSong(); - } - - if ((sOcarinaFlags != 0) && (sPrevOcarinaPitch != sCurOcarinaPitch)) { - sOcarinaDropInputTimer = 1; // Drops ocarina input for 1 frame - } - - sPrevOcarinaPitch = sCurOcarinaPitch; - } - - AudioOcarina_UpdatePlayingStaff(); - AudioOcarina_UpdatePlaybackStaff(); - AudioOcarina_UpdateRecordingStaff(); -} - -void AudioOcarina_PlayLongScarecrowSong(void) { - static u8 sScarecrowAfterCreditsState = 0; - static u8 sScarecrowAfterCreditsIntrumentId = OCARINA_INSTRUMENT_DEFAULT; - static u16 sScarecrowAfterCreditsTimer = 1200; - - switch (sScarecrowAfterCreditsState) { - case 0: - if (sScarecrowAfterCreditsTimer-- == 0) { - if (sScarecrowAfterCreditsIntrumentId < OCARINA_INSTRUMENT_MAX) { - // set next ocarina instrument and restart - sScarecrowAfterCreditsState++; - } else { - // finished - sScarecrowAfterCreditsState = 3; - AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF); - } - sScarecrowAfterCreditsTimer = 1200; - } - break; - case 1: - Audio_SetSfxBanksMute(0); - AudioOcarina_SetInstrument(sScarecrowAfterCreditsIntrumentId); - AudioOcarina_SetPlaybackSong(OCARINA_SONG_SCARECROW_LONG + 1, 1); - sScarecrowAfterCreditsIntrumentId++; - sScarecrowAfterCreditsState++; - break; - case 2: - if (AudioOcarina_GetPlaybackStaff()->state == 0) { - sScarecrowAfterCreditsState = 0; - } - break; - } -} - -void AudioOcarina_ResetStaffs(void) { - sPlayingStaff.buttonIndex = OCARINA_BTN_INVALID; - sPlayingStaff.state = 0xFF; - sPlayingStaff.pos = 0; - sPlaybackStaff.buttonIndex = OCARINA_BTN_INVALID; - sPlaybackStaff.state = 0; - sPlaybackStaff.pos = 0; - sRecordingStaff.buttonIndex = OCARINA_BTN_INVALID; - sRecordingStaff.state = OCARINA_RECORD_REJECTED; - sRecordingStaff.pos = 0; - sOcarinaDropInputTimer = 0; -} - -f32 D_80131C8C = 0.0f; - -// =========== Audio Debugging =========== - -u32 sDebugPadHold; -u32 sDebugPadBtnLast; -u32 sDebugPadPress; -s32 sAudioUpdateTaskStart; -s32 sAudioUpdateTaskEnd; - -f32 sAudioUpdateDuration = 0.0f; -f32 sAudioUpdateDurationMax = 0.0f; -u8 sAudioDebugEverOpened = 0; -u8 sAudioSfxMuted = 0; -u8 sAudioDebugPage = 0; -u8 sAudioSndContSel = 0; -u8 sAudioDebugTextColor = 7; -char sAudioDebugPageNames[15][23] = { - "Non", - "Sound Control", - "Spec Info", - "Heap Info", - "Grp Track Info", - "Sub Track Info", - "Channel Info", - "Interface Info", - "SE Flag Swap", - "Block Change BGM", - "Natural Sound Control", - "Ocarina Test", - "SE Parameter Change", - "Scroll Print", - "Free Area", -}; -u16 sAudioSndContWork[11] = { 0 }; -u16 sAudioSndContWorkLims[11] = { 128, 128, 7, 512, 4, 2, 16, 32, 2, 2, 2 }; -char sSfxBankNames[7][11] = { "PLAYER", "ITEM", "ENVIROMENT", "ENEMY", "SYSTEM", "OCARINA", "VOICE" }; -char sSoundModeNames[5][10] = { "W-STEREO", "HEADPHONE", "3D SOUND", "MONO", "" }; -s8 sAudioIntInfoX = 0; -s8 sAudioIntInfoY = 0; -s8 sAudioIntInfoSel = 0; -s8 sAudioIntInfoBankPage[7] = { 0, 0, 2, 2, 0, 0, 0 }; -u8 sAudioScrPrtSel = 0; -u8 sAudioScrPrtInd = 0; -u8 sAudioScrPrtOverflow = 0; -s8 sAudioScrPrtX = 26; -s8 sAudioScrPrtY = 1; -u8 sAudioScrPrtWork[11] = { 1, 19, 6, 0, 0, 0, 0, 0, 0, 0, 1 }; -u8 sAudioScrPrtWorkLims[11] = { 2, SCROLL_PRINT_BUF_SIZE, 8, 2, 2, 2, 2, 2, 2, 2, 2 }; -u8 sAudioSubTrackInfoSpec = 0; -u8 sAudioSfxSwapIsEditing = 0; -u8 sAudioSfxSwapSel = 0; -u8 sAudioSfxSwapNibbleSel = 0; -char sAudioSfxSwapModeNames[2][5] = { "SWAP", "ADD" }; -u8 sAudioSfxParamChgSel = 0; -u8 sAudioSfxParamChgBitSel = 0; -u16 sAudioSfxParamChgWork[4] = { 0 }; -u8 sAudioSubTrackInfoPlayerSel = SEQ_PLAYER_BGM_MAIN; -u8 sAudioSubTrackInfoChannelSel = 0; -u8 sSeqPlayerPeakNumLayers[20] = { 0 }; -char sAudioSceneNames[3][2] = { "A", "S", "X" }; -u8 sAudioBlkChgBgmWork[2] = { 0 }; -u8 sAudioBlkChgBgmSel = 0; -char sBoolStrs[3][5] = { "OFF", "ON", "STBY" }; -u8 sAudioNatureFailed = false; -u8 sPeakNumNotes = 0; - -void AudioDebug_SetInput(void) { - Input inputs[MAXCONTROLLERS]; - u32 btn; - - PadMgr_RequestPadData(&gPadMgr, inputs, false); - btn = inputs[3].cur.button; - sDebugPadHold = btn & 0xFFFF; - sDebugPadPress = (btn ^ sDebugPadBtnLast) & btn; - sDebugPadBtnLast = btn; -} - -char* AudioDebug_ToStringBinary(u32 num, u8 bits) { - u8 i; - u32 flg = 1; - - for (i = 0; i < bits; flg *= 2, i++) { - if (num & flg) { - sBinToStrBuf[bits - i - 1] = '1'; - } else { - sBinToStrBuf[bits - i - 1] = '0'; - } - } - - sBinToStrBuf[bits] = '\0'; - return sBinToStrBuf; -} - -void AudioDebug_Draw(GfxPrint* printer) { - s32 pad[3]; - u8 i; - u8 j; - u8 ctr; - u8 ctr2; - s8 k; - s8 k2; - s8 ind; - u8 numEnabledNotes = 0; - char digitStr[2] = "1"; - -#define SETCOL_COMMON(v, r, g, b) \ - GfxPrint_SetColor(printer, ((v & 4) >> 2) * (r), ((v & 2) >> 1) * (g), (v & 1) * (b), 255) -#define SETCOL(r, g, b) SETCOL_COMMON(sAudioDebugTextColor, r, g, b) -#define SETCOL_SCROLLPRINT(r, g, b) SETCOL_COMMON(sAudioScrPrtWork[2], r, g, b) - - sAudioDebugEverOpened = true; - GfxPrint_SetPos(printer, 3, 2); - SETCOL(255, 255, 255); - GfxPrint_Printf(printer, "Audio Debug Mode"); - - GfxPrint_SetPos(printer, 3, 3); - GfxPrint_Printf(printer, "- %s -", sAudioDebugPageNames[sAudioDebugPage]); - - for (i = 0; i < gAudioSpecs[gAudioSpecId].numNotes; i++) { - if (gAudioCtx.notes[i].noteSubEu.bitField0.enabled == 1) { - numEnabledNotes++; - } - } - - if (sPeakNumNotes < numEnabledNotes) { - sPeakNumNotes = numEnabledNotes; - } - if (sAudioSpecPeakNumNotes[gAudioSpecId] < numEnabledNotes) { - sAudioSpecPeakNumNotes[gAudioSpecId] = numEnabledNotes; - } - - if (sAudioScrPrtWork[0] != 0) { - GfxPrint_SetPos(printer, sAudioScrPrtX, sAudioScrPrtY); - SETCOL_SCROLLPRINT(200, 200, 200); - GfxPrint_Printf(printer, "Audio ScrPrt"); - - ind = sAudioScrPrtInd; - for (k = 0; k < sAudioScrPrtWork[1] + 1; k++) { - if (ind == 0) { - if (sAudioScrPrtOverflow == 1) { - ind = SCROLL_PRINT_BUF_SIZE - 1; - } else { - k = sAudioScrPrtWork[1] + 1; // "break;" - } - } else { - ind--; - } - if (k != sAudioScrPrtWork[1] + 1) { - if ((ind % 5) != 0) { - SETCOL_SCROLLPRINT(180, 180, 180); - } else { - SETCOL_SCROLLPRINT(120, 120, 120); - } - GfxPrint_SetPos(printer, 2 + sAudioScrPrtX, sAudioScrPrtY + sAudioScrPrtWork[1] + 1 - k); - GfxPrint_Printf(printer, "%s", sAudioScrPrtBuf[ind].str); - - GfxPrint_SetPos(printer, 7 + sAudioScrPrtX, sAudioScrPrtY + sAudioScrPrtWork[1] + 1 - k); - GfxPrint_Printf(printer, "%04X", sAudioScrPrtBuf[ind].num); - } - } - } - - switch (sAudioDebugPage) { - case PAGE_NON: - GfxPrint_SetPos(printer, 3, 4); - SETCOL(255, 64, 64); - GfxPrint_Printf(printer, "BGM CANCEL:%s", sBoolStrs[sAudioSndContWork[5]]); - - GfxPrint_SetPos(printer, 3, 5); - GfxPrint_Printf(printer, "SE MUTE:%s", sBoolStrs[sAudioSfxMuted]); - - GfxPrint_SetPos(printer, 18, 4); - SETCOL(255, 255, 255); - GfxPrint_Printf(printer, "PUSH CONT-4 A-BTN"); - - ind = (s8)sAudioSndContWork[2]; - i = gSfxBanks[ind][0].next; - j = 0; - SETCOL(255, 255, 255); - GfxPrint_SetPos(printer, 3, 6); - GfxPrint_Printf(printer, "SE HANDLE:%s", sSfxBankNames[ind]); - - while (i != 0xFF) { - GfxPrint_SetPos(printer, 3, 7 + j++); - GfxPrint_Printf(printer, "%02x %04x %02x %08x", i, gSfxBanks[ind][i].sfxId, gSfxBanks[ind][i].state, - gSfxBanks[ind][i].priority); - i = gSfxBanks[ind][i].next; - } - break; - - case PAGE_SOUND_CONTROL: - GfxPrint_SetPos(printer, 2, 4 + sAudioSndContSel); - SETCOL(127, 255, 127); - GfxPrint_Printf(printer, "*"); - - SETCOL(255, 255, 255); - GfxPrint_SetPos(printer, 3, 4); - GfxPrint_Printf(printer, "Seq 0 : %2x", sAudioSndContWork[0]); - - GfxPrint_SetPos(printer, 3, 5); - GfxPrint_Printf(printer, "Seq 1 : %2x", sAudioSndContWork[1]); - - GfxPrint_SetPos(printer, 3, 6); - GfxPrint_Printf(printer, "SE HD : %2x %s", sAudioSndContWork[2], sSfxBankNames[sAudioSndContWork[2]]); - - GfxPrint_SetPos(printer, 3, 7); - GfxPrint_Printf(printer, "SE No. :%3x", sAudioSndContWork[3]); - - GfxPrint_SetPos(printer, 3, 8); - GfxPrint_Printf(printer, "S-Out : %2x %s", sAudioSndContWork[4], sSoundModeNames[sAudioSndContWork[4]]); - - GfxPrint_SetPos(printer, 3, 9); - GfxPrint_Printf(printer, "BGM Ent: %2x", sAudioSndContWork[5]); - - GfxPrint_SetPos(printer, 3, 10); - GfxPrint_Printf(printer, "Spec : %2x", sAudioSndContWork[6]); - - GfxPrint_SetPos(printer, 3, 11); - GfxPrint_Printf(printer, "Na Snd : %2x", sAudioSndContWork[7]); - - GfxPrint_SetPos(printer, 3, 12); - GfxPrint_Printf(printer, "Cam Wt : %s", sBoolStrs[sAudioSndContWork[8]]); - - GfxPrint_SetPos(printer, 3, 13); - GfxPrint_Printf(printer, "Lnk Wt : %s", sBoolStrs[sAudioSndContWork[9]]); - - GfxPrint_SetPos(printer, 3, 14); - GfxPrint_Printf(printer, "SE Ent : %2x", sAudioSndContWork[10]); - break; - - case PAGE_INTERFACE_INFO: - ind = 0; - for (k = 0; k < 7; k++) { - if (k == sAudioIntInfoSel) { - SETCOL(255, 127, 127); - } else { - SETCOL(255, 255, 255); - } - GfxPrint_SetPos(printer, 2 + sAudioIntInfoX, 4 + ind + sAudioIntInfoY); - GfxPrint_Printf(printer, "%s <%d>", sSfxBankNames[k], sAudioIntInfoBankPage[k]); - - for (k2 = 0; k2 < gChannelsPerBank[gSfxChannelLayout][k]; k2++) { -#define entryIndex (gActiveSfx[k][k2].entryIndex) -#define entry (&gSfxBanks[k][entryIndex]) -#define chan (gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[entry->channelIdx]) - GfxPrint_SetPos(printer, 2 + sAudioIntInfoX, 5 + ind + sAudioIntInfoY); - if (sAudioIntInfoBankPage[k] == 1) { - if ((entryIndex != 0xFF) && - ((entry->state == SFX_STATE_PLAYING_1) || (entry->state == SFX_STATE_PLAYING_2))) { - GfxPrint_Printf(printer, "%2X %5d %5d %5d %02X %04X %04X", entryIndex, (s32)*entry->posX, - (s32)*entry->posY, (s32)*entry->posZ, entry->sfxImportance, - entry->sfxParams, entry->sfxId); - } else { - GfxPrint_Printf(printer, "FF ----- ----- ----- -- ---- ----"); - } - } else if (sAudioIntInfoBankPage[k] == 2) { - if ((entryIndex != 0xFF) && - ((entry->state == SFX_STATE_PLAYING_1) || (entry->state == SFX_STATE_PLAYING_2))) { - GfxPrint_Printf(printer, "%2X %5d %5d %5d %3d %3d %04X", entryIndex, (s32)*entry->posX, - (s32)*entry->posY, (s32)*entry->posZ, (s32)(chan->volume * 127.1f), - chan->newPan, entry->sfxId); - } else { - GfxPrint_Printf(printer, "FF ----- ----- ----- --- --- ----"); - } - } else if (sAudioIntInfoBankPage[k] == 3) { - if ((entryIndex != 0xFF) && - ((entry->state == SFX_STATE_PLAYING_1) || (entry->state == SFX_STATE_PLAYING_2))) { - GfxPrint_Printf(printer, "%2X %5d %5d %5d %3d %3d %04X", entryIndex, (s32)*entry->posX, - (s32)*entry->posY, (s32)*entry->posZ, (s32)(chan->freqScale * 100.0f), - chan->reverb, entry->sfxId); - } else { - GfxPrint_Printf(printer, "FF ----- ----- ----- --- --- ----"); - } - } else if (sAudioIntInfoBankPage[k] == 4) { - if ((entryIndex != 0xFF) && - ((entry->state == SFX_STATE_PLAYING_1) || (entry->state == SFX_STATE_PLAYING_2))) { - GfxPrint_Printf(printer, "%2X %04X", entryIndex, entry->sfxId); - } else { - GfxPrint_Printf(printer, "FF ----"); - } - } -#undef entryIndex -#undef entry -#undef chan - - if (sAudioIntInfoBankPage[k] != 0) { - ind++; - } - } - ind++; - } - break; - - case PAGE_SCROLL_PRINT: - GfxPrint_SetPos(printer, 2, 4 + sAudioScrPrtSel); - SETCOL(255, 255, 255); - GfxPrint_Printf(printer, "*"); - - SETCOL(255, 255, 255); - GfxPrint_SetPos(printer, 3, 4); - GfxPrint_Printf(printer, "Swicth : %d", sAudioScrPrtWork[0]); - - GfxPrint_SetPos(printer, 3, 5); - GfxPrint_Printf(printer, "Lines : %d", sAudioScrPrtWork[1] + 1); - - GfxPrint_SetPos(printer, 3, 6); - GfxPrint_Printf(printer, "Color : %d", sAudioScrPrtWork[2]); - - GfxPrint_SetPos(printer, 3, 7); - GfxPrint_Printf(printer, "%s : %d", sSfxBankNames[0], sAudioScrPrtWork[3]); - - GfxPrint_SetPos(printer, 3, 8); - GfxPrint_Printf(printer, "%s : %d", sSfxBankNames[1], sAudioScrPrtWork[4]); - - GfxPrint_SetPos(printer, 3, 9); - GfxPrint_Printf(printer, "ENVRONM : %d", sAudioScrPrtWork[5]); - - GfxPrint_SetPos(printer, 3, 10); - GfxPrint_Printf(printer, "%s : %d", sSfxBankNames[3], sAudioScrPrtWork[6]); - - GfxPrint_SetPos(printer, 3, 11); - GfxPrint_Printf(printer, "%s : %d", sSfxBankNames[4], sAudioScrPrtWork[7]); - - GfxPrint_SetPos(printer, 3, 12); - GfxPrint_Printf(printer, "%s : %d", sSfxBankNames[5], sAudioScrPrtWork[8]); - - GfxPrint_SetPos(printer, 3, 13); - GfxPrint_Printf(printer, "%s : %d", sSfxBankNames[6], sAudioScrPrtWork[9]); - - GfxPrint_SetPos(printer, 3, 14); - GfxPrint_Printf(printer, "SEQ ENT : %d", sAudioScrPrtWork[10]); - break; - - case PAGE_SFX_SWAP: - GfxPrint_SetPos(printer, 3, 4); - SETCOL(255, 255, 255); - if (gAudioSfxSwapOff) { - GfxPrint_Printf(printer, "SWAP OFF"); - } - - if (sAudioSfxSwapIsEditing == 0) { - SETCOL(255, 255, 255); - } else { - SETCOL(127, 127, 127); - } - GfxPrint_SetPos(printer, 2, 6 + sAudioSfxSwapSel); - GfxPrint_Printf(printer, "*"); - - ctr = sAudioSfxSwapNibbleSel; - if (sAudioSfxSwapNibbleSel >= 4) { - ctr++; - } - if (sAudioSfxSwapIsEditing == 1) { - SETCOL(255, 255, 255); - GfxPrint_SetPos(printer, 3 + ctr, 5); - GfxPrint_Printf(printer, "V"); - } - - for (i = 0; i < 10; i++) { - if (i == sAudioSfxSwapSel) { - if (sAudioSfxSwapIsEditing == 0) { - SETCOL(192, 192, 192); - } else { - SETCOL(255, 255, 255); - } - } else if (sAudioSfxSwapIsEditing == 0) { - SETCOL(144, 144, 144); - } else { - SETCOL(96, 96, 96); - } - GfxPrint_SetPos(printer, 3, 6 + i); - GfxPrint_Printf(printer, "%04x %04x %s", gAudioSfxSwapSource[i], gAudioSfxSwapTarget[i], - sAudioSfxSwapModeNames[gAudioSfxSwapMode[i]]); - } - break; - - case PAGE_SUB_TRACK_INFO: - GfxPrint_SetPos(printer, 3, 4); - SETCOL(255, 255, 255); - GfxPrint_Printf(printer, "Group Track:%d", sAudioSubTrackInfoPlayerSel); - - GfxPrint_SetPos(printer, 3, 5); - GfxPrint_Printf(printer, "Sub Track :%d", sAudioSubTrackInfoChannelSel); - - GfxPrint_SetPos(printer, 3, 6); - GfxPrint_Printf(printer, "TRK NO. "); - - GfxPrint_SetPos(printer, 3, 7); - GfxPrint_Printf(printer, "ENTRY "); - - GfxPrint_SetPos(printer, 3, 8); - GfxPrint_Printf(printer, "MUTE "); - - GfxPrint_SetPos(printer, 3, 9); - GfxPrint_Printf(printer, "OPENNOTE"); - - ctr2 = 0; - for (i = 0; i < 16; i++) { - if (i == sAudioSubTrackInfoChannelSel) { - SETCOL(255, 255, 255); - } else { - SETCOL(200, 200, 200); - } - GfxPrint_SetPos(printer, 15 + i, 6); - GfxPrint_Printf(printer, "%1X", i); - - GfxPrint_SetPos(printer, 15 + i, 7); - if (gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel].channels[i]->enabled) { - GfxPrint_Printf(printer, "O"); - } else { - GfxPrint_Printf(printer, "X"); - } - - GfxPrint_SetPos(printer, 15 + i, 8); - if (gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel].channels[i]->stopSomething2) { - GfxPrint_Printf(printer, "O"); - } else { - GfxPrint_Printf(printer, "X"); - } - - GfxPrint_SetPos(printer, 15 + i, 9); - ctr = 0; - for (j = 0; j < 4; j++) { - if (gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel].channels[i]->layers[j] != NULL) { - ctr++; - } - } - - GfxPrint_Printf(printer, "%1X", ctr); - ctr2 += ctr; - } - - SETCOL(255, 255, 255); - if (sSeqPlayerPeakNumLayers[sAudioSubTrackInfoPlayerSel] < ctr2) { - sSeqPlayerPeakNumLayers[sAudioSubTrackInfoPlayerSel] = ctr2; - } - GfxPrint_SetPos(printer, 16 + i, 9); - GfxPrint_Printf(printer, "%2d,%2d", ctr2, sSeqPlayerPeakNumLayers[sAudioSubTrackInfoPlayerSel]); - - GfxPrint_SetPos(printer, 3, 11); - GfxPrint_Printf(printer, "VOL "); - - GfxPrint_SetPos(printer, 3, 12); - GfxPrint_Printf(printer, "E VOL "); - - GfxPrint_SetPos(printer, 3, 13); - GfxPrint_Printf(printer, "BANK ID "); - - GfxPrint_SetPos(printer, 3, 14); - GfxPrint_Printf(printer, "PROG "); - - GfxPrint_SetPos(printer, 3, 15); - GfxPrint_Printf(printer, "PAN "); - - GfxPrint_SetPos(printer, 3, 16); - GfxPrint_Printf(printer, "PANPOW "); - - GfxPrint_SetPos(printer, 3, 17); - GfxPrint_Printf(printer, "FXMIX "); - - GfxPrint_SetPos(printer, 3, 18); - GfxPrint_Printf(printer, "PRIO "); - - GfxPrint_SetPos(printer, 3, 19); - GfxPrint_Printf(printer, "VIB PIT "); - - GfxPrint_SetPos(printer, 3, 20); - GfxPrint_Printf(printer, "VIB DEP "); - - GfxPrint_SetPos(printer, 3, 21); - GfxPrint_Printf(printer, "TUNE "); - - GfxPrint_SetPos(printer, 3, 22); - GfxPrint_Printf(printer, "TUNE "); - - for (i = 0; i < 8; i++) { - GfxPrint_SetPos(printer, 15 + 3 * i, 22); - GfxPrint_Printf(printer, "%02X ", - (u8)gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel] - .channels[sAudioSubTrackInfoChannelSel] - ->soundScriptIO[i]); - } - - if (gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel].channels[sAudioSubTrackInfoChannelSel]->enabled) { - GfxPrint_SetPos(printer, 15, 11); - GfxPrint_Printf(printer, "%d", - (u8)(gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel] - .channels[sAudioSubTrackInfoChannelSel] - ->volume * - 127.1)); - - GfxPrint_SetPos(printer, 15, 12); - GfxPrint_Printf(printer, "%d", - (u8)(gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel] - .channels[sAudioSubTrackInfoChannelSel] - ->volumeScale * - 127.1)); - - GfxPrint_SetPos(printer, 15, 13); - GfxPrint_Printf( - printer, "%X", - gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel].channels[sAudioSubTrackInfoChannelSel]->fontId); - - ctr = (u8)(gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel] - .channels[sAudioSubTrackInfoChannelSel] - ->instOrWave); - - if (ctr == 0) { - ctr2 = 0x7F; - } else if (ctr < 0x80) { - ctr2 = ctr - 1; - } else { - ctr2 = ctr; - } - - GfxPrint_SetPos(printer, 15, 14); - GfxPrint_Printf(printer, "%d", ctr2); - - GfxPrint_SetPos(printer, 15, 15); - GfxPrint_Printf( - printer, "%d", - gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel].channels[sAudioSubTrackInfoChannelSel]->newPan); - - GfxPrint_SetPos(printer, 15, 16); - GfxPrint_Printf(printer, "%d", - gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel] - .channels[sAudioSubTrackInfoChannelSel] - ->panChannelWeight); - - GfxPrint_SetPos(printer, 15, 17); - GfxPrint_Printf( - printer, "%d", - gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel].channels[sAudioSubTrackInfoChannelSel]->reverb); - - GfxPrint_SetPos(printer, 15, 18); - GfxPrint_Printf(printer, "%d", - gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel] - .channels[sAudioSubTrackInfoChannelSel] - ->notePriority); - - GfxPrint_SetPos(printer, 15, 19); - GfxPrint_Printf(printer, "%d", - (u8)(gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel] - .channels[sAudioSubTrackInfoChannelSel] - ->vibratoRateTarget / - 32)); - - GfxPrint_SetPos(printer, 15, 20); - GfxPrint_Printf(printer, "%d", - (u8)(gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel] - .channels[sAudioSubTrackInfoChannelSel] - ->vibratoExtentTarget / - 8)); - - GfxPrint_SetPos(printer, 15, 21); - GfxPrint_Printf(printer, "%d", - (u16)(gAudioCtx.seqPlayers[sAudioSubTrackInfoPlayerSel] - .channels[sAudioSubTrackInfoChannelSel] - ->freqScale * - 100)); - } - break; - - case PAGE_HEAP_INFO: - SETCOL(255, 255, 255); - GfxPrint_SetPos(printer, 3, 4); - GfxPrint_Printf(printer, "TOTAL %d", gAudioHeapInitSizes.heapSize); - - GfxPrint_SetPos(printer, 3, 5); - GfxPrint_Printf(printer, "DRIVER %05X / %05X", - gAudioCtx.miscPool.curRamAddr - gAudioCtx.miscPool.startRamAddr, gAudioCtx.miscPool.size); - - GfxPrint_SetPos(printer, 3, 6); - GfxPrint_Printf( - printer, "AT-SEQ %02X-%02X (%05X-%05X / %05X)", (u8)gAudioCtx.seqCache.temporary.entries[0].id, - (u8)gAudioCtx.seqCache.temporary.entries[1].id, gAudioCtx.seqCache.temporary.entries[0].size, - gAudioCtx.seqCache.temporary.entries[1].size, gAudioCtx.seqCache.temporary.pool.size); - - GfxPrint_SetPos(printer, 3, 7); - GfxPrint_Printf( - printer, "AT-BNK %02X-%02X (%05X-%05X / %05X)", (u8)gAudioCtx.fontCache.temporary.entries[0].id, - (u8)gAudioCtx.fontCache.temporary.entries[1].id, gAudioCtx.fontCache.temporary.entries[0].size, - gAudioCtx.fontCache.temporary.entries[1].size, gAudioCtx.fontCache.temporary.pool.size); - - GfxPrint_SetPos(printer, 3, 8); - GfxPrint_Printf(printer, "ST-SEQ %02Xseqs (%05X / %06X)", gAudioCtx.seqCache.persistent.numEntries, - gAudioCtx.seqCache.persistent.pool.curRamAddr - - gAudioCtx.seqCache.persistent.pool.startRamAddr, - gAudioCtx.seqCache.persistent.pool.size); - - for (k = 0; (u32)k < gAudioCtx.seqCache.persistent.numEntries; k++) { - GfxPrint_SetPos(printer, 3 + 3 * k, 9); - GfxPrint_Printf(printer, "%02x", gAudioCtx.seqCache.persistent.entries[k].id); - } - - GfxPrint_SetPos(printer, 3, 10); - GfxPrint_Printf(printer, "ST-BNK %02Xbanks (%05X / %06X)", gAudioCtx.fontCache.persistent.numEntries, - gAudioCtx.fontCache.persistent.pool.curRamAddr - - gAudioCtx.fontCache.persistent.pool.startRamAddr, - gAudioCtx.fontCache.persistent.pool.size); - - for (k = 0; (u32)k < gAudioCtx.fontCache.persistent.numEntries; k++) { - GfxPrint_SetPos(printer, 3 + 3 * k, 11); - GfxPrint_Printf(printer, "%02x", gAudioCtx.fontCache.persistent.entries[k].id); - } - - GfxPrint_SetPos(printer, 3, 12); - GfxPrint_Printf(printer, "E-MEM %05X / %05X", - gAudioCtx.permanentPool.curRamAddr - gAudioCtx.permanentPool.startRamAddr, - gAudioCtx.permanentPool.size); - break; - - case PAGE_BLOCK_CHANGE_BGM: - SETCOL(255, 255, 255); - GfxPrint_SetPos(printer, 3, 4); - GfxPrint_Printf(printer, "BGM No. %02X", sAudioBlkChgBgmWork[0]); - - GfxPrint_SetPos(printer, 3, 5); - GfxPrint_Printf(printer, "SCENE SET %02X %s", sAudioBlkChgBgmWork[1], - sAudioSceneNames[sAudioBlkChgBgmWork[1]]); - - SETCOL(0x64, 255, 0x64); - GfxPrint_SetPos(printer, 2, 4 + sAudioBlkChgBgmSel); - GfxPrint_Printf(printer, "*"); - - SETCOL(255, 255, 255); - GfxPrint_SetPos(printer, 3, 7); - GfxPrint_Printf(printer, "NEXT SCENE %02X %s", - (u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[2], - sAudioSceneNames[(u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[2]]); - - GfxPrint_SetPos(printer, 3, 8); - GfxPrint_Printf(printer, "NOW SCENE %02X %s", - (u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[4], - sAudioSceneNames[(u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[4]]); - - GfxPrint_SetPos(printer, 3, 9); - GfxPrint_Printf(printer, "NOW BLOCK %02X", - (gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[5] + 1) & 0xFF); - - GfxPrint_SetPos(printer, 3, 11); - GfxPrint_Printf(printer, "PORT"); - - GfxPrint_SetPos(printer, 3, 12); - GfxPrint_Printf(printer, "%02X %02X %02X %02X", - (u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[0], - (u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[1], - (u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[2], - (u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[3]); - - GfxPrint_SetPos(printer, 3, 13); - GfxPrint_Printf(printer, "%02X %02X %02X %02X", - (u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[4], - (u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[5], - (u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[6], - (u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[7]); - break; - - case PAGE_OCARINA_TEST: - SETCOL(255, 255, 255); - GfxPrint_SetPos(printer, 3, 4); - GfxPrint_Printf(printer, "SEQ INFO : %2d %02x %d", sPlaybackStaff.buttonIndex, sPlaybackStaff.state, - sPlaybackStaff.pos); - - GfxPrint_SetPos(printer, 3, 5); - GfxPrint_Printf(printer, "PLAY INFO : %2d %02x %d", sPlayingStaff.buttonIndex, sPlayingStaff.state, - sPlayingStaff.pos); - - GfxPrint_SetPos(printer, 3, 6); - GfxPrint_Printf(printer, "8note REC POINTER : %08x", gScarecrowSpawnSongPtr); - - ctr = 0; - for (j = 0; j < 4; j++) { - for (i = 0; i < 8; i++) { - GfxPrint_SetPos(printer, 3 + 3 * i, 7 + j); - GfxPrint_Printf(printer, "%02x", gScarecrowSpawnSongPtr[ctr++]); - } - } - - GfxPrint_SetPos(printer, 3, 24); - GfxPrint_Printf(printer, "OCA:%02x SEQ:%04x PLAY:%02x REC:%02x", sOcarinaInstrumentId, sOcarinaFlags, - sPlaybackState, sRecordingState); - break; - - case PAGE_SFX_PARAMETER_CHANGE: - GfxPrint_SetPos(printer, 2, 4 + sAudioSfxParamChgSel); - SETCOL(127, 255, 127); - GfxPrint_Printf(printer, "*"); - - SETCOL(255, 255, 255); - GfxPrint_SetPos(printer, 3, 4); - GfxPrint_Printf(printer, "SE HD : %02x %s", sAudioSfxParamChgWork[0], - sSfxBankNames[sAudioSfxParamChgWork[0]]); - - GfxPrint_SetPos(printer, 3, 5); - GfxPrint_Printf(printer, "SE No. : %02x", sAudioSfxParamChgWork[1]); - - GfxPrint_SetPos(printer, 20, 6); - GfxPrint_Printf(printer, " : %04x", - gSfxParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].params); - - GfxPrint_SetPos(printer, 3, 6); - GfxPrint_Printf( - printer, "SE SW %s", - AudioDebug_ToStringBinary(gSfxParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].params, 16)); - - SETCOL(127, 255, 127); - digitStr[0] = (char)('0' + ((gSfxParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].params >> - (15 - sAudioSfxParamChgBitSel)) & - 1)); - GfxPrint_SetPos(printer, 12 + sAudioSfxParamChgBitSel, 6); - GfxPrint_Printf(printer, "%s", digitStr); - - SETCOL(255, 255, 255); - GfxPrint_SetPos(printer, 3, 7); - GfxPrint_Printf(printer, "SE PR : %02x", - gSfxParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].importance); - break; - - case PAGE_FREE_AREA: - GfxPrint_SetPos(printer, 3, 4); - SETCOL(255, 255, 255); - GfxPrint_Printf(printer, "env_fx %d code_fx %d SPEC %d", sAudioEnvReverb, sAudioCodeReverb, gAudioSpecId); - - if (sAudioUpdateTaskStart == sAudioUpdateTaskEnd) { - sAudioUpdateDuration = OS_CYCLES_TO_NSEC(sAudioUpdateEndTime - sAudioUpdateStartTime) / (1e9f / 20); - if (sAudioUpdateDurationMax < sAudioUpdateDuration) { - sAudioUpdateDurationMax = sAudioUpdateDuration; - } - } - - GfxPrint_SetPos(printer, 3, 6); - GfxPrint_Printf(printer, "SOUND GAME FRAME NOW %f", sAudioUpdateDuration); - - GfxPrint_SetPos(printer, 3, 7); - GfxPrint_Printf(printer, "SOUND GAME FRAME MAX %f", sAudioUpdateDurationMax); - - GfxPrint_SetPos(printer, 3, 9); - GfxPrint_Printf(printer, "SWITCH BGM MODE %d %d %d (FLAG %d)", sPrevSeqMode, sNumFramesStill, - sNumFramesMoving, sSeqModeInput); - - GfxPrint_SetPos(printer, 3, 10); - GfxPrint_Printf(printer, "ENEMY DIST %f VOL %3d", sAudioEnemyDist, sAudioEnemyVol); - - GfxPrint_SetPos(printer, 3, 11); - GfxPrint_Printf(printer, "GANON DIST VOL %3d", sGanonsTowerVol); - - GfxPrint_SetPos(printer, 3, 12); - GfxPrint_Printf(printer, "DEMO FLAG %d", sAudioCutsceneFlag); - - GfxPrint_SetPos(printer, 3, 12); - if (sIsMalonSinging == true) { - GfxPrint_Printf(printer, "MARON BGM DIST %f", sMalonSingingDist); - sIsMalonSinging = false; - } - - GfxPrint_SetPos(printer, 3, 23); - if (sAudioNatureFailed != false) { - GfxPrint_Printf(printer, "NATURE FAILED %01x", sAudioNatureFailed); - } - - GfxPrint_SetPos(printer, 3, 24); - if (sSariaBgmPtr != NULL) { - GfxPrint_Printf(printer, "SARIA BGM PTR %08x", sSariaBgmPtr); - } - - GfxPrint_SetPos(printer, 3, 25); - GfxPrint_Printf(printer, "POLI %d(%d)", sPeakNumNotes, numEnabledNotes); - - for (i = 0; i < 11; i++) { - GfxPrint_SetPos(printer, 3 + 3 * i, 26); - GfxPrint_Printf(printer, "%d", sAudioSpecPeakNumNotes[i]); - } - break; - } -#undef SETCOL_COMMON -#undef SETCOL -#undef SETCOL_SCROLLPRINT -} - -void AudioDebug_ProcessInput_SndCont(void) { - u16 step = 1; - - if (CHECK_BTN_ANY(sDebugPadHold, BTN_CDOWN)) { - if (sAudioSndContWorkLims[sAudioSndContSel] >= 16) { - step = 16; - } - } else if (CHECK_BTN_ANY(sDebugPadHold, BTN_CLEFT)) { - if (sAudioSndContWorkLims[sAudioSndContSel] >= 16) { - step = 8; - } - } else if (CHECK_BTN_ANY(sDebugPadHold, BTN_CUP)) { - sAudioSndContWork[sAudioSndContSel] = 0; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) { - if (sAudioSndContSel > 0) { - sAudioSndContSel--; - } else { - sAudioSndContSel = 10; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) { - if (sAudioSndContSel < 10) { - sAudioSndContSel++; - } else { - sAudioSndContSel = 0; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) { - if (sAudioSndContWork[sAudioSndContSel] >= step) { - if (1) { - sAudioSndContWork[sAudioSndContSel] -= step; - } - } else { - sAudioSndContWork[sAudioSndContSel] += sAudioSndContWorkLims[sAudioSndContSel] - step; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) { - if (sAudioSndContWork[sAudioSndContSel] + step < sAudioSndContWorkLims[sAudioSndContSel]) { - sAudioSndContWork[sAudioSndContSel] += step; - } else { - sAudioSndContWork[sAudioSndContSel] += step - sAudioSndContWorkLims[sAudioSndContSel]; - } - } - - if (sAudioSndContSel == 8) { - if (sAudioSndContWork[sAudioSndContSel] != 0) { - Audio_SetExtraFilter(0x20); - } else { - Audio_SetExtraFilter(0); - } - } - - if (sAudioSndContSel == 9) { - if (sAudioSndContWork[sAudioSndContSel] != 0) { - Audio_SetBaseFilter(0x20); - } else { - Audio_SetBaseFilter(0); - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) { - switch (sAudioSndContSel) { - case 0: - case 1: - SEQCMD_PLAY_SEQUENCE(sAudioSndContSel, 0, 0, sAudioSndContWork[sAudioSndContSel]); - break; - case 2: - case 3: - Audio_PlaySfxGeneral(((sAudioSndContWork[2] << 12) & 0xFFFF) + sAudioSndContWork[3] + SFX_FLAG, - &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultReverb); - break; - case 4: - func_800F6700(sAudioSndContWork[sAudioSndContSel]); - break; - case 5: - SEQCMD_DISABLE_PLAY_SEQUENCES(sAudioSndContWork[sAudioSndContSel]); - break; - case 6: - SEQCMD_RESET_AUDIO_HEAP(0, sAudioSndContWork[sAudioSndContSel]); - sAudioSubTrackInfoSpec = sAudioSndContWork[6]; - if (sAudioSubTrackInfoPlayerSel > gAudioSpecs[sAudioSubTrackInfoSpec].numSequencePlayers - 1) { - sAudioSubTrackInfoPlayerSel = gAudioSpecs[sAudioSubTrackInfoSpec].numSequencePlayers - 1; - } - break; - case 7: - Audio_PlayNatureAmbienceSequence(sAudioSndContWork[sAudioSndContSel]); - break; - case 8: - case 9: - break; - case 10: - Audio_SetSfxBanksMute(sAudioSndContWork[sAudioSndContSel] * 0x7F); - break; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) { - switch (sAudioSndContSel) { - case 0: - case 1: - SEQCMD_STOP_SEQUENCE(sAudioSndContSel, 0); - break; - case 7: - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0); - break; - case 2: - case 3: - Audio_StopSfxByBank(sAudioSndContWork[2]); - break; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CDOWN)) { - if (sAudioSndContSel == 0) { - if (1) {} - Audio_PlaySequenceInCutscene(sAudioSndContWork[sAudioSndContSel]); - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CRIGHT)) { - if (sAudioSndContSel == 0) { - if (1) {} - func_800F5ACC(sAudioSndContWork[sAudioSndContSel]); - } - } -} - -void AudioDebug_ProcessInput_IntInfo(void) { - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CUP)) { - sAudioIntInfoY--; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CDOWN)) { - sAudioIntInfoY++; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CLEFT)) { - sAudioIntInfoX--; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CRIGHT)) { - sAudioIntInfoX++; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) { - sAudioIntInfoX = 0; - sAudioIntInfoY = 0; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP) && sAudioIntInfoSel > 0) { - sAudioIntInfoSel--; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN) && sAudioIntInfoSel < 6) { - sAudioIntInfoSel++; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT) && sAudioIntInfoBankPage[sAudioIntInfoSel] > 0) { - sAudioIntInfoBankPage[sAudioIntInfoSel]--; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT) && sAudioIntInfoBankPage[sAudioIntInfoSel] < 4) { - sAudioIntInfoBankPage[sAudioIntInfoSel]++; - } -} - -void AudioDebug_ProcessInput_ScrPrt(void) { - if (sAudioScrPrtWork[0] != 0) { - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CUP)) { - sAudioScrPrtY--; - } - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CDOWN)) { - sAudioScrPrtY++; - } - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CLEFT)) { - sAudioScrPrtX--; - } - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CRIGHT)) { - sAudioScrPrtX++; - } - if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) { - sAudioScrPrtX = 26; - sAudioScrPrtY = 1; - sAudioScrPrtWork[2] = 6; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) { - sAudioScrPrtInd = 0; - sAudioScrPrtOverflow = 0; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) { - if (sAudioScrPrtSel > 0) { - sAudioScrPrtSel--; - } else { - sAudioScrPrtSel = 10; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) { - if (sAudioScrPrtSel < 10) { - sAudioScrPrtSel++; - } else { - sAudioScrPrtSel = 0; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) { - if (sAudioScrPrtWork[sAudioScrPrtSel] > 0) { - sAudioScrPrtWork[sAudioScrPrtSel]--; - } else { - sAudioScrPrtWork[sAudioScrPrtSel] = sAudioScrPrtWorkLims[sAudioScrPrtSel] - 1; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) { - if (sAudioScrPrtWork[sAudioScrPrtSel] < sAudioScrPrtWorkLims[sAudioScrPrtSel] - 1) { - sAudioScrPrtWork[sAudioScrPrtSel]++; - } else { - sAudioScrPrtWork[sAudioScrPrtSel] = 0; - } - } - - D_801333F0 = sAudioScrPrtWork[3] + (sAudioScrPrtWork[4] * 2) + (sAudioScrPrtWork[5] * 4) + - (sAudioScrPrtWork[6] * 8) + (sAudioScrPrtWork[7] * 0x10) + (sAudioScrPrtWork[8] * 0x20); -} - -void AudioDebug_ProcessInput_SfxSwap(void) { - s16 step; - u16 val; - u8 prev; - - if (!sAudioSfxSwapIsEditing) { - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) { - if (sAudioSfxSwapSel > 0) { - sAudioSfxSwapSel--; - } else { - sAudioSfxSwapSel = 9; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) { - if (sAudioSfxSwapSel < 9) { - sAudioSfxSwapSel++; - } else { - sAudioSfxSwapSel = 0; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) { - sAudioSfxSwapIsEditing = true; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) { - gAudioSfxSwapSource[sAudioSfxSwapSel] = 0; - gAudioSfxSwapTarget[sAudioSfxSwapSel] = 0; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_START)) { - if (sAudioSfxSwapSel != 0) { - prev = sAudioSfxSwapSel - 1; - } else { - prev = 9; - } - gAudioSfxSwapSource[sAudioSfxSwapSel] = gAudioSfxSwapSource[prev]; - gAudioSfxSwapTarget[sAudioSfxSwapSel] = gAudioSfxSwapTarget[prev]; - } - } else { - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) { - if (sAudioSfxSwapNibbleSel > 0) { - sAudioSfxSwapNibbleSel--; - } else { - sAudioSfxSwapNibbleSel = 7; - } - } - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) { - if (sAudioSfxSwapNibbleSel < 7) { - sAudioSfxSwapNibbleSel++; - } else { - sAudioSfxSwapNibbleSel = 0; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP) || CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) { - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) { - step = CHECK_BTN_ANY(sDebugPadHold, BTN_CUP) ? 8 : 1; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) { - step = CHECK_BTN_ANY(sDebugPadHold, BTN_CUP) ? -8 : -1; - } - - if (sAudioSfxSwapNibbleSel < 4) { - val = gAudioSfxSwapSource[sAudioSfxSwapSel] >> ((3 - sAudioSfxSwapNibbleSel) * 4); - val = (val + step) & 0xF; - gAudioSfxSwapSource[sAudioSfxSwapSel] = - (gAudioSfxSwapSource[sAudioSfxSwapSel] & ((0xF << ((3 - sAudioSfxSwapNibbleSel) * 4)) ^ 0xFFFF)) + - (val << ((3 - sAudioSfxSwapNibbleSel) * 4)); - } else { - val = gAudioSfxSwapTarget[sAudioSfxSwapSel] >> ((7 - sAudioSfxSwapNibbleSel) * 4); - val = (val + step) & 0xF; - gAudioSfxSwapTarget[sAudioSfxSwapSel] = - (gAudioSfxSwapTarget[sAudioSfxSwapSel] & ((0xF << ((7 - sAudioSfxSwapNibbleSel) * 4)) ^ 0xFFFF)) + - (val << ((7 - sAudioSfxSwapNibbleSel) * 4)); - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) { - sAudioSfxSwapIsEditing = false; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) { - if (sAudioSfxSwapNibbleSel < 4) { - gAudioSfxSwapSource[sAudioSfxSwapSel] = 0; - } else { - gAudioSfxSwapTarget[sAudioSfxSwapSel] = 0; - } - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CLEFT)) { - gAudioSfxSwapOff ^= 1; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CDOWN)) { - gAudioSfxSwapMode[sAudioSfxSwapSel] ^= 1; - } -} - -void AudioDebug_ProcessInput_SubTrackInfo(void) { - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) { - if (sAudioSubTrackInfoPlayerSel != 0) { - sAudioSubTrackInfoPlayerSel--; - } else { - sAudioSubTrackInfoPlayerSel = gAudioSpecs[sAudioSubTrackInfoSpec].numSequencePlayers - 1; - } - } - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) { - if (sAudioSubTrackInfoPlayerSel < gAudioSpecs[sAudioSubTrackInfoSpec].numSequencePlayers - 1) { - sAudioSubTrackInfoPlayerSel++; - } else { - sAudioSubTrackInfoPlayerSel = SEQ_PLAYER_BGM_MAIN; - } - } - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) { - sAudioSubTrackInfoChannelSel = (sAudioSubTrackInfoChannelSel - 1) & 0xF; - } - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) { - sAudioSubTrackInfoChannelSel = (sAudioSubTrackInfoChannelSel + 1) & 0xF; - } - if (CHECK_BTN_ANY(sDebugPadPress, BTN_START)) { - sSeqPlayerPeakNumLayers[sAudioSubTrackInfoPlayerSel] = SEQ_PLAYER_BGM_MAIN; - } -} - -void AudioDebug_ProcessInput_HeapInfo(void) { -} - -void AudioDebug_ProcessInput_BlkChgBgm(void) { - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) { - if (sAudioBlkChgBgmSel > 0) { - sAudioBlkChgBgmSel--; - } else { - sAudioBlkChgBgmSel = 1; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) { - if (sAudioBlkChgBgmSel <= 0) { - sAudioBlkChgBgmSel++; - } else { - sAudioBlkChgBgmSel = 0; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) { - sAudioBlkChgBgmWork[sAudioBlkChgBgmSel]--; - if (sAudioBlkChgBgmSel == 1) { - Audio_SetSequenceMode(sAudioBlkChgBgmWork[1]); - ; // might be a fake match? - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) { - sAudioBlkChgBgmWork[sAudioBlkChgBgmSel]++; - if (sAudioBlkChgBgmSel == 1) { - Audio_SetSequenceMode(sAudioBlkChgBgmWork[1]); - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) { - Audio_QueueCmdS8(MK_CMD(0x46, SEQ_PLAYER_BGM_MAIN, 0x00, 0x00), sAudioBlkChgBgmWork[1]); - SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 1, 0, sAudioBlkChgBgmWork[0]); - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) { - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 1); - } -} - -void AudioDebug_ProcessInput_OcaTest(void) { -} - -void AudioDebug_ProcessInput_SfxParamChg(void) { - s32 step; - u16 sfx; - - if (CHECK_BTN_ANY(sDebugPadHold, BTN_CLEFT)) { - step = 8; - } else { - step = 1; - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DUP)) { - if (sAudioSfxParamChgSel > 0) { - sAudioSfxParamChgSel--; - } else { - sAudioSfxParamChgSel = 3; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DDOWN)) { - if (sAudioSfxParamChgSel < 3) { - sAudioSfxParamChgSel++; - } else { - sAudioSfxParamChgSel = 0; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DLEFT)) { - if (sAudioSfxParamChgSel < 2) { - if (sAudioSfxParamChgSel == 0) { - if (sAudioSfxParamChgWork[sAudioSfxParamChgSel] > 0) { - sAudioSfxParamChgWork[sAudioSfxParamChgSel]--; - } else { - sAudioSfxParamChgWork[sAudioSfxParamChgSel] = sAudioSndContWorkLims[2] - 1; - } - } else { - sAudioSfxParamChgWork[sAudioSfxParamChgSel] -= step; - sAudioSfxParamChgWork[sAudioSfxParamChgSel] &= 0x1FF; - } - } else if (sAudioSfxParamChgSel == 3) { - gSfxParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].importance -= step; - } else { - sAudioSfxParamChgBitSel = (sAudioSfxParamChgBitSel - 1) & 0xF; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_DRIGHT)) { - if (sAudioSfxParamChgSel < 2) { - if (sAudioSfxParamChgSel == 0) { - if (sAudioSfxParamChgWork[sAudioSfxParamChgSel] < (sAudioSndContWorkLims[2] - 1)) { - sAudioSfxParamChgWork[sAudioSfxParamChgSel]++; - } else { - sAudioSfxParamChgWork[sAudioSfxParamChgSel] = 0; - } - } else { - sAudioSfxParamChgWork[sAudioSfxParamChgSel] += step; - sAudioSfxParamChgWork[sAudioSfxParamChgSel] &= 0x1FF; - } - } else if (sAudioSfxParamChgSel == 3) { - gSfxParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].importance += step; - } else { - sAudioSfxParamChgBitSel = (sAudioSfxParamChgBitSel + 1) & 0xF; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) { - sfx = (u16)(sAudioSfxParamChgWork[0] << 12) + sAudioSfxParamChgWork[1] + SFX_FLAG; - Audio_PlaySfxGeneral(sfx, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultReverb); - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) { - Audio_StopSfxByBank(sAudioSfxParamChgWork[0]); - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CDOWN)) { - if (sAudioSfxParamChgSel == 2) { - gSfxParams[sAudioSfxParamChgWork[0]][sAudioSfxParamChgWork[1]].params ^= - (1 << (0xF - sAudioSfxParamChgBitSel)); - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_CUP)) { - if (sAudioSfxParamChgSel < 2) { - sAudioSfxParamChgWork[sAudioSfxParamChgSel] = 0; - } - } -} - -void AudioDebug_ScrPrt(const char* str, u16 num) { - u8 i = 0; - - sAudioScrPrtBuf[sAudioScrPrtInd].num = num; - - while (str[i] != '\0') { - sAudioScrPrtBuf[sAudioScrPrtInd].str[i] = str[i]; - i++; - } - - while (i < 5) { - sAudioScrPrtBuf[sAudioScrPrtInd].str[i] = '\0'; - i++; - } - - if (sAudioScrPrtInd < 25 - 1) { - sAudioScrPrtInd++; - } else { - sAudioScrPrtInd = 0; - sAudioScrPrtOverflow = 1; - } -} - -void AudioDebug_ProcessInput(void) { - if (!sAudioDebugEverOpened) { - return; - } - - if (sAudioSfxMuted) { - Audio_SetSfxBanksMute(0x6F); - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_L)) { - if (sAudioDebugPage < PAGE_MAX - 1) { - sAudioDebugPage++; - } else { - sAudioDebugPage = 0; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_R)) { - if (sAudioDebugPage > 0) { - sAudioDebugPage--; - } else { - sAudioDebugPage = PAGE_MAX - 1; - } - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_Z)) { - sAudioDebugTextColor++; - sAudioDebugTextColor &= 7; - } - - switch (sAudioDebugPage) { - case PAGE_NON: - if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) { - sAudioSndContWork[5] ^= 1; - SEQCMD_DISABLE_PLAY_SEQUENCES(sAudioSndContWork[5]); - if (Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_NATURE_AMBIENCE) { - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0); - } - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, 0); - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_SUB, 0); - } - - if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) { - sAudioSfxMuted ^= 1; - if (!sAudioSfxMuted) { - Audio_SetSfxBanksMute(0); - } - } - break; - case PAGE_SOUND_CONTROL: - AudioDebug_ProcessInput_SndCont(); - break; - case PAGE_INTERFACE_INFO: - AudioDebug_ProcessInput_IntInfo(); - break; - case PAGE_SCROLL_PRINT: - AudioDebug_ProcessInput_ScrPrt(); - break; - case PAGE_SFX_SWAP: - AudioDebug_ProcessInput_SfxSwap(); - break; - case PAGE_SUB_TRACK_INFO: - AudioDebug_ProcessInput_SubTrackInfo(); - break; - case PAGE_HEAP_INFO: - AudioDebug_ProcessInput_HeapInfo(); - break; - case PAGE_BLOCK_CHANGE_BGM: - AudioDebug_ProcessInput_BlkChgBgm(); - break; - case PAGE_OCARINA_TEST: - AudioDebug_ProcessInput_OcaTest(); - break; - case PAGE_SFX_PARAMETER_CHANGE: - AudioDebug_ProcessInput_SfxParamChg(); - break; - case PAGE_FREE_AREA: - default: - break; - } - - gAudioDebugPrintSeqCmd = sAudioScrPrtWork[10]; -} - -void Audio_UpdateRiverSoundVolumes(void); -void Audio_UpdateFanfare(void); - -/** - * This is Audio_Update for the graph thread - */ -void func_800F3054(void) { - if (func_800FAD34() == 0) { - sAudioUpdateTaskStart = gAudioCtx.totalTaskCount; - sAudioUpdateStartTime = osGetTime(); - AudioOcarina_Update(); - Audio_StepFreqLerp(&sRiverFreqScaleLerp); - Audio_StepFreqLerp(&sWaterfallFreqScaleLerp); - Audio_UpdateRiverSoundVolumes(); - Audio_UpdateSceneSequenceResumePoint(); - Audio_UpdateFanfare(); - if (gAudioSpecId == 7) { - Audio_ClearSariaBgm(); - } - Audio_ProcessSfxRequests(); - Audio_ProcessSeqCmds(); - func_800F8F88(); - Audio_UpdateActiveSequences(); - AudioDebug_SetInput(); - AudioDebug_ProcessInput(); - Audio_ScheduleProcessCmds(); - sAudioUpdateTaskEnd = gAudioCtx.totalTaskCount; - sAudioUpdateEndTime = osGetTime(); - } -} - -void func_800F3138(UNK_TYPE arg0) { -} - -void func_800F3140(UNK_TYPE arg0, UNK_TYPE arg1) { -} - -void func_800F314C(s8 arg0) { - Audio_QueueCmdS32(0x82 << 24 | SEQ_PLAYER_BGM_MAIN << 16 | (((u8)arg0 & 0xFF) << 8), 1); -} - -f32 Audio_ComputeSfxVolume(u8 bankId, u8 entryIdx) { - SfxBankEntry* bankEntry = &gSfxBanks[bankId][entryIdx]; - f32 minDist; - f32 baseDist; - f32 ret; - - if (bankEntry->sfxParams & SFX_FLAG_13) { - return 1.0f; - } - - if (bankEntry->dist > 10000.0f) { - ret = 0.0f; - } else { - switch ((bankEntry->sfxParams & SFX_PARAM_01_MASK) >> SFX_PARAM_01_SHIFT) { - case 1: - baseDist = 10000.0f / 15.0f; - break; - case 2: - baseDist = 10000.0f / 10.5f; - break; - case 3: - baseDist = 10000.0f / 2.6f; - break; - default: - baseDist = 10000.0f / 20.0f; - break; - } - - minDist = baseDist / 5.0f; - - // Volume grows as inverse square of distance. Linearly approximate - // the inverse part, then square. - if (bankEntry->dist < minDist) { - ret = 1.0f; - } else if (bankEntry->dist < baseDist) { - ret = ((((baseDist - minDist) - (bankEntry->dist - minDist)) / (baseDist - minDist)) * 0.19f) + 0.81f; - } else { - ret = (1.0f - ((bankEntry->dist - baseDist) / (10000.0f - baseDist))) * 0.81f; - } - ret = SQ(ret); - } - - return ret; -} - -s8 Audio_ComputeSfxReverb(u8 bankId, u8 entryIdx, u8 channelIdx) { - s8 distAdd = 0; - s32 scriptAdd = 0; - SfxBankEntry* entry = &gSfxBanks[bankId][entryIdx]; - s32 reverb; - - if (!(entry->sfxParams & SFX_FLAG_12)) { - if (entry->dist < 2500.0f) { - distAdd = *entry->posZ > 0.0f ? (entry->dist / 2500.0f) * 70.0f : (entry->dist / 2500.0f) * 91.0f; - } else { - distAdd = 70; - } - } - - if (IS_SEQUENCE_CHANNEL_VALID(gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[channelIdx])) { - scriptAdd = gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[channelIdx]->soundScriptIO[1]; - if (gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[channelIdx]->soundScriptIO[1] <= SEQ_IO_VAL_NONE) { - scriptAdd = 0; - } - } - - reverb = *entry->reverbAdd + distAdd + scriptAdd; - if ((bankId != BANK_OCARINA) || !((entry->sfxId & 0x1FF) < 2)) { - reverb += sAudioEnvReverb + sAudioCodeReverb + sSpecReverb; - } - - if (reverb > 0x7F) { - reverb = 0x7F; - } - - return reverb; -} - -s8 Audio_ComputeSfxPanSigned(f32 x, f32 z, u8 token) { - f32 absX; - f32 absZ; - f32 pan; - - if (x < 0) { - absX = -x; - } else { - absX = x; - } - if (z < 0) { - absZ = -z; - } else { - absZ = z; - } - - if (absX > 8000.0f) { - absX = 8000.0f; - } - - if (absZ > 8000.0f) { - absZ = 8000.0f; - } - - if ((x == 0.0f) && (z == 0.0f)) { - pan = 0.5f; - } else if (absZ <= absX) { - pan = (16000.0f - absX) / (3.3f * (16000.0f - absZ)); - if (x >= 0.0f) { - pan = 1.0f - pan; - } - } else { - pan = (x / (5.0769234f * absZ)) + 0.5f; // about 66 / 13 - } - - if (absZ < 50.0f) { - if (absX < 50.0f) { - pan = ((pan - 0.5f) * SQ(absX / 50.0f)) + 0.5f; - } - } - return (s8)((pan * 127.0f) + 0.5f); -} - -f32 Audio_ComputeSfxFreqScale(u8 bankId, u8 entryIdx) { - s32 phi_v0 = 0; - SfxBankEntry* entry = &gSfxBanks[bankId][entryIdx]; - f32 unk1C; - f32 freq = 1.0f; - - if (entry->sfxParams & SFX_FLAG_14) { - freq = 1.0f - ((gAudioCtx.audioRandom & 0xF) / 192.0f); - } - - switch (bankId) { - case BANK_PLAYER: - case BANK_ITEM: - case BANK_VOICE: - if (sAudioBaseFilter2 != 0) { - phi_v0 = 1; - } - break; - case BANK_ENV: - case BANK_ENEMY: - if (sAudioExtraFilter2 != 0) { - phi_v0 = 1; - } - break; - case BANK_SYSTEM: - case BANK_OCARINA: - break; - } - - if (phi_v0 == 1) { - if (!(entry->sfxParams & SFX_FLAG_11)) { - freq *= (1.0293 - ((gAudioCtx.audioRandom & 0xF) / 144.0f)); - } - } - - unk1C = entry->dist; - if (!(entry->sfxParams & SFX_FLAG_13)) { - if (!(entry->sfxParams & SFX_FLAG_15)) { - if (unk1C >= 10000.0f) { - freq += 0.2f; - } else { - freq += (0.2f * (unk1C / 10000.0f)); - } - } - } - - if ((entry->sfxParams & SFX_PARAM_67_MASK) != (0 << SFX_PARAM_67_SHIFT)) { - freq += (entry->unk_2F / 192.0f); - } - - return freq; -} - -u8 func_800F37B8(f32 behindScreenZ, SfxBankEntry* arg1, s8 arg2) { - s8 phi_v0; - u8 phi_v1; - f32 phi_f0; - f32 phi_f12; - - if (*arg1->posZ < behindScreenZ) { - phi_v0 = arg2 < 65 ? arg2 : 0x7F - arg2; - - if (phi_v0 < 30) { - phi_v1 = 0; - } else { - phi_v1 = (((phi_v0 & 0xFFFF) * 10) - 300) / 34; - if (phi_v1 != 0) { - phi_v1 = 0x10 - phi_v1; - } - } - } else { - phi_v1 = 0; - } - - if (phi_v1 == 0) { - if (arg1->sfxParams & SFX_FLAG_9) { - phi_v1 = 0xF; - } - } - - switch ((arg1->sfxParams & SFX_PARAM_01_MASK) >> SFX_PARAM_01_SHIFT) { - case 1: - phi_f0 = 12.0f; - break; - case 2: - phi_f0 = 9.0f; - break; - case 3: - phi_f0 = 6.0f; - break; - default: - phi_f0 = 15.0f; - break; - } - - phi_f12 = CLAMP_MAX(arg1->dist, 10000.0f / 5.2f); - - return (phi_v1 * 0x10) + (u8)((phi_f0 * phi_f12) / (10000.0f / 5.2f)); -} - -s8 func_800F3990(f32 arg0, u16 sfxParams) { - s8 ret = 0; - - if (arg0 >= 0.0f) { - if (arg0 > 625.0f) { - ret = 127; - } else { - ret = (arg0 / 625.0f) * 126.0f; - } - } - return ret | 1; -} - -void Audio_SetSfxProperties(u8 bankId, u8 entryIdx, u8 channelIdx) { - f32 vol = 1.0f; - s8 volS8; - s8 reverb = 0; - f32 freqScale = 1.0f; - s8 panSigned = 0x40; - u8 stereoBits = 0; - u8 filter = 0; - s8 sp38 = 0; - f32 behindScreenZ; - u8 baseFilter = 0; - SfxBankEntry* entry = &gSfxBanks[bankId][entryIdx]; - - switch (bankId) { - case BANK_PLAYER: - case BANK_ITEM: - case BANK_ENV: - case BANK_ENEMY: - case BANK_VOICE: - if (sSoundMode == SOUNDMODE_SURROUND) { - sp38 = func_800F3990(*entry->posY, entry->sfxParams); - } - FALLTHROUGH; - case BANK_OCARINA: - entry->dist = sqrtf(entry->dist); - vol = Audio_ComputeSfxVolume(bankId, entryIdx) * *entry->vol; - reverb = Audio_ComputeSfxReverb(bankId, entryIdx, channelIdx); - panSigned = Audio_ComputeSfxPanSigned(*entry->posX, *entry->posZ, entry->token); - freqScale = Audio_ComputeSfxFreqScale(bankId, entryIdx) * *entry->freqScale; - - if (sSoundMode == SOUNDMODE_SURROUND) { - behindScreenZ = sBehindScreenZ[(entry->sfxParams & SFX_FLAG_10) >> SFX_FLAG_10_SHIFT]; - if (!(entry->sfxParams & SFX_FLAG_11)) { - if (*entry->posZ < behindScreenZ) { - stereoBits = 0x10; - } - - if ((sSfxChannelState[channelIdx].stereoBits ^ stereoBits) & 0x10) { - if (panSigned < 0x40) { - stereoBits = sSfxChannelState[channelIdx].stereoBits ^ 0x14; - } else { - stereoBits = sSfxChannelState[channelIdx].stereoBits ^ 0x18; - } - } else { - stereoBits = sSfxChannelState[channelIdx].stereoBits; - } - } - } - if (sAudioBaseFilter != 0) { - if ((bankId == BANK_ITEM) || (bankId == BANK_PLAYER) || (bankId == BANK_VOICE)) { - baseFilter = sAudioBaseFilter; - } - } - - if ((baseFilter | sAudioExtraFilter) != 0) { - filter = (baseFilter | sAudioExtraFilter); - } else if ((sSoundMode == SOUNDMODE_SURROUND) && !(entry->sfxParams & SFX_FLAG_13)) { - filter = func_800F37B8(behindScreenZ, entry, panSigned); - } - break; - case BANK_SYSTEM: - break; - } - - if (sSfxChannelState[channelIdx].vol != vol) { - volS8 = (u8)(vol * 127.0f); - sSfxChannelState[channelIdx].vol = vol; - } else { - volS8 = -1; - } - - // CHAN_UPD_SCRIPT_IO (slot 2, sets volume) - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8) | 2, volS8); - if (reverb != sSfxChannelState[channelIdx].reverb) { - Audio_QueueCmdS8(0x5 << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), reverb); - sSfxChannelState[channelIdx].reverb = reverb; - } - if (freqScale != sSfxChannelState[channelIdx].freqScale) { - Audio_QueueCmdF32(0x4 << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), freqScale); - sSfxChannelState[channelIdx].freqScale = freqScale; - } - if (stereoBits != sSfxChannelState[channelIdx].stereoBits) { - Audio_QueueCmdS8(0xE << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), stereoBits | 0x10); - sSfxChannelState[channelIdx].stereoBits = stereoBits; - } - if (filter != sSfxChannelState[channelIdx].filter) { - // CHAN_UPD_SCRIPT_IO (slot 3, sets filter) - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8) | 3, filter); - sSfxChannelState[channelIdx].filter = filter; - } - if (sp38 != sSfxChannelState[channelIdx].unk_0C) { - // CHAN_UPD_UNK_0F - Audio_QueueCmdS8(0xC << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), 0x10); - // CHAN_UPD_UNK_20 - Audio_QueueCmdU16(0xD << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), ((u16)(sp38) << 8) + 0xFF); - sSfxChannelState[channelIdx].unk_0C = sp38; - } - if (panSigned != sSfxChannelState[channelIdx].panSigned) { - Audio_QueueCmdS8(0x3 << 24 | SEQ_PLAYER_SFX << 16 | (channelIdx << 8), panSigned); - sSfxChannelState[channelIdx].panSigned = panSigned; - } -} - -void Audio_ResetSfxChannelState(void) { - u8 i; - SfxPlayerState* state; - - for (i = 0; i < 16; i++) { - state = &sSfxChannelState[i]; - state->vol = 1.0f; - state->freqScale = 1.0f; - state->reverb = 0; - state->panSigned = 0x40; - state->stereoBits = 0; - state->filter = 0xFF; - state->unk_0C = 0xFF; - } - - sSfxChannelState[SFX_CHANNEL_OCARINA].unk_0C = 0; - sPrevSeqMode = 0; - sAudioCodeReverb = 0; -} - -void Audio_PlayCutsceneEffectsSequence(u8 csEffectType) { - if (gSfxBankMuted[0] != 1) { - SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_SUB, 0, 0, NA_BGM_CUTSCENE_EFFECTS); - SEQCMD_SET_CHANNEL_IO(SEQ_PLAYER_BGM_SUB, 0, 0, csEffectType); - } -} - -f32 func_800F3F84(f32 arg0) { - f32 ret = 1.0f; - - if (arg0 > 6.0f) { - D_8016B7A8 = 1.0f; - D_8016B7B0 = 1.1f; - } else { - ret = arg0 / 6.0f; - D_8016B7A8 = (ret * 0.22500002f) + 0.775f; - D_8016B7B0 = (ret * 0.2f) + 0.9f; - } - return ret; -} - -void func_800F4010(Vec3f* pos, u16 sfxId, f32 arg2) { - f32 sp24; - f32 phi_f0; - u8 phi_v0; - u16 sfxId2; - - D_80131C8C = arg2; - sp24 = func_800F3F84(arg2); - Audio_PlaySfxGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &gSfxDefaultReverb); - - if ((sfxId & 0xF0) == 0xB0) { - phi_f0 = 0.3f; - phi_v0 = 1; - sp24 = 1.0f; - } else { - phi_f0 = 1.1f; - phi_v0 = gAudioCtx.audioRandom % 2; - } - - if ((phi_f0 < arg2) && (phi_v0 != 0)) { - if ((sfxId & 0x80) != 0) { - sfxId2 = NA_SE_PL_METALEFFECT_ADULT; - } else { - sfxId2 = NA_SE_PL_METALEFFECT_KID; - } - D_8016B7AC = (sp24 * 0.7) + 0.3; - Audio_PlaySfxGeneral(sfxId2, pos, 4, &D_8016B7B0, &D_8016B7AC, &gSfxDefaultReverb); - } -} - -void func_800F4138(Vec3f* pos, u16 sfxId, f32 arg2) { - func_800F3F84(arg2); - Audio_PlaySfxGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &gSfxDefaultReverb); -} - -void func_800F4190(Vec3f* pos, u16 sfxId) { - Audio_PlaySfxGeneral(sfxId, pos, 4, &D_801305B0, &gSfxDefaultFreqAndVolScale, &D_801305B4); -} -void Audio_PlaySfxRandom(Vec3f* pos, u16 baseSfxId, u8 randLim) { - u8 offset = Audio_NextRandom() % randLim; - - Audio_PlaySfxGeneral(baseSfxId + offset, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultReverb); -} - -void func_800F4254(Vec3f* pos, u8 level) { - level &= 3; - if (level != sPrevChargeLevel) { - D_801305F4 = D_801305E4[level]; - switch (level) { - case 1: - Audio_PlaySfxGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultReverb); - break; - case 2: - Audio_PlaySfxGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultReverb); - break; - } - - sPrevChargeLevel = level; - } - - if (level != 0) { - Audio_PlaySfxGeneral(NA_SE_IT_SWORD_CHARGE - SFX_FLAG, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultReverb); - } -} - -void func_800F436C(Vec3f* pos, u16 sfxId, f32 arg2) { - if (arg2 < 0.75f) { - D_8016B7D8 = ((arg2 / 0.75f) * 0.25f) + 0.5f; - } else { - D_8016B7D8 = arg2; - } - - if (D_8016B7D8 > 0.5f) { - Audio_PlaySfxGeneral(sfxId, pos, 4, &D_8016B7D8, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - } -} - -void func_800F4414(Vec3f* pos, u16 sfxId, f32 arg2) { - D_801305B8--; - if (D_801305B8 == 0) { - Audio_PlaySfxGeneral(sfxId, pos, 4, &D_8016B7D8, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - - if (arg2 > 2.0f) { - arg2 = 2.0f; - } - D_801305B8 = (s8)((D_801305C0 - D_801305BC) * (1.0f - arg2)) + D_801305C0; - } -} - -void func_800F44EC(s8 arg0, s8 arg1) { - D_801305B8 = 1; - D_801305BC = arg1; - D_801305C0 = arg0; -} - -void func_800F4524(Vec3f* pos, u16 sfxId, s8 arg2) { - D_8016B7DC = arg2; - Audio_PlaySfxGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &D_8016B7DC); -} - -void func_800F4578(Vec3f* pos, u16 sfxId, f32 arg2) { - D_8016B7E0 = arg2; - Audio_PlaySfxGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &D_8016B7E0, &gSfxDefaultReverb); -} - -void func_800F45D0(f32 arg0) { - func_800F4414(&gSfxDefaultPos, NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG, arg0); - func_800F436C(&gSfxDefaultPos, 0, (0.15f * arg0) + 1.4f); -} - -void Audio_PlaySfxRiver(Vec3f* pos, f32 freqScale) { - if (!Audio_IsSfxPlaying(NA_SE_EV_RIVER_STREAM - SFX_FLAG)) { - sRiverFreqScaleLerp.value = freqScale; - } else if (freqScale != sRiverFreqScaleLerp.value) { - sRiverFreqScaleLerp.target = freqScale; - sRiverFreqScaleLerp.remainingFrames = 40; - sRiverFreqScaleLerp.step = (sRiverFreqScaleLerp.target - sRiverFreqScaleLerp.value) / 40; - } - Audio_PlaySfxGeneral(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); -} - -void Audio_PlaySfxWaterfall(Vec3f* pos, f32 freqScale) { - if (!Audio_IsSfxPlaying(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG)) { - sWaterfallFreqScaleLerp.value = freqScale; - } else if (freqScale != sWaterfallFreqScaleLerp.value) { - sWaterfallFreqScaleLerp.target = freqScale; - sWaterfallFreqScaleLerp.remainingFrames = 40; - sWaterfallFreqScaleLerp.step = (sWaterfallFreqScaleLerp.target - sWaterfallFreqScaleLerp.value) / 40; - } - Audio_PlaySfxGeneral(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, pos, 4, &sWaterfallFreqScaleLerp.value, - &sWaterfallFreqScaleLerp.value, &gSfxDefaultReverb); -} - -void Audio_StepFreqLerp(FreqLerp* lerp) { - if (lerp->remainingFrames != 0) { - lerp->remainingFrames--; - if (lerp->remainingFrames != 0) { - lerp->value += lerp->step; - } else { - lerp->value = lerp->target; - } - } -} - -void Audio_SetBgmVolumeOffDuringFanfare(void) { - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_FANFARE, 0, 10); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_FANFARE, 0, 10); -} - -void Audio_SetBgmVolumeOnDuringFanfare(void) { - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_FANFARE, 0x7F, 3); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_FANFARE, 0x7F, 3); -} - -void Audio_SetMainBgmVolume(u8 targetVol, u8 volFadeTimer) { - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_MAIN, targetVol, volFadeTimer); -} - -/** - * Incrementally increase volume of NA_BGM_GANON_TOWER for each new room during the climb of Ganon's Tower - */ -void Audio_SetGanonsTowerBgmVolumeLevel(u8 ganonsTowerLevel) { - u8 channelIdx; - s8 pan = 0; - - // Ganondorf's Lair - if (ganonsTowerLevel == 0) { - pan = 0x7F; - } - - for (channelIdx = 0; channelIdx < 16; channelIdx++) { - // CHAN_UPD_PAN_UNSIGNED - Audio_QueueCmdS8(_SHIFTL(0x7, 24, 8) | _SHIFTL(SEQ_PLAYER_BGM_MAIN, 16, 8) | _SHIFTL(channelIdx, 8, 8) | - _SHIFTL(0, 0, 8), - pan); - } - - // Lowest room in Ganon's Tower (Entrance Room) - if (ganonsTowerLevel == 7) { - // Adds a delay to setting the volume in the first room - sEnterGanonsTowerTimer = 2; - } else { - Audio_SetGanonsTowerBgmVolume(sGanonsTowerLevelsVol[ganonsTowerLevel % ARRAY_COUNTU(sGanonsTowerLevelsVol)]); - } -} - -/** - * If a new volume is requested for ganon's tower, update the volume and - * calculate a new low-pass filter cutoff and reverb based on the new volume - */ -s32 Audio_SetGanonsTowerBgmVolume(u8 targetVol) { - u8 lowPassFilterCutoff; - u16 reverb; - u8 channelIdx; - - if (sGanonsTowerVol != targetVol) { - // Sets the volume - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_MAIN, targetVol, 2); - - // Sets the filter cutoff of the form (lowPassFilterCutoff << 4) | (highPassFilter & 0xF). highPassFilter is - // always set to 0 - if (targetVol < 0x40) { - // Only the first room - lowPassFilterCutoff = 1 << 4; - } else { - // Higher volume leads to a higher cut-off frequency in the low-pass filtering - lowPassFilterCutoff = (((targetVol - 0x40) >> 2) + 1) << 4; - } - // Set lowPassFilterCutoff to io port 4 from channel 15 - SEQCMD_SET_CHANNEL_IO(SEQ_PLAYER_BGM_MAIN, 15, 4, lowPassFilterCutoff); - - // Sets the reverb - for (channelIdx = 0; channelIdx < 16; channelIdx++) { - if (gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIdx] != &gAudioCtx.sequenceChannelNone) { - // soundScriptIO[5] is set to 0x40 in channels 0, 1, and 4 - if ((u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIdx]->soundScriptIO[5] != - (u8)SEQ_IO_VAL_NONE) { - // Higher volume leads to lower reverb - reverb = ((u16)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIdx]->soundScriptIO[5] - - targetVol) + - 0x7F; - if (reverb > 0x7F) { - reverb = 0x7F; - } - // CHAN_UPD_REVERB - Audio_QueueCmdS8(_SHIFTL(0x5, 24, 8) | _SHIFTL(SEQ_PLAYER_BGM_MAIN, 16, 8) | - _SHIFTL(channelIdx, 8, 8) | _SHIFTL(0, 0, 8), - (u8)reverb); - } - } - } - sGanonsTowerVol = targetVol; - } - return -1; -} - -/** - * Responsible for lowering market bgm in Child Market Entrance and Child Market Back Alley - * Only lowers volume for 1 frame, so must be called every frame to maintain lower volume - */ -void Audio_LowerMainBgmVolume(u8 volume) { - sRiverSoundMainBgmVol = volume; - sRiverSoundMainBgmLower = true; -} - -void Audio_UpdateRiverSoundVolumes(void) { - // Updates Main Bgm Volume (RiverSound of type RS_LOWER_MAIN_BGM_VOLUME) - if (sRiverSoundMainBgmLower == true) { - if (sRiverSoundMainBgmCurrentVol != sRiverSoundMainBgmVol) { - // lowers the volume for 1 frame - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_MAIN, sRiverSoundMainBgmVol, 10); - sRiverSoundMainBgmCurrentVol = sRiverSoundMainBgmVol; - sRiverSoundMainBgmRestore = true; - } - sRiverSoundMainBgmLower = false; - } else if (sRiverSoundMainBgmRestore == true && D_80130608 == 0) { - // restores the volume every frame - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_MAIN, 0x7F, 10); - sRiverSoundMainBgmCurrentVol = 0x7F; - sRiverSoundMainBgmRestore = false; - } - - // Update Ganon's Tower Volume (RiverSound of type RS_GANON_TOWER_7) - if (sEnterGanonsTowerTimer != 0) { - sEnterGanonsTowerTimer--; - if (sEnterGanonsTowerTimer == 0) { - Audio_SetGanonsTowerBgmVolume(sGanonsTowerLevelsVol[7]); - } - } -} - -void Audio_PlaySfxIncreasinglyTransposed(Vec3f* pos, s16 sfxId, u8* semitones) { - Audio_PlaySfxGeneral(sfxId, pos, 4, &gPitchFrequencies[semitones[sAudioIncreasingTranspose] + 39], - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - - if (sAudioIncreasingTranspose < 15) { - sAudioIncreasingTranspose++; - } -} - -void Audio_ResetIncreasingTranspose(void) { - sAudioIncreasingTranspose = 0; -} - -void Audio_PlaySfxTransposed(Vec3f* pos, u16 sfxId, s8 semitone) { - Audio_PlaySfxGeneral(sfxId, pos, 4, &gPitchFrequencies[semitone + 39], &gSfxDefaultFreqAndVolScale, - &gSfxDefaultReverb); -} - -void func_800F4C58(Vec3f* pos, u16 sfxId, u8 arg2) { - u8 phi_s1 = 0; - u8 i; - u8 bankId; - - bankId = SFX_BANK_SHIFT(sfxId); - for (i = 0; i < bankId; i++) { - phi_s1 += gChannelsPerBank[gSfxChannelLayout][i]; - } - - for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) { - if ((gActiveSfx[bankId][i].entryIndex != 0xFF) && - (sfxId == gSfxBanks[bankId][gActiveSfx[bankId][i].entryIndex].sfxId)) { - Audio_QueueCmdS8( - _SHIFTL(0x6, 24, 8) | _SHIFTL(SEQ_PLAYER_SFX, 16, 8) | _SHIFTL(phi_s1, 8, 8) | _SHIFTL(6, 0, 8), arg2); - } - phi_s1++; - } - Audio_PlaySfxGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); -} - -void func_800F4E30(Vec3f* pos, f32 arg1) { - f32 phi_f22; - s8 phi_s4; - u8 i; - - if (sSariaBgmPtr == NULL) { - sSariaBgmPtr = pos; - D_80130650 = arg1; - } else if (pos != sSariaBgmPtr) { - if (arg1 < D_80130650) { - sSariaBgmPtr = pos; - D_80130650 = arg1; - } - } else { - D_80130650 = arg1; - } - - if (sSariaBgmPtr->x > 100.0f) { - phi_s4 = 0x7F; - } else if (sSariaBgmPtr->x < -100.0f) { - phi_s4 = 0; - } else { - phi_s4 = ((sSariaBgmPtr->x / 100.0f) * 64.0f) + 64.0f; - } - - if (D_80130650 > 400.0f) { - phi_f22 = 0.1f; - } else if (D_80130650 < 120.0f) { - phi_f22 = 1.0f; - } else { - phi_f22 = ((1.0f - ((D_80130650 - 120.0f) / 280.0f)) * 0.9f) + 0.1f; - } - - for (i = 0; i < 0x10; i++) { - if (i != 9) { - SEQCMD_SET_CHANNEL_VOLUME(SEQ_PLAYER_BGM_MAIN, i, 2, (127.0f * phi_f22)); - Audio_QueueCmdS8(0x3 << 24 | SEQ_PLAYER_BGM_MAIN << 16 | ((u8)((u32)i) << 8), phi_s4); - } - } -} - -void Audio_ClearSariaBgm(void) { - if (sSariaBgmPtr != NULL) { - sSariaBgmPtr = NULL; - } -} - -void Audio_ClearSariaBgmAtPos(Vec3f* pos) { - if (sSariaBgmPtr == pos) { - sSariaBgmPtr = NULL; - } -} - -/** - * Turns on and off channels from both bgm players in a way that splits - * equally between the two bgm channels. Split based on note priority - */ -void Audio_SplitBgmChannels(s8 volSplit) { - u8 volume; - u8 notePriority; - u16 channelBits; - u8 bgmPlayers[2] = { SEQ_PLAYER_BGM_MAIN, SEQ_PLAYER_BGM_SUB }; - u8 channelIdx; - u8 i; - - if ((Audio_GetActiveSeqId(SEQ_PLAYER_FANFARE) == NA_BGM_DISABLED) && - (Audio_GetActiveSeqId(SEQ_PLAYER_BGM_SUB) != NA_BGM_LONLON)) { - for (i = 0; i < ARRAY_COUNT(bgmPlayers); i++) { - if (i == 0) { - // Main Bgm SeqPlayer - volume = volSplit; - } else { - // Sub Bgm SeqPlayer - volume = 0x7F - volSplit; - } - - if (volume > 100) { - notePriority = 11; - } else if (volume < 20) { - notePriority = 2; - } else { - notePriority = ((volume - 20) / 10) + 2; - } - - channelBits = 0; - for (channelIdx = 0; channelIdx < 16; channelIdx++) { - if (notePriority > gAudioCtx.seqPlayers[bgmPlayers[i]].channels[channelIdx]->notePriority) { - // If the note currently playing in the channel is a high enough priority, - // then keep the channel on by setting a channelBit - // If this condition fails, then the channel will be shut off - channelBits += (1 << channelIdx); - } - } - - SEQCMD_SET_CHANNEL_DISABLE_MASK(bgmPlayers[i], channelBits); - } - } -} - -void Audio_PlaySariaBgm(Vec3f* pos, u16 seqId, u16 distMax) { - f32 absY; - f32 dist; - u8 vol; - f32 prevDist; - - if (D_8016B9F3 != 0) { - D_8016B9F3--; - return; - } - - dist = sqrtf(SQ(pos->z) + SQ(pos->x)); - if (sSariaBgmPtr == NULL) { - sSariaBgmPtr = pos; - Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_SUB, seqId, 0, 7, 2); - } else { - prevDist = sqrtf(SQ(sSariaBgmPtr->z) + SQ(sSariaBgmPtr->x)); - if (dist < prevDist) { - sSariaBgmPtr = pos; - } else { - dist = prevDist; - } - } - - if (pos->y < 0.0f) { - absY = -pos->y; - } else { - absY = pos->y; - } - - if ((distMax / 15.0f) < absY) { - vol = 0; - } else if (dist < distMax) { - vol = (1.0f - (dist / distMax)) * 127.0f; - } else { - vol = 0; - } - - if (seqId != NA_BGM_GREAT_FAIRY) { - Audio_SplitBgmChannels(vol); - } - - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_BGM_SUB, vol, 0); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_SUB, 0x7F - vol, 0); -} - -void Audio_ClearSariaBgm2(void) { - sSariaBgmPtr = NULL; -} - -void Audio_PlayMorningSceneSequence(u16 seqId) { - Audio_PlaySceneSequence(seqId); - // Writing a value of 1 to ioPort 0 will be used by - // `NA_BGM_FIELD_LOGIC` to play `NA_BGM_FIELD_MORNING` first - Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_MAIN, seqId, 0, 0, 1); -} - -void Audio_PlaySceneSequence(u16 seqId) { - u8 fadeInDuration = 0; - u8 skipHarpIntro; - - if (Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_WINDMILL) { - if (Audio_GetActiveSeqId(SEQ_PLAYER_BGM_SUB) == NA_BGM_LONLON) { - Audio_StopSequence(SEQ_PLAYER_BGM_SUB, 0); - // Terminate all internal audio cmds - Audio_QueueCmdS32(0xF8000000, 0); - } - - if ((sSeqFlags[sPrevSceneSeqId] & SEQ_FLAG_RESUME_PREV) && (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_RESUME)) { - // Resume the sequence from the point where it left off last time it was played in the scene - if ((sSeqResumePoint & 0x3F) != 0) { - fadeInDuration = 30; - } - - // Write the sequence resumePoint to start from into ioPort 7 - Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_MAIN, seqId, fadeInDuration, 7, sSeqResumePoint); - - sSeqResumePoint = 0; - } else { - // Start the sequence from the beginning - - // Writes to ioPort 7. See `SEQ_FLAG_SKIP_HARP_INTRO` for writing a value of 1 to ioPort 7. - skipHarpIntro = (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_SKIP_HARP_INTRO) ? 1 : (u8)SEQ_IO_VAL_NONE; - Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_MAIN, seqId, 0, 7, skipHarpIntro); - - if (!(sSeqFlags[seqId] & SEQ_FLAG_RESUME_PREV)) { - // Reset the sequence resumePoint - sSeqResumePoint = SEQ_RESUME_POINT_NONE; - } - } - sPrevSceneSeqId = seqId & 0xFF; - } -} - -void Audio_UpdateSceneSequenceResumePoint(void) { - u16 seqId = Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN); - - if ((seqId != NA_BGM_DISABLED) && (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_RESUME)) { - if (sSeqResumePoint != SEQ_RESUME_POINT_NONE) { - // Get the current point to resume from - sSeqResumePoint = gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].soundScriptIO[3]; - } else { - // Initialize the point to resume from to the start of the sequence. - sSeqResumePoint = 0; - } - } -} - -void Audio_PlayWindmillBgm(void) { - if (Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_WINDMILL) { - SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, 0, NA_BGM_WINDMILL); - } -} - -void Audio_SetMainBgmTempoFreqAfterFanfare(f32 scaleTempoAndFreq, u8 duration) { - if (scaleTempoAndFreq == 1.0f) { - // Should instead use `SEQCMD_SETUP_RESET_TEMPO` to wait until the fanfare is finished - SEQCMD_RESET_TEMPO(SEQ_PLAYER_BGM_MAIN, duration); - } else { - SEQCMD_SETUP_SCALE_TEMPO(SEQ_PLAYER_FANFARE, SEQ_PLAYER_BGM_MAIN, duration, scaleTempoAndFreq * 100.0f); - } - - SEQCMD_SETUP_SET_PLAYER_FREQ(SEQ_PLAYER_FANFARE, SEQ_PLAYER_BGM_MAIN, duration, scaleTempoAndFreq * 100.0f); -} - -/** - * Set the tempo for the timed minigame sequence to 210 bpm, - * which is faster than the default tempo - */ -void Audio_SetFastTempoForTimedMinigame(void) { - if ((Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) == NA_BGM_TIMED_MINI_GAME) && - Audio_IsSeqCmdNotQueued(SEQCMD_OP_PLAY_SEQUENCE << 28, SEQCMD_OP_MASK)) { - SEQCMD_SET_TEMPO(SEQ_PLAYER_BGM_MAIN, 5, 210); - } -} - -void Audio_PlaySequenceInCutscene(u16 seqId) { - if (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_FANFARE) { - Audio_PlayFanfare(seqId); - } else if (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_FANFARE_GANON) { - SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_FANFARE, 0, 0, seqId); - } else { - Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_MAIN, seqId, 0, 7, SEQ_IO_VAL_NONE); - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, 0); - } -} - -void Audio_StopSequenceInCutscene(u16 seqId) { - if (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_FANFARE) { - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, 0); - } else if (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_FANFARE_GANON) { - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, 0); - } else { - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0); - } -} - -s32 Audio_IsSequencePlaying(u16 seqId) { - u8 seqPlayerIndex = SEQ_PLAYER_BGM_MAIN; - - if (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_FANFARE) { - seqPlayerIndex = SEQ_PLAYER_FANFARE; - } else if (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_FANFARE_GANON) { - seqPlayerIndex = SEQ_PLAYER_FANFARE; - } - - if ((seqId & 0xFF) == (Audio_GetActiveSeqId(seqPlayerIndex) & 0xFF)) { - return true; - } else { - return false; - } -} - -/** - * Plays a sequence on the main bgm player, but stores the previous sequence to return to later - * Designed for the mini-boss sequence, but also used by mini-game 2 sequence - */ -void func_800F5ACC(u16 seqId) { - u16 curSeqId = Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN); - - if ((curSeqId & 0xFF) != NA_BGM_GANON_TOWER && (curSeqId & 0xFF) != NA_BGM_ESCAPE && curSeqId != seqId) { - Audio_SetSequenceMode(SEQ_MODE_IGNORE); - if (curSeqId != NA_BGM_DISABLED) { - sPrevMainBgmSeqId = curSeqId; - } else { - osSyncPrintf("Middle Boss BGM Start not stack \n"); - } - - SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, 0, seqId); - } -} - -/** - * Restores the previous sequence to the main bgm player before func_800F5ACC was called - */ -void func_800F5B58(void) { - if ((Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_DISABLED) && (sPrevMainBgmSeqId != NA_BGM_DISABLED) && - (sSeqFlags[Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) & 0xFF] & SEQ_FLAG_RESTORE)) { - if (sPrevMainBgmSeqId == NA_BGM_DISABLED) { - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0); - } else { - SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, 0, sPrevMainBgmSeqId); - } - - sPrevMainBgmSeqId = NA_BGM_DISABLED; - } -} - -/** - * Plays the nature ambience sequence on the main bgm player, but stores the previous sequence to return to later - */ -void func_800F5BF0(u8 natureAmbienceId) { - u16 curSeqId = Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN); - - if (curSeqId != NA_BGM_NATURE_AMBIENCE) { - sPrevMainBgmSeqId = curSeqId; - } - - Audio_PlayNatureAmbienceSequence(natureAmbienceId); -} - -/** - * Restores the previous sequence to the main bgm player before func_800F5BF0 was called - */ -void func_800F5C2C(void) { - if (sPrevMainBgmSeqId != NA_BGM_DISABLED) { - SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, 0, sPrevMainBgmSeqId); - } - sPrevMainBgmSeqId = NA_BGM_DISABLED; -} - -void Audio_PlayFanfare(u16 seqId) { - u16 curSeqId; - u32 outNumFonts; - u8* curFontId; - u8* requestedFontId; - - curSeqId = Audio_GetActiveSeqId(SEQ_PLAYER_FANFARE); - - curFontId = func_800E5E84(curSeqId & 0xFF, &outNumFonts); - requestedFontId = func_800E5E84(seqId & 0xFF, &outNumFonts); - - if ((curSeqId == NA_BGM_DISABLED) || (*curFontId == *requestedFontId)) { - sFanfareStartTimer = 1; - } else { - // Give extra time to start the fanfare if both another fanfare needs to be stopped - // and a new fontId needs to be loaded in - sFanfareStartTimer = 5; - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, 0); - } - sFanfareSeqId = seqId; -} - -void Audio_UpdateFanfare(void) { - u16 seqIdFanfare; - u16 seqIdBgmMain; - u16 seqIdBgmSub; - - if (sFanfareStartTimer != 0) { - sFanfareStartTimer--; - if (sFanfareStartTimer == 0) { - Audio_QueueCmdS32(0xE3000000, SEQUENCE_TABLE); - Audio_QueueCmdS32(0xE3000000, FONT_TABLE); - - seqIdBgmMain = Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN); - seqIdFanfare = Audio_GetActiveSeqId(SEQ_PLAYER_FANFARE); - seqIdBgmSub = Audio_GetActiveSeqId(SEQ_PLAYER_BGM_SUB); - - (void)seqIdBgmMain; // suppresses set but unused warning - if (seqIdFanfare == NA_BGM_DISABLED) { - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_FANFARE, 0, 5); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_FANFARE, 0, 5); - SEQCMD_SETUP_RESTORE_PLAYER_VOLUME_WITH_SCALE_INDEX(SEQ_PLAYER_FANFARE, SEQ_PLAYER_BGM_MAIN, - VOL_SCALE_INDEX_FANFARE, 10); - SEQCMD_SETUP_RESTORE_PLAYER_VOLUME_WITH_SCALE_INDEX(SEQ_PLAYER_FANFARE, SEQ_PLAYER_BGM_SUB, - VOL_SCALE_INDEX_FANFARE, 10); - SEQCMD_SETUP_SET_CHANNEL_DISABLE_MASK(SEQ_PLAYER_FANFARE, SEQ_PLAYER_BGM_MAIN, 0); - if (seqIdBgmSub != NA_BGM_LONLON) { - SEQCMD_SETUP_SET_CHANNEL_DISABLE_MASK(SEQ_PLAYER_FANFARE, SEQ_PLAYER_BGM_SUB, 0); - } - } - SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_FANFARE, 1, 0, sFanfareSeqId); - SEQCMD_SET_CHANNEL_DISABLE_MASK(SEQ_PLAYER_BGM_MAIN, 0xFFFF); - if (seqIdBgmSub != NA_BGM_LONLON) { - SEQCMD_SET_CHANNEL_DISABLE_MASK(SEQ_PLAYER_BGM_SUB, 0xFFFF); - } - } - } -} - -void Audio_PlaySequenceWithSeqPlayerIO(u8 seqPlayerIndex, u16 seqId, u8 fadeInDuration, s8 ioPort, s8 ioData) { - SEQCMD_SET_PLAYER_IO(seqPlayerIndex, ioPort, ioData); - SEQCMD_PLAY_SEQUENCE(seqPlayerIndex, fadeInDuration, 0, seqId); -} - -void Audio_SetSequenceMode(u8 seqMode) { - s32 volumeFadeInTimer; - u16 seqId; - u8 volumeFadeOutTimer; - - sSeqModeInput = seqMode; - if (sPrevMainBgmSeqId == NA_BGM_DISABLED) { - if (sAudioCutsceneFlag) { - seqMode = SEQ_MODE_IGNORE; - } - - seqId = gActiveSeqs[SEQ_PLAYER_BGM_MAIN].seqId; - - if (seqId == NA_BGM_FIELD_LOGIC && Audio_GetActiveSeqId(SEQ_PLAYER_BGM_SUB) == (NA_BGM_ENEMY | 0x800)) { - seqMode = SEQ_MODE_IGNORE; - } - - if ((seqId == NA_BGM_DISABLED) || (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_ENEMY) || - ((sPrevSeqMode & 0x7F) == SEQ_MODE_ENEMY)) { - if (seqMode != (sPrevSeqMode & 0x7F)) { - if (seqMode == SEQ_MODE_ENEMY) { - // Start playing enemy bgm - if (gActiveSeqs[SEQ_PLAYER_BGM_SUB].volScales[VOL_SCALE_INDEX_FANFARE] - sAudioEnemyVol < 0) { - volumeFadeInTimer = - -(gActiveSeqs[SEQ_PLAYER_BGM_SUB].volScales[VOL_SCALE_INDEX_FANFARE] - sAudioEnemyVol); - } else { - volumeFadeInTimer = - gActiveSeqs[SEQ_PLAYER_BGM_SUB].volScales[VOL_SCALE_INDEX_FANFARE] - sAudioEnemyVol; - } - - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_BGM_SUB, sAudioEnemyVol, - volumeFadeInTimer); - SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_SUB, 10, 8, NA_BGM_ENEMY); - - if (seqId != NA_BGM_NATURE_AMBIENCE) { - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_SUB, - (0x7F - sAudioEnemyVol) & 0xFF, 0xA); - Audio_SplitBgmChannels(sAudioEnemyVol); - } - } else if ((sPrevSeqMode & 0x7F) == SEQ_MODE_ENEMY) { - // Stop playing enemy bgm - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_SUB, 10); - if (seqMode == SEQ_MODE_IGNORE) { - volumeFadeOutTimer = 0; - } else { - volumeFadeOutTimer = 10; - } - - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_SUB, 0x7F, volumeFadeOutTimer); - Audio_SplitBgmChannels(0); - } - - sPrevSeqMode = seqMode + 0x80; - } - } else { - // Hyrule Field will play slightly different background music depending on whether player is standing - // still or moving. This is the logic to determine the transition between those two states - if (seqMode == SEQ_MODE_DEFAULT) { - if (sPrevSeqMode == SEQ_MODE_STILL) { - sNumFramesMoving = 0; - } - sNumFramesStill = 0; - sNumFramesMoving++; - } else { - sNumFramesStill++; - } - - if (seqMode == SEQ_MODE_STILL && sNumFramesStill < 30 && sNumFramesMoving > 20) { - seqMode = SEQ_MODE_DEFAULT; - } - - sPrevSeqMode = seqMode; - SEQCMD_SET_PLAYER_IO(SEQ_PLAYER_BGM_MAIN, 2, seqMode); - } - } -} - -void Audio_SetBgmEnemyVolume(f32 dist) { - f32 adjDist; - - if (sPrevSeqMode == (0x80 | SEQ_MODE_ENEMY)) { - if (dist != sAudioEnemyDist) { - if (dist < 150.0f) { - adjDist = 0.0f; - } else if (dist > 500.0f) { - adjDist = 350.0f; - } else { - adjDist = dist - 150.0f; - } - - sAudioEnemyVol = ((350.0f - adjDist) * 127.0f) / 350.0f; - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_BGM_SUB, sAudioEnemyVol, 10); - if (gActiveSeqs[SEQ_PLAYER_BGM_MAIN].seqId != NA_BGM_NATURE_AMBIENCE) { - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_SUB, (0x7F - sAudioEnemyVol), 10); - } - } - if (gActiveSeqs[SEQ_PLAYER_BGM_MAIN].seqId != NA_BGM_NATURE_AMBIENCE) { - Audio_SplitBgmChannels(sAudioEnemyVol); - } - } - sAudioEnemyDist = dist; -} - -void Audio_UpdateMalonSinging(f32 dist, u16 seqId) { - s8 pad; - s8 melodyVolume; - s16 curSeqId; - - sIsMalonSinging = true; - sMalonSingingDist = dist; - - if (sMalonSingingDisabled) { - return; - } - - curSeqId = (s8)(Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) & 0xFF); - - if (curSeqId == (seqId & 0xFF)) { - if ((seqId & 0xFF) == NA_BGM_LONLON) { - // Malon is singing along with the Lon Lon Sequence - - if (dist > 2000.0f) { - melodyVolume = 127; - } else if (dist < 200.0f) { - melodyVolume = 0; - } else { - melodyVolume = (s8)(((dist - 200.0f) * 127.0f) / 1800.0f); - } - - // Update volume for channels 0 & 1, which contain Malon's singing - SEQCMD_SET_CHANNEL_VOLUME(SEQ_PLAYER_BGM_MAIN, 0, 3, 127 - melodyVolume); - SEQCMD_SET_CHANNEL_VOLUME(SEQ_PLAYER_BGM_MAIN, 1, 3, 127 - melodyVolume); - - // Update volume for channel 13, which contains the melody line for Lon Lon's Sequence - SEQCMD_SET_CHANNEL_VOLUME(SEQ_PLAYER_BGM_MAIN, 13, 3, melodyVolume); - if (sMalonSingingTimer == 0) { - sMalonSingingTimer++; - } - } - } else if ((curSeqId == NA_BGM_NATURE_AMBIENCE) && ((seqId & 0xFF) == NA_BGM_LONLON)) { - // Malon is singing along with ambience - curSeqId = (s8)(Audio_GetActiveSeqId(SEQ_PLAYER_BGM_SUB) & 0xFF); - - if ((curSeqId != (seqId & 0xFF)) && (sMalonSingingTimer < 10)) { - Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_SUB, NA_BGM_LONLON, 0, 0, 0); - // Disable all channels between 2-15. - // Only allow the two channels with Malon's singing to play, and suppress the full lon lon sequence. - SEQCMD_SET_CHANNEL_DISABLE_MASK(SEQ_PLAYER_BGM_SUB, 0xFFFC); - sMalonSingingTimer = 10; - } - - if (dist > 2000.0f) { - melodyVolume = 127; - } else if (dist < 200.0f) { - melodyVolume = 0; - } else { - melodyVolume = (s8)(((dist - 200.0f) * 127.0f) / 1800.0f); - } - - // Update volume for channels 0 & 1, which contain Malon's singing - SEQCMD_SET_CHANNEL_VOLUME(SEQ_PLAYER_BGM_SUB, 0, 3, 127 - melodyVolume); - SEQCMD_SET_CHANNEL_VOLUME(SEQ_PLAYER_BGM_SUB, 1, 3, 127 - melodyVolume); - } - - if (sMalonSingingTimer < 10) { - sMalonSingingTimer++; - } -} - -void func_800F64E0(u8 arg0) { - D_80130608 = arg0; - if (arg0 != 0) { - Audio_PlaySfxGeneral(NA_SE_SY_WIN_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - Audio_QueueCmdS32(0xF1000000, 0); - } else { - Audio_PlaySfxGeneral(NA_SE_SY_WIN_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - Audio_QueueCmdS32(0xF2000000, 0); - } -} - -/** - * Enable or disable Malon's singing - * - * @param malonSingingDisabled true to disable, false to enable - */ -void Audio_ToggleMalonSinging(u8 malonSingingDisabled) { - u8 seqPlayerIndex; - u16 channelMaskDisable; - - sMalonSingingDisabled = malonSingingDisabled; - - if ((Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) & 0xFF) == NA_BGM_LONLON) { - // Malon is singing along with the Lon Lon Sequence - seqPlayerIndex = SEQ_PLAYER_BGM_MAIN; - // Do not disable any channel. - // Allow the full lon lon sequence to play in addition to Malon's singing. - channelMaskDisable = 0; - } else if ((u8)Audio_GetActiveSeqId(SEQ_PLAYER_BGM_SUB) == NA_BGM_LONLON) { - // Malon is singing along with ambience - seqPlayerIndex = SEQ_PLAYER_BGM_SUB; - // Disable all channels between 2-15. - // Only allow the two channels with Malon's singing to play, and suppress the full lon lon sequence. - channelMaskDisable = 0xFFFC; - } else { - return; - } - - if (malonSingingDisabled) { - // Turn volume off for channels 0 & 1, which contain Malon's singing - SEQCMD_SET_CHANNEL_VOLUME(seqPlayerIndex, 0, 1, 0); - SEQCMD_SET_CHANNEL_VOLUME(seqPlayerIndex, 1, 1, 0); - - if (seqPlayerIndex == SEQ_PLAYER_BGM_SUB) { - // When singing along with ambience, disable all 16 channels - SEQCMD_SET_CHANNEL_DISABLE_MASK(seqPlayerIndex, channelMaskDisable | 3); - } - } else { - if (seqPlayerIndex == SEQ_PLAYER_BGM_SUB) { - // When singing along with ambience, start the sequence - Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_SUB, NA_BGM_LONLON, 0, 0, 0); - } - - // Turn volume on for only channels 0 & 1, which contain Malon's singing - SEQCMD_SET_CHANNEL_VOLUME(seqPlayerIndex, 0, 1, 0x7F); - SEQCMD_SET_CHANNEL_VOLUME(seqPlayerIndex, 1, 1, 0x7F); - - if (seqPlayerIndex == SEQ_PLAYER_BGM_SUB) { - // When singing along with ambience, disable channels 2-15 - SEQCMD_SET_CHANNEL_DISABLE_MASK(seqPlayerIndex, channelMaskDisable); - } - } -} - -void Audio_SetEnvReverb(s8 reverb) { - sAudioEnvReverb = reverb & 0x7F; -} - -void Audio_SetCodeReverb(s8 reverb) { - if (reverb != 0) { - sAudioCodeReverb = reverb & 0x7F; - } -} - -void func_800F6700(s8 audioSetting) { - s8 soundModeIndex; - - switch (audioSetting) { - case 0: - soundModeIndex = SOUNDMODE_STEREO; - sSoundMode = SOUNDMODE_STEREO; - break; - - case 1: - soundModeIndex = SOUNDMODE_MONO; - sSoundMode = SOUNDMODE_MONO; - break; - - case 2: - soundModeIndex = SOUNDMODE_HEADSET; - sSoundMode = SOUNDMODE_HEADSET; - break; - - case 3: - soundModeIndex = SOUNDMODE_STEREO; - sSoundMode = SOUNDMODE_SURROUND; - break; - } - - SEQCMD_SET_SOUND_MODE(soundModeIndex); -} - -void Audio_SetBaseFilter(u8 filter) { - if (sAudioBaseFilter != filter) { - if (filter == 0) { - Audio_StopSfxById(NA_SE_PL_IN_BUBBLE); - } else if (sAudioBaseFilter == 0) { - Audio_PlaySfxGeneral(NA_SE_PL_IN_BUBBLE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - } - } - sAudioBaseFilter = filter; - sAudioBaseFilter2 = filter; -} - -void Audio_SetExtraFilter(u8 filter) { - u32 t; - u8 i; - - sAudioExtraFilter2 = filter; - sAudioExtraFilter = filter; - if (gActiveSeqs[SEQ_PLAYER_BGM_MAIN].seqId == NA_BGM_NATURE_AMBIENCE) { - for (i = 0; i < 16; i++) { - t = i; - // CHAN_UPD_SCRIPT_IO (seq player 0, all channels, slot 6) - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_BGM_MAIN << 16 | ((t & 0xFF) << 8) | 6, filter); - } - } -} - -void Audio_SetCutsceneFlag(s8 flag) { - sAudioCutsceneFlag = flag; -} - -void Audio_PlaySfxGeneralIfNotInCutscene(u16 sfxId, Vec3f* pos, u8 arg2, f32* freqScale, f32* arg4, s8* reverbAdd) { - if (!sAudioCutsceneFlag) { - Audio_PlaySfxGeneral(sfxId, pos, arg2, freqScale, arg4, reverbAdd); - } -} - -void Audio_PlaySfxIfNotInCutscene(u16 sfxId) { - Audio_PlaySfxGeneralIfNotInCutscene(sfxId, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); -} - -void func_800F6964(u16 arg0) { - s32 skip; - u8 channelIdx; - - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, (arg0 * 3) / 2); - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, (arg0 * 3) / 2); - for (channelIdx = 0; channelIdx < 16; channelIdx++) { - skip = false; - switch (channelIdx) { - case SFX_CHANNEL_SYSTEM0: - case SFX_CHANNEL_SYSTEM1: - if (gAudioSpecId == 10) { - skip = true; - } - break; - case SFX_CHANNEL_OCARINA: - skip = true; - break; - } - - if (!skip) { - SEQCMD_SET_CHANNEL_VOLUME(SEQ_PLAYER_SFX, channelIdx, arg0 >> 1, 0); - } - } - - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_SUB, (arg0 * 3) / 2); -} - -void Audio_StopBgmAndFanfare(u16 fadeOutDuration) { - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, fadeOutDuration); - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_FANFARE, fadeOutDuration); - SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_SUB, fadeOutDuration); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_SUB, 0x7F, 0); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_FANFARE, 0x7F, 0); -} - -void func_800F6B3C(void) { - Audio_StartSequence(SEQ_PLAYER_SFX, 0, 0xFF, 5); -} - -void Audio_DisableAllSeq(void) { - Audio_DisableSeq(SEQ_PLAYER_BGM_MAIN, 0); - Audio_DisableSeq(SEQ_PLAYER_FANFARE, 0); - Audio_DisableSeq(SEQ_PLAYER_SFX, 0); - Audio_DisableSeq(SEQ_PLAYER_BGM_SUB, 0); - Audio_ScheduleProcessCmds(); -} - -s8 func_800F6BB8(void) { - return func_800E6680(); -} - -void func_800F6BDC(void) { - Audio_DisableAllSeq(); - Audio_ScheduleProcessCmds(); - while (true) { - if (!func_800F6BB8()) { - return; - } - } -} - -void Audio_PreNMI(void) { - Audio_PreNMIInternal(); -} - -void func_800F6C34(void) { - sPrevSeqMode = 0; - D_8016B7A8 = 1.0f; - D_8016B7B0 = 1.0f; - sAudioBaseFilter = 0; - sAudioExtraFilter = 0; - sAudioBaseFilter2 = 0; - sAudioExtraFilter2 = 0; - AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF); - sRiverFreqScaleLerp.remainingFrames = 0; - sWaterfallFreqScaleLerp.remainingFrames = 0; - sRiverFreqScaleLerp.value = 1.0f; - sWaterfallFreqScaleLerp.value = 1.0f; - D_8016B7D8 = 1.0f; - sRiverSoundMainBgmVol = 0x7F; - sRiverSoundMainBgmCurrentVol = 0x7F; - sRiverSoundMainBgmLower = false; - sRiverSoundMainBgmRestore = false; - sGanonsTowerVol = 0xFF; - sMalonSingingTimer = 0; - sSpecReverb = sSpecReverbs[gAudioSpecId]; - D_80130608 = 0; - sPrevMainBgmSeqId = NA_BGM_DISABLED; - Audio_QueueCmdS8(0x46 << 24 | SEQ_PLAYER_BGM_MAIN << 16, -1); - sSariaBgmPtr = NULL; - sFanfareStartTimer = 0; - D_8016B9F3 = 1; - sMalonSingingDisabled = false; -} - -void Audio_SetNatureAmbienceChannelIO(u8 channelIdxRange, u8 ioPort, u8 ioData) { - u8 firstChannelIdx; - u8 lastChannelIdx; - u8 channelIdx; - - if ((gActiveSeqs[SEQ_PLAYER_BGM_MAIN].seqId != NA_BGM_NATURE_AMBIENCE) && - Audio_IsSeqCmdNotQueued(SEQCMD_OP_PLAY_SEQUENCE << 28 | NA_BGM_NATURE_AMBIENCE, SEQCMD_OP_MASK | 0xFF)) { - sAudioNatureFailed = true; - return; - } - - // channelIdxRange = 01 on ioPort 1 - if (((channelIdxRange << 8) + ioPort) == ((NATURE_CHANNEL_CRITTER_0 << 8) + CHANNEL_IO_PORT_1)) { - if (Audio_GetActiveSeqId(SEQ_PLAYER_BGM_SUB) != NA_BGM_LONLON) { - sMalonSingingTimer = 0; - } - } - - firstChannelIdx = channelIdxRange >> 4; - lastChannelIdx = channelIdxRange & 0xF; - - if (firstChannelIdx == 0) { - firstChannelIdx = channelIdxRange & 0xF; - } - - for (channelIdx = firstChannelIdx; channelIdx <= lastChannelIdx; channelIdx++) { - SEQCMD_SET_CHANNEL_IO(SEQ_PLAYER_BGM_MAIN, channelIdx, ioPort, ioData); - } -} - -void Audio_StartNatureAmbienceSequence(u16 playerIO, u16 channelMask) { - u8 channelIdx; - - if (Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) == NA_BGM_WINDMILL) { - Audio_PlayCutsceneEffectsSequence(SEQ_CS_EFFECTS_RAINFALL); - return; - } - - SEQCMD_SET_PLAYER_IO(SEQ_PLAYER_BGM_MAIN, 0, 1); - SEQCMD_SET_PLAYER_IO(SEQ_PLAYER_BGM_MAIN, 4, playerIO >> 8); - SEQCMD_SET_PLAYER_IO(SEQ_PLAYER_BGM_MAIN, 5, playerIO & 0xFF); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_BGM_MAIN, 0x7F, 1); - - channelIdx = false; - if (gStartSeqDisabled) { - channelIdx = true; - SEQCMD_DISABLE_PLAY_SEQUENCES(false); - } - - SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, 0, NA_BGM_NATURE_AMBIENCE); - - if (channelIdx) { - SEQCMD_DISABLE_PLAY_SEQUENCES(true); - } - - for (channelIdx = 0; channelIdx < 16; channelIdx++) { - if (!(channelMask & (1 << channelIdx)) && (playerIO & (1 << channelIdx))) { - SEQCMD_SET_CHANNEL_IO(SEQ_PLAYER_BGM_MAIN, channelIdx, CHANNEL_IO_PORT_1, 1); - } - } -} - -void Audio_PlayNatureAmbienceSequence(u8 natureAmbienceId) { - u8 i = 0; - u8 channelIdx; - u8 ioPort; - u8 ioData; - - if ((gActiveSeqs[SEQ_PLAYER_BGM_MAIN].seqId == NA_BGM_DISABLED) || - !(sSeqFlags[gActiveSeqs[SEQ_PLAYER_BGM_MAIN].seqId & 0xFF & 0xFF] & SEQ_FLAG_NO_AMBIENCE)) { - - Audio_StartNatureAmbienceSequence(sNatureAmbienceDataIO[natureAmbienceId].playerIO, - sNatureAmbienceDataIO[natureAmbienceId].channelMask); - - while ((sNatureAmbienceDataIO[natureAmbienceId].channelIO[i] != 0xFF) && (i < 100)) { - channelIdx = sNatureAmbienceDataIO[natureAmbienceId].channelIO[i++]; - ioPort = sNatureAmbienceDataIO[natureAmbienceId].channelIO[i++]; - ioData = sNatureAmbienceDataIO[natureAmbienceId].channelIO[i++]; - SEQCMD_SET_CHANNEL_IO(SEQ_PLAYER_BGM_MAIN, channelIdx, ioPort, ioData); - } - - SEQCMD_SET_CHANNEL_IO(SEQ_PLAYER_BGM_MAIN, NATURE_CHANNEL_UNK, CHANNEL_IO_PORT_7, sSoundMode); - } -} - -void Audio_Init(void) { - AudioLoad_Init(NULL, 0); -} - -void Audio_InitSound(void) { - func_800F6C34(); - AudioOcarina_ResetStaffs(); - Audio_ResetSfxChannelState(); - Audio_ResetActiveSequencesAndVolume(); - Audio_ResetSfx(); - Audio_StartSequence(SEQ_PLAYER_SFX, 0, 0x70, 10); -} - -void func_800F7170(void) { - Audio_StartSequence(SEQ_PLAYER_SFX, 0, 0x70, 1); - Audio_QueueCmdS32(0xF2000000, 1); - Audio_ScheduleProcessCmds(); - Audio_QueueCmdS32(0xF8000000, 0); -} - -void func_800F71BC(s32 arg0) { - D_80133418 = 1; - func_800F6C34(); - AudioOcarina_ResetStaffs(); - Audio_ResetSfxChannelState(); - Audio_ResetActiveSequences(); - Audio_ResetSfx(); -} - -void func_800F7208(void) { - Audio_ResetActiveSequences(); - Audio_QueueCmdS32(0xF2000000, 1); - func_800F6C34(); - Audio_ResetSfxChannelState(); - Audio_StartSequence(SEQ_PLAYER_SFX, 0, 0x70, 1); -} diff --git a/src/code/code_800F7260.c b/src/code/code_800F7260.c deleted file mode 100644 index 4fa6b50a9..000000000 --- a/src/code/code_800F7260.c +++ /dev/null @@ -1,729 +0,0 @@ -#include "ultra64.h" -#include "global.h" -#include "terminal.h" - -typedef struct { - /* 0x00 */ u16 sfxId; - /* 0x04 */ Vec3f* pos; - /* 0x08 */ u8 token; - /* 0x0C */ f32* freqScale; - /* 0x10 */ f32* vol; - /* 0x14 */ s8* reverbAdd; -} SfxRequest; // size = 0x18 - -typedef struct { - /* 0x00 */ f32 value; - /* 0x04 */ f32 target; - /* 0x08 */ f32 step; - /* 0x0C */ u16 remainingFrames; -} UnusedBankLerp; // size = 0x10 - -SfxBankEntry D_8016BAD0[9]; -SfxBankEntry D_8016BC80[12]; -SfxBankEntry D_8016BEC0[22]; -SfxBankEntry D_8016C2E0[20]; -SfxBankEntry D_8016C6A0[8]; -SfxBankEntry D_8016C820[3]; -SfxBankEntry D_8016C8B0[5]; -SfxRequest sSfxRequests[0x100]; -u8 sSfxBankListEnd[7]; -u8 sSfxBankFreeListStart[7]; -u8 sSfxBankUnused[7]; -ActiveSfx gActiveSfx[7][3]; -u8 sCurSfxPlayerChannelIdx; -u8 gSfxBankMuted[7]; -UnusedBankLerp sUnusedBankLerp[7]; -u16 gAudioSfxSwapSource[10]; -u16 gAudioSfxSwapTarget[10]; -u8 gAudioSfxSwapMode[10]; - -void Audio_SetSfxBanksMute(u16 muteMask) { - u8 bankId; - - for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) { - if (muteMask & 1) { - gSfxBankMuted[bankId] = true; - } else { - gSfxBankMuted[bankId] = false; - } - muteMask = muteMask >> 1; - } -} - -void Audio_QueueSeqCmdMute(u8 channelIdx) { - D_801333D0 |= (1 << channelIdx); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_SFX, 0x40, 0xF); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_SFX, 0x40, 0xF); -} - -void Audio_ClearBGMMute(u8 channelIdx) { - D_801333D0 &= ((1 << channelIdx) ^ 0xFFFF); - if (D_801333D0 == 0) { - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_SFX, 0x7F, 0xF); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_SFX, 0x7F, 0xF); - } -} - -void Audio_PlaySfxGeneral(u16 sfxId, Vec3f* pos, u8 token, f32* freqScale, f32* vol, s8* reverbAdd) { - u8 i; - SfxRequest* req; - - if (!gSfxBankMuted[SFX_BANK_SHIFT(sfxId)]) { - req = &sSfxRequests[gSfxRequestWriteIndex]; - if (!gAudioSfxSwapOff) { - for (i = 0; i < 10; i++) { - if (sfxId == gAudioSfxSwapSource[i]) { - if (gAudioSfxSwapMode[i] == 0) { // "SWAP" - sfxId = gAudioSfxSwapTarget[i]; - } else { // "ADD" - req->sfxId = gAudioSfxSwapTarget[i]; - req->pos = pos; - req->token = token; - req->freqScale = freqScale; - req->vol = vol; - req->reverbAdd = reverbAdd; - gSfxRequestWriteIndex++; - req = &sSfxRequests[gSfxRequestWriteIndex]; - } - i = 10; // "break;" - } - } - } - req->sfxId = sfxId; - req->pos = pos; - req->token = token; - req->freqScale = freqScale; - req->vol = vol; - req->reverbAdd = reverbAdd; - gSfxRequestWriteIndex++; - } -} - -void Audio_RemoveMatchingSfxRequests(u8 aspect, SfxBankEntry* cmp) { - SfxRequest* req; - s32 remove; - u8 i = gSfxRequestReadIndex; - - for (; i != gSfxRequestWriteIndex; i++) { - remove = false; - req = &sSfxRequests[i]; - switch (aspect) { - case 0: - if (SFX_BANK_MASK(req->sfxId) == SFX_BANK_MASK(cmp->sfxId)) { - remove = true; - } - break; - case 1: - if (SFX_BANK_MASK(req->sfxId) == SFX_BANK_MASK(cmp->sfxId) && (&req->pos->x == cmp->posX)) { - remove = true; - } - break; - case 2: - if (&req->pos->x == cmp->posX) { - remove = true; - } - break; - case 3: - if (&req->pos->x == cmp->posX && req->sfxId == cmp->sfxId) { - remove = true; - } - break; - case 4: - if (req->token == cmp->token && req->sfxId == cmp->sfxId) { - remove = true; - } - break; - case 5: - if (req->sfxId == cmp->sfxId) { - remove = true; - } - break; - } - if (remove) { - req->sfxId = NA_SE_NONE; - } - } -} - -void Audio_ProcessSfxRequest(void) { - u16 sfxId; - u8 count; - u8 index; - SfxRequest* req; - SfxBankEntry* entry; - SfxParams* sfxParams; - s32 bankId; - u8 evictImportance; - u8 evictIndex; - - req = &sSfxRequests[gSfxRequestReadIndex]; - evictIndex = 0x80; - - if (req->sfxId == NA_SE_NONE) { - return; - } - - bankId = SFX_BANK(req->sfxId); - if ((1 << bankId) & D_801333F0) { - AudioDebug_ScrPrt("SE", req->sfxId); - bankId = SFX_BANK(req->sfxId); - } - count = 0; - index = gSfxBanks[bankId][0].next; - while (index != 0xFF && index != 0) { - if (gSfxBanks[bankId][index].posX == &req->pos->x) { - if ((gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].params & SFX_FLAG_5) && - gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].importance == - gSfxBanks[bankId][index].sfxImportance) { - return; - } - if (gSfxBanks[bankId][index].sfxId == req->sfxId) { - count = gUsedChannelsPerBank[gSfxChannelLayout][bankId]; - } else { - if (count == 0) { - evictIndex = index; - sfxId = gSfxBanks[bankId][index].sfxId & 0xFFFF; - evictImportance = gSfxParams[SFX_BANK_SHIFT(sfxId)][SFX_INDEX(sfxId)].importance; - } else if (gSfxBanks[bankId][index].sfxImportance < evictImportance) { - evictIndex = index; - sfxId = gSfxBanks[bankId][index].sfxId & 0xFFFF; - evictImportance = gSfxParams[SFX_BANK_SHIFT(sfxId)][SFX_INDEX(sfxId)].importance; - } - count++; - if (count == gUsedChannelsPerBank[gSfxChannelLayout][bankId]) { - if (gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].importance >= evictImportance) { - index = evictIndex; - } else { - index = 0; - } - } - } - if (count == gUsedChannelsPerBank[gSfxChannelLayout][bankId]) { - sfxParams = &gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)]; - if ((req->sfxId & 0xC00) || (sfxParams->params & SFX_FLAG_2) || (index == evictIndex)) { - if ((gSfxBanks[bankId][index].sfxParams & SFX_FLAG_3) && - gSfxBanks[bankId][index].state != SFX_STATE_QUEUED) { - Audio_ClearBGMMute(gSfxBanks[bankId][index].channelIdx); - } - gSfxBanks[bankId][index].token = req->token; - gSfxBanks[bankId][index].sfxId = req->sfxId; - gSfxBanks[bankId][index].state = SFX_STATE_QUEUED; - gSfxBanks[bankId][index].freshness = 2; - gSfxBanks[bankId][index].freqScale = req->freqScale; - gSfxBanks[bankId][index].vol = req->vol; - gSfxBanks[bankId][index].reverbAdd = req->reverbAdd; - gSfxBanks[bankId][index].sfxParams = sfxParams->params; - gSfxBanks[bankId][index].sfxImportance = sfxParams->importance; - } else if (gSfxBanks[bankId][index].state == SFX_STATE_PLAYING_2) { - gSfxBanks[bankId][index].state = SFX_STATE_PLAYING_1; - } - index = 0; - } - } - if (index != 0) { - index = gSfxBanks[bankId][index].next; - } - } - if (gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].next != 0xFF && index != 0) { - index = sSfxBankFreeListStart[bankId]; - entry = &gSfxBanks[bankId][index]; - entry->posX = &req->pos->x; - entry->posY = &req->pos->y; - entry->posZ = &req->pos->z; - entry->token = req->token; - entry->freqScale = req->freqScale; - entry->vol = req->vol; - entry->reverbAdd = req->reverbAdd; - sfxParams = &gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)]; - entry->sfxParams = sfxParams->params; - entry->sfxImportance = sfxParams->importance; - entry->sfxId = req->sfxId; - entry->state = SFX_STATE_QUEUED; - entry->freshness = 2; - entry->prev = sSfxBankListEnd[bankId]; - gSfxBanks[bankId][sSfxBankListEnd[bankId]].next = sSfxBankFreeListStart[bankId]; - sSfxBankListEnd[bankId] = sSfxBankFreeListStart[bankId]; - sSfxBankFreeListStart[bankId] = gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].next; - gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].prev = 0xFF; - entry->next = 0xFF; - } -} - -void Audio_RemoveSfxBankEntry(u8 bankId, u8 entryIndex) { - SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex]; - u8 i; - - if (entry->sfxParams & SFX_FLAG_3) { - Audio_ClearBGMMute(entry->channelIdx); - } - if (entryIndex == sSfxBankListEnd[bankId]) { - sSfxBankListEnd[bankId] = entry->prev; - } else { - gSfxBanks[bankId][entry->next].prev = entry->prev; - } - gSfxBanks[bankId][entry->prev].next = entry->next; - entry->next = sSfxBankFreeListStart[bankId]; - entry->prev = 0xFF; - gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].prev = entryIndex; - sSfxBankFreeListStart[bankId] = entryIndex; - entry->state = SFX_STATE_EMPTY; - - for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) { - if (gActiveSfx[bankId][i].entryIndex == entryIndex) { - gActiveSfx[bankId][i].entryIndex = 0xFF; - i = gChannelsPerBank[gSfxChannelLayout][bankId]; - } - } -} - -void Audio_ChooseActiveSfx(u8 bankId) { - u8 numChosenSfx; - u8 numChannels; - u8 entryIndex; - u8 i; - u8 j; - u8 k; - u8 sfxImportance; - u8 needNewSfx; - u8 chosenEntryIndex; - u16 temp3; - f32 tempf1; - SfxBankEntry* entry; - ActiveSfx chosenSfx[MAX_CHANNELS_PER_BANK]; - ActiveSfx* activeSfx; - s32 pad; - - numChosenSfx = 0; - for (i = 0; i < MAX_CHANNELS_PER_BANK; i++) { - chosenSfx[i].priority = 0x7FFFFFFF; - chosenSfx[i].entryIndex = 0xFF; - } - entryIndex = gSfxBanks[bankId][0].next; - k = 0; - while (entryIndex != 0xFF) { - if ((gSfxBanks[bankId][entryIndex].state == SFX_STATE_QUEUED) && - (gSfxBanks[bankId][entryIndex].sfxId & 0xC00)) { - gSfxBanks[bankId][entryIndex].freshness--; - } else if (!(gSfxBanks[bankId][entryIndex].sfxId & 0xC00) && - (gSfxBanks[bankId][entryIndex].state == SFX_STATE_PLAYING_2)) { - Audio_QueueCmdS8((gSfxBanks[bankId][entryIndex].channelIdx << 8) | 0x6020000, 0); - Audio_RemoveSfxBankEntry(bankId, entryIndex); - } - if (gSfxBanks[bankId][entryIndex].freshness == 0) { - Audio_RemoveSfxBankEntry(bankId, entryIndex); - } else if (gSfxBanks[bankId][entryIndex].state != SFX_STATE_EMPTY) { - entry = &gSfxBanks[bankId][entryIndex]; - - if (&gSfxDefaultPos.x == entry[0].posX) { - entry->dist = 0.0f; - } else { - tempf1 = *entry->posY * 1; - entry->dist = (SQ(*entry->posX) + SQ(tempf1) + SQ(*entry->posZ)) * 1; - } - sfxImportance = entry->sfxImportance; - if (entry->sfxParams & SFX_FLAG_4) { - entry->priority = SQ(0xFF - sfxImportance) * SQ(76); - } else { - if (entry->dist > 0x7FFFFFD0) { - entry->dist = 0x70000008; - osSyncPrintf(VT_COL(RED, WHITE) "<INAGAKI CHECK> dist over! " - "flag:%04X ptr:%08X pos:%f-%f-%f" VT_RST "\n", - entry->sfxId, entry->posX, entry->posZ, *entry->posX, *entry->posY, *entry->posZ); - } - temp3 = entry->sfxId; // fake - entry->priority = (u32)entry->dist + (SQ(0xFF - sfxImportance) * SQ(76)) + temp3 - temp3; - if (*entry->posZ < 0.0f) { - entry->priority += (s32)(-*entry->posZ * 6.0f); - } - } - if (entry->dist > SQ(1e5f)) { - if (entry->state == SFX_STATE_PLAYING_1) { - Audio_QueueCmdS8((entry->channelIdx << 8) | 0x6020000, 0); - if (entry->sfxId & 0xC00) { - Audio_RemoveSfxBankEntry(bankId, entryIndex); - entryIndex = k; - } - } - } else { - numChannels = gChannelsPerBank[gSfxChannelLayout][bankId]; - for (i = 0; i < numChannels; i++) { - if (chosenSfx[i].priority >= entry->priority) { - if (numChosenSfx < gChannelsPerBank[gSfxChannelLayout][bankId]) { - numChosenSfx++; - } - for (j = numChannels - 1; j > i; j--) { - chosenSfx[j].priority = chosenSfx[j - 1].priority; - chosenSfx[j].entryIndex = chosenSfx[j - 1].entryIndex; - } - chosenSfx[i].priority = entry->priority; - chosenSfx[i].entryIndex = entryIndex; - i = numChannels; // "break;" - } - } - } - k = entryIndex; - } - entryIndex = gSfxBanks[bankId][k].next; - } - for (i = 0; i < numChosenSfx; i++) { - entry = &gSfxBanks[bankId][chosenSfx[i].entryIndex]; - if (entry->state == SFX_STATE_QUEUED) { - entry->state = SFX_STATE_READY; - } else if (entry->state == SFX_STATE_PLAYING_1) { - entry->state = SFX_STATE_PLAYING_REFRESH; - } - } - - // Pick something to play for all channels. - numChannels = gChannelsPerBank[gSfxChannelLayout][bankId]; - for (i = 0; i < numChannels; i++) { - needNewSfx = false; - activeSfx = &gActiveSfx[bankId][i]; - - if (activeSfx->entryIndex == 0xFF) { - needNewSfx = true; - } else { - entry = &gSfxBanks[bankId][activeSfx[0].entryIndex]; - if (entry->state == SFX_STATE_PLAYING_1) { - if (entry->sfxId & 0xC00) { - Audio_RemoveSfxBankEntry(bankId, activeSfx->entryIndex); - } else { - entry->state = SFX_STATE_QUEUED; - } - needNewSfx = true; - } else if (entry->state == SFX_STATE_EMPTY) { - activeSfx->entryIndex = 0xFF; - needNewSfx = true; - } else { - // Sfx is already playing as it should, nothing to do. - for (j = 0; j < numChannels; j++) { - if (activeSfx->entryIndex == chosenSfx[j].entryIndex) { - chosenSfx[j].entryIndex = 0xFF; - j = numChannels; - } - } - numChosenSfx--; - } - } - - if (needNewSfx == true) { - for (j = 0; j < numChannels; j++) { - chosenEntryIndex = chosenSfx[j].entryIndex; - if ((chosenEntryIndex != 0xFF) && - (gSfxBanks[bankId][chosenEntryIndex].state != SFX_STATE_PLAYING_REFRESH)) { - for (k = 0; k < numChannels; k++) { - if (chosenEntryIndex == gActiveSfx[bankId][k].entryIndex) { - needNewSfx = false; - k = numChannels; // "break;" - } - } - if (needNewSfx == true) { - activeSfx->entryIndex = chosenEntryIndex; - chosenSfx[j].entryIndex = 0xFF; - j = numChannels + 1; - numChosenSfx--; - } - } - } - if (j == numChannels) { - // nothing found - activeSfx->entryIndex = 0xFF; - } - } - } -} - -void Audio_PlayActiveSfx(u8 bankId) { - u8 entryIndex; - SequenceChannel* channel; - SfxBankEntry* entry; - u8 i; - - for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) { - entryIndex = gActiveSfx[bankId][i].entryIndex; - if (entryIndex != 0xFF) { - entry = &gSfxBanks[bankId][entryIndex]; - channel = gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[sCurSfxPlayerChannelIdx]; - if (entry->state == SFX_STATE_READY) { - entry->channelIdx = sCurSfxPlayerChannelIdx; - if (entry->sfxParams & SFX_FLAG_3) { - Audio_QueueSeqCmdMute(sCurSfxPlayerChannelIdx); - } - if ((entry->sfxParams & SFX_PARAM_67_MASK) != (0 << SFX_PARAM_67_SHIFT)) { - switch (entry->sfxParams & SFX_PARAM_67_MASK) { - case (1 << SFX_PARAM_67_SHIFT): - entry->unk_2F = Audio_NextRandom() & 0xF; - break; - case (2 << SFX_PARAM_67_SHIFT): - entry->unk_2F = Audio_NextRandom() & 0x1F; - break; - case (3 << SFX_PARAM_67_SHIFT): - entry->unk_2F = Audio_NextRandom() & 0x3F; - break; - default: - entry->unk_2F = 0; - break; - } - } - Audio_SetSfxProperties(bankId, entryIndex, sCurSfxPlayerChannelIdx); - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((sCurSfxPlayerChannelIdx & 0xFF) << 8), 1); - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((sCurSfxPlayerChannelIdx & 0xFF) << 8) | 4, - entry->sfxId & 0xFF); - if (gIsLargeSfxBank[bankId]) { - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((sCurSfxPlayerChannelIdx & 0xFF) << 8) | 5, - (entry->sfxId & 0x100) >> 8); - } - if (entry->sfxId & 0xC00) { - entry->state = SFX_STATE_PLAYING_1; - } else { - entry->state = SFX_STATE_PLAYING_2; - } - } else if ((u8)channel->soundScriptIO[1] == (u8)SEQ_IO_VAL_NONE) { - Audio_RemoveSfxBankEntry(bankId, entryIndex); - } else if (entry->state == SFX_STATE_PLAYING_REFRESH) { - Audio_SetSfxProperties(bankId, entryIndex, sCurSfxPlayerChannelIdx); - if (entry->sfxId & 0xC00) { - entry->state = SFX_STATE_PLAYING_1; - } else { - entry->state = SFX_STATE_PLAYING_2; - } - } - } - sCurSfxPlayerChannelIdx++; - } -} - -void Audio_StopSfxByBank(u8 bankId) { - SfxBankEntry* entry; - s32 pad; - SfxBankEntry cmp; - u8 entryIndex = gSfxBanks[bankId][0].next; - - while (entryIndex != 0xFF) { - entry = &gSfxBanks[bankId][entryIndex]; - if (entry->state >= SFX_STATE_PLAYING_REFRESH) { - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0); - } - if (entry->state != SFX_STATE_EMPTY) { - Audio_RemoveSfxBankEntry(bankId, entryIndex); - } - entryIndex = gSfxBanks[bankId][0].next; - } - cmp.sfxId = bankId << 12; - Audio_RemoveMatchingSfxRequests(0, &cmp); -} - -void func_800F8884(u8 bankId, Vec3f* pos) { - SfxBankEntry* entry; - u8 entryIndex = gSfxBanks[bankId][0].next; - u8 prevEntryIndex = 0; - - while (entryIndex != 0xFF) { - entry = &gSfxBanks[bankId][entryIndex]; - if (entry->posX == &pos->x) { - if (entry->state >= SFX_STATE_PLAYING_REFRESH) { - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0); - } - if (entry->state != SFX_STATE_EMPTY) { - Audio_RemoveSfxBankEntry(bankId, entryIndex); - } - } else { - prevEntryIndex = entryIndex; - } - entryIndex = gSfxBanks[bankId][prevEntryIndex].next; - } -} - -void Audio_StopSfxByPosAndBank(u8 bankId, Vec3f* pos) { - SfxBankEntry cmp; - - func_800F8884(bankId, pos); - cmp.sfxId = bankId << 12; - cmp.posX = &pos->x; - Audio_RemoveMatchingSfxRequests(1, &cmp); -} - -void Audio_StopSfxByPos(Vec3f* pos) { - u8 i; - SfxBankEntry cmp; - - for (i = 0; i < ARRAY_COUNT(gSfxBanks); i++) { - func_800F8884(i, pos); - } - cmp.posX = &pos->x; - Audio_RemoveMatchingSfxRequests(2, &cmp); -} - -void Audio_StopSfxByPosAndId(Vec3f* pos, u16 sfxId) { - SfxBankEntry* entry; - u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next; - u8 prevEntryIndex = 0; - SfxBankEntry cmp; - - while (entryIndex != 0xFF) { - entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex]; - if (entry->posX == &pos->x && entry->sfxId == sfxId) { - if (entry->state >= SFX_STATE_PLAYING_REFRESH) { - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0); - } - if (entry->state != SFX_STATE_EMPTY) { - Audio_RemoveSfxBankEntry(SFX_BANK(sfxId), entryIndex); - } - entryIndex = 0xFF; - } else { - prevEntryIndex = entryIndex; - } - if (entryIndex != 0xFF) { - entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next; - } - } - cmp.posX = &pos->x; - cmp.sfxId = sfxId; - Audio_RemoveMatchingSfxRequests(3, &cmp); -} - -void Audio_StopSfxByTokenAndId(u8 token, u16 sfxId) { - SfxBankEntry* entry; - u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next; - u8 prevEntryIndex = 0; - SfxBankEntry cmp; - - while (entryIndex != 0xFF) { - entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex]; - if (entry->token == token && entry->sfxId == sfxId) { - if (entry->state >= SFX_STATE_PLAYING_REFRESH) { - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0); - } - if (entry->state != SFX_STATE_EMPTY) { - Audio_RemoveSfxBankEntry(SFX_BANK(sfxId), entryIndex); - } - } else { - prevEntryIndex = entryIndex; - } - if (entryIndex != 0xFF) { - entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next; - } - } - cmp.token = token; - cmp.sfxId = sfxId; - Audio_RemoveMatchingSfxRequests(4, &cmp); -} - -void Audio_StopSfxById(u32 sfxId) { - SfxBankEntry* entry; - u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next; - u8 prevEntryIndex = 0; - SfxBankEntry cmp; - - while (entryIndex != 0xFF) { - entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex]; - if (entry->sfxId == sfxId) { - if (entry->state >= SFX_STATE_PLAYING_REFRESH) { - Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0); - } - if (entry->state != SFX_STATE_EMPTY) { - Audio_RemoveSfxBankEntry(SFX_BANK(sfxId), entryIndex); - } - } else { - prevEntryIndex = entryIndex; - } - entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next; - } - cmp.sfxId = sfxId; - Audio_RemoveMatchingSfxRequests(5, &cmp); -} - -void Audio_ProcessSfxRequests(void) { - while (gSfxRequestWriteIndex != gSfxRequestReadIndex) { - Audio_ProcessSfxRequest(); - gSfxRequestReadIndex++; - } -} - -void Audio_SetUnusedBankLerp(u8 bankId, u8 target, u16 delay) { - if (delay == 0) { - delay++; - } - sUnusedBankLerp[bankId].target = target / 127.0f; - sUnusedBankLerp[bankId].remainingFrames = delay; - sUnusedBankLerp[bankId].step = ((sUnusedBankLerp[bankId].value - sUnusedBankLerp[bankId].target) / delay); -} - -void Audio_StepUnusedBankLerp(u8 bankId) { - if (sUnusedBankLerp[bankId].remainingFrames != 0) { - sUnusedBankLerp[bankId].remainingFrames--; - if (sUnusedBankLerp[bankId].remainingFrames != 0) { - sUnusedBankLerp[bankId].value -= sUnusedBankLerp[bankId].step; - } else { - sUnusedBankLerp[bankId].value = sUnusedBankLerp[bankId].target; - } - } -} - -void func_800F8F88(void) { - u8 bankId; - - if (IS_SEQUENCE_CHANNEL_VALID(gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[0])) { - sCurSfxPlayerChannelIdx = 0; - for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) { - Audio_ChooseActiveSfx(bankId); - Audio_PlayActiveSfx(bankId); - Audio_StepUnusedBankLerp(bankId); - } - } -} - -u8 Audio_IsSfxPlaying(u32 sfxId) { - SfxBankEntry* entry; - u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next; - - while (entryIndex != 0xFF) { - entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex]; - if (entry->sfxId == sfxId) { - return true; - } - entryIndex = entry->next; - } - return false; -} - -void Audio_ResetSfx(void) { - u8 bankId; - u8 i; - u8 entryIndex; - - gSfxRequestWriteIndex = 0; - gSfxRequestReadIndex = 0; - D_801333D0 = 0; - for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) { - sSfxBankListEnd[bankId] = 0; - sSfxBankFreeListStart[bankId] = 1; - sSfxBankUnused[bankId] = 0; - gSfxBankMuted[bankId] = false; - sUnusedBankLerp[bankId].value = 1.0f; - sUnusedBankLerp[bankId].remainingFrames = 0; - } - for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) { - for (i = 0; i < MAX_CHANNELS_PER_BANK; i++) { - gActiveSfx[bankId][i].entryIndex = 0xFF; - } - } - for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) { - gSfxBanks[bankId][0].prev = 0xFF; - gSfxBanks[bankId][0].next = 0xFF; - for (i = 1; i < gSfxBankSizes[bankId] - 1; i++) { - gSfxBanks[bankId][i].prev = i - 1; - gSfxBanks[bankId][i].next = i + 1; - } - gSfxBanks[bankId][i].prev = i - 1; - gSfxBanks[bankId][i].next = 0xFF; - } - if (D_801333F8 == 0) { - for (bankId = 0; bankId < 10; bankId++) { - gAudioSfxSwapSource[bankId] = 0; - gAudioSfxSwapTarget[bankId] = 0; - gAudioSfxSwapMode[bankId] = 0; - } - D_801333F8++; - } -} diff --git a/src/code/code_800F9280.c b/src/code/code_800F9280.c deleted file mode 100644 index 115789fe5..000000000 --- a/src/code/code_800F9280.c +++ /dev/null @@ -1,827 +0,0 @@ -/** - * @file code_800F9280.c - * - * This file implements a set of high-level audio sequence commands that allow sequences to be modified in real-time. - * These commands are intended to interface external to the audio library. - * - * These commands are generated using `Audio_QueueSeqCmd`, and a user-friendly interface for this function - * can be found in `seqcmd.h` - * - * These commands change sequences by generating internal audio commands `Audio_QueueCmd` which allows these - * sequence requests to be passed onto the audio thread. It is worth noting all functions in this file are - * called from the graph thread. - * - * These commands are not to be confused with the sequence instructions used by the sequences themselves - * which are a midi-based scripting language. - * - * Nor are these commands to be confused with the internal audio commands used to transfer requests from - * the graph thread to the audio thread. - */ -#include "ultra64.h" -#include "global.h" -#include "ultra64/abi.h" - -// Direct audio command (skips the queueing system) -#define SEQCMD_SET_PLAYER_VOLUME_NOW(seqPlayerIndex, duration, volume) \ - Audio_ProcessSeqCmd((SEQCMD_OP_SET_PLAYER_VOLUME << 28) | ((u8)(seqPlayerIndex) << 24) | ((u8)(duration) << 16) | \ - ((u8)((volume)*127.0f))); - -typedef struct { - u8 seqId; - u8 priority; // higher values have higher priority -} SeqRequest; - -SeqRequest sSeqRequests[4][5]; -u8 sNumSeqRequests[4]; -u32 sAudioSeqCmds[0x100]; -ActiveSequence gActiveSeqs[4]; - -void Audio_StartSequence(u8 seqPlayerIndex, u8 seqId, u8 seqArgs, u16 fadeInDuration) { - u8 channelIndex; - u16 duration; - s32 pad; - - if (!gStartSeqDisabled || (seqPlayerIndex == SEQ_PLAYER_SFX)) { - seqArgs &= 0x7F; - if (seqArgs == 0x7F) { - // `fadeInDuration` is interpreted as skip ticks - duration = (fadeInDuration >> 3) * 60 * gAudioCtx.audioBufferParameters.updatesPerFrame; - Audio_QueueCmdS32(0x85000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(seqId, 8, 8), duration); - } else { - // `fadeInDuration` is interpreted as number of frames at 30 fps - Audio_QueueCmdS32(0x82000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(seqId, 8, 8), - (fadeInDuration * (u16)gAudioCtx.audioBufferParameters.updatesPerFrame) / 4); - } - - gActiveSeqs[seqPlayerIndex].seqId = seqId | (seqArgs << 8); - gActiveSeqs[seqPlayerIndex].prevSeqId = seqId | (seqArgs << 8); - - if (gActiveSeqs[seqPlayerIndex].volCur != 1.0f) { - Audio_QueueCmdF32(0x41000000 | _SHIFTL(seqPlayerIndex, 16, 8), gActiveSeqs[seqPlayerIndex].volCur); - } - - gActiveSeqs[seqPlayerIndex].tempoTimer = 0; - gActiveSeqs[seqPlayerIndex].tempoOriginal = 0; - gActiveSeqs[seqPlayerIndex].tempoCmd = 0; - - for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) { - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volCur = 1.0f; - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volTimer = 0; - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleCur = 1.0f; - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleTimer = 0; - } - - gActiveSeqs[seqPlayerIndex].freqScaleChannelFlags = 0; - gActiveSeqs[seqPlayerIndex].volChannelFlags = 0; - } -} - -void Audio_StopSequence(u8 seqPlayerIndex, u16 fadeOutDuration) { - Audio_QueueCmdS32(0x83000000 | ((u8)seqPlayerIndex << 16), - (fadeOutDuration * (u16)gAudioCtx.audioBufferParameters.updatesPerFrame) / 4); - gActiveSeqs[seqPlayerIndex].seqId = NA_BGM_DISABLED; -} - -void Audio_ProcessSeqCmd(u32 cmd) { - s32 priority; - s32 channelMaskEnable; - u16 channelMaskDisable; - u16 fadeTimer; - u16 val; - u8 oldSpec; - u8 spec; - u8 op; - u8 subOp; - u8 seqPlayerIndex; - u8 seqId; - u8 seqArgs; - u8 found; - u8 port; - u8 duration; - u8 channelIndex; - u8 i; - f32 freqScaleTarget; - s32 pad; - - if (gAudioDebugPrintSeqCmd && (cmd & SEQCMD_OP_MASK) != (SEQCMD_OP_SET_PLAYER_IO << 28)) { - AudioDebug_ScrPrt("SEQ H", (cmd >> 16) & 0xFFFF); - AudioDebug_ScrPrt(" L", cmd & 0xFFFF); - } - - op = cmd >> 28; - seqPlayerIndex = (cmd & 0xF000000) >> 24; - - switch (op) { - case SEQCMD_OP_PLAY_SEQUENCE: - // Play a new sequence - seqId = cmd & 0xFF; - seqArgs = (cmd & 0xFF00) >> 8; - // `fadeTimer` is only shifted 13 bits instead of 16 bits. - // `fadeTimer` continues to be scaled in `Audio_StartSequence` - fadeTimer = (cmd & 0xFF0000) >> 13; - if (!gActiveSeqs[seqPlayerIndex].isWaitingForFonts && (seqArgs < 0x80)) { - Audio_StartSequence(seqPlayerIndex, seqId, seqArgs, fadeTimer); - } - break; - - case SEQCMD_OP_STOP_SEQUENCE: - // Stop a sequence and disable the sequence player - fadeTimer = (cmd & 0xFF0000) >> 13; - Audio_StopSequence(seqPlayerIndex, fadeTimer); - break; - - case SEQCMD_OP_QUEUE_SEQUENCE: - // Queue a sequence into `sSeqRequests` - seqId = cmd & 0xFF; - seqArgs = (cmd & 0xFF00) >> 8; - fadeTimer = (cmd & 0xFF0000) >> 13; - priority = seqArgs; - - // Checks if the requested sequence is first in the list of requests - // If it is already queued and first in the list, then play the sequence immediately - for (i = 0; i < sNumSeqRequests[seqPlayerIndex]; i++) { - if (sSeqRequests[seqPlayerIndex][i].seqId == seqId) { - if (i == 0) { - Audio_StartSequence(seqPlayerIndex, seqId, seqArgs, fadeTimer); - } - return; - } - } - - // Searches the sequence requests for the first request that does not have a higher priority - // than the current incoming request - found = sNumSeqRequests[seqPlayerIndex]; - for (i = 0; i < sNumSeqRequests[seqPlayerIndex]; i++) { - if (priority >= sSeqRequests[seqPlayerIndex][i].priority) { - found = i; - i = sNumSeqRequests[seqPlayerIndex]; // "break;" - } - } - - // Check if the queue is full - if (sNumSeqRequests[seqPlayerIndex] < ARRAY_COUNT(sSeqRequests[seqPlayerIndex])) { - sNumSeqRequests[seqPlayerIndex]++; - } - - for (i = sNumSeqRequests[seqPlayerIndex] - 1; i != found; i--) { - // Move all requests of lower priority backwards 1 place in the queue - // If the queue is full, overwrite the entry with the lowest priority - sSeqRequests[seqPlayerIndex][i].priority = sSeqRequests[seqPlayerIndex][i - 1].priority; - sSeqRequests[seqPlayerIndex][i].seqId = sSeqRequests[seqPlayerIndex][i - 1].seqId; - } - - // Fill the newly freed space in the queue with the new request - sSeqRequests[seqPlayerIndex][found].priority = seqArgs; - sSeqRequests[seqPlayerIndex][found].seqId = seqId; - - // The sequence is first in queue, so start playing. - if (found == 0) { - Audio_StartSequence(seqPlayerIndex, seqId, seqArgs, fadeTimer); - } - break; - - case SEQCMD_OP_UNQUEUE_SEQUENCE: - // Unqueue sequence - fadeTimer = (cmd & 0xFF0000) >> 13; - - found = sNumSeqRequests[seqPlayerIndex]; - for (i = 0; i < sNumSeqRequests[seqPlayerIndex]; i++) { - seqId = cmd & 0xFF; - if (sSeqRequests[seqPlayerIndex][i].seqId == seqId) { - found = i; - i = sNumSeqRequests[seqPlayerIndex]; // "break;" - } - } - - if (found != sNumSeqRequests[seqPlayerIndex]) { - // Move all requests of lower priority forward 1 place in the queue - for (i = found; i < sNumSeqRequests[seqPlayerIndex] - 1; i++) { - sSeqRequests[seqPlayerIndex][i].priority = sSeqRequests[seqPlayerIndex][i + 1].priority; - sSeqRequests[seqPlayerIndex][i].seqId = sSeqRequests[seqPlayerIndex][i + 1].seqId; - } - sNumSeqRequests[seqPlayerIndex]--; - } - - // If the sequence was first in queue (it is currently playing), - // Then stop the sequence and play the next sequence in the queue. - if (found == 0) { - Audio_StopSequence(seqPlayerIndex, fadeTimer); - if (sNumSeqRequests[seqPlayerIndex] != 0) { - Audio_StartSequence(seqPlayerIndex, sSeqRequests[seqPlayerIndex][0].seqId, - sSeqRequests[seqPlayerIndex][0].priority, fadeTimer); - } - } - break; - - case SEQCMD_OP_SET_PLAYER_VOLUME: - // Transition volume to a target volume for an entire player - duration = (cmd & 0xFF0000) >> 15; - val = cmd & 0xFF; - if (duration == 0) { - duration++; - } - // Volume is scaled relative to 127 - gActiveSeqs[seqPlayerIndex].volTarget = (f32)val / 127.0f; - if (gActiveSeqs[seqPlayerIndex].volCur != gActiveSeqs[seqPlayerIndex].volTarget) { - gActiveSeqs[seqPlayerIndex].volStep = - (gActiveSeqs[seqPlayerIndex].volCur - gActiveSeqs[seqPlayerIndex].volTarget) / (f32)duration; - gActiveSeqs[seqPlayerIndex].volTimer = duration; - } - break; - - case SEQCMD_OP_SET_PLAYER_FREQ: - // Transition freq scale to a target freq for all channels - duration = (cmd & 0xFF0000) >> 15; - val = cmd & 0xFFFF; - if (duration == 0) { - duration++; - } - // Frequency is scaled relative to 1000 - freqScaleTarget = (f32)val / 1000.0f; - for (i = 0; i < SEQ_NUM_CHANNELS; i++) { - gActiveSeqs[seqPlayerIndex].channelData[i].freqScaleTarget = freqScaleTarget; - gActiveSeqs[seqPlayerIndex].channelData[i].freqScaleTimer = duration; - gActiveSeqs[seqPlayerIndex].channelData[i].freqScaleStep = - (gActiveSeqs[seqPlayerIndex].channelData[i].freqScaleCur - freqScaleTarget) / (f32)duration; - } - gActiveSeqs[seqPlayerIndex].freqScaleChannelFlags = 0xFFFF; - break; - - case SEQCMD_OP_SET_CHANNEL_FREQ: - // Transition freq scale to a target for a specific channel - duration = (cmd & 0xFF0000) >> 15; - channelIndex = (cmd & 0xF000) >> 12; - val = cmd & 0xFFF; - if (duration == 0) { - duration++; - } - // Frequency is scaled relative to 1000 - freqScaleTarget = (f32)val / 1000.0f; - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleTarget = freqScaleTarget; - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleStep = - (gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleCur - freqScaleTarget) / (f32)duration; - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleTimer = duration; - gActiveSeqs[seqPlayerIndex].freqScaleChannelFlags |= 1 << channelIndex; - break; - - case SEQCMD_OP_SET_CHANNEL_VOLUME: - // Transition volume to a target volume for a specific channel - duration = (cmd & 0xFF0000) >> 15; - channelIndex = (cmd & 0xF00) >> 8; - val = cmd & 0xFF; - if (duration == 0) { - duration++; - } - // Volume is scaled relative to 127 - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volTarget = (f32)val / 127.0f; - if (gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volCur != - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volTarget) { - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volStep = - (gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volCur - - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volTarget) / - (f32)duration; - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volTimer = duration; - gActiveSeqs[seqPlayerIndex].volChannelFlags |= 1 << channelIndex; - } - break; - - case SEQCMD_OP_SET_PLAYER_IO: - // Set global io port - port = (cmd & 0xFF0000) >> 16; - val = cmd & 0xFF; - Audio_QueueCmdS8(0x46000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(port, 0, 8), val); - break; - - case SEQCMD_OP_SET_CHANNEL_IO: - // Set io port if channel masked - channelIndex = (cmd & 0xF00) >> 8; - port = (cmd & 0xFF0000) >> 16; - val = cmd & 0xFF; - if (!(gActiveSeqs[seqPlayerIndex].channelPortMask & (1 << channelIndex))) { - Audio_QueueCmdS8(0x06000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(channelIndex, 8, 8) | - _SHIFTL(port, 0, 8), - val); - } - break; - - case SEQCMD_OP_SET_CHANNEL_IO_DISABLE_MASK: - // Disable channel io specifically for - // `SEQCMD_OP_SET_CHANNEL_IO` This can be bypassed by setting channel io through `Audio_QueueCmdS8` 0x6 - // directly. This is accomplished by setting a channel mask. - gActiveSeqs[seqPlayerIndex].channelPortMask = cmd & 0xFFFF; - break; - - case SEQCMD_OP_SET_CHANNEL_DISABLE_MASK: - // Disable or Reenable channels - - // Disable channels - channelMaskDisable = cmd & 0xFFFF; - if (channelMaskDisable != 0) { - // Apply channel mask `channelMaskDisable` - Audio_QueueCmdU16(0x90000000 | _SHIFTL(seqPlayerIndex, 16, 8), channelMaskDisable); - // Disable channels - Audio_QueueCmdS8(0x08000000 | _SHIFTL(seqPlayerIndex, 16, 8) | 0xFF00, 1); - } - - // Reenable channels - channelMaskEnable = (channelMaskDisable ^ 0xFFFF); - if (channelMaskEnable != 0) { - // Apply channel mask `channelMaskEnable` - Audio_QueueCmdU16(0x90000000 | _SHIFTL(seqPlayerIndex, 16, 8), channelMaskEnable); - // Enable channels - Audio_QueueCmdS8(0x08000000 | _SHIFTL(seqPlayerIndex, 16, 8) | 0xFF00, 0); - } - break; - - case SEQCMD_OP_TEMPO_CMD: - // Update a tempo using a sub-command system. - // Stores the cmd for processing elsewhere. - gActiveSeqs[seqPlayerIndex].tempoCmd = cmd; - break; - - case SEQCMD_OP_SETUP_CMD: - // Queue a sub-command to execute once the sequence is finished playing - subOp = (cmd & 0xF00000) >> 20; - if (subOp != SEQCMD_SUB_OP_SETUP_RESET_SETUP_CMDS) { - // Ensure the maximum number of setup commands is not exceeded - if (gActiveSeqs[seqPlayerIndex].setupCmdNum < (ARRAY_COUNT(gActiveSeqs[seqPlayerIndex].setupCmd) - 1)) { - found = gActiveSeqs[seqPlayerIndex].setupCmdNum++; - if (found < ARRAY_COUNT(gActiveSeqs[seqPlayerIndex].setupCmd)) { - gActiveSeqs[seqPlayerIndex].setupCmd[found] = cmd; - // Adds a delay of 2 frames before executing any setup commands. - // This allows setup commands to be requested along with a new sequence on a seqPlayerIndex. - // This 2 frame delay ensures the player is enabled before its state is checked for - // the purpose of deciding if the setup commands should be run. - // Otherwise, the setup commands will be executed before the sequence starts, - // when the player is still disabled, instead of when the newly played sequence ends. - gActiveSeqs[seqPlayerIndex].setupCmdTimer = 2; - } - } - } else { - // `SEQCMD_SUB_OP_SETUP_RESET_SETUP_CMDS` - // Discard all setup command requests on `seqPlayerIndex` - gActiveSeqs[seqPlayerIndex].setupCmdNum = 0; - } - break; - - case SEQCMD_OP_GLOBAL_CMD: - // Apply a command that applies to all sequence players - subOp = (cmd & 0xF00) >> 8; - val = cmd & 0xFF; - switch (subOp) { - case SEQCMD_SUB_OP_GLOBAL_SET_SOUND_MODE: - // Set sound mode - Audio_QueueCmdS32(0xF0000000, gSoundModeList[val]); - break; - - case SEQCMD_SUB_OP_GLOBAL_DISABLE_NEW_SEQUENCES: - // Disable the starting of new sequences (except for the sfx player) - gStartSeqDisabled = val & 1; - break; - } - break; - - case SEQCMD_OP_RESET_AUDIO_HEAP: - // Resets the audio heap based on the audio specifications and sfx channel layout - spec = cmd & 0xFF; - gSfxChannelLayout = (cmd & 0xFF00) >> 8; - oldSpec = gAudioSpecId; - gAudioSpecId = spec; - func_800E5F88(spec); - func_800F71BC(oldSpec); - Audio_QueueCmdS32(0xF8000000, 0); - break; - } -} - -/** - * Add the sequence cmd to the `sAudioSeqCmds` queue - */ -void Audio_QueueSeqCmd(u32 cmd) { - sAudioSeqCmds[gSeqCmdWritePos++] = cmd; -} - -void Audio_ProcessSeqCmds(void) { - while (gSeqCmdWritePos != gSeqCmdReadPos) { - Audio_ProcessSeqCmd(sAudioSeqCmds[gSeqCmdReadPos++]); - } -} - -u16 Audio_GetActiveSeqId(u8 seqPlayerIndex) { - if (!gAudioCtx.seqPlayers[seqPlayerIndex].enabled) { - return NA_BGM_DISABLED; - } - return gActiveSeqs[seqPlayerIndex].seqId; -} - -s32 Audio_IsSeqCmdNotQueued(u32 cmdVal, u32 cmdMask) { - u8 i; - - for (i = gSeqCmdReadPos; i != gSeqCmdWritePos; i++) { - if ((sAudioSeqCmds[i] & cmdMask) == cmdVal) { - return false; - } - } - - return true; -} - -// Unused -void Audio_ResetSequenceRequests(u8 seqPlayerIndex) { - sNumSeqRequests[seqPlayerIndex] = 0; -} - -/** - * Check if the setup command is queued. If it is, then replace the command - * with `SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME`. - * Unused - */ -void Audio_ReplaceSeqCmdSetupOpVolRestore(u8 seqPlayerIndex, u8 setupOpDisabled) { - u8 i; - - for (i = 0; i < gActiveSeqs[seqPlayerIndex].setupCmdNum; i++) { - u8 setupOp = (gActiveSeqs[seqPlayerIndex].setupCmd[i] & 0xF00000) >> 20; - - if (setupOp == setupOpDisabled) { - gActiveSeqs[seqPlayerIndex].setupCmd[i] = 0xFF000000; - } - } -} - -void Audio_SetVolumeScale(u8 seqPlayerIndex, u8 scaleIndex, u8 targetVol, u8 volFadeTimer) { - f32 volScale; - u8 i; - - gActiveSeqs[seqPlayerIndex].volScales[scaleIndex] = targetVol & 0x7F; - - if (volFadeTimer != 0) { - gActiveSeqs[seqPlayerIndex].fadeVolUpdate = true; - gActiveSeqs[seqPlayerIndex].volFadeTimer = volFadeTimer; - } else { - for (i = 0, volScale = 1.0f; i < VOL_SCALE_INDEX_MAX; i++) { - volScale *= gActiveSeqs[seqPlayerIndex].volScales[i] / 127.0f; - } - - SEQCMD_SET_PLAYER_VOLUME_NOW(seqPlayerIndex, volFadeTimer, volScale); - } -} - -/** - * Update different commands and requests for active sequences - */ -void Audio_UpdateActiveSequences(void) { - u32 tempoCmd; - u8 tempoOp; - u16 tempoPrev; - u16 tempoTarget; - u8 setupOp; - u8 targetSeqPlayerIndex; - u8 setupVal2; - u8 setupVal1; - u16 seqId; - s32 pad[2]; - u16 channelMask; - u32 retMsg; - f32 volume; - u8 tempoTimer; - u8 seqPlayerIndex; - u8 j; - u8 channelIndex; - - for (seqPlayerIndex = 0; seqPlayerIndex < 4; seqPlayerIndex++) { - - // The setup for this block of code was not fully implemented until Majora's Mask. - // The intent was to load soundfonts asynchronously before playing a - // sequence in `Audio_StartSequence` using `(seqArgs & 0x80)`. - // Checks if the requested sequence is finished loading fonts - if (gActiveSeqs[seqPlayerIndex].isWaitingForFonts) { - switch (func_800E5E20(&retMsg)) { - case SEQ_PLAYER_BGM_MAIN + 1: - case SEQ_PLAYER_FANFARE + 1: - case SEQ_PLAYER_SFX + 1: - case SEQ_PLAYER_BGM_SUB + 1: - // The fonts have been loaded successfully. - gActiveSeqs[seqPlayerIndex].isWaitingForFonts = false; - // Queue the same command that was stored previously - // The code to store this command is missing in OoT, so no command is executed - Audio_ProcessSeqCmd(gActiveSeqs[seqPlayerIndex].startSeqCmd); - break; - } - } - - // Update global volume - if (gActiveSeqs[seqPlayerIndex].fadeVolUpdate) { - volume = 1.0f; - for (j = 0; j < VOL_SCALE_INDEX_MAX; j++) { - volume *= (gActiveSeqs[seqPlayerIndex].volScales[j] / 127.0f); - } - SEQCMD_SET_PLAYER_VOLUME(seqPlayerIndex, gActiveSeqs[seqPlayerIndex].volFadeTimer, (u8)(volume * 127.0f)); - gActiveSeqs[seqPlayerIndex].fadeVolUpdate = false; - } - - if (gActiveSeqs[seqPlayerIndex].volTimer != 0) { - gActiveSeqs[seqPlayerIndex].volTimer--; - - if (gActiveSeqs[seqPlayerIndex].volTimer != 0) { - gActiveSeqs[seqPlayerIndex].volCur -= gActiveSeqs[seqPlayerIndex].volStep; - } else { - gActiveSeqs[seqPlayerIndex].volCur = gActiveSeqs[seqPlayerIndex].volTarget; - } - - Audio_QueueCmdF32(0x41000000 | _SHIFTL(seqPlayerIndex, 16, 8), gActiveSeqs[seqPlayerIndex].volCur); - } - - // Process tempo - if (gActiveSeqs[seqPlayerIndex].tempoCmd != 0) { - tempoCmd = gActiveSeqs[seqPlayerIndex].tempoCmd; - tempoTimer = (tempoCmd & 0xFF0000) >> 15; - tempoTarget = tempoCmd & 0xFFF; - if (tempoTimer == 0) { - tempoTimer++; - } - - // Process tempo commands - if (gAudioCtx.seqPlayers[seqPlayerIndex].enabled) { - tempoPrev = gAudioCtx.seqPlayers[seqPlayerIndex].tempo / TATUMS_PER_BEAT; - tempoOp = (tempoCmd & 0xF000) >> 12; - switch (tempoOp) { - case SEQCMD_SUB_OP_TEMPO_SPEED_UP: - // Speed up tempo by `tempoTarget` amount - tempoTarget += tempoPrev; - break; - - case SEQCMD_SUB_OP_TEMPO_SLOW_DOWN: - // Slow down tempo by `tempoTarget` amount - if (tempoTarget < tempoPrev) { - tempoTarget = tempoPrev - tempoTarget; - } - break; - - case SEQCMD_SUB_OP_TEMPO_SCALE: - // Scale tempo by a multiplicative factor - tempoTarget = tempoPrev * (tempoTarget / 100.0f); - break; - - case SEQCMD_SUB_OP_TEMPO_RESET: - // Reset tempo to original tempo - tempoTarget = (gActiveSeqs[seqPlayerIndex].tempoOriginal != 0) - ? gActiveSeqs[seqPlayerIndex].tempoOriginal - : tempoPrev; - break; - - default: // `SEQCMD_SUB_OP_TEMPO_SET` - // `tempoTarget` is the new tempo - break; - } - - if (tempoTarget > 300) { - tempoTarget = 300; - } - - if (gActiveSeqs[seqPlayerIndex].tempoOriginal == 0) { - gActiveSeqs[seqPlayerIndex].tempoOriginal = tempoPrev; - } - - gActiveSeqs[seqPlayerIndex].tempoTarget = tempoTarget; - gActiveSeqs[seqPlayerIndex].tempoCur = gAudioCtx.seqPlayers[seqPlayerIndex].tempo / TATUMS_PER_BEAT; - gActiveSeqs[seqPlayerIndex].tempoStep = - (gActiveSeqs[seqPlayerIndex].tempoCur - gActiveSeqs[seqPlayerIndex].tempoTarget) / tempoTimer; - gActiveSeqs[seqPlayerIndex].tempoTimer = tempoTimer; - gActiveSeqs[seqPlayerIndex].tempoCmd = 0; - } - } - - // Step tempo to target - if (gActiveSeqs[seqPlayerIndex].tempoTimer != 0) { - gActiveSeqs[seqPlayerIndex].tempoTimer--; - if (gActiveSeqs[seqPlayerIndex].tempoTimer != 0) { - gActiveSeqs[seqPlayerIndex].tempoCur -= gActiveSeqs[seqPlayerIndex].tempoStep; - } else { - gActiveSeqs[seqPlayerIndex].tempoCur = gActiveSeqs[seqPlayerIndex].tempoTarget; - } - // Set tempo - Audio_QueueCmdS32(0x47000000 | _SHIFTL(seqPlayerIndex, 16, 8), gActiveSeqs[seqPlayerIndex].tempoCur); - } - - // Update channel volumes - if (gActiveSeqs[seqPlayerIndex].volChannelFlags != 0) { - for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) { - if (gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volTimer != 0) { - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volTimer--; - if (gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volTimer != 0) { - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volCur -= - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volStep; - } else { - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volCur = - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volTarget; - gActiveSeqs[seqPlayerIndex].volChannelFlags ^= (1 << channelIndex); - } - // `CHAN_UPD_VOL_SCALE` - Audio_QueueCmdF32(0x01000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(channelIndex, 8, 8), - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volCur); - } - } - } - - // Update frequencies - if (gActiveSeqs[seqPlayerIndex].freqScaleChannelFlags != 0) { - for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) { - if (gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleTimer != 0) { - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleTimer--; - if (gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleTimer != 0) { - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleCur -= - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleStep; - } else { - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleCur = - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleTarget; - gActiveSeqs[seqPlayerIndex].freqScaleChannelFlags ^= (1 << channelIndex); - } - // `CHAN_UPD_FREQ_SCALE` - Audio_QueueCmdF32(0x04000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(channelIndex, 8, 8), - gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleCur); - } - } - } - - // Process setup commands - if (gActiveSeqs[seqPlayerIndex].setupCmdNum != 0) { - // If there is a SeqCmd to reset the audio heap queued, then drop all setup commands - if (!Audio_IsSeqCmdNotQueued(SEQCMD_OP_RESET_AUDIO_HEAP << 28, SEQCMD_OP_MASK)) { - gActiveSeqs[seqPlayerIndex].setupCmdNum = 0; - return; - } - - // Only process setup commands once the timer reaches zero - if (gActiveSeqs[seqPlayerIndex].setupCmdTimer != 0) { - gActiveSeqs[seqPlayerIndex].setupCmdTimer--; - continue; - } - - // Only process setup commands if `seqPlayerIndex` if no longer playing - // i.e. the `seqPlayer` is no longer enabled - if (gAudioCtx.seqPlayers[seqPlayerIndex].enabled) { - continue; - } - - for (j = 0; j < gActiveSeqs[seqPlayerIndex].setupCmdNum; j++) { - setupOp = (gActiveSeqs[seqPlayerIndex].setupCmd[j] & 0x00F00000) >> 20; - targetSeqPlayerIndex = (gActiveSeqs[seqPlayerIndex].setupCmd[j] & 0x000F0000) >> 16; - setupVal2 = (gActiveSeqs[seqPlayerIndex].setupCmd[j] & 0xFF00) >> 8; - setupVal1 = gActiveSeqs[seqPlayerIndex].setupCmd[j] & 0xFF; - - switch (setupOp) { - case SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME: - // Restore `targetSeqPlayerIndex` volume back to normal levels - Audio_SetVolumeScale(targetSeqPlayerIndex, VOL_SCALE_INDEX_FANFARE, 0x7F, setupVal1); - break; - - case SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME_IF_QUEUED: - // Restore `targetSeqPlayerIndex` volume back to normal levels, - // but only if the number of sequence queue requests from `sSeqRequests` - // exactly matches the argument to the command - if (setupVal1 == sNumSeqRequests[seqPlayerIndex]) { - Audio_SetVolumeScale(targetSeqPlayerIndex, VOL_SCALE_INDEX_FANFARE, 0x7F, setupVal2); - } - break; - - case SEQCMD_SUB_OP_SETUP_SEQ_UNQUEUE: - // Unqueue `seqPlayerIndex` from sSeqRequests - //! @bug this command does not work as intended as unqueueing - //! the sequence relies on `gActiveSeqs[seqPlayerIndex].seqId` - //! However, `gActiveSeqs[seqPlayerIndex].seqId` is reset before the sequence on - //! `seqPlayerIndex` is requested to stop, i.e. before the sequence is disabled and setup - //! commands (including this command) can run. A simple fix would have been to unqueue based on - //! `gActiveSeqs[seqPlayerIndex].prevSeqId` instead - SEQCMD_UNQUEUE_SEQUENCE(seqPlayerIndex, 0, gActiveSeqs[seqPlayerIndex].seqId); - break; - - case SEQCMD_SUB_OP_SETUP_RESTART_SEQ: - // Restart the currently active sequence on `targetSeqPlayerIndex` with full volume. - // Sequence on `targetSeqPlayerIndex` must still be active to play (can be muted) - SEQCMD_PLAY_SEQUENCE(targetSeqPlayerIndex, 1, 0, gActiveSeqs[targetSeqPlayerIndex].seqId); - gActiveSeqs[targetSeqPlayerIndex].fadeVolUpdate = true; - gActiveSeqs[targetSeqPlayerIndex].volScales[VOL_SCALE_INDEX_FANFARE] = 0x7F; - break; - - case SEQCMD_SUB_OP_SETUP_TEMPO_SCALE: - // Scale tempo by a multiplicative factor - SEQCMD_SCALE_TEMPO(targetSeqPlayerIndex, setupVal2, setupVal1); - break; - - case SEQCMD_SUB_OP_SETUP_TEMPO_RESET: - // Reset tempo to previous tempo - SEQCMD_RESET_TEMPO(targetSeqPlayerIndex, setupVal1); - break; - - case SEQCMD_SUB_OP_SETUP_PLAY_SEQ: - // Play the requested sequence - // Uses the fade timer set by `SEQCMD_SUB_OP_SETUP_SET_FADE_TIMER` - seqId = gActiveSeqs[seqPlayerIndex].setupCmd[j] & 0xFFFF; - SEQCMD_PLAY_SEQUENCE(targetSeqPlayerIndex, gActiveSeqs[targetSeqPlayerIndex].setupFadeTimer, 0, - seqId); - Audio_SetVolumeScale(targetSeqPlayerIndex, VOL_SCALE_INDEX_FANFARE, 0x7F, 0); - gActiveSeqs[targetSeqPlayerIndex].setupFadeTimer = 0; - break; - - case SEQCMD_SUB_OP_SETUP_SET_FADE_TIMER: - // A command specifically to support `SEQCMD_SUB_OP_SETUP_PLAY_SEQ` - // Sets the fade timer for the sequence requested in `SEQCMD_SUB_OP_SETUP_PLAY_SEQ` - gActiveSeqs[seqPlayerIndex].setupFadeTimer = setupVal2; - break; - - case SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME_WITH_SCALE_INDEX: - // Restore the volume back to default levels - // Allows a `scaleIndex` to be specified. - Audio_SetVolumeScale(targetSeqPlayerIndex, setupVal2, 0x7F, setupVal1); - break; - - case SEQCMD_SUB_OP_SETUP_POP_PERSISTENT_CACHE: - // Discard audio data by popping one more audio caches from the audio heap - if (setupVal1 & (1 << SEQUENCE_TABLE)) { - Audio_QueueCmdS32(0xE3000000, SEQUENCE_TABLE); - } - if (setupVal1 & (1 << FONT_TABLE)) { - Audio_QueueCmdS32(0xE3000000, FONT_TABLE); - } - if (setupVal1 & (1 << SAMPLE_TABLE)) { - Audio_QueueCmdS32(0xE3000000, SAMPLE_TABLE); - } - break; - - case SEQCMD_SUB_OP_SETUP_SET_CHANNEL_DISABLE_MASK: - // Disable (or reenable) specific channels of `targetSeqPlayerIndex` - channelMask = gActiveSeqs[seqPlayerIndex].setupCmd[j] & 0xFFFF; - SEQCMD_SET_CHANNEL_DISABLE_MASK(targetSeqPlayerIndex, channelMask); - break; - - case SEQCMD_SUB_OP_SETUP_SET_PLAYER_FREQ: - // Scale all channels of `targetSeqPlayerIndex` - SEQCMD_SET_PLAYER_FREQ(targetSeqPlayerIndex, setupVal2, (setupVal1 * 10) & 0xFFFF); - break; - } - } - - gActiveSeqs[seqPlayerIndex].setupCmdNum = 0; - } - } -} - -u8 func_800FAD34(void) { - if (D_80133418 != 0) { - if (D_80133418 == 1) { - if (func_800E5EDC() == 1) { - D_80133418 = 0; - Audio_QueueCmdS8(0x46020000, gSfxChannelLayout); - func_800F7170(); - } - } else if (D_80133418 == 2) { - while (func_800E5EDC() != 1) {} - D_80133418 = 0; - Audio_QueueCmdS8(0x46020000, gSfxChannelLayout); - func_800F7170(); - } - } - - return D_80133418; -} - -void Audio_ResetActiveSequences(void) { - u8 seqPlayerIndex; - u8 scaleIndex; - - for (seqPlayerIndex = 0; seqPlayerIndex < 4; seqPlayerIndex++) { - sNumSeqRequests[seqPlayerIndex] = 0; - - gActiveSeqs[seqPlayerIndex].seqId = NA_BGM_DISABLED; - gActiveSeqs[seqPlayerIndex].prevSeqId = NA_BGM_DISABLED; - gActiveSeqs[seqPlayerIndex].tempoTimer = 0; - gActiveSeqs[seqPlayerIndex].tempoOriginal = 0; - gActiveSeqs[seqPlayerIndex].tempoCmd = 0; - gActiveSeqs[seqPlayerIndex].channelPortMask = 0; - gActiveSeqs[seqPlayerIndex].setupCmdNum = 0; - gActiveSeqs[seqPlayerIndex].setupFadeTimer = 0; - gActiveSeqs[seqPlayerIndex].freqScaleChannelFlags = 0; - gActiveSeqs[seqPlayerIndex].volChannelFlags = 0; - for (scaleIndex = 0; scaleIndex < VOL_SCALE_INDEX_MAX; scaleIndex++) { - gActiveSeqs[seqPlayerIndex].volScales[scaleIndex] = 0x7F; - } - - gActiveSeqs[seqPlayerIndex].volFadeTimer = 1; - gActiveSeqs[seqPlayerIndex].fadeVolUpdate = true; - } -} - -void Audio_ResetActiveSequencesAndVolume(void) { - u8 seqPlayerIndex; - u8 scaleIndex; - - for (seqPlayerIndex = 0; seqPlayerIndex < 4; seqPlayerIndex++) { - gActiveSeqs[seqPlayerIndex].volCur = 1.0f; - gActiveSeqs[seqPlayerIndex].volTimer = 0; - gActiveSeqs[seqPlayerIndex].fadeVolUpdate = false; - for (scaleIndex = 0; scaleIndex < VOL_SCALE_INDEX_MAX; scaleIndex++) { - gActiveSeqs[seqPlayerIndex].volScales[scaleIndex] = 0x7F; - } - } - Audio_ResetActiveSequences(); -} |
