diff options
| author | engineer124 <47598039+engineer124@users.noreply.github.com> | 2023-03-07 22:14:43 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-08 00:14:43 -0300 |
| commit | 9b33e6a3a55cbb3cb423c3b89ed4a712e34c0c4f (patch) | |
| tree | ff36994185c13f2e444e347b84d5fa88da76e76b /src/code | |
| parent | e8f906100b73872174004a6ca354ba459a3e9bb4 (diff) | |
rename audio files (#1188)
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/audio/aisetnextbuf.c | 107 | ||||
| -rw-r--r-- | src/code/audio/audio_data.c | 1026 | ||||
| -rw-r--r-- | src/code/audio/audio_dcache.c | 15 | ||||
| -rw-r--r-- | src/code/audio/audio_effects.c | 341 | ||||
| -rw-r--r-- | src/code/audio/audio_heap.c | 1700 | ||||
| -rw-r--r-- | src/code/audio/audio_init_params.c | 184 | ||||
| -rw-r--r-- | src/code/audio/audio_load.c | 2239 | ||||
| -rw-r--r-- | src/code/audio/audio_playback.c | 1012 | ||||
| -rw-r--r-- | src/code/audio/audio_seqplayer.c | 2313 | ||||
| -rw-r--r-- | src/code/audio/audio_sfx_params.c | 41 | ||||
| -rw-r--r-- | src/code/audio/audio_synthesis.c | 1697 | ||||
| -rw-r--r-- | src/code/audio/audio_thread.c | 977 | ||||
| -rw-r--r-- | src/code/audio/code_8019AF00.c | 5176 | ||||
| -rw-r--r-- | src/code/audio/code_801A4EB0.c | 17 | ||||
| -rw-r--r-- | src/code/audio/code_801A51F0.c | 42 | ||||
| -rw-r--r-- | src/code/audio/code_801A5BD0.c | 944 | ||||
| -rw-r--r-- | src/code/audio/code_801A7B10.c | 31 | ||||
| -rw-r--r-- | src/code/audio_stop_all_sfx.c (renamed from src/code/code_80172BC0.c) | 0 | ||||
| -rw-r--r-- | src/code/audio_thread_manager.c (renamed from src/code/audioMgr.c) | 0 |
19 files changed, 0 insertions, 17862 deletions
diff --git a/src/code/audio/aisetnextbuf.c b/src/code/audio/aisetnextbuf.c deleted file mode 100644 index b82f28e6f..000000000 --- a/src/code/audio/aisetnextbuf.c +++ /dev/null @@ -1,107 +0,0 @@ -#include "global.h" - -//! Note that this is not the same as the original libultra -//! osAiSetNextBuffer, see comments in the function - -s32 osAiSetNextBuffer(void* buf, u32 size) { - static u8 D_801D6010 = false; - u32 bufAdjusted = (u32)buf; - s32 status; - - if (D_801D6010) { - bufAdjusted = (u32)buf - 0x2000; - } - if ((((u32)buf + size) & 0x1FFF) == 0) { - D_801D6010 = true; - } else { - D_801D6010 = false; - } - - // Originally a call to __osAiDeviceBusy - status = HW_REG(AI_STATUS_REG, s32); - if (status & AI_STATUS_AI_FULL) { - return -1; - } - - // OS_K0_TO_PHYSICAL replaces osVirtualToPhysical, this replacement - // assumes that only KSEG0 addresses are given - HW_REG(AI_DRAM_ADDR_REG, u32) = OS_K0_TO_PHYSICAL(bufAdjusted); - HW_REG(AI_LEN_REG, u32) = size; - return 0; -} - -//! Note that the remaining data and functions are unused and not part of the -//! original libultra osAiSetNextBuffer - -s16 D_801D6014[] = { - 19720, 18360, 17680, 16320, 14960, 13600, 12240, 10880, 9520, 0, -}; -s8 D_801D6028[7][16] = { - { 0, 1, 2, 2, 1, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3 }, { 0, 1, 2, 3, 3, 2, 1, 4, 5, 6, 7, 8, 7, 6, 5, 4 }, - { 0, 1, 2, 3, 4, 4, 3, 2, 1, 5, 6, 7, 8, 7, 6, 5 }, { 0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 6, 7, 8, 7, 6 }, - { 0, 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 7, 8, 7 }, { 0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 8 }, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1 }, -}; -s16 D_801D6098[7][17] = { - { 0, 268, 560, 834, 1126, 1418, 1692, 1966, 2240, 2514, 2718, 2922, 3196, 3470, 3744, 4018, 4292 }, - { 0, 268, 560, 834, 1108, 1382, 1674, 1966, 2240, 2514, 2788, 2992, 3196, 3470, 3744, 4018, 4292 }, - { 0, 268, 560, 834, 1108, 1382, 1656, 1930, 2222, 2514, 2788, 3062, 3266, 3470, 3744, 4018, 4292 }, - { 0, 268, 560, 834, 1108, 1382, 1656, 1930, 2204, 2478, 2770, 3062, 3336, 3540, 3744, 4018, 4292 }, - { 0, 268, 560, 834, 1108, 1382, 1656, 1930, 2222, 2514, 2752, 3026, 3318, 3610, 3814, 4018, 4292 }, - { 0, 268, 560, 834, 1108, 1382, 1656, 1930, 2134, 2408, 2682, 2956, 3230, 3504, 3796, 4088, 4292 }, - { 0, 268, 560, 834, 1108, 1382, 1656, 1930, 2134, 2338, 2612, 2886, 3163, 3434, 3708, 4000, 4292 }, -}; -s16* D_801D6188 = D_801D6098[0]; -s8* D_801D618C = D_801D6028[0]; - -// Unused -void func_80194804(s32 index) { - D_801D6188 = D_801D6098[index]; - D_801D618C = D_801D6028[index]; -} - -// Only used below -s16 func_80194840(s32 arg0) { - s32 i; - s32 j = 0; - - for (i = 1; i < 16; i++) { - if (arg0 < D_801D6188[i]) { - break; - } - j++; - } - - if (i == 16) { - return 0; - } else { - j = D_801D618C[j]; - return D_801D6014[j]; - } -} - -// Unused -s32 func_801948B0(s32* arg0, s32* arg1) { - s32 temp_v0; - s32 phi_s0 = *arg0; - s32 phi_s1 = *arg1; - - while (true) { - temp_v0 = func_80194840(phi_s0); - if (temp_v0 == 0) { - return -1; - } - - if (phi_s1 < temp_v0) { - break; - } - - phi_s1 -= temp_v0; - phi_s0++; - } - - *arg0 = phi_s0; - *arg1 = phi_s1; - - return 0; -} diff --git a/src/code/audio/audio_data.c b/src/code/audio/audio_data.c deleted file mode 100644 index eb931262b..000000000 --- a/src/code/audio/audio_data.c +++ /dev/null @@ -1,1026 +0,0 @@ -#include "global.h" - -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, // low-freq cutoff (more filtering) - /* 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, // high-freq cutoff (less filtering) -}; - -s16 gHighPassFilterData[15 * 8] = { - /* 0x0 */ -289, -291, -289, 30736, -289, -291, -289, -290, // low-freq cutoff (less filtering) - /* 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, // high-freq cutoff (more filtering) -}; - -// clang-format off -s16 gBandStopFilterData[105 * 8] = { - // Block 0 - /* 0x00 */ -43, -716, -1205, 28210, -1205, -716, -43, 629, - /* 0x01 */ 249, -919, -1819, 25489, -1819, -919, 249, 1301, - /* 0x02 */ 1267, -802, -2650, 20722, -2650, -802, 1267, 2603, - /* 0x03 */ 2497, -210, -3196, 17617, -3196, -210, 2497, 3339, - /* 0x04 */ 3413, 690, -3385, 14754, -3385, 690, 3413, 3035, - /* 0x05 */ 3859, 1734, -3416, 12704, -3416, 1734, 3859, 2042, - /* 0x06 */ 3858, 2907, -3414, 11516, -3414, 2907, 3858, 890, - /* 0x07 */ 3374, 4194, -3345, 10859, -3345, 4194, 3374, 80, - /* 0x08 */ 2446, 5521, -3130, 10483, -3130, 5521, 2446, 86, - /* 0x09 */ 1275, 6760, -2665, 10225, -2665, 6760, 1275, 1140, - /* 0x0A */ 252, 7778, -1836, 10022, -1836, 7778, 252, 3010, - /* 0x0B */ -98, 8427, -461, 9805, -461, 8427, -98, 4988, - /* 0x0C */ 719, 7392, 1528, 8201, 1528, 7392, 719, 5286, - /* 0x0D */ 2499, 5359, 3651, 5985, 3651, 5359, 2499, 3761, - - // Block 1 - /* 0x0E */ 711, -205, -1026, 27608, -1026, -205, 711, 1271, - /* 0x0F */ 1335, -108, -1520, 24836, -1520, -108, 1335, 2003, - /* 0x10 */ 2540, 455, -2104, 19853, -2104, 455, 2540, 2712, - /* 0x11 */ 3406, 1298, -2347, 16266, -2347, 1298, 3406, 2397, - /* 0x12 */ 3860, 2321, -2440, 14094, -2440, 2321, 3860, 1428, - /* 0x13 */ 3858, 3511, -2439, 12888, -2439, 3511, 3858, 259, - /* 0x14 */ 3248, 4679, -2238, 11859, -2238, 4679, 3248, -575, - /* 0x15 */ 2329, 6021, -1929, 11579, -1929, 6021, 2329, -626, - /* 0x16 */ 1225, 7613, -1395, 11967, -1395, 7613, 1225, 332, - /* 0x17 */ 172, 8785, -352, 12028, -352, 8785, 172, 2119, - /* 0x18 */ -172, 8198, 1139, 10360, 1139, 8198, -172, 3385, - /* 0x19 */ 511, 7006, 2830, 8649, 2830, 7006, 511, 3421, - /* 0x1A */ 1995, 5313, 4595, 6801, 4595, 5313, 1995, 2158, - - // Block 2 - /* 0x1B */ 1196, 313, -815, 26961, -815, 313, 1196, 1154, - /* 0x1C */ 1896, 666, -1159, 23821, -1159, 666, 1896, 1500, - /* 0x1D */ 2934, 1569, -1548, 19353, -1548, 1569, 2934, 1308, - /* 0x1E */ 3463, 2673, -1703, 16770, -1703, 2673, 3463, 316, - /* 0x1F */ 3269, 3757, -1608, 14587, -1608, 3757, 3269, -910, - /* 0x20 */ 2585, 4889, -1364, 13325, -1364, 4889, 2585, -1763, - /* 0x21 */ 1588, 6277, -970, 13171, -970, 6277, 1588, -1922, - /* 0x22 */ 337, 8121, -265, 14134, -265, 8121, 337, -1186, - /* 0x23 */ -795, 8193, 882, 12631, 882, 8193, -795, 391, - /* 0x24 */ -1058, 7224, 2132, 10492, 2132, 7224, -1058, 1444, - /* 0x25 */ -503, 6540, 3803, 9532, 3803, 6540, -503, 1541, - /* 0x26 */ 906, 5326, 5759, 8358, 5759, 5326, 906, 423, - - // Block 3 - /* 0x27 */ 1298, 781, -597, 27018, -597, 781, 1298, 392, - /* 0x28 */ 1914, 1364, -834, 24334, -834, 1364, 1914, 205, - /* 0x29 */ 2474, 2527, -1015, 19916, -1015, 2527, 2474, -817, - /* 0x2A */ 2277, 3649, -934, 16994, -934, 3649, 2277, -2050, - /* 0x2B */ 1545, 4865, -673, 15635, -673, 4865, 1545, -2964, - /* 0x2C */ 366, 6363, -181, 15693, -181, 6363, 366, -3252, - /* 0x2D */ -1017, 6734, 611, 13854, 611, 6734, -1017, -2187, - /* 0x2E */ -1937, 6500, 1558, 12000, 1558, 6500, -1937, -774, - /* 0x2F */ -2216, 6018, 2714, 10698, 2714, 6018, -2216, 171, - /* 0x30 */ -1795, 5344, 4221, 9864, 4221, 5344, -1795, 182, - /* 0x31 */ -659, 4411, 6228, 9260, 6228, 4411, -659, -908, - - // Block 4 - /* 0x32 */ 968, 1138, -358, 27228, -358, 1138, 968, -607, - /* 0x33 */ 1251, 1846, -453, 24418, -453, 1846, 1251, -1246, - /* 0x34 */ 1138, 3176, -412, 20709, -412, 3176, 1138, -2601, - /* 0x35 */ 313, 4550, -119, 19167, -119, 4550, 313, -3633, - /* 0x36 */ -972, 5170, 419, 16290, 419, 5170, -972, -3351, - /* 0x37 */ -2123, 5230, 1090, 13680, 1090, 5230, -2123, -2199, - /* 0x38 */ -2916, 5066, 1926, 12019, 1926, 5066, -2916, -929, - /* 0x39 */ -3202, 4669, 2995, 10953, 2995, 4669, -3202, -80, - /* 0x3A */ -2874, 3990, 4369, 10214, 4369, 3990, -2874, -84, - /* 0x3B */ -1937, 3001, 6108, 9601, 6108, 3001, -1937, -1071, - - // Block 5 - /* 0x3C */ 310, 1351, -102, 27950, -102, 1351, 310, -1287, - /* 0x3D */ 169, 2166, -55, 25895, -55, 2166, 169, -2088, - /* 0x3E */ -697, 3332, 252, 21292, 252, 3332, -697, -2909, - /* 0x3F */ -1846, 3873, 739, 17298, 739, 3873, -1846, -2549, - /* 0x40 */ -2904, 4036, 1371, 14658, 1371, 4036, -2904, -1485, - /* 0x41 */ -3657, 3912, 2183, 12999, 2183, 3912, -3657, -261, - /* 0x42 */ -3814, 3385, 3124, 11558, 3124, 3385, -3814, 561, - /* 0x43 */ -3535, 2679, 4428, 10890, 4428, 2679, -3535, 589, - /* 0x44 */ -2812, 1718, 6312, 10782, 6312, 1718, -2812, -299, - - // Block 6 - /* 0x45 */ -472, 1315, 164, 27677, 164, 1315, -472, -1185, - /* 0x46 */ -993, 1945, 353, 24630, 353, 1945, -993, -1551, - /* 0x47 */ -2181, 2706, 860, 19924, 860, 2706, -2181, -1347, - /* 0x48 */ -3275, 2979, 1521, 16895, 1521, 2979, -3275, -319, - /* 0x49 */ -3842, 2725, 2248, 14245, 2248, 2725, -3842, 889, - /* 0x4A */ -3933, 2186, 3141, 12579, 3141, 2186, -3933, 1665, - /* 0x4B */ -3664, 1431, 4428, 11971, 4428, 1431, -3664, 1747, - /* 0x4C */ -3021, 346, 6399, 12209, 6399, 346, -3021, 1024, - - // Block 7 - /* 0x4D */ -1075, 1074, 417, 27236, 417, 1074, -1075, -395, - /* 0x4E */ -1798, 1521, 741, 24438, 741, 1521, -1798, -206, - /* 0x4F */ -2921, 1848, 1426, 19572, 1426, 1848, -2921, 803, - /* 0x50 */ -3491, 1649, 2169, 16192, 2169, 1649, -3491, 1954, - /* 0x51 */ -3600, 1124, 3106, 14379, 3106, 1124, -3600, 2726, - /* 0x52 */ -3300, 278, 4453, 13834, 4453, 278, -3300, 2867, - /* 0x53 */ -2282, -916, 5804, 12748, 5804, -916, -2282, 2012, - - // Block 8 - /* 0x54 */ -1306, 682, 649, 26892, 649, 682, -1306, 599, - /* 0x55 */ -1951, 858, 1073, 23787, 1073, 858, -1951, 1214, - /* 0x56 */ -2705, 755, 1945, 19505, 1945, 755, -2705, 2450, - /* 0x57 */ -2857, 207, 2996, 17354, 2996, 207, -2857, 3289, - /* 0x58 */ -2261, -722, 4101, 15425, 4101, -722, -2261, 3173, - /* 0x59 */ -1164, -1891, 5287, 13853, 5287, -1891, -1164, 2227, - - // Block 9 - /* 0x5A */ -1119, 202, 869, 27136, 869, 202, -1119, 1249, - /* 0x5B */ -1545, 108, 1432, 24611, 1432, 108, -1545, 1984, - /* 0x5C */ -1675, -472, 2529, 20597, 2529, -472, -1675, 2814, - /* 0x5D */ -1040, -1426, 3661, 17877, 3661, -1426, -1040, 2634, - /* 0x5E */ 105, -2626, 4871, 15944, 4871, -2626, 105, 1615, - - // Block 10 - /* 0x5F */ -554, -321, 1071, 27687, 1071, -321, -554, 1185, - /* 0x60 */ -562, -704, 1738, 25171, 1738, -704, -562, 1585, - /* 0x61 */ 73, -1749, 3045, 21572, 3045, -1749, 73, 1458, - /* 0x62 */ 1152, -2704, 3884, 16963, 3884, -2704, 1152, 320, - - // Block 11 - /* 0x63 */ 222, -806, 1221, 27862, 1221, -806, 222, 404, - /* 0x64 */ 632, -1385, 1908, 24706, 1908, -1385, 632, 208, - /* 0x65 */ 1605, -2339, 2840, 18439, 2840, -2339, 1605, -756, - - // Block 12 - /* 0x66 */ 861, -1081, 1224, 25856, 1224, -1081, 861, -576, - /* 0x67 */ 1422, -1655, 1804, 21885, 1804, -1655, 1422, -1117, - - // Block 13 - /* 0x68 */ 434, -453, 467, 29652, 467, -453, 434, -405, -}; - -s16 gBandPassFilterData[105 * 8] = { - // Block 0 - /* 0x00 */ 687, 4058, 6599, 7544, 6599, 4058, 687, -2532, - /* 0x01 */ -1303, 2777, 6337, 7745, 6337, 2777, -1303, -4185, - /* 0x02 */ -2873, 1376, 5931, 7886, 5931, 1376, -2873, -4520, - /* 0x03 */ -4108, 0, 5913, 8723, 5913, 0, -4108, -3999, - /* 0x04 */ -4233, -1334, 5242, 8775, 5242, -1334, -4233, -2371, - /* 0x05 */ -3882, -2547, 4808, 9389, 4808, -2547, -3882, -900, - /* 0x06 */ -3072, -3668, 4423, 10438, 4423, -3668, -3072, 0, - /* 0x07 */ -1914, -4609, 3950, 11819, 3950, -4609, -1914, 0, - /* 0x08 */ -678, -5227, 3301, 13449, 3301, -5227, -678, -903, - /* 0x09 */ 246, -5250, 2363, 14858, 2363, -5250, 246, -2189, - /* 0x0A */ 509, -4812, 1262, 16454, 1262, -4812, 509, -3143, - /* 0x0B */ 0, -4404, 0, 20367, 0, -4404, 0, -3591, - /* 0x0C */ -1151, -2707, -1393, 19954, -1393, -2707, -1151, -2310, - /* 0x0D */ -1765, -1920, -2014, 19800, -2014, -1920, -1765, -1566, - - // Block 1 - /* 0x0E */ -3122, 1346, 5464, 7125, 5464, 1346, -3122, -5776, - /* 0x0F */ -4566, 0, 5211, 7489, 5211, 0, -4566, -5723, - /* 0x10 */ -4941, -1265, 4474, 7249, 4474, -1265, -4941, -4155, - /* 0x11 */ -4932, -2431, 4021, 7549, 4021, -2431, -4932, -2447, - /* 0x12 */ -4511, -3587, 3678, 8286, 3678, -3587, -4511, -927, - /* 0x13 */ -3660, -4711, 3314, 9396, 3314, -4711, -3660, 0, - /* 0x14 */ -2471, -5685, 2820, 10810, 2820, -5685, -2471, 0, - /* 0x15 */ -1213, -6349, 2123, 12463, 2123, -6349, -1213, -929, - /* 0x16 */ -272, -6581, 1189, 14354, 1189, -6581, -272, -2327, - /* 0x17 */ 0, -6351, 0, 16604, 0, -6351, 0, -3460, - /* 0x18 */ -509, -4812, -1262, 16454, -1262, -4812, -509, -3143, - /* 0x19 */ -1488, -3277, -2395, 16401, -2395, -3277, -1488, -2045, - /* 0x1A */ -2021, -2555, -2910, 16397, -2910, -2555, -2021, -1392, - - // Block 2 - /* 0x1B */ -5281, -1216, 4054, 6441, 4054, -1216, -5281, -5221, - /* 0x1C */ -5495, -2330, 3552, 6498, 3552, -2330, -5495, -3511, - /* 0x1D */ -5377, -3474, 3206, 6991, 3206, -3474, -5377, -1659, - /* 0x1E */ -4853, -4693, 2893, 7887, 2893, -4693, -4853, 0, - /* 0x1F */ -3646, -5586, 2357, 8623, 2357, -5586, -3646, 965, - /* 0x20 */ -2373, -6636, 1821, 10132, 1821, -6636, -2373, 971, - /* 0x21 */ -1086, -7852, 1115, 12658, 1115, -7852, -1086, 0, - /* 0x22 */ 0, -8182, 0, 14837, 0, -8182, 0, -1565, - /* 0x23 */ 272, -6581, -1189, 14354, -1189, -6581, 272, -2326, - /* 0x24 */ -246, -5250, -2363, 14858, -2363, -5250, -246, -2189, - /* 0x25 */ -1231, -3701, -3393, 14931, -3393, -3701, -1231, -1181, - /* 0x26 */ -1768, -2974, -3865, 14981, -3865, -2974, -1768, -569, - - // Block 3 - /* 0x27 */ -5832, -3391, 2948, 6305, 2948, -3391, -5832, -2116, - /* 0x28 */ -5587, -4647, 2641, 7014, 2641, -4647, -5587, 0, - /* 0x29 */ -4365, -5434, 2063, 7306, 2063, -5434, -4365, 1734, - /* 0x2A */ -3036, -6379, 1534, 8205, 1534, -6379, -3036, 2660, - /* 0x2B */ -1576, -7586, 916, 9927, 916, -7586, -1576, 2682, - /* 0x2C */ 0, -9097, 0, 12831, 0, -9097, 0, 1740, - /* 0x2D */ 1086, -7852, -1115, 12658, -1115, -7852, 1086, 0, - /* 0x2E */ 1213, -6349, -2123, 12463, -2123, -6349, 1213, -929, - /* 0x2F */ 678, -5227, -3301, 13449, -3301, -5227, 678, -903, - /* 0x30 */ -406, -3992, -4605, 14759, -4605, -3992, -406, 0, - /* 0x31 */ -979, -3083, -4882, 14287, -4882, -3083, -979, 589, - - // Block 4 - /* 0x32 */ -4748, -5319, 1902, 6607, 1902, -5319, -4748, 2218, - /* 0x33 */ -3402, -6148, 1363, 7101, 1363, -6148, -3402, 3837, - /* 0x34 */ -1853, -7246, 787, 8259, 787, -7246, -1853, 4733, - /* 0x35 */ 0, -8777, 0, 10430, 0, -8777, 0, 4782, - /* 0x36 */ 1576, -7586, -916, 9927, -916, -7586, 1576, 2682, - /* 0x37 */ 2373, -6636, -1821, 10132, -1821, -6636, 2373, 971, - /* 0x38 */ 2471, -5685, -2820, 10810, -2820, -5685, 2471, 0, - /* 0x39 */ 1914, -4609, -3950, 11819, -3950, -4609, 1914, 0, - /* 0x3A */ 846, -3385, -5195, 13035, -5195, -3385, 846, 875, - /* 0x3B */ 214, -2741, -5841, 13679, -5841, -2741, 214, 1492, - - // Block 5 - /* 0x3C */ -1989, -7002, 716, 7373, 716, -7002, -1989, 5976, - /* 0x3D */ 0, -8439, 0, 9006, 0, -8439, 0, 6882, - /* 0x3E */ 1853, -7246, -787, 8259, -787, -7246, 1853, 4733, - /* 0x3F */ 3036, -6379, -1534, 8205, -1534, -6379, 3036, 2660, - /* 0x40 */ 3646, -5586, -2357, 8623, -2357, -5586, 3646, 965, - /* 0x41 */ 3660, -4711, -3314, 9396, -3314, -4711, 3660, 0, - /* 0x42 */ 3072, -3668, -4423, 10438, -4423, -3668, 3072, 0, - /* 0x43 */ 2003, -2459, -5656, 11656, -5656, -2459, 2003, 869, - /* 0x44 */ 1374, -1820, -6298, 12297, -6298, -1820, 1374, 1483, - - // Block 6 - /* 0x45 */ 1989, -7002, -716, 7373, -716, -7002, 1989, 5976, - /* 0x46 */ 3402, -6148, -1363, 7101, -1363, -6148, 3402, 3837, - /* 0x47 */ 4365, -5434, -2063, 7306, -2063, -5434, 4365, 1734, - /* 0x48 */ 4853, -4693, -2893, 7887, -2893, -4693, 4853, 0, - /* 0x49 */ 4511, -3587, -3678, 8286, -3678, -3587, 4511, -927, - /* 0x4A */ 3882, -2547, -4808, 9389, -4808, -2547, 3882, -900, - /* 0x4B */ 2938, -1390, -6423, 11264, -6423, -1390, 2938, 0, - /* 0x4C */ 2253, -695, -7120, 11961, -7120, -695, 2253, 667, - - // Block 7 - /* 0x4D */ 4748, -5319, -1902, 6607, -1902, -5319, 4748, 2218, - /* 0x4E */ 5587, -4647, -2641, 7014, -2641, -4647, 5587, 0, - /* 0x4F */ 5377, -3474, -3206, 6991, -3206, -3474, 5377, -1659, - /* 0x50 */ 4932, -2431, -4021, 7549, -4021, -2431, 4932, -2447, - /* 0x51 */ 4233, -1334, -5242, 8775, -5242, -1334, 4233, -2371, - /* 0x52 */ 3218, 0, -7035, 10795, -7035, 0, 3218, -1464, - /* 0x53 */ 2355, 725, -7440, 11027, -7440, 725, 2355, -698, - - // Block 8 - /* 0x54 */ 5832, -3391, -2948, 6305, -2948, -3391, 5832, -2116, - /* 0x55 */ 5495, -2330, -3552, 6498, -3552, -2330, 5495, -3511, - /* 0x56 */ 4941, -1265, -4474, 7249, -4474, -1265, 4941, -4155, - /* 0x57 */ 4108, 0, -5913, 8723, -5913, 0, 4108, -3999, - /* 0x58 */ 2383, 1404, -6726, 9241, -6726, 1404, 2383, -2496, - /* 0x59 */ 1559, 2063, -7145, 9545, -7145, 2063, 1559, -1684, - - // Block 9 - /* 0x5A */ 5281, -1216, -4054, 6441, -4054, -1216, 5281, -5221, - /* 0x5B */ 4566, 0, -5211, 7489, -5211, 0, 4566, -5723, - /* 0x5C */ 2873, 1376, -5931, 7886, -5931, 1376, 2873, -4520, - /* 0x5D */ 1113, 2760, -6833, 8572, -6833, 2760, 1113, -2779, - /* 0x5E */ 267, 3420, -7291, 8943, -7291, 3420, 267, -1864, - - // Block 10 - /* 0x5F */ 3122, 1346, -5464, 7125, -5464, 1346, 3122, -5776, - /* 0x60 */ 1303, 2777, -6337, 7745, -6337, 2777, 1303, -4185, - /* 0x61 */ -605, 3972, -6859, 7994, -6859, 3972, -605, -1897, - /* 0x62 */ -1333, 4196, -6647, 7610, -6647, 4196, -1333, -803, - - // Block 11 - /* 0x63 */ -687, 4058, -6599, 7544, -6599, 4058, -687, -2532, - /* 0x64 */ -2251, 4520, -6201, 6821, -6201, 4520, -2251, 0, - /* 0x65 */ -2636, 4433, -5763, 6253, -5763, 4433, -2636, 847, - - // Block 12 - /* 0x66 */ -3207, 4379, -5163, 5439, -5163, 4379, -3207, 1826, - /* 0x67 */ -3414, 4314, -4915, 5127, -4915, 4314, -3414, 2350, - - // Block 13 - /* 0x68 */ -3854, 4188, -4398, 4469, -4398, 4188, -3854, 3415, -}; - -s16 gSawtoothWaveSample[] = { - // 1st Harmonic - 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, - - // 2nd Harmonic - 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, - - // 4th Harmonic - 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, - - // 8th Harmonic - 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[] = { - // 1st Harmonic - 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, - - // 2nd Harmonic - 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, - - // 4th Harmonic - 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, - - // 8th Harmonic - 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[] = { - // 1st Harmonic - 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, - - // 2nd Harmonic - 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, - - // 4th Harmonic - 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, - - // 8th Harmonic - 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[] = { - // 1st Harmonic - 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, - - // 2nd Harmonic - 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, - - // 4th Harmonic - -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, - - // 8th Harmonic - 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[] = { - // 1st Harmonic - 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, - - // 2nd Harmonic - 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, - - // 4th Harmonic - 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, - - // 8th Harmonic - 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_801D4790[] = { - // 1st Harmonic - 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, - - // 2nd Harmonic - 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, - - // 4th Harmonic - 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, - - // 8th Harmonic - 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[] = { - // 1st Harmonic - 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, - - // 2nd Harmonic - 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, - - // 4th Harmonic - 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, - - // 8th Harmonic - 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[] = { - // 1st Harmonic - 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, - - // 2nd Harmonic - 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, - - // 4th Harmonic - 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, - - // 8th Harmonic - 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_801D4790, 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 }, -}; - -NoteSampleState gZeroedSampleState = { 0 }; - -NoteSampleState gDefaultSampleState = { - { true, true, false, false, false, false, false, false }, - { 0 }, - 0, // gain - 0, // haasEffectLeftDelaySize - 0, // haasEffectRightDelaySize - 0, // targetReverbVol - 0, // harmonicIndexCurAndPrev - 0, // combFilterSize - 0, // targetVolLeft - 0, // targetVolRight - 0, // frequencyFixedPoint - 0, // combFilterGain - NULL, // tunedSample - NULL, // filter - 0, // unk_18 - 0, // surroundEffectIndex - 0, // unk_1A -}; - -u16 gHaasEffectDelaySize[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_801D58A4 = 0; - -// clang-format off -s16 gInvalidAdpcmCodeBook[] = { - 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, -}; - -// clang-format off -s16 D_801D5F24[8 * (2 + 3 + 3)] = { - // floor(sin(i * M_PI / 16) * (2^15 - 1)) - 0, 6392, 12539, 18204, 23169, 27244, 30272, 32137, - 32767, 32137, 30272, 27244, 23169, 18204, 12539, 6392, - // -floor(sin(i * M_PI / 32) * (2^15 - 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, - // -floor(sin(i * M_PI / 32) * (2^15 - 1)) - -23169, -25329, -27244, -28897, -30272, -31356, -32137, -32609, - -32767, -32609, -32137, -31356, -30272, -28897, -27244, -25329, - -23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211, -}; -// clang-format on diff --git a/src/code/audio/audio_dcache.c b/src/code/audio/audio_dcache.c deleted file mode 100644 index 27f019fef..000000000 --- a/src/code/audio/audio_dcache.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "global.h" - -void Audio_InvalDCache(void* buf, size_t size) { - OSIntMask prevMask = osSetIntMask(1); - - osInvalDCache(buf, size); - osSetIntMask(prevMask); -} - -void Audio_WritebackDCache(void* buf, size_t size) { - OSIntMask prevMask = osSetIntMask(1); - - osWritebackDCache(buf, size); - osSetIntMask(prevMask); -} diff --git a/src/code/audio/audio_effects.c b/src/code/audio/audio_effects.c deleted file mode 100644 index 0dcdcda88..000000000 --- a/src/code/audio/audio_effects.c +++ /dev/null @@ -1,341 +0,0 @@ -#include "global.h" - -void AudioEffects_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->muteFlags & MUTE_FLAGS_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 < ARRAY_COUNT(channel->layers); 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 AudioEffects_SequencePlayerProcessSound(SequencePlayer* seqPlayer) { - s32 i; - - if ((seqPlayer->fadeTimer != 0) && (seqPlayer->skipTicks == 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 == SEQPLAYER_STATE_FADE_OUT)) { - AudioSeq_SequencePlayerDisable(seqPlayer); - return; - } - } - - if (seqPlayer->recalculateVolume) { - seqPlayer->appliedFadeVolume = seqPlayer->fadeVolume * seqPlayer->fadeVolumeScale; - } - - for (i = 0; i < ARRAY_COUNT(seqPlayer->channels); i++) { - if (seqPlayer->channels[i]->enabled == true) { - AudioEffects_SequenceChannelProcessSound(seqPlayer->channels[i], seqPlayer->recalculateVolume, - seqPlayer->applyBend); - } - } - - seqPlayer->recalculateVolume = false; -} - -f32 AudioEffects_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 = AUDIO_LERPIMP(1.0f, gBendPitchOneOctaveFrequencies[loResCur + 128], portamento->extent); - - return portamentoFreq; -} - -s16 AudioEffects_GetVibratoPitchChange(VibratoState* vib) { - s32 index; - - vib->time += (s32)vib->rate; - index = (vib->time >> 10) & 0x3F; - return vib->curve[index]; -} - -f32 AudioEffects_GetVibratoFreqScale(VibratoState* vib) { - static f32 activeVibratoFreqScaleSum = 0.0f; - static s32 activeVibratoCount = 0; - f32 pitchChange; - f32 depth; - f32 invDepth; - f32 result; - f32 scaledDepth; - VibratoSubStruct* subVib = vib->vibSubStruct; - - if (vib->delay != 0) { - vib->delay--; - return 1.0f; - } - - if (subVib != NULL) { - if (vib->depthChangeTimer) { - if (vib->depthChangeTimer == 1) { - vib->depth = (s32)subVib->vibratoDepthTarget; - } else { - vib->depth += ((s32)subVib->vibratoDepthTarget - vib->depth) / (s32)vib->depthChangeTimer; - } - - vib->depthChangeTimer--; - } else if (subVib->vibratoDepthTarget != (s32)vib->depth) { - if ((vib->depthChangeTimer = subVib->vibratoDepthChangeDelay) == 0) { - vib->depth = (s32)subVib->vibratoDepthTarget; - } - } - - if (vib->rateChangeTimer) { - if (vib->rateChangeTimer == 1) { - vib->rate = (s32)subVib->vibratoRateTarget; - } else { - vib->rate += ((s32)subVib->vibratoRateTarget - vib->rate) / (s32)vib->rateChangeTimer; - } - - vib->rateChangeTimer--; - } else if (subVib->vibratoRateTarget != (s32)vib->rate) { - if ((vib->rateChangeTimer = subVib->vibratoRateChangeDelay) == 0) { - vib->rate = (s32)subVib->vibratoRateTarget; - } - } - } - - if (vib->depth == 0.0f) { - return 1.0f; - } - - pitchChange = AudioEffects_GetVibratoPitchChange(vib) + 32768.0f; - scaledDepth = vib->depth / 4096.0f; - depth = scaledDepth + 1.0f; - invDepth = 1.0f / depth; - - // inverse linear interpolation - result = 1.0f / ((depth - invDepth) * pitchChange / 65536.0f + invDepth); - - activeVibratoFreqScaleSum += result; - activeVibratoCount++; - - return result; -} - -void AudioEffects_NoteVibratoUpdate(Note* note) { - if (note->playbackState.portamento.mode != 0) { - note->playbackState.portamentoFreqScale = AudioEffects_GetPortamentoFreqScale(¬e->playbackState.portamento); - } - if (note->playbackState.vibratoState.active) { - note->playbackState.vibratoFreqScale = AudioEffects_GetVibratoFreqScale(¬e->playbackState.vibratoState); - } -} - -void AudioEffects_NoteVibratoInit(Note* note) { - NotePlaybackState* playbackState = ¬e->playbackState; - VibratoState* vib = &playbackState->vibratoState; - VibratoSubStruct* subVib; - - vib->active = true; - vib->curve = gWaveSamples[2]; - - if (playbackState->parentLayer->unk_0A.s.bit_3 == 1) { - vib->vibSubStruct = &playbackState->parentLayer->channel->vibrato; - } else { - vib->vibSubStruct = &playbackState->parentLayer->vibrato; - } - - subVib = vib->vibSubStruct; - - if ((vib->depthChangeTimer = subVib->vibratoDepthChangeDelay) == 0) { - vib->depth = (s32)subVib->vibratoDepthTarget; - } else { - vib->depth = (s32)subVib->vibratoDepthStart; - } - - if ((vib->rateChangeTimer = subVib->vibratoRateChangeDelay) == 0) { - vib->rate = (s32)subVib->vibratoRateTarget; - } else { - vib->rate = (s32)subVib->vibratoRateStart; - } - - playbackState->vibratoFreqScale = 1.0f; - vib->time = 0; - vib->delay = subVib->vibratoDelay; -} - -void AudioEffects_NotePortamentoInit(Note* note) { - note->playbackState.portamentoFreqScale = 1.0f; - note->playbackState.portamento = note->playbackState.parentLayer->portamento; -} - -void AudioEffects_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; - adsr->velocity = 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 AudioEffects_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; - // fallthrough - retry: - 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/audio_heap.c b/src/code/audio/audio_heap.c deleted file mode 100644 index d767f7de3..000000000 --- a/src/code/audio/audio_heap.c +++ /dev/null @@ -1,1700 +0,0 @@ -#include "global.h" - -void* AudioHeap_SearchRegularCaches(s32 tableType, s32 cache, s32 id); -void AudioHeap_InitSampleCaches(size_t persistentSampleCacheSize, size_t temporarySampleCacheSize); -SampleCacheEntry* AudioHeap_AllocTemporarySampleCacheEntry(size_t size); -void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry); -void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, Sample* sample); -SampleCacheEntry* AudioHeap_AllocPersistentSampleCacheEntry(size_t size); -void AudioHeap_DiscardSampleCaches(void); -void AudioHeap_DiscardSampleBank(s32 sampleBankId); -void AudioHeap_ApplySampleBankCacheInternal(s32 apply, s32 sampleBankId); -void AudioHeap_DiscardSampleBanks(void); -void AudioHeap_InitReverb(s32 reverbIndex, ReverbSettings* settings, s32 isFirstInit); - -#define gTatumsPerBeat (gAudioTatumInit[1]) - -/** - * 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 < ARRAY_COUNT(gAudioCtx.fontLoadStatus); i++) { - if (gAudioCtx.fontLoadStatus[i] != LOAD_STATUS_PERMANENT) { - gAudioCtx.fontLoadStatus[i] = LOAD_STATUS_NOT_LOADED; - } - } - - for (i = 0; i < ARRAY_COUNT(gAudioCtx.sampleFontLoadStatus); i++) { - if (gAudioCtx.sampleFontLoadStatus[i] != LOAD_STATUS_PERMANENT) { - gAudioCtx.sampleFontLoadStatus[i] = LOAD_STATUS_NOT_LOADED; - } - } - - for (i = 0; i < ARRAY_COUNT(gAudioCtx.seqLoadStatus); i++) { - if (gAudioCtx.seqLoadStatus[i] != LOAD_STATUS_PERMANENT) { - 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.status == PLAYBACK_STATUS_0) && (note->playbackState.priority != 0)) { - note->playbackState.parentLayer->enabled = false; - note->playbackState.parentLayer->finished = true; - } - - AudioPlayback_NoteDisable(note); - AudioPlayback_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->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 L1 data cache to the ram. - */ -void* AudioHeap_WritebackDCache(void* addr, size_t size) { - Audio_WritebackDCache(addr, size); - if (addr) {} - - // KSEG0 to KSEG1 (ensures data is written straight to ram instead of the data cache) - return OS_PHYSICAL_TO_K1(OS_K0_TO_PHYSICAL(addr)); -} - -/** - * Attempt to allocated space on an external device. If no external device is available, - * then allocate space on the pool provided in the argument. - * Afterwards, zero all data pool the new allocated space - */ -void* AudioHeap_AllocZeroedAttemptExternal(AudioAllocPool* pool, size_t size) { - void* addr = NULL; - - if (gAudioCtx.externalPool.startAddr != NULL) { - addr = AudioHeap_AllocZeroed(&gAudioCtx.externalPool, size); - } - - if (addr == NULL) { - addr = AudioHeap_AllocZeroed(pool, size); - } - - return addr; -} - -/** - * Attempt to allocated space on an external device. If no external device is available, - * then allocate space on the pool provided in the argument - */ -void* AudioHeap_AllocAttemptExternal(AudioAllocPool* pool, size_t size) { - void* addr = NULL; - - if (gAudioCtx.externalPool.startAddr != NULL) { - addr = AudioHeap_Alloc(&gAudioCtx.externalPool, size); - } - - if (addr == NULL) { - addr = AudioHeap_Alloc(pool, size); - } - - return addr; -} - -void* AudioHeap_AllocDmaMemory(AudioAllocPool* pool, size_t size) { - void* addr = AudioHeap_Alloc(pool, size); - - if (addr != NULL) { - addr = AudioHeap_WritebackDCache(addr, size); - } - - return addr; -} - -void* AudioHeap_AllocDmaMemoryZeroed(AudioAllocPool* pool, size_t size) { - void* addr = AudioHeap_AllocZeroed(pool, size); - - if (addr != NULL) { - addr = AudioHeap_WritebackDCache(addr, size); - } - - return addr; -} - -/** - * Allocates space on a pool contained withing the heap and sets all the allocated space to 0 - */ -void* AudioHeap_AllocZeroed(AudioAllocPool* pool, size_t size) { - u8* addr = AudioHeap_Alloc(pool, size); - u8* ptr; - - if (addr != NULL) { - for (ptr = addr; ptr < pool->curAddr; ptr++) { - *ptr = 0; - } - } - - return addr; -} - -/** - * Tests the pool to see if the requested allocation would fit without actually allocating space. - * Returns NULL if there is not enough space on the pool. - * Else, return the address that would have been allocated - */ -void* AudioHeap_TestAlloc(AudioAllocPool* pool, size_t size) { - u8* oldAddr = pool->curAddr; - void* addr = AudioHeap_Alloc(pool, size); - - // remove allocation from pool - if (addr != NULL) { - pool->curAddr = oldAddr; - pool->count--; - } - - return addr; -} - -/** - * Allocates space on the pool contained withing the heap. If there is not enough space on the pool, return NULL - */ -void* AudioHeap_Alloc(AudioAllocPool* pool, size_t size) { - size_t alignedSize = ALIGN16(size); - u8* curAddr = pool->curAddr; - - if ((pool->startAddr + pool->size) >= (pool->curAddr + alignedSize)) { - pool->curAddr += alignedSize; - } else { - return NULL; - } - - pool->count++; - return curAddr; -} - -/** - * Initialize a pool at the requested address with the requested size. - * Store the metadata of this pool in AudioAllocPool* pool - */ -void AudioHeap_InitPool(AudioAllocPool* pool, void* addr, size_t size) { - pool->curAddr = pool->startAddr = (u8*)ALIGN16((uintptr_t)addr); - pool->size = size - ((uintptr_t)addr & 0xF); - pool->count = 0; -} - -void AudioHeap_InitPersistentCache(AudioPersistentCache* persistent) { - persistent->pool.count = 0; - persistent->numEntries = 0; - persistent->pool.curAddr = persistent->pool.startAddr; -} - -void AudioHeap_InitTemporaryCache(AudioTemporaryCache* temporary) { - temporary->pool.count = 0; - temporary->pool.curAddr = temporary->pool.startAddr; - temporary->nextSide = 0; - temporary->entries[0].addr = temporary->pool.startAddr; - temporary->entries[1].addr = temporary->pool.startAddr + temporary->pool.size; - temporary->entries[0].id = -1; - temporary->entries[1].id = -1; -} - -void AudioHeap_ResetPool(AudioAllocPool* pool) { - pool->count = 0; - pool->curAddr = pool->startAddr; -} - -void AudioHeap_PopPersistentCache(s32 tableType) { - AudioCache* loadedCache; - AudioAllocPool* persistentHeap; - AudioPersistentCache* persistent; - void* entryAddr; - 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; - persistentHeap = &persistent->pool; - - if (persistent->numEntries == 0) { - return; - } - - entryAddr = persistent->entries[persistent->numEntries - 1].addr; - persistentHeap->curAddr = entryAddr; - persistentHeap->count--; - - 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_InitMainPool(size_t initPoolSize) { - AudioHeap_InitPool(&gAudioCtx.initPool, gAudioCtx.audioHeap, initPoolSize); - AudioHeap_InitPool(&gAudioCtx.sessionPool, gAudioCtx.audioHeap + initPoolSize, - gAudioCtx.audioHeapSize - initPoolSize); - - gAudioCtx.externalPool.startAddr = NULL; -} - -void AudioHeap_InitSessionPool(AudioSessionPoolSplit* split) { - gAudioCtx.sessionPool.curAddr = gAudioCtx.sessionPool.startAddr; - - 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_InitCachePool(AudioCachePoolSplit* split) { - gAudioCtx.cachePool.curAddr = gAudioCtx.cachePool.startAddr; - - 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.curAddr = gAudioCtx.persistentCommonPool.startAddr; - - 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.curAddr = gAudioCtx.temporaryCommonPool.startAddr; - - 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, size_t size, s32 cache, s32 id) { - AudioCache* loadedCache; - AudioTemporaryCache* temporaryCache; - AudioAllocPool* temporaryPool; - void* persistentAddr; - void* temporaryAddr; - 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 ((s32)temporaryPool->size < (s32)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].sampleState.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].sampleState.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].sampleState.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].sampleState.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].addr = temporaryPool->startAddr; - temporaryCache->entries[0].id = id; - temporaryCache->entries[0].size = size; - temporaryPool->curAddr = temporaryPool->startAddr + size; - - if ((temporaryCache->entries[1].id != -1) && - (temporaryCache->entries[1].addr < temporaryPool->curAddr)) { - 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].addr = temporaryPool->startAddr + temporaryPool->size; - } - - temporaryAddr = temporaryCache->entries[0].addr; - break; - - case 1: - temporaryCache->entries[1].addr = - (u8*)((uintptr_t)(temporaryPool->startAddr + temporaryPool->size - size) & ~0xF); - temporaryCache->entries[1].id = id; - temporaryCache->entries[1].size = size; - if ((temporaryCache->entries[0].id != -1) && - (temporaryCache->entries[1].addr < temporaryPool->curAddr)) { - 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->curAddr = temporaryPool->startAddr; - } - - temporaryAddr = temporaryCache->entries[1].addr; - break; - - default: - return NULL; - } - - temporaryCache->nextSide ^= 1; - return temporaryAddr; - } - - persistentAddr = AudioHeap_Alloc(&loadedCache->persistent.pool, size); - loadedCache->persistent.entries[loadedCache->persistent.numEntries].addr = persistentAddr; - - if (persistentAddr == 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++].addr; -} - -void* AudioHeap_SearchCaches(s32 tableType, s32 cache, s32 id) { - void* addr; - - // Always search the permanent cache in addition to the regular ones. - addr = AudioHeap_SearchPermanentCache(tableType, id); - if (addr != NULL) { - return addr; - } - 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].addr; - } else if (temporary->entries[1].id == id) { - temporary->nextSide = 0; - return temporary->entries[1].addr; - } else { - return NULL; - } - } - - persistent = &loadedCache->persistent; - - for (i = 0; i < persistent->numEntries; i++) { - if (persistent->entries[i].id == id) { - return persistent->entries[i].addr; - } - } - - if (cache == CACHE_EITHER) { - return AudioHeap_SearchCaches(tableType, CACHE_TEMPORARY, id); - } - return NULL; -} - -void func_8018C4E4(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; - s32 j; - s32 k; - s32 cutOff; - - //! @bug filter is never set if (lowPassCutoff == highPassCutoff) and does not equal 0 - 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 { - k = 0; - j = 14; - - cutOff = lowPassCutoff; - if (lowPassCutoff < highPassCutoff) { - - for (i = 1; i < cutOff; i++) { - k += j; - j--; - } - - k += highPassCutoff - lowPassCutoff - 1; - for (i = 0; i < 8; i++) { - //! @bug should be gBandStopFilterData[8 * k + i]; - filter[i] = gBandStopFilterData[k + i]; - } - } else if (highPassCutoff < lowPassCutoff) { - - cutOff = highPassCutoff; - for (i = 1; i < cutOff; i++) { - k += j; - j--; - } - - k += lowPassCutoff - highPassCutoff - 1; - for (i = 0; i < 8; i++) { - //! @bug should be gBandPassFilterData[8 * k + i]; - filter[i] = gBandPassFilterData[k + i]; - } - } - } -} - -void AudioHeap_UpdateReverb(SynthesisReverb* reverb) { -} - -void AudioHeap_UpdateReverbs(void) { - s32 count; - s32 reverbIndex; - s32 j; - - if (gAudioCtx.audioBufferParameters.specUnk4 == 2) { - count = 2; - } else { - count = 1; - } - - for (reverbIndex = 0; reverbIndex < gAudioCtx.numSynthesisReverbs; reverbIndex++) { - for (j = 0; j < count; j++) { - AudioHeap_UpdateReverb(&gAudioCtx.synthesisReverbs[reverbIndex]); - } - } -} - -/** - * Clear the Audio Interface Buffers - */ -void AudioHeap_ClearAiBuffers(void) { - s32 curAiBufferIndex = gAudioCtx.curAiBufferIndex; - s32 i; - - gAudioCtx.numSamplesPerFrame[curAiBufferIndex] = gAudioCtx.audioBufferParameters.numSamplesPerFrameMin; - - for (i = 0; i < AIBUF_LEN; i++) { - gAudioCtx.aiBuffers[curAiBufferIndex][i] = 0; - } -} - -s32 AudioHeap_ResetStep(void) { - s32 i; - s32 j; - s32 count; - - if (gAudioCtx.audioBufferParameters.specUnk4 == 2) { - count = 2; - } else { - count = 1; - } - - switch (gAudioCtx.resetStatus) { - case 5: - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - AudioSeq_SequencePlayerDisableAsFinished(&gAudioCtx.seqPlayers[i]); - } - gAudioCtx.audioResetFadeOutFramesLeft = 2 / count; - 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].sampleState.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 / count; - gAudioCtx.resetStatus--; - } - break; - - case 3: - if (gAudioCtx.audioResetFadeOutFramesLeft != 0) { - gAudioCtx.audioResetFadeOutFramesLeft--; - AudioHeap_UpdateReverbs(); - } else { - gAudioCtx.audioResetFadeOutFramesLeft = 2 / count; - gAudioCtx.resetStatus--; - } - break; - - case 2: - AudioHeap_ClearAiBuffers(); - 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 < ARRAY_COUNT(gAudioCtx.numSamplesPerFrame); i++) { - gAudioCtx.numSamplesPerFrame[i] = gAudioCtx.audioBufferParameters.numSamplesPerFrameMax; - 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* addr; - size_t persistentSize; - size_t temporarySize; - size_t cachePoolSize; - size_t miscPoolSize; - u32 intMask; - s32 reverbIndex; - s32 i; - s32 pad2; - AudioSpec* spec = &gAudioSpecs[gAudioCtx.specId]; // Audio Specifications - - gAudioCtx.sampleDmaCount = 0; - - // audio buffer parameters - gAudioCtx.audioBufferParameters.samplingFreq = spec->samplingFreq; - gAudioCtx.audioBufferParameters.aiSamplingFreq = osAiSetFrequency(gAudioCtx.audioBufferParameters.samplingFreq); - - gAudioCtx.audioBufferParameters.numSamplesPerFrameTarget = - ALIGN16(gAudioCtx.audioBufferParameters.samplingFreq / gAudioCtx.refreshRate); - gAudioCtx.audioBufferParameters.numSamplesPerFrameMin = - gAudioCtx.audioBufferParameters.numSamplesPerFrameTarget - 0x10; - gAudioCtx.audioBufferParameters.numSamplesPerFrameMax = - gAudioCtx.audioBufferParameters.numSamplesPerFrameTarget + 0x10; - gAudioCtx.audioBufferParameters.updatesPerFrame = - ((gAudioCtx.audioBufferParameters.numSamplesPerFrameTarget + 0x10) / 0xD0) + 1; - gAudioCtx.audioBufferParameters.numSamplesPerUpdate = - (gAudioCtx.audioBufferParameters.numSamplesPerFrameTarget / gAudioCtx.audioBufferParameters.updatesPerFrame) & - ~7; - gAudioCtx.audioBufferParameters.numSamplesPerUpdateMax = gAudioCtx.audioBufferParameters.numSamplesPerUpdate + 8; - gAudioCtx.audioBufferParameters.numSamplesPerUpdateMin = gAudioCtx.audioBufferParameters.numSamplesPerUpdate - 8; - gAudioCtx.audioBufferParameters.resampleRate = 32000.0f / (s32)gAudioCtx.audioBufferParameters.samplingFreq; - 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; - - // sample dma size - gAudioCtx.sampleDmaBufSize1 = spec->sampleDmaBufSize1; - gAudioCtx.sampleDmaBufSize2 = spec->sampleDmaBufSize2; - - gAudioCtx.numNotes = spec->numNotes; - gAudioCtx.audioBufferParameters.numSequencePlayers = spec->numSequencePlayers; - - if (gAudioCtx.audioBufferParameters.numSequencePlayers > 5) { - gAudioCtx.audioBufferParameters.numSequencePlayers = 5; - } - - gAudioCtx.numAbiCmdsMax = 8; - gAudioCtx.unk_2 = spec->unk_14; - gAudioCtx.maxTempo = - (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.aiSamplingFreq; - gAudioCtx.unk_2870 /= gAudioCtx.maxTempo; - - gAudioCtx.audioBufferParameters.specUnk4 = spec->unk_04; - gAudioCtx.audioBufferParameters.numSamplesPerFrameTarget *= gAudioCtx.audioBufferParameters.specUnk4; - gAudioCtx.audioBufferParameters.numSamplesPerFrameMax *= gAudioCtx.audioBufferParameters.specUnk4; - gAudioCtx.audioBufferParameters.numSamplesPerFrameMin *= gAudioCtx.audioBufferParameters.specUnk4; - gAudioCtx.audioBufferParameters.updatesPerFrame *= gAudioCtx.audioBufferParameters.specUnk4; - - if (gAudioCtx.audioBufferParameters.specUnk4 >= 2) { - gAudioCtx.audioBufferParameters.numSamplesPerFrameMax -= 0x10; - } - - // Determine the maximum allowable number of audio command list entries for the rsp microcode - gAudioCtx.maxAudioCmds = - gAudioCtx.numNotes * 20 * gAudioCtx.audioBufferParameters.updatesPerFrame + spec->numReverbs * 30 + 800; - - // 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.startAddr != NULL) { - gAudioCtx.externalPool.curAddr = gAudioCtx.externalPool.startAddr; - } - - // Session Pool Split (split into Cache and Misc heaps) - gAudioCtx.sessionPoolSplit.miscPoolSize = miscPoolSize; - gAudioCtx.sessionPoolSplit.cachePoolSize = cachePoolSize; - AudioHeap_InitSessionPool(&gAudioCtx.sessionPoolSplit); - - // Cache Pool Split (Split into Persistent and Temporary heaps) - gAudioCtx.cachePoolSplit.persistentCommonPoolSize = persistentSize; - gAudioCtx.cachePoolSplit.temporaryCommonPoolSize = temporarySize; - AudioHeap_InitCachePool(&gAudioCtx.cachePoolSplit); - - // Persistent Pool Split (Split into Sequences, SoundFonts, Samples) - 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) - 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)); - AudioPlayback_NoteInitAll(); - AudioPlayback_InitNoteFreeList(); - gAudioCtx.sampleStateList = - AudioHeap_AllocZeroed(&gAudioCtx.miscPool, gAudioCtx.audioBufferParameters.updatesPerFrame * - gAudioCtx.numNotes * sizeof(NoteSampleState)); - - // Initialize audio binary interface command list buffer - for (i = 0; i < ARRAY_COUNT(gAudioCtx.abiCmdBufs); 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, 0x100 * sizeof(f32)); - AudioHeap_InitAdsrDecayTable(); - - // Initialize reverbs - for (reverbIndex = 0; reverbIndex < ARRAY_COUNT(gAudioCtx.synthesisReverbs); reverbIndex++) { - gAudioCtx.synthesisReverbs[reverbIndex].useReverb = 0; - } - - gAudioCtx.numSynthesisReverbs = spec->numReverbs; - for (reverbIndex = 0; reverbIndex < gAudioCtx.numSynthesisReverbs; reverbIndex++) { - AudioHeap_InitReverb(reverbIndex, &spec->reverbSettings[reverbIndex], true); - } - - // Initialize sequence players - AudioSeq_InitSequencePlayers(); - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - AudioSeq_InitSequencePlayerChannels(i); - AudioSeq_ResetSequencePlayer(&gAudioCtx.seqPlayers[i]); - } - - // Initialize two additional caches on the audio heap to store individual audio samples - AudioHeap_InitSampleCaches(spec->persistentSampleCacheSize, spec->temporarySampleCacheSize); - AudioLoad_InitSampleDmaBuffers(gAudioCtx.numNotes); - - // Initalize Loads - gAudioCtx.preloadSampleStackTop = 0; - AudioLoad_InitSlowLoads(); - AudioLoad_InitScriptLoads(); - AudioLoad_InitAsyncLoads(); - gAudioCtx.unk_4 = 0x1000; - AudioLoad_LoadPermanentSamples(); - - intMask = osSetIntMask(1); - osWritebackDCacheAll(); - osSetIntMask(intMask); -} - -void* AudioHeap_SearchPermanentCache(s32 tableType, s32 id) { - s32 i; - - for (i = 0; i < gAudioCtx.permanentPool.count; i++) { - if (gAudioCtx.permanentEntries[i].tableType == tableType && gAudioCtx.permanentEntries[i].id == id) { - return gAudioCtx.permanentEntries[i].addr; - } - } - return NULL; -} - -void* AudioHeap_AllocPermanent(s32 tableType, s32 id, size_t size) { - void* addr; - s32 index = gAudioCtx.permanentPool.count; - - addr = AudioHeap_Alloc(&gAudioCtx.permanentPool, size); - gAudioCtx.permanentEntries[index].addr = addr; - - if (addr == NULL) { - return NULL; - } - - gAudioCtx.permanentEntries[index].tableType = tableType; - gAudioCtx.permanentEntries[index].id = id; - gAudioCtx.permanentEntries[index].size = size; - //! @bug UB: missing return. "addr" is in v0 at this point, but doing an - // explicit return uses an additional register. - // return addr; -} - -void* AudioHeap_AllocSampleCache(size_t size, s32 sampleBankId, void* sampleAddr, s8 medium, s32 cache) { - SampleCacheEntry* entry; - - if (cache == CACHE_TEMPORARY) { - entry = AudioHeap_AllocTemporarySampleCacheEntry(size); - } else { - entry = AudioHeap_AllocPersistentSampleCacheEntry(size); - } - - if (entry != NULL) { - entry->sampleBankId = sampleBankId; - 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 heap. - */ -void AudioHeap_InitSampleCaches(size_t persistentSampleCacheSize, size_t temporarySampleCacheSize) { - void* addr; - - addr = AudioHeap_AllocAttemptExternal(&gAudioCtx.miscPool, persistentSampleCacheSize); - if (addr == NULL) { - gAudioCtx.persistentSampleCache.pool.size = 0; - } else { - AudioHeap_InitPool(&gAudioCtx.persistentSampleCache.pool, addr, persistentSampleCacheSize); - } - - addr = AudioHeap_AllocAttemptExternal(&gAudioCtx.miscPool, temporarySampleCacheSize); - if (addr == NULL) { - gAudioCtx.temporarySampleCache.pool.size = 0; - } else { - AudioHeap_InitPool(&gAudioCtx.temporarySampleCache.pool, addr, temporarySampleCacheSize); - } - - gAudioCtx.persistentSampleCache.numEntries = 0; - gAudioCtx.temporarySampleCache.numEntries = 0; -} - -SampleCacheEntry* AudioHeap_AllocTemporarySampleCacheEntry(size_t size) { - s32 pad2[2]; - void* addr; - s32 pad3[2]; - u8* allocAfter; - u8* allocBefore; - s32 pad1; - s32 index; - s32 i; - SampleCacheEntry* entry; - AudioPreloadReq* preload; - AudioSampleCache* cache; - u8* startAddr; - u8* endAddr; - - cache = &gAudioCtx.temporarySampleCache; - allocBefore = cache->pool.curAddr; - addr = AudioHeap_Alloc(&cache->pool, size); - if (addr == NULL) { - // Reset the heap and try again. We still keep pointers to within the - // heap, so we have to be careful to discard existing overlapping - // allocations further down. - u8* oldAddr = cache->pool.curAddr; - - cache->pool.curAddr = cache->pool.startAddr; - addr = AudioHeap_Alloc(&cache->pool, size); - if (addr == NULL) { - cache->pool.curAddr = oldAddr; - return NULL; - } - allocBefore = cache->pool.startAddr; - } - - allocAfter = cache->pool.curAddr; - - index = -1; - for (i = 0; i < gAudioCtx.preloadSampleStackTop; i++) { - preload = &gAudioCtx.preloadSampleStack[i]; - if (preload->isFree == false) { - startAddr = preload->ramAddr; - endAddr = preload->ramAddr + preload->sample->size - 1; - - if ((endAddr < allocBefore) && (startAddr < allocBefore)) { - continue; - } - if ((endAddr >= allocAfter) && (startAddr >= allocAfter)) { - continue; - } - - // Overlap, skip this preload. - preload->isFree = true; - } - } - - for (i = 0; i < cache->numEntries; i++) { - if (!cache->entries[i].inUse) { - continue; - } - - startAddr = cache->entries[i].allocatedAddr; - endAddr = startAddr + cache->entries[i].size - 1; - - if ((endAddr < allocBefore) && (startAddr < allocBefore)) { - continue; - } - if ((endAddr >= allocAfter) && (startAddr >= allocAfter)) { - continue; - } - - // Overlap, discard existing entry. - AudioHeap_DiscardSampleCacheEntry(&cache->entries[i]); - cache->entries[i].inUse = false; - if (index == -1) { - index = i; - } - } - - if (index == -1) { - for (i = 0; i < cache->numEntries; i++) { - if (!cache->entries[i].inUse) { - break; - } - } - - index = i; - if (index == cache->numEntries) { - if (cache->numEntries == 128) { - return NULL; - } - cache->numEntries++; - } - } - - entry = &cache->entries[index]; - entry->inUse = 1; - entry->allocatedAddr = addr; - 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 = AudioPlayback_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 = AudioPlayback_GetDrum(fontId, drumId); - if (drum != NULL) { - AudioHeap_UnapplySampleCache(entry, drum->tunedSample.sample); - } - } - - for (sfxId = 0; sfxId < gAudioCtx.soundFontList[fontId].numSfx; sfxId++) { - soundEffect = AudioPlayback_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 || - entry->sampleBankId == 0xFE) { - if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, fontId) != NULL) { - if (1) {} - 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(size_t size) { - AudioSampleCache* cache; - SampleCacheEntry* entry; - void* addr; - - cache = &gAudioCtx.persistentSampleCache; - addr = AudioHeap_Alloc(&cache->pool, size); - if (addr == NULL) { - return NULL; - } - - if (cache->numEntries == 128) { - return NULL; - } - - entry = &cache->entries[cache->numEntries]; - entry->inUse = true; - entry->allocatedAddr = addr; - 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 { - uintptr_t oldAddr; - uintptr_t newAddr; - size_t size; - u8 newMedium; -} StorageChange; - -void AudioHeap_ChangeStorage(StorageChange* change, Sample* sample) { - if (sample != NULL && ((sample->medium == change->newMedium) || (D_801FD120 != 1)) && - ((sample->medium == MEDIUM_RAM) || (D_801FD120 != 0))) { - uintptr_t startAddr = change->oldAddr; - uintptr_t endAddr = change->oldAddr + change->size; - - if (startAddr <= (uintptr_t)sample->sampleAddr && (uintptr_t)sample->sampleAddr < endAddr) { - sample->sampleAddr = sample->sampleAddr - startAddr + change->newAddr; - if (D_801FD120 == 0) { - sample->medium = change->newMedium; - } else { - sample->medium = MEDIUM_RAM; - } - } - } -} - -void AudioHeap_DiscardSampleBank(s32 sampleBankId) { - D_801FD120 = 0; - AudioHeap_ApplySampleBankCacheInternal(false, sampleBankId); -} - -void AudioHeap_ApplySampleBankCache(s32 sampleBankId) { - D_801FD120 = 1; - 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; - uintptr_t* newAddr; - s32 pad[4]; - - sampleBankTable = gAudioCtx.sampleBankTable; - numFonts = gAudioCtx.soundFontTable->numEntries; - change.oldAddr = AudioHeap_SearchCaches(SAMPLE_TABLE, CACHE_EITHER, sampleBankId); - if (change.oldAddr == 0) { - return; - } - - entry = &sampleBankTable->entries[sampleBankId]; - change.size = entry->size; - change.newMedium = entry->medium; - change.newAddr = entry->romAddr; - - newAddr = &change.oldAddr; - if (apply && (apply == true)) { - uintptr_t oldAddr; - - oldAddr = change.newAddr; - - change.newAddr = *newAddr; - change.oldAddr = oldAddr; - } - - 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 = AudioPlayback_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 = AudioPlayback_GetDrum(fontId, drumId); - if (drum != NULL) { - AudioHeap_ChangeStorage(&change, drum->tunedSample.sample); - } - } - - for (sfxId = 0; sfxId < gAudioCtx.soundFontList[fontId].numSfx; sfxId++) { - soundEffect = AudioPlayback_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); - } -} - -void AudioHeap_SetReverbData(s32 reverbIndex, u32 dataType, s32 data, s32 isFirstInit) { - s32 delayNumSamples; - SynthesisReverb* reverb = &gAudioCtx.synthesisReverbs[reverbIndex]; - - switch (dataType) { - case REVERB_DATA_TYPE_SETTINGS: - AudioHeap_InitReverb(reverbIndex, (ReverbSettings*)data, false); - break; - - case REVERB_DATA_TYPE_DELAY: - if (data < 4) { - data = 4; - } - - delayNumSamples = data * 64; - if (delayNumSamples < (16 * SAMPLES_PER_FRAME)) { - delayNumSamples = 16 * SAMPLES_PER_FRAME; - } - - delayNumSamples /= reverb->downsampleRate; - - if (!isFirstInit) { - if (reverb->delayNumSamplesAfterDownsampling < (data / reverb->downsampleRate)) { - break; - } - if ((reverb->nextReverbBufPos >= delayNumSamples) || (reverb->delayNumSamplesUnk >= delayNumSamples)) { - reverb->nextReverbBufPos = 0; - reverb->delayNumSamplesUnk = 0; - } - } - - reverb->delayNumSamples = delayNumSamples; - - if ((reverb->downsampleRate != 1) || reverb->resampleEffectOn) { - reverb->downsamplePitch = 0x8000 / reverb->downsampleRate; - if (reverb->leftLoadResampleBuf == NULL) { - reverb->leftLoadResampleBuf = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); - reverb->rightLoadResampleBuf = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); - reverb->leftSaveResampleBuf = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); - reverb->rightSaveResampleBuf = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); - if (reverb->rightSaveResampleBuf == NULL) { - reverb->downsampleRate = 1; - } - } - } - break; - - case REVERB_DATA_TYPE_DECAY: - gAudioCtx.synthesisReverbs[reverbIndex].decayRatio = data; - break; - - case REVERB_DATA_TYPE_SUB_VOLUME: - gAudioCtx.synthesisReverbs[reverbIndex].subVolume = data; - break; - - case REVERB_DATA_TYPE_VOLUME: - gAudioCtx.synthesisReverbs[reverbIndex].volume = data; - break; - - case REVERB_DATA_TYPE_LEAK_RIGHT: - gAudioCtx.synthesisReverbs[reverbIndex].leakRtl = data; - break; - - case REVERB_DATA_TYPE_LEAK_LEFT: - gAudioCtx.synthesisReverbs[reverbIndex].leakLtr = data; - break; - - case REVERB_DATA_TYPE_FILTER_LEFT: - if (data != 0) { - if (isFirstInit || (reverb->filterLeftInit == NULL)) { - reverb->filterLeftState = - AudioHeap_AllocDmaMemoryZeroed(&gAudioCtx.miscPool, 2 * (FILTER_BUF_PART1 + FILTER_BUF_PART2)); - reverb->filterLeftInit = AudioHeap_AllocDmaMemory(&gAudioCtx.miscPool, FILTER_SIZE); - } - - reverb->filterLeft = reverb->filterLeftInit; - if (reverb->filterLeft != NULL) { - AudioHeap_LoadLowPassFilter(reverb->filterLeft, data); - } - } else { - reverb->filterLeft = NULL; - - if (isFirstInit) { - reverb->filterLeftInit = NULL; - } - } - break; - - case REVERB_DATA_TYPE_FILTER_RIGHT: - if (data != 0) { - if (isFirstInit || (reverb->filterRightInit == NULL)) { - reverb->filterRightState = - AudioHeap_AllocDmaMemoryZeroed(&gAudioCtx.miscPool, 2 * (FILTER_BUF_PART1 + FILTER_BUF_PART2)); - reverb->filterRightInit = AudioHeap_AllocDmaMemory(&gAudioCtx.miscPool, FILTER_SIZE); - } - reverb->filterRight = reverb->filterRightInit; - if (reverb->filterRight != NULL) { - AudioHeap_LoadLowPassFilter(reverb->filterRight, data); - } - } else { - reverb->filterRight = NULL; - if (isFirstInit) { - reverb->filterRightInit = NULL; - } - } - break; - - case REVERB_DATA_TYPE_9: - reverb->resampleEffectExtraSamples = data; - if (data == 0) { - reverb->resampleEffectOn = false; - } else { - reverb->resampleEffectOn = true; - } - break; - - default: - break; - } -} - -void AudioHeap_InitReverb(s32 reverbIndex, ReverbSettings* settings, s32 isFirstInit) { - SynthesisReverb* reverb = &gAudioCtx.synthesisReverbs[reverbIndex]; - - if (isFirstInit) { - reverb->delayNumSamplesAfterDownsampling = settings->delayNumSamples / settings->downsampleRate; - reverb->leftLoadResampleBuf = NULL; - } else if (reverb->delayNumSamplesAfterDownsampling < (settings->delayNumSamples / settings->downsampleRate)) { - return; - } - - reverb->downsampleRate = settings->downsampleRate; - reverb->resampleEffectOn = false; - reverb->resampleEffectExtraSamples = 0; - reverb->resampleEffectLoadUnk = 0; - reverb->resampleEffectSaveUnk = 0; - AudioHeap_SetReverbData(reverbIndex, REVERB_DATA_TYPE_DELAY, settings->delayNumSamples, isFirstInit); - reverb->decayRatio = settings->decayRatio; - reverb->volume = settings->volume; - reverb->subDelay = settings->subDelay * 64; - reverb->subVolume = settings->subVolume; - reverb->leakRtl = settings->leakRtl; - reverb->leakLtr = settings->leakLtr; - reverb->mixReverbIndex = settings->mixReverbIndex; - reverb->mixReverbStrength = settings->mixReverbStrength; - reverb->useReverb = 8; // used as a boolean - - if (isFirstInit) { - reverb->leftReverbBuf = AudioHeap_AllocZeroedAttemptExternal(&gAudioCtx.miscPool, reverb->delayNumSamples * 2); - reverb->rightReverbBuf = AudioHeap_AllocZeroedAttemptExternal(&gAudioCtx.miscPool, reverb->delayNumSamples * 2); - reverb->resampleFlags = 1; - reverb->nextReverbBufPos = 0; - reverb->delayNumSamplesUnk = 0; - reverb->curFrame = 0; - reverb->framesToIgnore = 2; - } - - 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->delayNumSamples * SAMPLE_SIZE; - reverb->sample.sampleAddr = (u8*)reverb->leftReverbBuf; - reverb->loop.start = 0; - reverb->loop.count = 1; - reverb->loop.loopEnd = reverb->delayNumSamples; - - AudioHeap_SetReverbData(reverbIndex, REVERB_DATA_TYPE_FILTER_LEFT, settings->lowPassFilterCutoffLeft, isFirstInit); - AudioHeap_SetReverbData(reverbIndex, REVERB_DATA_TYPE_FILTER_RIGHT, settings->lowPassFilterCutoffRight, - isFirstInit); -} diff --git a/src/code/audio/audio_init_params.c b/src/code/audio/audio_init_params.c deleted file mode 100644 index 6bba865e9..000000000 --- a/src/code/audio/audio_init_params.c +++ /dev/null @@ -1,184 +0,0 @@ -#include "global.h" - -const s16 gAudioTatumInit[] = { - 0x1C00, // unused - TATUMS_PER_BEAT, // gTatumsPerBeat -}; - -// TODO: Extract from table? -#define NUM_SOUNDFONTS 41 -#define SFX_SEQ_SIZE 0xC6A0 -#define AMBIENCE_SEQ_SIZE 0xFC0 -#define SOUNDFONT_0_SIZE 0x81C0 -#define SOUNDFONT_1_SIZE 0x36D0 -#define SOUNDFONT_2_SIZE 0xCE0 - -// 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)) - -// 0x19BD0 -#define PERMANENT_POOL_SIZE \ - (SFX_SEQ_SIZE + AMBIENCE_SEQ_SIZE + SOUNDFONT_0_SIZE + SOUNDFONT_1_SIZE + SOUNDFONT_2_SIZE + 0x430) - -const AudioHeapInitSizes gAudioHeapInitSizes = { - ALIGN16(sizeof(gAudioHeap) - 0x100), // audio heap size - ALIGN16(PERMANENT_POOL_SIZE + AI_BUFFERS_SIZE + SOUNDFONT_LIST_SIZE + 0x40), // init pool size - ALIGN16(PERMANENT_POOL_SIZE), // permanent pool size -}; - -#define REVERB_INDEX_0_SETTINGS \ - { 1, 0x30, 0x3000, 0, 0, 0x7FFF, 0x0000, 0x0000, REVERB_INDEX_NONE, 0x3000, 0, 0 } - -ReverbSettings reverbSettings0[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x20, 0x0800, 0, 0, 0x7FFF, 0x0000, 0x0000, REVERB_INDEX_NONE, 0x0000, 0, 0 }, -}; - -ReverbSettings reverbSettings1[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x30, 0x1800, 0, 0, 0x7FFF, 0x0000, 0x0000, REVERB_INDEX_NONE, 0x0000, 11, 11 }, -}; - -ReverbSettings reverbSettings2[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x38, 0x2800, 0, 0, 0x7FFF, 0x0000, 0x0000, REVERB_INDEX_NONE, 0x0000, 7, 7 }, -}; - -ReverbSettings reverbSettings3[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x30, 0x6800, 0, 0, 0x7FFF, 0x1400, 0x1400, REVERB_INDEX_NONE, 0x3000, 6, 6 }, - { 2, 0x50, 0x6000, 0, 0, 0x7FFF, 0xD000, 0x3000, REVERB_INDEX_NONE, 0x3000, 0, 0 }, -}; - -ReverbSettings reverbSettings4[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x40, 0x5000, 0, 0, 0x7FFF, 0x1800, 0x1800, REVERB_INDEX_NONE, 0x3000, 7, 7 }, -}; - -ReverbSettings reverbSettings5[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x40, 0x5C00, 0, 0, 0x7FFF, 0x2000, 0x2000, REVERB_INDEX_NONE, 0x3000, 4, 4 }, -}; - -ReverbSettings reverbSettings6[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x30, 0x6000, 0, 0, 0x7FFF, 0x1000, 0x1000, REVERB_INDEX_NONE, 0x3000, 10, 10 }, -}; - -ReverbSettings reverbSettings7[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x30, 0x6800, 0, 0, 0x7FFF, 0x1400, 0x1400, REVERB_INDEX_NONE, 0x3000, 6, 6 }, -}; - -ReverbSettings reverbSettings8[2] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x50, 0x5000, 0, 0, 0x7FFF, 0xD000, 0x3000, REVERB_INDEX_NONE, 0x3000, 0, 0 }, -}; - -ReverbSettings reverbSettings9[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x20, 0x0000, 0, 0, 0x7FFF, 0x0000, 0x0000, REVERB_INDEX_NONE, 0x0000, 0, 0 }, -}; - -ReverbSettings reverbSettingsA[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x30, 0x1800, 0, 0, 0x7FFF, 0x0000, 0x0000, REVERB_INDEX_NONE, 0x0000, 11, 11 }, -}; - -ReverbSettings reverbSettingsB[3] = { - REVERB_INDEX_0_SETTINGS, -}; - -ReverbSettings reverbSettingsC[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x40, 0x5000, 0, 0, 0x7FFF, 0x0000, 0x0000, REVERB_INDEX_NONE, 0x3000, 0, 0 }, -}; - -ReverbSettings reverbSettingsD[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x30, 0x6800, 0, 0, 0x7FFF, 0x1400, 0x1400, REVERB_INDEX_NONE, 0x3000, 6, 6 }, - { 2, 0x50, 0x6000, 0, 0, 0x7FFF, 0xD000, 0x3000, REVERB_INDEX_NONE, 0x3000, 0, 0 }, -}; - -ReverbSettings reverbSettingsE[3] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x30, 0x1800, 0, 0, 0x7FFF, 0x0000, 0x0000, REVERB_INDEX_NONE, 0x0000, 11, 11 }, - { 1, 0x40, 0x5000, 0, 0, 0x7FFF, 0x1800, 0x1800, REVERB_INDEX_NONE, 0x3000, 7, 7 }, -}; - -ReverbSettings reverbSettingsF[2] = { - REVERB_INDEX_0_SETTINGS, - { 1, 0x50, 0x1800, 0, 0, 0x7FFF, 0x0000, 0x0000, REVERB_INDEX_NONE, 0x0000, 11, 11 }, -}; - -ReverbSettings* gReverbSettingsTable[] = { - reverbSettings0, reverbSettings1, reverbSettings2, reverbSettings4, reverbSettings5, - reverbSettings6, reverbSettings7, reverbSettings8, reverbSettings9, reverbSettings3, -}; - -AudioSpec gAudioSpecs[21] = { - /* 0x0 */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettingsF, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x1 */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettingsF, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x2 */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettingsF, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x3 */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettingsF, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x4 */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettingsF, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x5 */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettingsF, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x6 */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettingsF, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x7 */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettingsF, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x8 */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettingsF, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x9 */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettingsF, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0xA */ - { 32000, 1, 28, 3, 0, 0, 2, reverbSettingsA, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x2800, 0x2D00, 0, 0, - 0xDC800 }, - /* 0xB */ - { 32000, 1, 28, 3, 0, 0, 2, reverbSettingsA, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0xC */ - { 32000, 1, 28, 5, 0, 0, 2, reverbSettingsA, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xCC800 }, - /* 0xD */ - { 32000, 1, 24, 5, 0, 0, 3, reverbSettingsD, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0xE */ - { 32000, 1, 24, 5, 0, 0, 3, reverbSettingsE, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0xF */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettingsF, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4000, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x10 */ - { 32000, 1, 22, 5, 0, 0, 2, reverbSettings0, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x11 */ - { 32000, 1, 22, 5, 0, 0, 2, reverbSettings8, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x12 */ - { 32000, 1, 16, 5, 0, 0, 2, reverbSettings0, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x13 */ - { 22050, 1, 24, 5, 0, 0, 2, reverbSettings0, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x4100, 0x2D00, 0, 0, - 0xDC800 }, - /* 0x14 */ - { 32000, 1, 24, 5, 0, 0, 2, reverbSettings2, 0x500, 0x200, 0x7FFF, 0xAF0, 0x2D80, 0, 0x3600, 0x2600, 0, 0, - 0xDC800 }, -}; diff --git a/src/code/audio/audio_load.c b/src/code/audio/audio_load.c deleted file mode 100644 index 28c27d2cc..000000000 --- a/src/code/audio/audio_load.c +++ /dev/null @@ -1,2239 +0,0 @@ -/** - * @file audio_load.c - * - * Implements the transfer of audio data from the cartridge to the audio heap. - * - * The audio data in ROM consists of: - * 1) Sequences stored as a midi-based script called the music-macro language (.mus files) - * 2) SoundFonts stored as various sound-font structs bundled togther in a custom way - * that is extracted through relocs (See SoundFontData, generic .o files) - * 3) Samples consisting of raw soundbytes stored using a compressed ADPCM algorithm (.aifc files) - */ - -#include "global.h" - -/** - * SoundFont Notes: - * - */ -// opaque type for soundfont data loaded into ram (should maybe get rid of this?) -typedef void SoundFontData; - -typedef struct { - /* 0x00 */ s32 sampleBankId1; - /* 0x04 */ s32 sampleBankId2; - /* 0x08 */ uintptr_t baseAddr1; - /* 0x0C */ uintptr_t baseAddr2; - /* 0x10 */ u32 medium1; - /* 0x14 */ u32 medium2; -} SampleBankRelocInfo; // size = 0x18 - -void AudioLoad_DiscardFont(s32 fontId); -s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIndex, s32 seqId, s32 arg2); -u8* AudioLoad_SyncLoadSeq(s32 seqId); -u32 AudioLoad_TrySyncLoadSampleBank(u32 sampleBankId, u32* outMedium, s32 noLoad); -SoundFontData* AudioLoad_SyncLoadFont(u32 fontId); -void* AudioLoad_SyncLoad(s32 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(uintptr_t devAddr, u8* ramAddr, size_t size, s32 medium); -void AudioLoad_SyncDmaUnkMedium(uintptr_t devAddr, u8* addr, size_t size, s32 unkMediumParam); -s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, uintptr_t devAddr, void* ramAddr, size_t size, - OSMesgQueue* reqQueue, s32 medium, const char* dmaFuncType); -void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, OSMesgQueue* retQueue); -Sample* AudioLoad_GetFontSample(s32 fontId, s32 instId); -void AudioLoad_ProcessSlowLoads(s32 resetStatus); -void AudioLoad_DmaSlowCopy(AudioSlowLoad* slowLoad, size_t size); -void AudioLoad_DmaSlowCopyUnkMedium(intptr_t devAddr, intptr_t ramAddr, size_t size, s32 arg3); -AudioAsyncLoad* AudioLoad_StartAsyncLoadUnkMedium(s32 unkMediumParam, uintptr_t devAddr, void* ramAddr, size_t size, - s32 medium, s32 nChunks, OSMesgQueue* retQueue, s32 retMsg); -AudioAsyncLoad* AudioLoad_StartAsyncLoad(uintptr_t devAddr, void* ramAddr, size_t size, s32 medium, s32 nChunks, - OSMesgQueue* retQueue, s32 retMsg); -void AudioLoad_ProcessAsyncLoads(s32 resetStatus); -void AudioLoad_ProcessAsyncLoadUnkMedium(AudioAsyncLoad* asyncLoad, s32 resetStatus); -void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus); -void AudioLoad_AsyncDma(AudioAsyncLoad* asyncLoad, size_t size); -void AudioLoad_AsyncDmaRamUnloaded(AudioAsyncLoad* asyncLoad, size_t size); -void AudioLoad_AsyncDmaUnkMedium(uintptr_t devAddr, void* ramAddr, size_t size, s16 arg3); -void AudioLoad_RelocateSample(TunedSample* tunedSample, SoundFontData* fontData, SampleBankRelocInfo* sampleBankReloc); -void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* fontData, SampleBankRelocInfo* sampleBankReloc, - s32 isAsync); -s32 AudioLoad_ProcessSamplePreloads(s32 resetStatus); - -#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_STATUS(v) ((u8)(v >> 0)) - -typedef enum { - /* 0 */ LOAD_STATUS_WAITING, - /* 1 */ LOAD_STATUS_START, - /* 2 */ LOAD_STATUS_LOADING, - /* 3 */ LOAD_STATUS_DONE -} SlowLoadStatus; - -#define OS_MESG_PRI_NORMAL 0 -#define OS_MESG_PRI_HIGH 1 - -typedef struct { - u16 numInstruments; - u16 numDrums; - u16 numSfx; -} UnloadedFonts; - -OSMesgQueue sScriptLoadQueue; -OSMesg sScriptLoadMesgBuf[0x10]; -s8* sScriptLoadDonePointers[0x10]; -s32 sAudioLoadPad1[2]; // file padding -s32 D_801FD1E0; - -DmaHandler sDmaHandler = osEPiStartDma; -void* sUnusedHandler = NULL; -s32 gAudioCtxInitalized = 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.unused2648 = 0; -} - -void* AudioLoad_DmaSampleData(uintptr_t devAddr, size_t size, s32 arg2, u8* dmaIndexRef, s32 medium) { - s32 pad1; - SampleDma* dma; - s32 hasDma = false; - uintptr_t 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.currAudioFrameDmaIoMesgBuf[gAudioCtx.curAudioFrameDmaCount++], OS_MESG_PRI_NORMAL, OS_READ, - dmaDevAddr, dma->ramAddr, transfer, &gAudioCtx.curAudioFrameDmaQueue, medium, "SUPERDMA"); - *dmaIndexRef = dmaIndex; - return (devAddr - dmaDevAddr) + dma->ramAddr; -} - -// This string does not appear to belong in context to any function between the previous string and the next string -const char D_801E030C[] = "TYPE %d:ID %d is not External Map.\n"; - -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; - - // First 3/4 sampleDmas - 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 = 0; - 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_PERMANENT)) { - gAudioCtx.fontLoadStatus[fontId] = loadStatus; - } -} - -void AudioLoad_SetSeqLoadStatus(s32 seqId, s32 loadStatus) { - if ((seqId != 0xFF) && (gAudioCtx.seqLoadStatus[seqId] != LOAD_STATUS_PERMANENT)) { - gAudioCtx.seqLoadStatus[seqId] = loadStatus; - } -} - -void AudioLoad_SetSampleFontLoadStatusAndApplyCaches(s32 sampleBankId, s32 loadStatus) { - if (sampleBankId != 0xFF) { - if (gAudioCtx.sampleFontLoadStatus[sampleBankId] != LOAD_STATUS_PERMANENT) { - gAudioCtx.sampleFontLoadStatus[sampleBankId] = loadStatus; - } - - if ((gAudioCtx.sampleFontLoadStatus[sampleBankId] == LOAD_STATUS_PERMANENT) || - (gAudioCtx.sampleFontLoadStatus[sampleBankId] == LOAD_STATUS_COMPLETE)) { - AudioHeap_ApplySampleBankCache(sampleBankId); - } - } -} - -void AudioLoad_SetSampleFontLoadStatus(s32 sampleBankId, s32 loadStatus) { - if ((sampleBankId != 0xFF) && (gAudioCtx.sampleFontLoadStatus[sampleBankId] != LOAD_STATUS_PERMANENT)) { - gAudioCtx.sampleFontLoadStatus[sampleBankId] = loadStatus; - } -} - -void AudioLoad_InitTable(AudioTable* table, uintptr_t 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 arg2, OSMesgQueue* arg3) { - s32 pad; - u32 defaultFontId; - - if (seqId < gAudioCtx.numSequences) { - if (arg1 & 2) { - AudioLoad_SyncLoadSeqFonts(seqId, &defaultFontId); - } - if (arg1 & 1) { - AudioLoad_SyncLoadSeq(seqId); - } - if (arg2 != 0) { - osSendMesg(arg3, arg2 << 0x18, OS_MESG_NOBLOCK); - } - } -} - -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(sample->sampleAddr, sampleAddr, sample->size, - gAudioCtx.sampleBankTable->unkMediumParam); - } else { - AudioLoad_SyncDma(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 = AudioPlayback_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); - } - // TODO: is this missing return UB? - } else if (instId == 0x7F) { - Drum* drum = AudioPlayback_GetDrum(fontId, drumId); - - if (drum == NULL) { - return -1; - } - AudioLoad_SyncLoadSample(drum->tunedSample.sample, fontId); - return 0; - } - // TODO: is this missing return UB? -} - -void AudioLoad_AsyncLoad(s32 tableType, s32 id, s32 nChunks, s32 retData, OSMesgQueue* retQueue) { - if (AudioLoad_AsyncLoadInner(tableType, id, nChunks, retData, retQueue) == NULL) { - osSendMesg(retQueue, 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); -} - -void func_8018FA60(u32 tableType, u32 id, s32 type, s32 data) { - AudioTable* table = AudioLoad_GetLoadTable(tableType); - - if (table->entries[id].medium == MEDIUM_RAM_UNLOADED) { - switch (type) { - case 0: - table->entries[id].romAddr = data; - break; - case 1: - table->entries[id].size = data; - break; - default: - break; - } - } -} - -s32 AudioLoad_SyncInitSeqPlayer(s32 playerIndex, s32 seqId, s32 arg2) { - if (gAudioCtx.resetTimer != 0) { - return 0; - } - - gAudioCtx.seqPlayers[playerIndex].skipTicks = 0; - AudioLoad_SyncInitSeqPlayerInternal(playerIndex, 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 playerIndex, s32 seqId, s32 skipTicks) { - if (gAudioCtx.resetTimer != 0) { - return 0; - } - - gAudioCtx.seqPlayers[playerIndex].skipTicks = skipTicks; - AudioLoad_SyncInitSeqPlayerInternal(playerIndex, seqId, 0); - // Missing return, see above. -} - -s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIndex, s32 seqId, s32 arg2) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[playerIndex]; - u8* seqData; - s32 index; - s32 numFonts; - s32 fontId; - - if (seqId >= gAudioCtx.numSequences) { - return 0; - } - - AudioSeq_SequencePlayerDisable(seqPlayer); - - if (1) {} - 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; - - if (fontId != 0xFF) { - seqPlayer->defaultFont = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId); - } else { - seqPlayer->defaultFont = 0xFF; - } - - seqPlayer->seqData = seqData; - seqPlayer->enabled = true; - seqPlayer->scriptState.pc = seqData; - seqPlayer->scriptState.depth = 0; - seqPlayer->delay = 0; - seqPlayer->finished = false; - seqPlayer->playerIndex = playerIndex; - //! @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* addr; - AudioTable* sampleBankTable; - u32 realTableId = AudioLoad_GetRealTableIndex(SAMPLE_TABLE, sampleBankId); - s8 cachePolicy; - - sampleBankTable = AudioLoad_GetLoadTable(SAMPLE_TABLE); - - addr = AudioLoad_SearchCaches(SAMPLE_TABLE, realTableId); - if (addr != NULL) { - if (gAudioCtx.sampleFontLoadStatus[realTableId] != LOAD_STATUS_IN_PROGRESS) { - AudioLoad_SetSampleFontLoadStatus(realTableId, LOAD_STATUS_COMPLETE); - } - - *outMedium = MEDIUM_RAM; - return addr; - } - - cachePolicy = sampleBankTable->entries[sampleBankId].cachePolicy; - - if ((cachePolicy == CACHE_LOAD_EITHER_NOSYNC) || (noLoad == true)) { - *outMedium = sampleBankTable->entries[sampleBankId].medium; - return sampleBankTable->entries[realTableId].romAddr; - } - - addr = AudioLoad_SyncLoad(SAMPLE_TABLE, sampleBankId, &noLoad); - if (addr != NULL) { - *outMedium = MEDIUM_RAM; - return addr; - } - - *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 (sampleBankReloc.sampleBankId1 != 0xFF) { - sampleBankReloc.baseAddr1 = - AudioLoad_TrySyncLoadSampleBank(sampleBankReloc.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(s32 tableType, u32 id, s32* didAllocate) { - size_t size; - AudioTable* table; - s32 medium2; - u32 medium; - s32 loadStatus; - uintptr_t romAddr; - s32 cachePolicy; - void* ramAddr; - u32 realId; - s32 mediumUnk = MEDIUM_UNK; - - 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 CACHE_LOAD_PERMANENT: - ramAddr = AudioHeap_AllocPermanent(tableType, realId, size); - if (ramAddr == NULL) { - return ramAddr; - } - break; - - case CACHE_LOAD_PERSISTENT: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - case CACHE_LOAD_TEMPORARY: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_TEMPORARY, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - - case CACHE_LOAD_EITHER: - case CACHE_LOAD_EITHER_NOSYNC: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_EITHER, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - } - - *didAllocate = true; - - medium2 = medium; - if (medium == MEDIUM_RAM_UNLOADED) { - if (romAddr == 0) { - return NULL; - } - - if (tableType == FONT_TABLE) { - SoundFont* soundFont = &gAudioCtx.soundFontList[realId]; - - soundFont->numInstruments = ((UnloadedFonts*)romAddr)->numInstruments; - soundFont->numDrums = ((UnloadedFonts*)romAddr)->numDrums; - soundFont->numSfx = ((UnloadedFonts*)romAddr)->numSfx; - romAddr += 0x10; - size -= 0x10; - } - - bcopy(romAddr, ramAddr, size); - } else if (medium2 == mediumUnk) { - AudioLoad_SyncDmaUnkMedium(romAddr, ramAddr, size, (s16)table->unkMediumParam); - } else { - AudioLoad_SyncDma(romAddr, ramAddr, size, medium); - } - - loadStatus = (cachePolicy == CACHE_LOAD_PERMANENT) ? LOAD_STATUS_PERMANENT : 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* addr; - - addr = AudioHeap_SearchPermanentCache(tableType, id); - if (addr != NULL) { - return addr; - } - - addr = AudioHeap_SearchCaches(tableType, CACHE_EITHER, id); - if (addr != NULL) { - return addr; - } - - 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 fontDataStartAddr 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) { - uintptr_t soundOffset; - uintptr_t soundListOffset; - 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(x) (void*)((uintptr_t)(x) + (uintptr_t)(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 = ((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 = soundOffset; - - // The drum may be in the list multiple times and already relocated - if (!drum->isRelocated) { - AudioLoad_RelocateSample(&drum->tunedSample, fontDataStartAddr, sampleBankReloc); - - soundOffset = drum->envelope; - drum->envelope = 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 = (TunedSample*)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) && (soundEffect->tunedSample.sample != NULL)) { - 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 = inst->envelope; - inst->envelope = (EnvelopePoint*)RELOC_TO_RAM(soundOffset); - - inst->isRelocated = true; - } - } - } - -#undef RELOC_TO_RAM - - // 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(uintptr_t devAddr, u8* ramAddr, size_t 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(uintptr_t devAddr, u8* ramAddr, size_t size, s32 unkMediumParam) { -} - -s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, uintptr_t devAddr, void* ramAddr, size_t 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) { - size_t size; - AudioTable* table; - void* ramAddr; - s32 medium; - s8 cachePolicy; - uintptr_t romAddr; - s32 loadStatus; - SoundFont* soundFont; - u32 realId = AudioLoad_GetRealTableIndex(tableType, id); - u32 pad; - - 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, 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; - romAddr = table->entries[realId].romAddr; - loadStatus = LOAD_STATUS_COMPLETE; - - switch (cachePolicy) { - case CACHE_LOAD_PERMANENT: - ramAddr = AudioHeap_AllocPermanent(tableType, realId, size); - if (ramAddr == NULL) { - return ramAddr; - } - loadStatus = LOAD_STATUS_PERMANENT; - break; - - case CACHE_LOAD_PERSISTENT: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - - case CACHE_LOAD_TEMPORARY: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_TEMPORARY, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - - case CACHE_LOAD_EITHER: - case CACHE_LOAD_EITHER_NOSYNC: - ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_EITHER, realId); - if (ramAddr == NULL) { - return ramAddr; - } - break; - } - - if (medium == MEDIUM_RAM_UNLOADED) { - if (romAddr == 0) { - return NULL; - } - - if (tableType == FONT_TABLE) { - soundFont = &gAudioCtx.soundFontList[realId]; - - soundFont->numInstruments = ((UnloadedFonts*)romAddr)->numInstruments; - soundFont->numDrums = ((UnloadedFonts*)romAddr)->numDrums; - soundFont->numSfx = ((UnloadedFonts*)romAddr)->numSfx; - romAddr += 0x10; - size += -0x10; - } - } - - if (medium == MEDIUM_UNK) { - AudioLoad_StartAsyncLoadUnkMedium((s16)table->unkMediumParam, romAddr, ramAddr, size, medium, nChunks, - retQueue, MK_ASYNC_MSG(retData, tableType, realId, loadStatus)); - } else { - AudioLoad_StartAsyncLoad(romAddr, 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, size_t heapSize) { - s32 pad1[9]; - s32 numFonts; - s32 pad2[2]; - u8* audioCtxPtr; - void* addr; - s32 i; - s32 j; - - gAudioCustomUpdateFunction = NULL; - gAudioCustomReverbFunction = NULL; - gAudioCustomSynthFunction = NULL; - - for (i = 0; i < ARRAY_COUNT(gAudioCtx.customSeqFunctions); i++) { - gAudioCtx.customSeqFunctions[i] = NULL; - } - - gAudioCtx.resetTimer = 0; - gAudioCtx.unk_29B8 = false; - - // Set all of gAudioCtx to 0 - audioCtxPtr = (u8*)&gAudioCtx; - for (j = sizeof(gAudioCtx); j >= 0; j--) { - *audioCtxPtr++ = 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; - } - - AudioThread_InitMesgQueues(); - - for (i = 0; i < ARRAY_COUNT(gAudioCtx.numSamplesPerFrame); i++) { - gAudioCtx.numSamplesPerFrame[i] = 0xA0; - } - - gAudioCtx.totalTaskCount = 0; - gAudioCtx.rspTaskIndex = 0; - gAudioCtx.curAiBufferIndex = 0; - gAudioCtx.soundMode = SOUNDMODE_STEREO; - gAudioCtx.curTask = NULL; - gAudioCtx.rspTask[0].task.t.dataSize = 0; - gAudioCtx.rspTask[1].task.t.dataSize = 0; - - osCreateMesgQueue(&gAudioCtx.syncDmaQueue, &gAudioCtx.syncDmaMesg, 1); - osCreateMesgQueue(&gAudioCtx.curAudioFrameDmaQueue, gAudioCtx.currAudioFrameDmaMesgBuf, - ARRAY_COUNT(gAudioCtx.currAudioFrameDmaMesgBuf)); - osCreateMesgQueue(&gAudioCtx.externalLoadQueue, gAudioCtx.externalLoadMesgBuf, - ARRAY_COUNT(gAudioCtx.externalLoadMesgBuf)); - osCreateMesgQueue(&gAudioCtx.preloadSampleQueue, gAudioCtx.preloadSampleMesgBuf, - ARRAY_COUNT(gAudioCtx.preloadSampleMesgBuf)); - 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 / (s32)sizeof(u64)); i++) { - ((u64*)gAudioCtx.audioHeap)[i] = 0; - } - - // Main Pool Split (split entirety of audio heap into initPool and sessionPool) - AudioHeap_InitMainPool(gAudioHeapInitSizes.initPoolSize); - - // Initialize the audio interface buffers - for (i = 0; i < ARRAY_COUNT(gAudioCtx.aiBuffers); i++) { - gAudioCtx.aiBuffers[i] = AudioHeap_AllocZeroed(&gAudioCtx.initPool, AIBUF_LEN * sizeof(s16)); - } - - // Connect audio tables to their tables in memory - gAudioCtx.sequenceTable = (AudioTable*)gSequenceTable; - gAudioCtx.soundFontTable = (AudioTable*)gSoundFontTable; - gAudioCtx.sampleBankTable = (AudioTable*)gSampleBankTable; - gAudioCtx.sequenceFontTable = gSequenceFontTable; - - gAudioCtx.numSequences = gAudioCtx.sequenceTable->numEntries; - - gAudioCtx.specId = 0; - gAudioCtx.resetStatus = 1; // Set reset to immediately initialize the audio heap - AudioHeap_ResetStep(); - - // Initialize audio tables - AudioLoad_InitTable(gAudioCtx.sequenceTable, SEGMENT_ROM_START(Audioseq), 0); - AudioLoad_InitTable(gAudioCtx.soundFontTable, SEGMENT_ROM_START(Audiobank), 0); - AudioLoad_InitTable(gAudioCtx.sampleBankTable, SEGMENT_ROM_START(Audiotable), 0); - - numFonts = gAudioCtx.soundFontTable->numEntries; - gAudioCtx.soundFontList = AudioHeap_Alloc(&gAudioCtx.initPool, numFonts * sizeof(SoundFont)); - - for (i = 0; i < numFonts; i++) { - AudioLoad_InitSoundFont(i); - } - - if (addr = AudioHeap_Alloc(&gAudioCtx.initPool, gAudioHeapInitSizes.permanentPoolSize), addr == NULL) { - // cast away const from gAudioHeapInitSizes - *((u32*)&gAudioHeapInitSizes.permanentPoolSize) = 0; - } - - AudioHeap_InitPool(&gAudioCtx.permanentPool, addr, gAudioHeapInitSizes.permanentPoolSize); - gAudioCtxInitalized = true; - osSendMesg(gAudioCtx.taskStartQueueP, (void*)gAudioCtx.totalTaskCount, OS_MESG_NOBLOCK); -} - -void AudioLoad_InitSlowLoads(void) { - gAudioCtx.slowLoads[0].status = 0; - gAudioCtx.slowLoads[1].status = 0; -} - -s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* isDone) { - Sample* sample; - AudioSlowLoad* slowLoad; - - sample = AudioLoad_GetFontSample(fontId, instId); - if (sample == NULL) { - *isDone = 0; - return -1; - } - - if (sample->medium == MEDIUM_RAM) { - *isDone = 2; - return 0; - } - - slowLoad = &gAudioCtx.slowLoads[gAudioCtx.slowLoadPos]; - if (slowLoad->status == LOAD_STATUS_DONE) { - slowLoad->status = LOAD_STATUS_WAITING; - } - - slowLoad->sample = *sample; - slowLoad->isDone = isDone; - slowLoad->curRamAddr = - AudioHeap_AllocSampleCache(sample->size, fontId, sample->sampleAddr, (s32)sample->medium, CACHE_TEMPORARY); - - if (slowLoad->curRamAddr == NULL) { - if (sample->medium == MEDIUM_UNK || sample->codec == CODEC_S16_INMEMORY) { - *isDone = 0; - return -1; - } else { - *isDone = 3; - return -1; - } - } - - slowLoad->status = LOAD_STATUS_START; - slowLoad->bytesRemaining = ALIGN16(sample->size); - slowLoad->ramAddr = slowLoad->curRamAddr; - slowLoad->curDevAddr = 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 = AudioPlayback_GetInstrumentInner(fontId, instId); - - if (instrument == NULL) { - return NULL; - } - sample = instrument->normalPitchTunedSample.sample; - } else if (instId < 0x100) { - Drum* drum = AudioPlayback_GetDrum(fontId, instId - 0x80); - - if (drum == NULL) { - return NULL; - } - sample = drum->tunedSample.sample; - } else { - SoundEffect* soundEffect = AudioPlayback_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].status) { - case LOAD_STATUS_LOADING: - if (slowLoad->medium != MEDIUM_UNK) { - osRecvMesg(&slowLoad->msgqueue, NULL, OS_MESG_BLOCK); - } - - if (resetStatus != 0) { - slowLoad->status = LOAD_STATUS_DONE; - continue; - } - case LOAD_STATUS_START: - slowLoad->status = LOAD_STATUS_LOADING; - if (slowLoad->bytesRemaining == 0) { - AudioLoad_FinishSlowLoad(slowLoad); - slowLoad->status = LOAD_STATUS_DONE; - *slowLoad->isDone = 1; - } else if ((s32)slowLoad->bytesRemaining < 0x400) { - if (slowLoad->medium == MEDIUM_UNK) { - size_t 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, size_t 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(intptr_t devAddr, intptr_t ramAddr, size_t size, s32 arg3) { -} - -s32 AudioLoad_SlowLoadSeq(s32 seqId, u8* ramAddr, s8* isDone) { - AudioSlowLoad* slowLoad; - AudioTable* seqTable; - size_t size; - - if (seqId >= gAudioCtx.numSequences) { - *isDone = 0; - return -1; - } - - seqId = AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId); - seqTable = AudioLoad_GetLoadTable(SEQUENCE_TABLE); - slowLoad = &gAudioCtx.slowLoads[gAudioCtx.slowLoadPos]; - if (slowLoad->status == LOAD_STATUS_DONE) { - slowLoad->status = LOAD_STATUS_WAITING; - } - - slowLoad->sample.sampleAddr = NULL; - slowLoad->isDone = isDone; - size = seqTable->entries[seqId].size; - size = ALIGN16(size); - slowLoad->curRamAddr = ramAddr; - slowLoad->status = LOAD_STATUS_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, uintptr_t devAddr, void* ramAddr, size_t 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, asyncLoad, OS_MESG_NOBLOCK); - asyncLoad->unkMediumParam = unkMediumParam; - return asyncLoad; -} - -AudioAsyncLoad* AudioLoad_StartAsyncLoad(uintptr_t devAddr, void* ramAddr, size_t 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 = LOAD_STATUS_START; - 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_STATUS(retMsg)); - break; - case SAMPLE_TABLE: - AudioLoad_SetSampleFontLoadStatusAndApplyCaches(ASYNC_ID(retMsg), ASYNC_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_STATUS(retMsg)); - AudioLoad_RelocateFontAndPreloadSamples(fontId, asyncLoad->ramAddr, &sampleBankReloc, true); - break; - } - - doneMsg = asyncLoad->retMsg; - if (1) {} - asyncLoad->status = LOAD_STATUS_WAITING; - 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 = LOAD_STATUS_WAITING; - 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 if (asyncLoad->medium == MEDIUM_RAM_UNLOADED) { - AudioLoad_AsyncDmaRamUnloaded(asyncLoad, asyncLoad->bytesRemaining); - } 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 if (asyncLoad->medium == MEDIUM_RAM_UNLOADED) { - AudioLoad_AsyncDmaRamUnloaded(asyncLoad, asyncLoad->chunkSize); - } else { - AudioLoad_AsyncDma(asyncLoad, asyncLoad->chunkSize); - } - - asyncLoad->bytesRemaining -= asyncLoad->chunkSize; - asyncLoad->curDevAddr += asyncLoad->chunkSize; - asyncLoad->curRamAddr = asyncLoad->curRamAddr + asyncLoad->chunkSize; -} - -void AudioLoad_AsyncDma(AudioAsyncLoad* asyncLoad, size_t size) { - if (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_AsyncDmaRamUnloaded(AudioAsyncLoad* asyncLoad, size_t size) { - if (size) {} - size = ALIGN16(size); - Audio_InvalDCache(asyncLoad->curRamAddr, size); - osCreateMesgQueue(&asyncLoad->msgQueue, &asyncLoad->msg, 1); - bcopy(asyncLoad->curDevAddr, asyncLoad->curRamAddr, size); - osSendMesg(&asyncLoad->msgQueue, NULL, OS_MESG_NOBLOCK); -} - -void AudioLoad_AsyncDmaUnkMedium(uintptr_t devAddr, void* ramAddr, size_t 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(v, base) (reloc = (void*)((uintptr_t)(v) + (uintptr_t)(base))) - - if ((uintptr_t)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; - size_t size; - s32 nChunks; - u8* sampleRamAddr; - s32 preloadInProgress; - s32 i; - - preloadInProgress = false; - if (gAudioCtx.preloadSampleStackTop != 0) { - preloadInProgress = true; - } else { - D_801FD1E0 = 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; - - default: - break; - } - if (sampleRamAddr == NULL) { - continue; - } - - switch (isAsync) { - case false: - if (sample->medium == MEDIUM_UNK) { - AudioLoad_SyncDmaUnkMedium((uintptr_t)sample->sampleAddr, sampleRamAddr, sample->size, - gAudioCtx.sampleBankTable->unkMediumParam); - sample->sampleAddr = sampleRamAddr; - sample->medium = MEDIUM_RAM; - } else { - AudioLoad_SyncDma((uintptr_t)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 = (uintptr_t)sample->sampleAddr + sample->size + sample->medium; - gAudioCtx.preloadSampleStackTop++; - break; - - default: - 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((uintptr_t)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 == false) { - sample = preload->sample; - key = (uintptr_t)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. - for (;;) { - 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 = (uintptr_t)sample->sampleAddr + sample->size + sample->medium; - if (key != preload->endAndMediumKey) { - preload->isFree = true; - gAudioCtx.preloadSampleStackTop--; - } else { - AudioLoad_StartAsyncLoad((uintptr_t)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 = AudioPlayback_GetDrum(fontId, i); - - if (1) {} - if (drum != NULL) { - numSamples = AudioLoad_AddToSampleSet(drum->tunedSample.sample, numSamples, sampleSet); - } - } - - for (i = 0; i < numInstruments; i++) { - Instrument* instrument = AudioPlayback_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; - size_t 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 = AudioPlayback_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 = AudioPlayback_GetDrum(fontId, i); - if (drum != NULL) { - AudioLoad_AddUsedSample(&drum->tunedSample); - } - } - - for (i = 0; i < numSfx; i++) { - soundEffect = AudioPlayback_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((uintptr_t)sample->sampleAddr, addr, sample->size, - gAudioCtx.sampleBankTable->unkMediumParam); - sample->sampleAddr = addr; - sample->medium = MEDIUM_RAM; - } else { - AudioLoad_SyncDma((uintptr_t)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 = (uintptr_t)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((uintptr_t)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.count; i++) { - SampleBankRelocInfo sampleBankReloc; - - if (gAudioCtx.permanentEntries[i].tableType == FONT_TABLE) { - fontId = AudioLoad_GetRealTableIndex(FONT_TABLE, gAudioCtx.permanentEntries[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* isDone) { - static u32 sLoadIndex = 0; - - sScriptLoadDonePointers[sLoadIndex] = isDone; - AudioLoad_AsyncLoad(tableType, id, 0, sLoadIndex, &sScriptLoadQueue); - sLoadIndex++; - if (sLoadIndex == 0x10) { - sLoadIndex = 0; - } -} - -void AudioLoad_ProcessScriptLoads(void) { - u32 temp; - u32 sp20; - s8* isDone; - - if (osRecvMesg(&sScriptLoadQueue, (OSMesg*)&sp20, OS_MESG_NOBLOCK) != -1) { - temp = sp20 >> 24; - isDone = sScriptLoadDonePointers[temp]; - if (isDone != NULL) { - *isDone = false; - } - } -} - -void AudioLoad_InitScriptLoads(void) { - osCreateMesgQueue(&sScriptLoadQueue, sScriptLoadMesgBuf, ARRAY_COUNT(sScriptLoadMesgBuf)); -} diff --git a/src/code/audio/audio_playback.c b/src/code/audio/audio_playback.c deleted file mode 100644 index 9f3c6f8ed..000000000 --- a/src/code/audio/audio_playback.c +++ /dev/null @@ -1,1012 +0,0 @@ -#include "global.h" - -void AudioPlayback_NoteSetResamplingRate(NoteSampleState* sampleState, f32 resamplingRateInput); -void AudioPlayback_AudioListPushFront(AudioListItem* list, AudioListItem* item); -void AudioPlayback_NoteInitForLayer(Note* note, SequenceLayer* layer); - -void AudioPlayback_InitSampleState(Note* note, NoteSampleState* sampleState, NoteSubAttributes* subAttrs) { - f32 volLeft; - f32 volRight; - s32 halfPanIndex; - u64 pad; - u8 strongLeft; - u8 strongRight; - f32 vel; - u8 pan; - u8 targetReverbVol; - StereoData stereoData; - s32 stereoHeadsetEffects = note->playbackState.stereoHeadsetEffects; - - vel = subAttrs->velocity; - pan = subAttrs->pan; - targetReverbVol = subAttrs->targetReverbVol; - stereoData = subAttrs->stereoData; - - sampleState->bitField0 = note->sampleState.bitField0; - sampleState->bitField1 = note->sampleState.bitField1; - sampleState->waveSampleAddr = note->sampleState.waveSampleAddr; - sampleState->harmonicIndexCurAndPrev = note->sampleState.harmonicIndexCurAndPrev; - - AudioPlayback_NoteSetResamplingRate(sampleState, subAttrs->frequency); - - pan &= 0x7F; - - sampleState->bitField0.strongRight = false; - sampleState->bitField0.strongLeft = false; - sampleState->bitField0.strongReverbRight = stereoData.strongReverbRight; - sampleState->bitField0.strongReverbLeft = stereoData.strongReverbLeft; - if (stereoHeadsetEffects && (gAudioCtx.soundMode == SOUNDMODE_HEADSET)) { - halfPanIndex = pan >> 1; - if (halfPanIndex > 0x3F) { - halfPanIndex = 0x3F; - } - - sampleState->haasEffectRightDelaySize = gHaasEffectDelaySize[halfPanIndex]; - sampleState->haasEffectLeftDelaySize = gHaasEffectDelaySize[0x3F - halfPanIndex]; - sampleState->bitField1.useHaasEffect = true; - - volLeft = gHeadsetPanVolume[pan]; - volRight = gHeadsetPanVolume[0x7F - pan]; - } else if (stereoHeadsetEffects && (gAudioCtx.soundMode == SOUNDMODE_STEREO)) { - strongLeft = strongRight = false; - sampleState->haasEffectLeftDelaySize = 0; - sampleState->haasEffectRightDelaySize = 0; - sampleState->bitField1.useHaasEffect = false; - - volLeft = gStereoPanVolume[pan]; - volRight = gStereoPanVolume[0x7F - pan]; - if (pan < 0x20) { - strongLeft = true; - } else if (pan > 0x60) { - strongRight = true; - } - - // case 0: - sampleState->bitField0.strongRight = strongRight; - sampleState->bitField0.strongLeft = strongLeft; - - switch (stereoData.type) { - case 0: - break; - - case 1: - sampleState->bitField0.strongRight = stereoData.strongRight; - sampleState->bitField0.strongLeft = stereoData.strongLeft; - break; - - case 2: - sampleState->bitField0.strongRight = stereoData.strongRight | strongRight; - sampleState->bitField0.strongLeft = stereoData.strongLeft | strongLeft; - break; - - case 3: - sampleState->bitField0.strongRight = stereoData.strongRight ^ strongRight; - sampleState->bitField0.strongLeft = stereoData.strongLeft ^ strongLeft; - break; - } - - } else if (gAudioCtx.soundMode == SOUNDMODE_MONO) { - sampleState->bitField0.strongReverbRight = false; - sampleState->bitField0.strongReverbLeft = false; - volLeft = 0.707f; // approx 1/sqrt(2) - volRight = 0.707f; - } else { - sampleState->bitField0.strongRight = stereoData.strongRight; - sampleState->bitField0.strongLeft = stereoData.strongLeft; - volLeft = gDefaultPanVolume[pan]; - volRight = gDefaultPanVolume[0x7F - pan]; - } - - vel = 0.0f > vel ? 0.0f : vel; - vel = 1.0f < vel ? 1.0f : vel; - - sampleState->targetVolLeft = (s32)((vel * volLeft) * (0x1000 - 0.001f)); - sampleState->targetVolRight = (s32)((vel * volRight) * (0x1000 - 0.001f)); - - sampleState->gain = subAttrs->gain; - sampleState->filter = subAttrs->filter; - sampleState->combFilterSize = subAttrs->combFilterSize; - sampleState->combFilterGain = subAttrs->combFilterGain; - sampleState->targetReverbVol = targetReverbVol; - sampleState->surroundEffectIndex = subAttrs->surroundEffectIndex; -} - -void AudioPlayback_NoteSetResamplingRate(NoteSampleState* sampleState, f32 resamplingRateInput) { - f32 resamplingRate = 0.0f; - - if (resamplingRateInput < 2.0f) { - sampleState->bitField1.hasTwoParts = false; - resamplingRate = CLAMP_MAX(resamplingRateInput, 1.99998f); - - } else { - sampleState->bitField1.hasTwoParts = true; - if (resamplingRateInput > 3.99996f) { - resamplingRate = 1.99998f; - } else { - resamplingRate = resamplingRateInput * 0.5f; - } - } - sampleState->frequencyFixedPoint = (s32)(resamplingRate * 32768.0f); -} - -void AudioPlayback_NoteInit(Note* note) { - if (note->playbackState.parentLayer->adsr.decayIndex == 0) { - AudioEffects_AdsrInit(¬e->playbackState.adsr, note->playbackState.parentLayer->channel->adsr.envelope, - ¬e->playbackState.adsrVolScaleUnused); - } else { - AudioEffects_AdsrInit(¬e->playbackState.adsr, note->playbackState.parentLayer->adsr.envelope, - ¬e->playbackState.adsrVolScaleUnused); - } - - note->playbackState.status = PLAYBACK_STATUS_0; - note->playbackState.adsr.action.s.state = ADSR_STATE_INITIAL; - note->sampleState = gDefaultSampleState; -} - -void AudioPlayback_NoteDisable(Note* note) { - if (note->sampleState.bitField0.needsInit == true) { - note->sampleState.bitField0.needsInit = false; - } - note->playbackState.priority = 0; - note->sampleState.bitField0.enabled = false; - note->playbackState.status = PLAYBACK_STATUS_0; - note->sampleState.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 AudioPlayback_ProcessNotes(void) { - s32 pad; - s32 playbackStatus; - NoteAttributes* attrs; - NoteSampleState* sampleState; - NoteSampleState* noteSampleState; - Note* note; - NotePlaybackState* playbackState; - NoteSubAttributes subAttrs; - u8 bookOffset; - f32 scale; - s32 i; - - for (i = 0; i < gAudioCtx.numNotes; i++) { - note = &gAudioCtx.notes[i]; - sampleState = &gAudioCtx.sampleStateList[gAudioCtx.sampleStateOffset + i]; - playbackState = ¬e->playbackState; - if (playbackState->parentLayer != NO_LAYER) { - if ((u32)playbackState->parentLayer < 0x7FFFFFFF) { - continue; - } - - if ((note != playbackState->parentLayer->note) && (playbackState->status == PLAYBACK_STATUS_0)) { - playbackState->adsr.action.s.release = true; - playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; - playbackState->priority = 1; - playbackState->status = PLAYBACK_STATUS_2; - goto out; - } else if (!playbackState->parentLayer->enabled && (playbackState->status == PLAYBACK_STATUS_0) && - (playbackState->priority >= 1)) { - // do nothing - } else if (playbackState->parentLayer->channel->seqPlayer == NULL) { - AudioSeq_SequenceChannelDisable(playbackState->parentLayer->channel); - playbackState->priority = 1; - playbackState->status = PLAYBACK_STATUS_1; - continue; - } else if (playbackState->parentLayer->channel->seqPlayer->muted && - (playbackState->parentLayer->channel->muteFlags & MUTE_FLAGS_STOP_NOTES)) { - // do nothing - } else { - goto out; - } - - AudioPlayback_SeqLayerNoteRelease(playbackState->parentLayer); - AudioPlayback_AudioListRemove(¬e->listItem); - AudioPlayback_AudioListPushFront(¬e->listItem.pool->decaying, ¬e->listItem); - playbackState->priority = 1; - playbackState->status = PLAYBACK_STATUS_2; - } else if ((playbackState->status == PLAYBACK_STATUS_0) && (playbackState->priority >= 1)) { - continue; - } - - out: - if (playbackState->priority != 0) { - //! FAKE: - if (1) {} - noteSampleState = ¬e->sampleState; - if ((playbackState->status >= 1) || noteSampleState->bitField0.finished) { - if ((playbackState->adsr.action.s.state == ADSR_STATE_DISABLED) || - noteSampleState->bitField0.finished) { - if (playbackState->wantedParentLayer != NO_LAYER) { - AudioPlayback_NoteDisable(note); - if (playbackState->wantedParentLayer->channel != NULL) { - AudioPlayback_NoteInitForLayer(note, playbackState->wantedParentLayer); - AudioEffects_NoteVibratoInit(note); - AudioEffects_NotePortamentoInit(note); - AudioPlayback_AudioListRemove(¬e->listItem); - AudioSeq_AudioListPushBack(¬e->listItem.pool->active, ¬e->listItem); - playbackState->wantedParentLayer = NO_LAYER; - // don't skip - } else { - AudioPlayback_NoteDisable(note); - AudioPlayback_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; - } - AudioPlayback_NoteDisable(note); - AudioPlayback_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; - } - AudioPlayback_NoteDisable(note); - AudioPlayback_AudioListRemove(¬e->listItem); - AudioSeq_AudioListPushBack(¬e->listItem.pool->disabled, ¬e->listItem); - continue; - } - - scale = AudioEffects_AdsrUpdate(&playbackState->adsr); - AudioEffects_NoteVibratoUpdate(note); - playbackStatus = playbackState->status; - attrs = &playbackState->attributes; - if ((playbackStatus == PLAYBACK_STATUS_1) || (playbackStatus == PLAYBACK_STATUS_2)) { - subAttrs.frequency = attrs->freqScale; - subAttrs.velocity = attrs->velocity; - subAttrs.pan = attrs->pan; - subAttrs.targetReverbVol = attrs->targetReverbVol; - subAttrs.stereoData = attrs->stereoData; - subAttrs.gain = attrs->gain; - subAttrs.filter = attrs->filter; - subAttrs.combFilterSize = attrs->combFilterSize; - subAttrs.combFilterGain = attrs->combFilterGain; - subAttrs.surroundEffectIndex = attrs->surroundEffectIndex; - bookOffset = noteSampleState->bitField1.bookOffset; - } else { - SequenceLayer* layer = playbackState->parentLayer; - SequenceChannel* channel = playbackState->parentLayer->channel; - - subAttrs.frequency = layer->noteFreqScale; - subAttrs.velocity = layer->noteVelocity; - subAttrs.pan = layer->notePan; - - if (layer->surroundEffectIndex == 0x80) { - subAttrs.surroundEffectIndex = channel->surroundEffectIndex; - } else { - subAttrs.surroundEffectIndex = layer->surroundEffectIndex; - } - - if (layer->stereoData.type == 0) { - subAttrs.stereoData = channel->stereoData; - } else { - subAttrs.stereoData = layer->stereoData; - } - - if (layer->unk_0A.s.bit_2 == 1) { - subAttrs.targetReverbVol = channel->targetReverbVol; - } else { - subAttrs.targetReverbVol = layer->targetReverbVol; - } - - if (layer->unk_0A.s.bit_9 == 1) { - subAttrs.gain = channel->gain; - } else { - subAttrs.gain = 0; - //! FAKE: - if (1) {} - } - - subAttrs.filter = channel->filter; - subAttrs.combFilterSize = channel->combFilterSize; - subAttrs.combFilterGain = channel->combFilterGain; - bookOffset = channel->bookOffset & 0x7; - - if (channel->seqPlayer->muted && (channel->muteFlags & MUTE_FLAGS_STOP_SAMPLES)) { - subAttrs.frequency = 0.0f; - subAttrs.velocity = 0.0f; - } - } - - subAttrs.frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale; - subAttrs.frequency *= gAudioCtx.audioBufferParameters.resampleRate; - subAttrs.velocity *= scale; - AudioPlayback_InitSampleState(note, sampleState, &subAttrs); - noteSampleState->bitField1.bookOffset = bookOffset; - skip:; - } - } -} - -TunedSample* AudioPlayback_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* AudioPlayback_GetInstrumentInner(s32 fontId, s32 instId) { - Instrument* inst; - - if (fontId == 0xFF) { - return NULL; - } - - if (!AudioLoad_IsFontLoadComplete(fontId)) { - gAudioCtx.audioErrorFlags = AUDIO_ERROR(0, fontId, AUDIO_ERROR_FONT_NOT_LOADED); - return NULL; - } - - if (instId >= gAudioCtx.soundFontList[fontId].numInstruments) { - gAudioCtx.audioErrorFlags = AUDIO_ERROR(fontId, instId, AUDIO_ERROR_INVALID_INST_ID); - return NULL; - } - - inst = gAudioCtx.soundFontList[fontId].instruments[instId]; - if (inst == NULL) { - gAudioCtx.audioErrorFlags = AUDIO_ERROR(fontId, instId, AUDIO_ERROR_NO_INST); - return inst; - } - - return inst; -} - -Drum* AudioPlayback_GetDrum(s32 fontId, s32 drumId) { - Drum* drum; - - if (fontId == 0xFF) { - return NULL; - } - - if (!AudioLoad_IsFontLoadComplete(fontId)) { - gAudioCtx.audioErrorFlags = AUDIO_ERROR(0, fontId, AUDIO_ERROR_FONT_NOT_LOADED); - return NULL; - } - - if (drumId >= gAudioCtx.soundFontList[fontId].numDrums) { - gAudioCtx.audioErrorFlags = AUDIO_ERROR(fontId, drumId, AUDIO_ERROR_INVALID_DRUM_SFX_ID); - 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 = AUDIO_ERROR(fontId, drumId, AUDIO_ERROR_NO_DRUM_SFX); - } - - return drum; -} - -SoundEffect* AudioPlayback_GetSoundEffect(s32 fontId, s32 sfxId) { - SoundEffect* soundEffect; - - if (fontId == 0xFF) { - return NULL; - } - - if (!AudioLoad_IsFontLoadComplete(fontId)) { - gAudioCtx.audioErrorFlags = AUDIO_ERROR(0, fontId, AUDIO_ERROR_FONT_NOT_LOADED); - return NULL; - } - - if (sfxId >= gAudioCtx.soundFontList[fontId].numSfx) { - gAudioCtx.audioErrorFlags = AUDIO_ERROR(fontId, sfxId, AUDIO_ERROR_INVALID_DRUM_SFX_ID); - 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 = AUDIO_ERROR(fontId, sfxId, AUDIO_ERROR_NO_DRUM_SFX); - } - - if (soundEffect->tunedSample.sample == NULL) { - return NULL; - } - - return soundEffect; -} - -s32 AudioPlayback_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 AudioPlayback_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) { - Note* note; - NoteAttributes* attrs; - SequenceChannel* channel; - 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) { - channel = layer->channel; - - if (layer->unk_0A.s.bit_2 == 1) { - attrs->targetReverbVol = channel->targetReverbVol; - } else { - attrs->targetReverbVol = layer->targetReverbVol; - } - - if (layer->surroundEffectIndex == 0x80) { - attrs->surroundEffectIndex = channel->surroundEffectIndex; - } else { - attrs->surroundEffectIndex = layer->surroundEffectIndex; - } - - if (layer->unk_0A.s.bit_9 == 1) { - attrs->gain = channel->gain; - } else { - attrs->gain = 0; - } - - attrs->filter = channel->filter; - - if (attrs->filter != NULL) { - for (i = 0; i < 8; i++) { - attrs->filterBuf[i] = attrs->filter[i]; - } - attrs->filter = attrs->filterBuf; - } - - attrs->combFilterGain = channel->combFilterGain; - attrs->combFilterSize = channel->combFilterSize; - if (channel->seqPlayer->muted && (channel->muteFlags & MUTE_FLAGS_STOP_SAMPLES)) { - note->sampleState.bitField0.finished = true; - } - - if (layer->stereoData.asByte == 0) { - attrs->stereoData = channel->stereoData; - } else { - attrs->stereoData = layer->stereoData; - } - note->playbackState.priority = channel->someOtherPriority; - } else { - attrs->stereoData = layer->stereoData; - 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.status = PLAYBACK_STATUS_2; - } else { - note->playbackState.status = PLAYBACK_STATUS_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) { - AudioPlayback_AudioListRemove(¬e->listItem); - AudioPlayback_AudioListPushFront(¬e->listItem.pool->decaying, ¬e->listItem); - } -} - -void AudioPlayback_SeqLayerNoteDecay(SequenceLayer* layer) { - AudioPlayback_SeqLayerDecayRelease(layer, ADSR_STATE_DECAY); -} - -void AudioPlayback_SeqLayerNoteRelease(SequenceLayer* layer) { - AudioPlayback_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 AudioPlayback_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->sampleState.waveSampleAddr = &gWaveSamples[waveId - 128][harmonicIndex * WAVE_SAMPLE_COUNT]; - - return harmonicIndex; -} - -void AudioPlayback_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 = AudioPlayback_BuildSyntheticWave(note, layer, waveId); - - if (curHarmonicIndex != prevHarmonicIndex) { - note->sampleState.harmonicIndexCurAndPrev = (curHarmonicIndex << 2) + prevHarmonicIndex; - } -} - -void AudioPlayback_InitNoteList(AudioListItem* list) { - list->prev = list; - list->next = list; - list->u.count = 0; -} - -void AudioPlayback_InitNoteLists(NotePool* pool) { - AudioPlayback_InitNoteList(&pool->disabled); - AudioPlayback_InitNoteList(&pool->decaying); - AudioPlayback_InitNoteList(&pool->releasing); - AudioPlayback_InitNoteList(&pool->active); - pool->disabled.pool = pool; - pool->decaying.pool = pool; - pool->releasing.pool = pool; - pool->active.pool = pool; -} - -void AudioPlayback_InitNoteFreeList(void) { - s32 i; - - AudioPlayback_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 AudioPlayback_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; - } - - for (;;) { - cur = source->next; - if (cur == source || cur == NULL) { - break; - } - AudioPlayback_AudioListRemove(cur); - AudioSeq_AudioListPushBack(dest, cur); - } - } -} - -void AudioPlayback_NotePoolFill(NotePool* pool, s32 count) { - s32 i; - s32 j; - Note* note; - AudioListItem* source; - AudioListItem* dest; - - AudioPlayback_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 AudioPlayback_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 AudioPlayback_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* AudioPlayback_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 AudioPlayback_NoteInitForLayer(Note* note, SequenceLayer* layer) { - s32 pad[3]; - s16 instId; - SequenceChannel* channel = layer->channel; - NotePlaybackState* playbackState = ¬e->playbackState; - NoteSampleState* noteSampleState = ¬e->sampleState; - - playbackState->prevParentLayer = NO_LAYER; - playbackState->parentLayer = layer; - playbackState->priority = channel->notePriority; - layer->notePropertiesNeedInit = true; - layer->bit3 = true; - layer->note = note; - channel->noteUnused = note; - channel->layerUnused = layer; - layer->noteVelocity = 0.0f; - AudioPlayback_NoteInit(note); - instId = layer->instOrWave; - - if (instId == 0xFF) { - instId = channel->instOrWave; - } - noteSampleState->tunedSample = layer->tunedSample; - - if (instId >= 0x80 && instId < 0xC0) { - noteSampleState->bitField1.isSyntheticWave = true; - } else { - noteSampleState->bitField1.isSyntheticWave = false; - } - - if (noteSampleState->bitField1.isSyntheticWave) { - AudioPlayback_BuildSyntheticWave(note, layer, instId); - } else if (channel->startSamplePos == 1) { - playbackState->startSamplePos = noteSampleState->tunedSample->sample->loop->start; - } else { - playbackState->startSamplePos = channel->startSamplePos; - if (playbackState->startSamplePos >= noteSampleState->tunedSample->sample->loop->loopEnd) { - playbackState->startSamplePos = 0; - } - } - - playbackState->fontId = channel->fontId; - playbackState->stereoHeadsetEffects = channel->stereoHeadsetEffects; - noteSampleState->bitField1.reverbIndex = channel->reverbIndex & 3; -} - -void func_801963E8(Note* note, SequenceLayer* layer) { - // similar to Audio_NoteReleaseAndTakeOwnership, hard to say what the difference is - AudioPlayback_SeqLayerNoteRelease(note->playbackState.parentLayer); - note->playbackState.wantedParentLayer = layer; -} - -void AudioPlayback_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* AudioPlayback_AllocNoteFromDisabled(NotePool* pool, SequenceLayer* layer) { - Note* note = AudioSeq_AudioListPopBack(&pool->disabled); - if (note != NULL) { - AudioPlayback_NoteInitForLayer(note, layer); - AudioPlayback_AudioListPushFront(&pool->active, ¬e->listItem); - } - return note; -} - -Note* AudioPlayback_AllocNoteFromDecaying(NotePool* pool, SequenceLayer* layer) { - Note* note = AudioPlayback_FindNodeWithPrioLessThan(&pool->decaying, layer->channel->notePriority); - - if (note != NULL) { - AudioPlayback_NoteReleaseAndTakeOwnership(note, layer); - AudioPlayback_AudioListRemove(¬e->listItem); - AudioSeq_AudioListPushBack(&pool->releasing, ¬e->listItem); - } - return note; -} - -Note* AudioPlayback_AllocNoteFromActive(NotePool* pool, SequenceLayer* layer) { - Note* rNote; - Note* aNote; - s32 rPriority; - s32 aPriority; - - rPriority = aPriority = 0x10; - rNote = AudioPlayback_FindNodeWithPrioLessThan(&pool->releasing, layer->channel->notePriority); - - if (rNote != NULL) { - rPriority = rNote->playbackState.priority; - } - - aNote = AudioPlayback_FindNodeWithPrioLessThan(&pool->active, layer->channel->notePriority); - - if (aNote != NULL) { - aPriority = aNote->playbackState.priority; - } - - if (rNote == NULL && aNote == NULL) { - return NULL; - } - - if (aPriority < rPriority) { - AudioPlayback_AudioListRemove(&aNote->listItem); - func_801963E8(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* AudioPlayback_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) { - AudioPlayback_NoteReleaseAndTakeOwnership(note, layer); - AudioPlayback_AudioListRemove(¬e->listItem); - AudioSeq_AudioListPushBack(¬e->listItem.pool->releasing, ¬e->listItem); - return note; - } - } - - if (policy & 2) { - if (!(note = AudioPlayback_AllocNoteFromDisabled(&layer->channel->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromDecaying(&layer->channel->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromActive(&layer->channel->notePool, layer))) { - goto null_return; - } - return note; - } - - if (policy & 4) { - if (!(note = AudioPlayback_AllocNoteFromDisabled(&layer->channel->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromDisabled(&layer->channel->seqPlayer->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromDecaying(&layer->channel->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromDecaying(&layer->channel->seqPlayer->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromActive(&layer->channel->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromActive(&layer->channel->seqPlayer->notePool, layer))) { - goto null_return; - } - return note; - } - - if (policy & 8) { - if (!(note = AudioPlayback_AllocNoteFromDisabled(&gAudioCtx.noteFreeLists, layer)) && - !(note = AudioPlayback_AllocNoteFromDecaying(&gAudioCtx.noteFreeLists, layer)) && - !(note = AudioPlayback_AllocNoteFromActive(&gAudioCtx.noteFreeLists, layer))) { - goto null_return; - } - return note; - } - - if (!(note = AudioPlayback_AllocNoteFromDisabled(&layer->channel->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromDisabled(&layer->channel->seqPlayer->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromDisabled(&gAudioCtx.noteFreeLists, layer)) && - !(note = AudioPlayback_AllocNoteFromDecaying(&layer->channel->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromDecaying(&layer->channel->seqPlayer->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromDecaying(&gAudioCtx.noteFreeLists, layer)) && - !(note = AudioPlayback_AllocNoteFromActive(&layer->channel->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromActive(&layer->channel->seqPlayer->notePool, layer)) && - !(note = AudioPlayback_AllocNoteFromActive(&gAudioCtx.noteFreeLists, layer))) { - goto null_return; - } - return note; - -null_return: - layer->bit3 = true; - return NULL; -} - -void AudioPlayback_NoteInitAll(void) { - Note* note; - s32 i; - - for (i = 0; i < gAudioCtx.numNotes; i++) { - note = &gAudioCtx.notes[i]; - note->sampleState = gZeroedSampleState; - note->playbackState.priority = 0; - note->playbackState.status = PLAYBACK_STATUS_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 = false; - note->playbackState.portamento.cur = 0; - note->playbackState.portamento.speed = 0; - note->playbackState.stereoHeadsetEffects = false; - note->playbackState.startSamplePos = 0; - note->synthesisState.synthesisBuffers = - AudioHeap_AllocDmaMemory(&gAudioCtx.miscPool, sizeof(NoteSynthesisBuffers)); - note->playbackState.attributes.filterBuf = AudioHeap_AllocDmaMemory(&gAudioCtx.miscPool, FILTER_SIZE); - } -} diff --git a/src/code/audio/audio_seqplayer.c b/src/code/audio/audio_seqplayer.c deleted file mode 100644 index a8c54420a..000000000 --- a/src/code/audio/audio_seqplayer.c +++ /dev/null @@ -1,2313 +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 "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_SeqLayerProcessScriptStep5(SequenceLayer* layer, s32 sameTunedSample); -s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer); -s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd); -s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd); -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), // 0xA0 (channel:) - CMD_ARGS_0(), // 0xA1 (channel:) - CMD_ARGS_1(s16), // 0xA2 (channel:) - CMD_ARGS_0(), // 0xA3 (channel:) - CMD_ARGS_1(u8), // 0xA4 (channel:) - CMD_ARGS_0(), // 0xA5 (channel:) - CMD_ARGS_2(u8, s16), // 0xA6 (channel:) - CMD_ARGS_1(u8), // 0xA7 (channel:) - CMD_ARGS_2(s16, s16), // 0xA8 (channel: random range large) - CMD_ARGS_0(), // 0xA9 () - CMD_ARGS_0(), // 0xAA () - CMD_ARGS_0(), // 0xAB () - CMD_ARGS_0(), // 0xAC () - CMD_ARGS_0(), // 0xAD () - CMD_ARGS_0(), // 0xAE () - CMD_ARGS_0(), // 0xAF () - CMD_ARGS_1(s16), // 0xB0 (channel: set filter) - CMD_ARGS_0(), // 0xB1 (channel: clear filter) - CMD_ARGS_1(s16), // 0xB2 (channel: dynread sequence large) - CMD_ARGS_1(u8), // 0xB3 (channel: load filter) - CMD_ARGS_0(), // 0xB4 (channel: set dyntable large) - CMD_ARGS_0(), // 0xB5 (channel: read dyntable large) - CMD_ARGS_0(), // 0xB6 (channel: read dyntable) - CMD_ARGS_1(s16), // 0xB7 (channel: random large) - CMD_ARGS_1(u8), // 0xB8 (channel: random) - CMD_ARGS_1(u8), // 0xB9 (channel: set velocity random variance) - CMD_ARGS_1(u8), // 0xBA (channel: set gatetime random variance) - CMD_ARGS_2(u8, s16), // 0xBB (channel:) - CMD_ARGS_1(s16), // 0xBC (channel: add large) - CMD_ARGS_1(s16), // 0xBD (channel:) - CMD_ARGS_1(u8), // 0xBE (channel:) - CMD_ARGS_0(), // 0xBF () - CMD_ARGS_0(), // 0xC0 () - CMD_ARGS_1(u8), // 0xC1 (channel: set instrument) - CMD_ARGS_1(s16), // 0xC2 (channel: set dyntable) - CMD_ARGS_0(), // 0xC3 (channel: large notes off) - CMD_ARGS_0(), // 0xC4 (channel: large notes on) - CMD_ARGS_0(), // 0xC5 (channel: dyn set dyntable) - CMD_ARGS_1(u8), // 0xC6 (channel: set soundFont) - CMD_ARGS_2(u8, s16), // 0xC7 (channel: write into sequence script) - CMD_ARGS_1(u8), // 0xC8 (channel: subtract -> set value) - CMD_ARGS_1(u8), // 0xC9 (channel: `bit and` -> set value) - CMD_ARGS_1(u8), // 0xCA (channel: set mute behavior) - CMD_ARGS_1(s16), // 0xCB (channel: read sequence -> set value) - CMD_ARGS_1(u8), // 0xCC (channel: set value) - CMD_ARGS_1(u8), // 0xCD (channel: disable channel) - CMD_ARGS_1(s16), // 0xCE (channel:) - CMD_ARGS_1(s16), // 0xCF (channel: write large into sequence script) - CMD_ARGS_1(u8), // 0xD0 (channel: stereo headset effects) - CMD_ARGS_1(u8), // 0xD1 (channel: set note allocation policy) - CMD_ARGS_1(u8), // 0xD2 (channel: set sustain) - CMD_ARGS_1(u8), // 0xD3 (channel: large bend pitch) - CMD_ARGS_1(u8), // 0xD4 (channel: set reverb) - CMD_ARGS_1(u8), // 0xD5 () - CMD_ARGS_1(u8), // 0xD6 () - CMD_ARGS_1(u8), // 0xD7 (channel: set vibrato rate) - CMD_ARGS_1(u8), // 0xD8 (channel: set vibrato depth) - CMD_ARGS_1(u8), // 0xD9 (channel: set decay index) - CMD_ARGS_1(s16), // 0xDA (channel: set envelope) - CMD_ARGS_1(u8), // 0xDB (channel: transpose) - CMD_ARGS_1(u8), // 0xDC (channel: set pan mix) - CMD_ARGS_1(u8), // 0xDD (channel: set pan) - CMD_ARGS_1(s16), // 0xDE (channel: set freqscale) - CMD_ARGS_1(u8), // 0xDF (channel: set volume) - CMD_ARGS_1(u8), // 0xE0 (channel: set volume scale) - CMD_ARGS_3(u8, u8, u8), // 0xE1 (channel: set vibratorate linear) - CMD_ARGS_3(u8, u8, u8), // 0xE2 (channel: set vibrato depth linear) - CMD_ARGS_1(u8), // 0xE3 (channel: set vibrato delay) - CMD_ARGS_0(), // 0xE4 (channel: dyncall) - CMD_ARGS_1(u8), // 0xE5 (channel: set reverb index) - CMD_ARGS_1(u8), // 0xE6 (channel: set book offset) - CMD_ARGS_1(s16), // 0xE7 (channel:) - CMD_ARGS_3(u8, u8, u8), // 0xE8 (channel:) - CMD_ARGS_1(u8), // 0xE9 (channel: set note priority) - CMD_ARGS_0(), // 0xEA (channel: stop script) - CMD_ARGS_2(u8, u8), // 0xEB (channel: set soundFont and instrument) - CMD_ARGS_0(), // 0xEC (channel: reset vibrato) - CMD_ARGS_1(u8), // 0xED (channel: set hilo gain) - CMD_ARGS_1(u8), // 0xEE (channel: small bend pitch) - CMD_ARGS_2(s16, u8), // 0xEF () - CMD_ARGS_0(), // 0xF0 (channel: unreserve notes) - CMD_ARGS_1(u8), // 0xF1 (channel: reserve notes) - // Control flow instructions (>= 0xF2) can only have 0 or 1 args - CMD_ARGS_1(u8), // 0xF2 (branch relative if less than zero) - CMD_ARGS_1(u8), // 0xF3 (branch relative if equal to zero) - CMD_ARGS_1(u8), // 0xF4 (jump relative) - CMD_ARGS_1(s16), // 0xF5 (branch if greater than or equal to zero) - CMD_ARGS_0(), // 0xF6 (break) - CMD_ARGS_0(), // 0xF7 (loop end) - CMD_ARGS_1(u8), // 0xF8 (loop) - CMD_ARGS_1(s16), // 0xF9 (branch if less than zero) - CMD_ARGS_1(s16), // 0xFA (branch if equal to zero) - CMD_ARGS_1(s16), // 0xFB (jump) - CMD_ARGS_1(s16), // 0xFC (call and jump to a function) - CMD_ARGS_0(), // 0xFD (delay n frames) - CMD_ARGS_0(), // 0xFE (delay 1 frame) - CMD_ARGS_0(), // 0xFF (end script) -}; - -/** - * 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 - 0xA0]; - 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) { - u32 depth; - - switch (cmd) { - case 0xFF: // end script - if (state->depth == 0) { - return PROCESS_SCRIPT_END; - } - state->pc = state->stack[--state->depth]; - break; - - case 0xFD: // delay n frames - return AudioSeq_ScriptReadCompressedU16(state); - - case 0xFE: // delay 1 frame - return 1; - - case 0xFC: // call and jump to a function - state->stack[depth = state->depth++] = state->pc; - state->pc = seqPlayer->seqData + (u16)cmdArg; - break; - - case 0xF8: // loop - state->remLoopIters[depth = state->depth] = cmdArg; - state->stack[state->depth++] = state->pc; - break; - - case 0xF7: // loop end - 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: // break - state->depth--; - break; - - case 0xF5: // branch if greater than or equal to zero - case 0xF9: // branch if less than zero - case 0xFA: // branch if equal to zero - case 0xFB: // jump - 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: // branch relative if less than zero - case 0xF3: // branch relative if equal to zero - case 0xF4: // jump relative - 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->muted = false; - channel->hasInstrument = false; - channel->stereoHeadsetEffects = false; - channel->transposition = 0; - channel->largeNotes = false; - channel->bookOffset = 0; - channel->stereoData.asByte = 0; - channel->changes.asByte = 0xFF; - channel->scriptState.depth = 0; - channel->newPan = 0x40; - channel->panChannelWeight = 0x80; - channel->surroundEffectIndex = 0xFF; - channel->velocityRandomVariance = 0; - channel->gateTimeRandomVariance = 0; - channel->noteUnused = NULL; - channel->reverbIndex = 0; - channel->targetReverbVol = 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->vibrato.vibratoRateTarget = 0x800; - channel->vibrato.vibratoRateStart = 0x800; - channel->vibrato.vibratoDepthTarget = 0; - channel->vibrato.vibratoDepthStart = 0; - channel->vibrato.vibratoRateChangeDelay = 0; - channel->vibrato.vibratoDepthChangeDelay = 0; - channel->vibrato.vibratoDelay = 0; - channel->filter = NULL; - channel->combFilterGain = 0; - channel->combFilterSize = 0; - channel->volume = 1.0f; - channel->volumeScale = 1.0f; - channel->freqScale = 1.0f; - - for (i = 0; i < ARRAY_COUNT(channel->seqScriptIO); i++) { - channel->seqScriptIO[i] = SEQ_IO_VAL_NONE; - } - - channel->unused = false; - AudioPlayback_InitNoteLists(&channel->notePool); - channel->startSamplePos = 0; - channel->unk_E0 = 0; - channel->sfxState = NULL; -} - -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 { - AudioPlayback_SeqLayerNoteDecay(channel->layers[layerIndex]); - } - - layer = channel->layers[layerIndex]; - - layer->channel = channel; - layer->adsr = channel->adsr; - layer->adsr.decayIndex = 0; - layer->targetReverbVol = channel->targetReverbVol; - layer->enabled = true; - layer->finished = false; - layer->muted = false; - layer->continuousNotes = false; - layer->bit3 = false; - layer->ignoreDrumPan = false; - layer->bit1 = false; - layer->notePropertiesNeedInit = false; - layer->gateTime = 0x80; - layer->surroundEffectIndex = 0x80; - layer->stereoData.asByte = 0; - layer->portamento.mode = PORTAMENTO_MODE_OFF; - layer->scriptState.depth = 0; - layer->pan = 0x40; - layer->transposition = 0; - layer->delay = 0; - layer->gateDelay = 0; - layer->delay2 = 0; - layer->note = NULL; - layer->instrument = NULL; - layer->instOrWave = 0xFF; - layer->unk_0A.asByte = 0xFFFF; - layer->vibrato.vibratoRateTarget = 0x800; - layer->vibrato.vibratoRateStart = 0x800; - layer->vibrato.vibratoDepthTarget = 0; - layer->vibrato.vibratoDepthStart = 0; - layer->vibrato.vibratoRateChangeDelay = 0; - layer->vibrato.vibratoDepthChangeDelay = 0; - layer->vibrato.vibratoDelay = 0; - layer->freqScale = 1.0f; - layer->bend = 1.0f; - layer->velocitySquare2 = 0.0f; - - return 0; -} - -void AudioSeq_SeqLayerDisable(SequenceLayer* layer) { - if (layer != NULL) { - if ((layer->channel != &gAudioCtx.sequenceChannelNone) && (layer->channel->seqPlayer->finished == true)) { - AudioPlayback_SeqLayerNoteRelease(layer); - } else { - AudioPlayback_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; - - channel->finished = true; - - for (i = 0; i < 4; i++) { - AudioSeq_SeqLayerFree(channel, i); - } - - AudioPlayback_NotePoolClear(&channel->notePool); - channel->enabled = false; -} - -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->muteFlags = seqPlayer->muteFlags; - 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); - AudioPlayback_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 = 1; - } else if (seqPlayer->defaultFont == gAudioCtx.fontCache.temporary.entries[1].id) { - gAudioCtx.fontCache.temporary.nextSide = 0; - } -} - -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->muted && (layer->delay <= layer->gateDelay)) { - AudioPlayback_SeqLayerNoteDecay(layer); - layer->muted = true; - } - return; - } - - AudioSeq_SeqLayerProcessScriptStep1(layer); - - do { - cmd = AudioSeq_SeqLayerProcessScriptStep2(layer); - if (cmd == PROCESS_SCRIPT_END) { - return; - } - - cmd = AudioSeq_SeqLayerProcessScriptStep3(layer, cmd); - - } while ((cmd == -1) && (layer->delay == 0)); - - if (cmd != PROCESS_SCRIPT_END) { - // returns `sameTunedSample` instead of a command - cmd = AudioSeq_SeqLayerProcessScriptStep4(layer, cmd); - } - - if (cmd != PROCESS_SCRIPT_END) { - AudioSeq_SeqLayerProcessScriptStep5(layer, cmd); - } - - if (layer->muted == true) { - if ((layer->note != NULL) || layer->continuousNotes) { - AudioPlayback_SeqLayerNoteDecay(layer); - } - } -} - -void AudioSeq_SeqLayerProcessScriptStep1(SequenceLayer* layer) { - if (!layer->continuousNotes) { - AudioPlayback_SeqLayerNoteDecay(layer); - } else if ((layer->note != NULL) && (layer->note->playbackState.wantedParentLayer == layer)) { - AudioPlayback_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->continuousNotes == true) && (layer->bit1 == true)) { - return 0; - } - - if ((layer->continuousNotes == true) && (layer->note != NULL) && layer->bit3 && (sameTunedSample == true) && - (layer->note->playbackState.parentLayer == layer)) { - if (layer->tunedSample == NULL) { - AudioPlayback_InitSyntheticWave(layer->note, layer); - } - } else { - if (!sameTunedSample) { - AudioPlayback_SeqLayerNoteDecay(layer); - } - - layer->note = AudioPlayback_AllocNote(layer); - - if (layer->note != NULL) { - note = layer->note; - - if (note->playbackState.parentLayer == layer) { - AudioEffects_NoteVibratoInit(note); - } - } - } - - if ((layer->note != NULL) && (layer->note->playbackState.parentLayer == layer)) { - note = layer->note; - - AudioEffects_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); - - // Note Commands - // 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: set short note velocity - case 0xCA: // layer: set pan - cmdArg8 = *(state->pc++); - if (cmd == 0xC1) { - layer->velocitySquare = SQ(cmdArg8) / SQ(127.0f); - } else { - layer->pan = cmdArg8; - } - break; - - case 0xC9: // layer: set short note gatetime - case 0xC2: // layer: set transposition in semitones - cmdArg8 = *(state->pc++); - if (cmd == 0xC9) { - layer->gateTime = cmdArg8; - } else { - layer->transposition = cmdArg8; - } - break; - - case 0xC4: // layer: continuous notes on - case 0xC5: // layer: continuous notes off - if (cmd == 0xC4) { - layer->continuousNotes = true; - } else { - layer->continuousNotes = false; - } - layer->bit1 = false; - AudioPlayback_SeqLayerNoteDecay(layer); - break; - - case 0xC3: // layer: set short note default delay - cmdArg16 = AudioSeq_ScriptReadCompressedU16(state); - layer->shortNoteDefaultDelay = cmdArg16; - break; - - case 0xC6: // layer: set instrument - 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: enable 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: disable portamento - layer->portamento.mode = PORTAMENTO_MODE_OFF; - break; - - case 0xCB: // layer: set envelope and decay index - cmdArg16 = AudioSeq_ScriptReadS16(state); - layer->adsr.envelope = (EnvelopePoint*)(seqPlayer->seqData + cmdArg16); - // fallthrough - case 0xCF: // layer: set decay index - layer->adsr.decayIndex = AudioSeq_ScriptReadU8(state); - break; - - case 0xCC: // layer: ignore drum pan - layer->ignoreDrumPan = true; - break; - - case 0xCD: // layer: stereo effects - layer->stereoData.asByte = AudioSeq_ScriptReadU8(state); - break; - - case 0xCE: // layer: bend pitch - cmdArg8 = AudioSeq_ScriptReadU8(state); - layer->bend = gBendPitchTwoSemitonesFrequencies[(u8)(cmdArg8 + 0x80)]; - break; - - case 0xF0: // layer: - cmdArg16 = AudioSeq_ScriptReadS16(state); - layer->unk_0A.asByte &= (cmdArg16 ^ 0xFFFF); - break; - - case 0xF1: // layer: - layer->surroundEffectIndex = AudioSeq_ScriptReadU8(state); - break; - - default: - switch (cmd & 0xF0) { - case 0xD0: // layer: set short note velocity from table - velocity = seqPlayer->shortNoteVelocityTable[cmd & 0xF]; - layer->velocitySquare = SQ(velocity) / SQ(127.0f); - break; - - case 0xE0: // layer: set short note gatetime from table - 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 = AudioPlayback_GetDrum(channel->fontId, semitone); - if (drum == NULL) { - layer->muted = 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 = AudioPlayback_GetSoundEffect(channel->fontId, sfxId); - if (soundEffect == NULL) { - layer->muted = 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->muted = 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 = AudioPlayback_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.maxTempo; - 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 = AudioPlayback_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->loopEnd; - } else { - time = 0.0f; - } - time *= seqPlayer->tempo; - time *= gAudioCtx.unk_2870; - time /= layer->freqScale; - //! FAKE: - if (1) {} - 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.maxTempo; - 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 - layer->delay = AudioSeq_ScriptReadCompressedU16(state); - layer->muted = true; - layer->bit1 = false; - return PROCESS_SCRIPT_END; - } - - layer->muted = false; - - if (channel->largeNotes == true) { - switch (cmd & 0xC0) { - case 0x00: // layer: large note 0 - delay = AudioSeq_ScriptReadCompressedU16(state); - velocity = *(state->pc++); - layer->gateTime = *(state->pc++); - layer->lastDelay = delay; - break; - - case 0x40: // layer: large note 1 - delay = AudioSeq_ScriptReadCompressedU16(state); - velocity = *(state->pc++); - layer->gateTime = 0; - layer->lastDelay = delay; - break; - - case 0x80: // layer: large note 2 - 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: // layer: small note 0 - delay = AudioSeq_ScriptReadCompressedU16(state); - layer->lastDelay = delay; - break; - - case 0x40: // layer: small note 1 - delay = layer->shortNoteDefaultDelay; - break; - - case 0x80: // layer: small note 2 - 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->muteFlags & (MUTE_FLAGS_STOP_NOTES | MUTE_FLAGS_STOP_LAYER))) || - channel->muted) { - layer->muted = true; - return PROCESS_SCRIPT_END; - } - - if (seqPlayer->skipTicks != 0) { - layer->muted = 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 = AudioPlayback_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; - u32 rand; - SequencePlayer* seqPlayer; - - if (channel->stopScript) { - goto exit_loop; - } - - seqPlayer = channel->seqPlayer; - if (seqPlayer->muted && (channel->muteFlags & MUTE_FLAGS_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; - u8 phi_v0_3; - u8 new_var; - u8 depth; - u8* seqData = seqPlayer->seqData; - u32 new_var2; - - // Commands 0xA0 - 0xFF - if (cmd >= 0xA0) { - highBits = sSeqInstructionArgsTable[cmd - 0xA0]; - 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: stop script - channel->stopScript = true; - goto exit_loop; - - case 0xF1: // channel: reserve notes - AudioPlayback_NotePoolClear(&channel->notePool); - cmd = (u8)cmdArgs[0]; - AudioPlayback_NotePoolFill(&channel->notePool, cmd); - break; - - case 0xF0: // channel: unreserve notes - AudioPlayback_NotePoolClear(&channel->notePool); - break; - - case 0xC2: // channel: set dyntable - cmdArgU16 = (u16)cmdArgs[0]; - channel->dynTable = (void*)&seqPlayer->seqData[cmdArgU16]; - break; - - case 0xC5: // channel: dyn set dyntable - if (scriptState->value != -1) { - data = (*channel->dynTable)[scriptState->value]; - cmdArgU16 = (u16)((data[0] << 8) + data[1]); - scriptState->pc = (void*)&seqPlayer->seqData[cmdArgU16]; - } - break; - - case 0xEB: // channel: set soundFont and instrument - 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: // channel: set instrument - cmd = (u8)cmdArgs[0]; - AudioSeq_SetInstrument(channel, cmd); - break; - - case 0xC3: // channel: large notes off - channel->largeNotes = false; - break; - - case 0xC4: // channel: large notes on - channel->largeNotes = true; - break; - - case 0xDF: // channel: set volume - cmd = (u8)cmdArgs[0]; - AudioSeq_SequenceChannelSetVolume(channel, cmd); - channel->changes.s.volume = true; - break; - - case 0xE0: // channel: set volume scale - cmd = (u8)cmdArgs[0]; - channel->volumeScale = (f32)(s32)cmd / 128.0f; - channel->changes.s.volume = true; - break; - - case 0xDE: // channel: set freqscale - cmdArgU16 = (u16)cmdArgs[0]; - channel->freqScale = (f32)(s32)cmdArgU16 / 0x8000; - channel->changes.s.freqScale = true; - break; - - case 0xD3: // channel: large bend pitch - cmd = (u8)cmdArgs[0]; - cmd += 0x80; - channel->freqScale = gBendPitchOneOctaveFrequencies[cmd]; - channel->changes.s.freqScale = true; - break; - - case 0xEE: // channel: small bend pitch - cmd = (u8)cmdArgs[0]; - cmd += 0x80; - channel->freqScale = gBendPitchTwoSemitonesFrequencies[cmd]; - channel->changes.s.freqScale = true; - break; - - case 0xDD: // channel: set pan - cmd = (u8)cmdArgs[0]; - channel->newPan = cmd; - channel->changes.s.pan = true; - break; - - case 0xDC: // channel: set pan mix - cmd = (u8)cmdArgs[0]; - channel->panChannelWeight = cmd; - channel->changes.s.pan = true; - break; - - case 0xDB: // channel: transpose - cmdArgS8 = (s8)cmdArgs[0]; - channel->transposition = cmdArgS8; - break; - - case 0xDA: // channel: set envelope - cmdArgU16 = (u16)cmdArgs[0]; - channel->adsr.envelope = (EnvelopePoint*)&seqPlayer->seqData[cmdArgU16]; - break; - - case 0xD9: // channel: set decay index - cmd = (u8)cmdArgs[0]; - channel->adsr.decayIndex = cmd; - break; - - case 0xD8: // channel: set vibrato depth - cmd = (u8)cmdArgs[0]; - channel->vibrato.vibratoDepthTarget = cmd * 8; - channel->vibrato.vibratoDepthStart = 0; - channel->vibrato.vibratoDepthChangeDelay = 0; - break; - - case 0xD7: // channel: set vibrato rate - cmd = (u8)cmdArgs[0]; - channel->vibrato.vibratoRateChangeDelay = 0; - channel->vibrato.vibratoRateTarget = cmd * 32; - channel->vibrato.vibratoRateStart = cmd * 32; - break; - - case 0xE2: // channel: set vibrato depth linear - cmd = (u8)cmdArgs[0]; - channel->vibrato.vibratoDepthStart = cmd * 8; - cmd = (u8)cmdArgs[1]; - channel->vibrato.vibratoDepthTarget = cmd * 8; - cmd = (u8)cmdArgs[2]; - channel->vibrato.vibratoDepthChangeDelay = cmd * 16; - break; - - case 0xE1: // channel: set vibratorate linear - cmd = (u8)cmdArgs[0]; - channel->vibrato.vibratoRateStart = cmd * 32; - cmd = (u8)cmdArgs[1]; - channel->vibrato.vibratoRateTarget = cmd * 32; - cmd = (u8)cmdArgs[2]; - channel->vibrato.vibratoRateChangeDelay = cmd * 16; - break; - - case 0xE3: // channel: set vibrato delay - cmd = (u8)cmdArgs[0]; - channel->vibrato.vibratoDelay = cmd * 16; - break; - - case 0xD4: // channel: set reverb volume - cmd = (u8)cmdArgs[0]; - channel->targetReverbVol = cmd; - break; - - case 0xC6: // channel: set soundFont - 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: // channel: write into sequence script - cmd = (u8)cmdArgs[0]; - cmdArgU16 = (u16)cmdArgs[1]; - seqData = &seqPlayer->seqData[cmdArgU16]; - seqData[0] = (u8)scriptState->value + cmd; - break; - - case 0xC8: // channel: subtract -> set value - case 0xCC: // channel: set value - case 0xC9: // channel: `bit and` -> set value - cmdArgS8 = (s8)cmdArgs[0]; - - if (cmd == 0xC8) { - scriptState->value -= cmdArgS8; - } else if (cmd == 0xCC) { - scriptState->value = cmdArgS8; - } else { - scriptState->value &= cmdArgS8; - } - break; - - case 0xCD: // channel: disable channel - cmd = (u8)cmdArgs[0]; - AudioSeq_SequenceChannelDisable(seqPlayer->channels[cmd]); - break; - - case 0xCA: // channel: set mute behavior - cmd = (u8)cmdArgs[0]; - channel->muteFlags = cmd; - channel->changes.s.volume = true; - break; - - case 0xCB: // channel: read sequence -> set value - cmdArgU16 = (u16)cmdArgs[0]; - scriptState->value = *(seqPlayer->seqData + (u32)(cmdArgU16 + scriptState->value)); - break; - - case 0xCE: // channel: - cmdArgU16 = (u16)cmdArgs[0]; - channel->unk_22 = cmdArgU16; - break; - - case 0xCF: // channel: write large into sequence script - cmdArgU16 = (u16)cmdArgs[0]; - seqData = &seqPlayer->seqData[cmdArgU16]; - seqData[0] = (channel->unk_22 >> 8) & 0xFF; - seqData[1] = channel->unk_22 & 0xFF; - break; - - case 0xD0: // channel: stereo headset effects - cmd = (u8)cmdArgs[0]; - if (cmd & 0x80) { - channel->stereoHeadsetEffects = true; - } else { - channel->stereoHeadsetEffects = false; - } - channel->stereoData.asByte = cmd & 0x7F; - break; - - case 0xD1: // channel: set note allocation policy - cmd = (u8)cmdArgs[0]; - channel->noteAllocPolicy = cmd; - break; - - case 0xD2: // channel: set sustain - cmd = (u8)cmdArgs[0]; - channel->adsr.sustain = cmd; - break; - - case 0xE5: // channel: set reverb index - cmd = (u8)cmdArgs[0]; - channel->reverbIndex = cmd; - break; - - case 0xE4: // channel: dyncall - if (scriptState->value != -1) { - data = (*channel->dynTable)[scriptState->value]; - depth = scriptState->depth; - //! @bug: Missing a stack depth check here - scriptState->stack[depth] = scriptState->pc; - scriptState->depth++; - cmdArgU16 = (u16)((data[0] << 8) + data[1]); - scriptState->pc = seqPlayer->seqData + cmdArgU16; - } - break; - - case 0xE6: // channel: set book offset - cmd = (u8)cmdArgs[0]; - channel->bookOffset = cmd; - break; - - case 0xE7: // channel: - cmdArgU16 = (u16)cmdArgs[0]; - data = &seqPlayer->seqData[cmdArgU16]; - channel->muteFlags = 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->targetReverbVol = data[-1]; - channel->reverbIndex = data[0]; - //! @bug: Not marking reverb state as changed - channel->changes.s.pan = true; - break; - - case 0xE8: // channel: - channel->muteFlags = 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->targetReverbVol = AudioSeq_ScriptReadU8(scriptState); - channel->reverbIndex = AudioSeq_ScriptReadU8(scriptState); - //! @bug: Not marking reverb state as changed - channel->changes.s.pan = true; - break; - - case 0xEC: // channel: reset vibrato - channel->vibrato.vibratoDepthTarget = 0; - channel->vibrato.vibratoDepthStart = 0; - channel->vibrato.vibratoDepthChangeDelay = 0; - channel->vibrato.vibratoRateTarget = 0; - channel->vibrato.vibratoRateStart = 0; - channel->vibrato.vibratoRateChangeDelay = 0; - channel->filter = NULL; - channel->gain = 0; - channel->adsr.sustain = 0; - channel->velocityRandomVariance = 0; - channel->gateTimeRandomVariance = 0; - channel->combFilterSize = 0; - channel->combFilterGain = 0; - channel->bookOffset = 0; - channel->startSamplePos = 0; - channel->unk_E0 = 0; - channel->freqScale = 1.0f; - break; - - case 0xE9: // channel: set note priority - AudioSeq_SetChannelPriorities(channel, (u8)cmdArgs[0]); - break; - - case 0xED: // channel: set hilo gain - cmd = (u8)cmdArgs[0]; - channel->gain = cmd; - break; - - case 0xB0: // channel: set filter - cmdArgU16 = (u16)cmdArgs[0]; - data = seqPlayer->seqData + cmdArgU16; - channel->filter = (s16*)data; - break; - - case 0xB1: // channel: clear filter - channel->filter = NULL; - break; - - case 0xB3: // channel: load filter - cmd = cmdArgs[0]; - - if (channel->filter != NULL) { - lowBits = (cmd >> 4) & 0xF; // LowPassCutoff - cmd &= 0xF; // HighPassCutoff - AudioHeap_LoadFilter(channel->filter, lowBits, cmd); - } - break; - - case 0xB2: // channel: dynread sequence large - cmdArgU16 = (u16)cmdArgs[0]; - channel->unk_22 = *(u16*)(seqPlayer->seqData + (u32)(cmdArgU16 + scriptState->value * 2)); - break; - - case 0xB4: // channel: set dyntable large - channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22]; - break; - - case 0xB5: // channel: read dyntable large - channel->unk_22 = ((u16*)(channel->dynTable))[scriptState->value]; - break; - - case 0xB6: // channel: read dyntable - scriptState->value = (*channel->dynTable)[0][scriptState->value]; - break; - - case 0xB7: // channel: random large - channel->unk_22 = - (cmdArgs[0] == 0) ? (gAudioCtx.audioRandom & 0xFFFF) : (gAudioCtx.audioRandom % cmdArgs[0]); - break; - - case 0xB8: // channel: random value - scriptState->value = - (cmdArgs[0] == 0) ? (gAudioCtx.audioRandom & 0xFFFF) : (gAudioCtx.audioRandom % cmdArgs[0]); - break; - - case 0xA8: // channel: random range large (only cmd that differs from OoT) - rand = AudioThread_NextRandom(); - channel->unk_22 = (cmdArgs[0] == 0) ? (rand & 0xFFFF) : (rand % 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: set velocity random variance - channel->velocityRandomVariance = cmdArgs[0]; - break; - - case 0xBA: // channel: set gatetime random variance - channel->gateTimeRandomVariance = cmdArgs[0]; - break; - - case 0xBB: // channel: - channel->combFilterSize = cmdArgs[0]; - channel->combFilterGain = cmdArgs[1]; - break; - - case 0xBC: // channel: add large - channel->unk_22 += cmdArgs[0]; - break; - - case 0xBD: // channel: - channel->startSamplePos = cmdArgs[0]; - break; - - case 0xBE: // channel: - if (cmdArgs[0] < 5) { - if (1) {} - if (gAudioCtx.customSeqFunctions[cmdArgs[0]] != NULL) { - gAudioCustomSeqFunction = gAudioCtx.customSeqFunctions[cmdArgs[0]]; - scriptState->value = gAudioCustomSeqFunction(scriptState->value, channel); - } - } - break; - - case 0xA0: // channel: read from SfxChannelState using arg - case 0xA1: // channel: read from SfxChannelState using unk_22 - case 0xA2: // channel: write to SfxChannelState using arg - case 0xA3: // channel: write to SfxChannelState using unk_22 - if ((cmd == 0xA0) || (cmd == 0xA2)) { - cmdArgU16 = (u16)cmdArgs[0]; - } else { - cmdArgU16 = channel->unk_22; - } - - if (channel->sfxState != NULL) { - if ((cmd == 0xA0) || (cmd == 0xA1)) { - scriptState->value = channel->sfxState[cmdArgU16]; - } else { - channel->sfxState[cmdArgU16] = scriptState->value; - } - } - break; - - case 0xA4: // channel: - channel->surroundEffectIndex = cmdArgs[0]; - break; - - case 0xA5: // channel: - scriptState->value += channel->channelIndex; - break; - - case 0xA6: // channel: - cmd = (u8)cmdArgs[0]; - cmdArgU16 = (u16)cmdArgs[1]; - seqData = seqPlayer->seqData + (u32)(cmdArgU16 + channel->channelIndex); - seqData[0] = (u8)scriptState->value + cmd; - break; - - case 0xA7: // channel: - new_var2 = (cmdArgs[0] & 0x80); - new_var = (scriptState->value & 0x80); - - if (!new_var2) { - phi_v0_3 = scriptState->value << (cmdArgs[0] & 0xF); - } else { - phi_v0_3 = scriptState->value >> (cmdArgs[0] & 0xF); - } - - if (cmdArgs[0] & 0x40) { - phi_v0_3 &= (u8)~0x80; - phi_v0_3 |= new_var; - } - - scriptState->value = phi_v0_3; - break; - } - continue; - } - - // Commands 0x70 - 0x9F - if (cmd >= 0x70) { - lowBits = cmd & 0x7; - - if (((cmd & 0xF8) != 0x70) && (lowBits >= 4)) { - lowBits = 0; - } - - switch (cmd & 0xF8) { - case 0x80: // channel: test layer is finished - if (channel->layers[lowBits] != NULL) { - scriptState->value = channel->layers[lowBits]->finished; - } else { - scriptState->value = -1; - } - break; - - case 0x88: // channel: set layer - cmdArgU16 = AudioSeq_ScriptReadS16(scriptState); - if (!AudioSeq_SeqChannelSetLayer(channel, lowBits)) { - channel->layers[lowBits]->scriptState.pc = &seqPlayer->seqData[cmdArgU16]; - } - break; - - case 0x90: // channel: free layer - AudioSeq_SeqLayerFree(channel, lowBits); - break; - - case 0x98: // channel: dynset layer - 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: io write value - channel->seqScriptIO[lowBits] = scriptState->value; - break; - - case 0x78: // channel: set layer relative - temp1 = AudioSeq_ScriptReadS16(scriptState); - if (!AudioSeq_SeqChannelSetLayer(channel, lowBits)) { - channel->layers[lowBits]->scriptState.pc = &scriptState->pc[temp1]; - } - break; - } - continue; - } - - // Commands 0x00 - 0x6F - lowBits = cmd & 0xF; - - switch (cmd & 0xF0) { - case 0x00: // channel: delay short - channel->delay = lowBits; - if (lowBits == 0) { - break; - } - goto exit_loop; - - case 0x10: // channel: load sample - if (lowBits < 8) { - channel->seqScriptIO[lowBits] = SEQ_IO_VAL_NONE; - if (AudioLoad_SlowLoadSample(channel->fontId, scriptState->value, &channel->seqScriptIO[lowBits]) == - -1) {} - } else { - lowBits -= 8; - channel->seqScriptIO[lowBits] = SEQ_IO_VAL_NONE; - if (AudioLoad_SlowLoadSample(channel->fontId, channel->unk_22 + 0x100, - &channel->seqScriptIO[lowBits]) == -1) {} - } - break; - - case 0x60: // channel: io read value - scriptState->value = channel->seqScriptIO[lowBits]; - if (lowBits < 2) { - channel->seqScriptIO[lowBits] = SEQ_IO_VAL_NONE; - } - break; - - case 0x50: // channel: io read value subtract - scriptState->value -= channel->seqScriptIO[lowBits]; - break; - - case 0x20: // channel: start channel - cmdArgU16 = AudioSeq_ScriptReadS16(scriptState); - AudioSeq_SequenceChannelEnable(seqPlayer, lowBits, &seqPlayer->seqData[cmdArgU16]); - break; - - case 0x30: // channel: io write value 2 - cmd = AudioSeq_ScriptReadU8(scriptState); - seqPlayer->channels[lowBits]->seqScriptIO[cmd] = scriptState->value; - break; - - case 0x40: // channel: io read value 2 - cmd = AudioSeq_ScriptReadU8(scriptState); - scriptState->value = seqPlayer->channels[lowBits]->seqScriptIO[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* data1; - u8* data2; - u8* data3; - u8* data4; - s32 tempoChange; - s32 j; - SequenceChannel* channel; - u16* new_var; - s32 delay; - - if (!seqPlayer->enabled) { - return; - } - - if (!AudioLoad_IsSeqLoadComplete(seqPlayer->seqId) || !AudioLoad_IsFontLoadComplete(seqPlayer->defaultFont)) { - // These function calls serve no purpose - if (AudioLoad_IsSeqLoadComplete(seqPlayer->seqId)) {} - if (AudioLoad_IsSeqLoadComplete(seqPlayer->defaultFont)) {} - - AudioSeq_SequencePlayerDisable(seqPlayer); - return; - } - - AudioLoad_SetSeqLoadStatus(seqPlayer->seqId, LOAD_STATUS_COMPLETE); - AudioLoad_SetFontLoadStatus(seqPlayer->defaultFont, LOAD_STATUS_COMPLETE); - - if (seqPlayer->muted && (seqPlayer->muteFlags & MUTE_FLAGS_STOP_SCRIPT)) { - return; - } - - seqPlayer->scriptCounter++; - - tempoChange = seqPlayer->tempo + seqPlayer->tempoChange; - if (tempoChange > gAudioCtx.maxTempo) { - tempoChange = gAudioCtx.maxTempo; - } - - seqPlayer->tempoAcc += tempoChange; - - if (seqPlayer->tempoAcc < gAudioCtx.maxTempo) { - return; - } - - seqPlayer->tempoAcc -= (u16)gAudioCtx.maxTempo; - seqPlayer->unk_16++; - - 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; - } - - // Commands 0xC0 - 0xF1 - if (cmd >= 0xC0) { - switch (cmd) { - case 0xF1: // seqPlayer: reserve notes - AudioPlayback_NotePoolClear(&seqPlayer->notePool); - cmd = AudioSeq_ScriptReadU8(seqScript); - AudioPlayback_NotePoolFill(&seqPlayer->notePool, cmd); - break; - - case 0xF0: // seqPlayer: unreserve notes - AudioPlayback_NotePoolClear(&seqPlayer->notePool); - break; - - case 0xDF: // seqPlayer: transpose - seqPlayer->transposition = 0; - // fallthrough - case 0xDE: // seqPlayer: transpose relative - seqPlayer->transposition += (s8)AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xDD: // seqPlayer: set tempo - seqPlayer->tempo = AudioSeq_ScriptReadU8(seqScript) * TATUMS_PER_BEAT; - if (seqPlayer->tempo > gAudioCtx.maxTempo) { - seqPlayer->tempo = gAudioCtx.maxTempo; - } - - if ((s16)seqPlayer->tempo <= 0) { - seqPlayer->tempo = 1; - } - break; - - case 0xDC: // seqPlayer: add tempo - seqPlayer->tempoChange = (s8)AudioSeq_ScriptReadU8(seqScript) * TATUMS_PER_BEAT; - break; - - case 0xDA: // seqPlayer: change volume - cmd = AudioSeq_ScriptReadU8(seqScript); - temp = AudioSeq_ScriptReadS16(seqScript); - switch (cmd) { - case SEQPLAYER_STATE_0: - case SEQPLAYER_STATE_FADE_IN: - if (seqPlayer->state != SEQPLAYER_STATE_FADE_OUT) { - seqPlayer->storedFadeTimer = temp; - seqPlayer->state = cmd; - } - break; - - case SEQPLAYER_STATE_FADE_OUT: - seqPlayer->fadeTimer = temp; - seqPlayer->state = cmd; - seqPlayer->fadeVelocity = (0.0f - seqPlayer->fadeVolume) / (s32)seqPlayer->fadeTimer; - break; - } - break; - - case 0xDB: // seqPlayer: set volume - value = AudioSeq_ScriptReadU8(seqScript); - switch (seqPlayer->state) { - case SEQPLAYER_STATE_FADE_IN: - seqPlayer->state = SEQPLAYER_STATE_0; - seqPlayer->fadeVolume = 0.0f; - // fallthrough - case SEQPLAYER_STATE_0: - seqPlayer->fadeTimer = seqPlayer->storedFadeTimer; - if (seqPlayer->storedFadeTimer != 0) { - seqPlayer->fadeVelocity = - ((value / 127.0f) - seqPlayer->fadeVolume) / (s32)seqPlayer->fadeTimer; - } else { - seqPlayer->fadeVolume = value / 127.0f; - } - break; - - case SEQPLAYER_STATE_FADE_OUT: - break; - } - break; - - case 0xD9: // seqPlayer: set volume scale - seqPlayer->fadeVolumeScale = (s8)AudioSeq_ScriptReadU8(seqScript) / 127.0f; - break; - - case 0xD7: // seqPlayer: initialize channels - temp = AudioSeq_ScriptReadS16(seqScript); - AudioSeq_SequencePlayerSetupChannels(seqPlayer, temp); - break; - - case 0xD6: // seqPlayer: disable channels - AudioSeq_ScriptReadS16(seqScript); - break; - - case 0xD5: // seqPlayer: set mute scale - seqPlayer->muteVolumeScale = (s8)AudioSeq_ScriptReadU8(seqScript) / 127.0f; - break; - - case 0xD4: // seqPlayer: mute - seqPlayer->muted = true; - break; - - case 0xD3: // seqPlayer: set mute behavior - seqPlayer->muteFlags = AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xD1: // seqPlayer: set short note gatetime table - case 0xD2: // seqPlayer: set short note velocity table - temp = AudioSeq_ScriptReadS16(seqScript); - data3 = &seqPlayer->seqData[temp]; - if (cmd == 0xD2) { - seqPlayer->shortNoteVelocityTable = data3; - } else { - seqPlayer->shortNoteGateTimeTable = data3; - } - break; - - case 0xD0: // seqPlayer: set note allocation policy - seqPlayer->noteAllocPolicy = AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xCE: // seqPlayer: random value - cmd = AudioSeq_ScriptReadU8(seqScript); - if (cmd == 0) { - seqScript->value = (gAudioCtx.audioRandom >> 2) & 0xFF; - } else { - seqScript->value = (gAudioCtx.audioRandom >> 2) % cmd; - } - break; - - case 0xCD: // seqPlayer: dyncall - temp = AudioSeq_ScriptReadS16(seqScript); - if ((seqScript->value != -1) && (seqScript->depth != 3)) { - data1 = seqPlayer->seqData + (u32)(temp + (seqScript->value << 1)); - seqScript->stack[seqScript->depth] = seqScript->pc; - seqScript->depth++; - temp = (data1[0] << 8) + data1[1]; - seqScript->pc = &seqPlayer->seqData[temp]; - } - break; - - case 0xCC: // seqPlayer: set value - seqScript->value = AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xC9: // seqPlayer: `bit and` -> set value - seqScript->value &= AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xC8: // seqPlayer: subtract -> set value - seqScript->value -= AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xC7: // seqPlayer: write into sequence script - cmd = AudioSeq_ScriptReadU8(seqScript); - temp = AudioSeq_ScriptReadS16(seqScript); - data2 = &seqPlayer->seqData[temp]; - *data2 = (u8)seqScript->value + cmd; - break; - - case 0xC2: // seqPlayer: - temp = AudioSeq_ScriptReadS16(seqScript); - if (seqScript->value != -1) { - data4 = seqPlayer->seqData + (u32)(temp + (seqScript->value << 1)); - - temp = (data4[0] << 8) + data4[1]; - seqScript->pc = &seqPlayer->seqData[temp]; - } - break; - - case 0xC6: // seqPlayer: stop script - seqPlayer->stopScript = true; - return; - - case 0xC5: // seqPlayer: - seqPlayer->unk_16 = AudioSeq_ScriptReadS16(seqScript); - break; - - case 0xEF: // seqPlayer: - AudioSeq_ScriptReadS16(seqScript); - AudioSeq_ScriptReadU8(seqScript); - break; - - case 0xC4: // seqPlayer: start sequence - cmd = AudioSeq_ScriptReadU8(seqScript); - if (cmd == 0xFF) { - cmd = seqPlayer->playerIndex; - if (seqPlayer->state == SEQPLAYER_STATE_FADE_OUT) { - break; - } - } - - cmdLowBits = AudioSeq_ScriptReadU8(seqScript); - AudioLoad_SyncInitSeqPlayer(cmd, cmdLowBits, 0); - if (cmd == (u8)seqPlayer->playerIndex) { - return; - } - break; - - case 0xC3: // seqPlayer: - temp = AudioSeq_ScriptReadS16(seqScript); - if (seqScript->value != -1) { - new_var = (u16*)(seqPlayer->seqData + (u32)(temp + seqScript->value * 2)); - temp = *new_var; - - for (i = 0; i < ARRAY_COUNT(seqPlayer->channels); i++) { - seqPlayer->channels[i]->muted = temp & 1; - temp = temp >> 1; - } - } - break; - } - continue; - } - - // Commands 0x00 - 0xBF - cmdLowBits = cmd & 0x0F; - - switch (cmd & 0xF0) { - case 0x00: // seqPlayer: test channel disabled - seqScript->value = seqPlayer->channels[cmdLowBits]->enabled ^ 1; - break; - - case 0x50: // seqPlayer: io read value subtract - seqScript->value -= seqPlayer->seqScriptIO[cmdLowBits]; - break; - - case 0x70: // seqPlayer: io write value - seqPlayer->seqScriptIO[cmdLowBits] = seqScript->value; - break; - - case 0x80: // seqPlayer: io read value - seqScript->value = seqPlayer->seqScriptIO[cmdLowBits]; - if (cmdLowBits < 2) { - seqPlayer->seqScriptIO[cmdLowBits] = SEQ_IO_VAL_NONE; - } - break; - - case 0x40: // seqPlayer: disable channel - AudioSeq_SequenceChannelDisable(seqPlayer->channels[cmdLowBits]); - break; - - case 0x90: // seqPlayer: start channel - temp = AudioSeq_ScriptReadS16(seqScript); - AudioSeq_SequenceChannelEnable(seqPlayer, cmdLowBits, (void*)&seqPlayer->seqData[temp]); - break; - - case 0xA0: // seqPlayer: start channel relative - tempS = AudioSeq_ScriptReadS16(seqScript); - AudioSeq_SequenceChannelEnable(seqPlayer, cmdLowBits, (void*)&seqScript->pc[tempS]); - break; - - case 0xB0: // seqPlayer: load sequence - cmd = AudioSeq_ScriptReadU8(seqScript); - temp = AudioSeq_ScriptReadS16(seqScript); - data2 = &seqPlayer->seqData[temp]; - AudioLoad_SlowLoadSeq(cmd, data2, &seqPlayer->seqScriptIO[cmdLowBits]); - break; - - case 0x60: // seqPlayer: async load - cmd = AudioSeq_ScriptReadU8(seqScript); - value = cmd; - temp = AudioSeq_ScriptReadU8(seqScript); - AudioLoad_ScriptLoad(value, temp, &seqPlayer->seqScriptIO[cmdLowBits]); - break; - } - } - } - - for (j = 0; j < SEQ_NUM_CHANNELS; j++) { - channel = seqPlayer->channels[j]; - if (channel->enabled) { - AudioSeq_SequenceChannelProcessScript(channel); - } - } -} - -void AudioSeq_ProcessSequences(s32 arg0) { - SequencePlayer* seqPlayer; - u32 i; - - gAudioCtx.sampleStateOffset = (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); - AudioEffects_SequencePlayerProcessSound(seqPlayer); - } - } - - AudioPlayback_ProcessNotes(); -} - -void AudioSeq_SkipForwardSequence(SequencePlayer* seqPlayer) { - while (seqPlayer->skipTicks > 0) { - AudioSeq_SequencePlayerProcessSequence(seqPlayer); - AudioEffects_SequencePlayerProcessSound(seqPlayer); - seqPlayer->skipTicks--; - } -} - -void AudioSeq_ResetSequencePlayer(SequencePlayer* seqPlayer) { - s32 channelIndex; - - AudioSeq_SequencePlayerDisable(seqPlayer); - seqPlayer->stopScript = false; - seqPlayer->delay = 0; - seqPlayer->state = SEQPLAYER_STATE_FADE_IN; - seqPlayer->fadeTimer = 0; - seqPlayer->storedFadeTimer = 0; - seqPlayer->tempoAcc = 0; - seqPlayer->tempo = 120 * TATUMS_PER_BEAT; // 120 BPM - seqPlayer->tempoChange = 0; - seqPlayer->transposition = 0; - seqPlayer->noteAllocPolicy = 0; - seqPlayer->shortNoteVelocityTable = gDefaultShortNoteVelocityTable; - seqPlayer->shortNoteGateTimeTable = gDefaultShortNoteGateTimeTable; - seqPlayer->scriptCounter = 0; - seqPlayer->unk_16 = 0; - seqPlayer->fadeVolume = 1.0f; - seqPlayer->fadeVelocity = 0.0f; - seqPlayer->volume = 0.0f; - seqPlayer->muteVolumeScale = 0.5f; - - for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) { - AudioSeq_InitSequenceChannel(seqPlayer->channels[channelIndex]); - } -} - -void AudioSeq_InitSequencePlayerChannels(s32 seqPlayerIndex) { - SequenceChannel* channel; - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex]; - s32 channelIndex; - s32 layerIndex; - - for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) { - seqPlayer->channels[channelIndex] = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(SequenceChannel)); - if (seqPlayer->channels[channelIndex] == NULL) { - seqPlayer->channels[channelIndex] = &gAudioCtx.sequenceChannelNone; - } else { - channel = seqPlayer->channels[channelIndex]; - channel->seqPlayer = seqPlayer; - channel->enabled = false; - channel->channelIndex = channelIndex; - for (layerIndex = 0; layerIndex < ARRAY_COUNT(channel->layers); layerIndex++) { - channel->layers[layerIndex] = NULL; - } - } - - AudioSeq_InitSequenceChannel(seqPlayer->channels[channelIndex]); - } -} - -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->seqScriptIO); j++) { - seqPlayer->seqScriptIO[j] = SEQ_IO_VAL_NONE; - } - - seqPlayer->muteFlags = MUTE_FLAGS_SOFTEN | MUTE_FLAGS_STOP_NOTES; - seqPlayer->fadeVolumeScale = 1.0f; - seqPlayer->bend = 1.0f; - - AudioPlayback_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/audio_sfx_params.c b/src/code/audio/audio_sfx_params.c deleted file mode 100644 index 0066328b1..000000000 --- a/src/code/audio/audio_sfx_params.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "global.h" - -#define DEFINE_SFX(_0, importance, distParam, randParam, flags2, flags1) \ - { importance, flags2, \ - ((((distParam) << SFX_PARAM_DIST_RANGE_SHIFT) & SFX_PARAM_DIST_RANGE_MASK) | \ - (((randParam) << SFX_PARAM_RAND_FREQ_RAISE_SHIFT) & SFX_PARAM_RAND_FREQ_RAISE_MASK) | (flags1)) }, - -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/audio/audio_synthesis.c b/src/code/audio/audio_synthesis.c deleted file mode 100644 index 057668f37..000000000 --- a/src/code/audio/audio_synthesis.c +++ /dev/null @@ -1,1697 +0,0 @@ -#include "global.h" - -// DMEM Addresses for the RSP -#define DMEM_TEMP 0x3B0 -#define DMEM_TEMP2 0x3C0 -#define DMEM_SURROUND_TEMP 0x4B0 -#define DMEM_UNCOMPRESSED_NOTE 0x570 -#define DMEM_HAAS_TEMP 0x5B0 -#define DMEM_COMB_TEMP 0x750 // = DMEM_TEMP + DMEM_2CH_SIZE + a bit more -#define DMEM_COMPRESSED_ADPCM_DATA 0x930 // = DMEM_LEFT_CH -#define DMEM_LEFT_CH 0x930 -#define DMEM_RIGHT_CH 0xAD0 -#define DMEM_WET_TEMP 0x3D0 -#define DMEM_WET_SCRATCH 0x710 // = DMEM_WET_TEMP + DMEM_2CH_SIZE -#define DMEM_WET_LEFT_CH 0xC70 -#define DMEM_WET_RIGHT_CH 0xE10 // = 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_SaveResampledReverbSamplesImpl(Acmd* cmd, u16 dmem, u16 size, uintptr_t startAddr); -Acmd* AudioSynth_LoadReverbSamplesImpl(Acmd* cmd, u16 dmem, u16 startPos, s32 size, SynthesisReverb* reverb); -Acmd* AudioSynth_SaveReverbSamplesImpl(Acmd* cmd, u16 dmem, u16 startPos, s32 size, SynthesisReverb* reverb); -Acmd* AudioSynth_ProcessSamples(s16* aiBuf, s32 numSamplesPerUpdate, Acmd* cmd, s32 updateIndex); -Acmd* AudioSynth_ProcessSample(s32 noteIndex, NoteSampleState* sampleState, NoteSynthesisState* synthState, s16* aiBuf, - s32 numSamplesPerUpdate, Acmd* cmd, s32 updateIndex); -Acmd* AudioSynth_ApplySurroundEffect(Acmd* cmd, NoteSampleState* sampleState, NoteSynthesisState* synthState, - s32 numSamplesPerUpdate, s32 haasDmem, s32 flags); -Acmd* AudioSynth_FinalResample(Acmd* cmd, NoteSynthesisState* synthState, s32 size, u16 pitch, u16 inpDmem, - s32 resampleFlags); -Acmd* AudioSynth_ProcessEnvelope(Acmd* cmd, NoteSampleState* sampleState, NoteSynthesisState* synthState, - s32 numSamplesPerUpdate, u16 dmemSrc, s32 haasEffectDelaySide, s32 flags); -Acmd* AudioSynth_LoadWaveSamples(Acmd* cmd, NoteSampleState* sampleState, NoteSynthesisState* synthState, - s32 numSamplesToLoad); -Acmd* AudioSynth_ApplyHaasEffect(Acmd* cmd, NoteSampleState* sampleState, NoteSynthesisState* synthState, s32 size, - s32 flags, s32 haasEffectDelaySide); - -s32 D_801D5FB0 = 0; - -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 = - AUDIO_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 = - AUDIO_MK_CMD(DMEM_LEFT_CH >> 4, DMEM_HAAS_TEMP >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); - -u32 sEnvMixerDefaultDmemDests = - AUDIO_MK_CMD(DMEM_LEFT_CH >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); - -// Unused Data -u16 D_801D5FC4[] = { - 0x7FFF, 0xD001, 0x3FFF, 0xF001, 0x5FFF, 0x9001, 0x7FFF, 0x8001, -}; - -u8 sNumSamplesPerWavePeriod[] = { - WAVE_SAMPLE_COUNT / 1, // 1st harmonic - WAVE_SAMPLE_COUNT / 2, // 2nd harmonic - WAVE_SAMPLE_COUNT / 4, // 4th harmonic - WAVE_SAMPLE_COUNT / 8, // 8th harmonic -}; - -/** - * Add a collection of s16-samples as a single entry to the reverb buffer - */ -void AudioSynth_AddReverbBufferEntry(s32 numSamples, s32 updateIndex, s32 reverbIndex) { - SynthesisReverb* reverb; - ReverbBufferEntry* entry; - s32 extraSamples; - s32 numSamplesAfterDownsampling; - s32 reverbBufPos; - s32 temp_t2; - s32 temp_t4; - s32 count1; - s32 count2; - s32 nextReverbSubBufPos; - - reverb = &gAudioCtx.synthesisReverbs[reverbIndex]; - entry = &reverb->bufEntry[reverb->curFrame][updateIndex]; - - numSamplesAfterDownsampling = numSamples / gAudioCtx.synthesisReverbs[reverbIndex].downsampleRate; - - // Apply resampling effect - if (gAudioCtx.synthesisReverbs[reverbIndex].resampleEffectOn) { - if (reverb->downsampleRate == 1) { - count1 = 0; - count2 = 0; - - numSamplesAfterDownsampling += reverb->resampleEffectExtraSamples; - - entry->saveResampleNumSamples = numSamplesAfterDownsampling; - entry->loadResamplePitch = ((u16)numSamplesAfterDownsampling << 0xF) / numSamples; - entry->saveResamplePitch = (numSamples << 0xF) / (u16)numSamplesAfterDownsampling; - - while (true) { - temp_t2 = (entry->loadResamplePitch * numSamples * 2) + reverb->resampleEffectLoadUnk; - temp_t4 = temp_t2 >> 0x10; - - if ((temp_t4 != numSamplesAfterDownsampling) && (count1 == 0)) { - entry->loadResamplePitch = - ((numSamplesAfterDownsampling << 0x10) - reverb->resampleEffectLoadUnk) / (numSamples * 2); - count1++; - } else { - count1++; - if (temp_t4 > numSamplesAfterDownsampling) { - entry->loadResamplePitch--; - } else if (temp_t4 < numSamplesAfterDownsampling) { - entry->loadResamplePitch++; - } else { - break; - } - } - } - - reverb->resampleEffectLoadUnk = temp_t2 & 0xFFFF; - - while (true) { - temp_t2 = (entry->saveResamplePitch * numSamplesAfterDownsampling * 2) + reverb->resampleEffectSaveUnk; - temp_t4 = temp_t2 >> 0x10; - - if ((temp_t4 != numSamples) && (count2 == 0)) { - entry->saveResamplePitch = - ((numSamples << 0x10) - reverb->resampleEffectSaveUnk) / (numSamplesAfterDownsampling * 2); - count2++; - } else { - count2++; - if (temp_t4 > numSamples) { - entry->saveResamplePitch--; - } else if (temp_t4 < numSamples) { - entry->saveResamplePitch++; - } else { - break; - } - } - } - - reverb->resampleEffectSaveUnk = temp_t2 & 0xFFFF; - } - } - - extraSamples = (reverb->nextReverbBufPos + numSamplesAfterDownsampling) - reverb->delayNumSamples; - reverbBufPos = reverb->nextReverbBufPos; - - // Add a reverb entry - if (extraSamples < 0) { - entry->size = numSamplesAfterDownsampling * SAMPLE_SIZE; - entry->wrappedSize = 0; - entry->startPos = reverb->nextReverbBufPos; - reverb->nextReverbBufPos += numSamplesAfterDownsampling; - } else { - // End of the buffer is reached. Loop back around - entry->size = (numSamplesAfterDownsampling - extraSamples) * SAMPLE_SIZE; - entry->wrappedSize = extraSamples * SAMPLE_SIZE; - entry->startPos = reverb->nextReverbBufPos; - reverb->nextReverbBufPos = extraSamples; - } - - entry->numSamplesAfterDownsampling = numSamplesAfterDownsampling; - entry->numSamples = numSamples; - - // Add a sub-reverb entry - if (reverb->subDelay != 0) { - nextReverbSubBufPos = reverb->subDelay + reverbBufPos; - if (nextReverbSubBufPos >= reverb->delayNumSamples) { - nextReverbSubBufPos -= reverb->delayNumSamples; - } - - entry = &reverb->subBufEntry[reverb->curFrame][updateIndex]; - numSamplesAfterDownsampling = numSamples / reverb->downsampleRate; - extraSamples = (nextReverbSubBufPos + numSamplesAfterDownsampling) - reverb->delayNumSamples; - - if (extraSamples < 0) { - entry->size = numSamplesAfterDownsampling * SAMPLE_SIZE; - entry->wrappedSize = 0; - entry->startPos = nextReverbSubBufPos; - } else { - // End of the buffer is reached. Loop back around - entry->size = (numSamplesAfterDownsampling - extraSamples) * SAMPLE_SIZE; - entry->wrappedSize = extraSamples * SAMPLE_SIZE; - entry->startPos = nextReverbSubBufPos; - } - - entry->numSamplesAfterDownsampling = numSamplesAfterDownsampling; - entry->numSamples = numSamples; - } -} - -/** - * Sync the sample states between the notes and the list - */ -void AudioSynth_SyncSampleStates(s32 updateIndex) { - NoteSampleState* noteSampleState; - NoteSampleState* sampleState; - s32 sampleStateBaseIndex; - s32 i; - - sampleStateBaseIndex = gAudioCtx.numNotes * updateIndex; - for (i = 0; i < gAudioCtx.numNotes; i++) { - noteSampleState = &gAudioCtx.notes[i].sampleState; - sampleState = &gAudioCtx.sampleStateList[sampleStateBaseIndex + i]; - if (noteSampleState->bitField0.enabled) { - noteSampleState->bitField0.needsInit = false; - } else { - sampleState->bitField0.enabled = false; - } - - noteSampleState->harmonicIndexCurAndPrev = 0; - } -} - -Acmd* AudioSynth_Update(Acmd* abiCmdStart, s32* numAbiCmds, s16* aiBufStart, s32 numSamplesPerFrame) { - s32 numSamplesPerUpdate; - s16* curAiBufPos; - Acmd* curCmd = abiCmdStart; - s32 reverseUpdateIndex; - s32 reverbIndex; - SynthesisReverb* reverb; - - for (reverseUpdateIndex = gAudioCtx.audioBufferParameters.updatesPerFrame; reverseUpdateIndex > 0; - reverseUpdateIndex--) { - AudioSeq_ProcessSequences(reverseUpdateIndex - 1); - AudioSynth_SyncSampleStates(gAudioCtx.audioBufferParameters.updatesPerFrame - reverseUpdateIndex); - } - - curAiBufPos = aiBufStart; - gAudioCtx.adpcmCodeBook = NULL; - - // Process/Update all samples multiple times in a single frame - for (reverseUpdateIndex = gAudioCtx.audioBufferParameters.updatesPerFrame; reverseUpdateIndex > 0; - reverseUpdateIndex--) { - if (reverseUpdateIndex == 1) { - // Final Update - numSamplesPerUpdate = numSamplesPerFrame; - } else if ((numSamplesPerFrame / reverseUpdateIndex) >= - gAudioCtx.audioBufferParameters.numSamplesPerUpdateMax) { - numSamplesPerUpdate = gAudioCtx.audioBufferParameters.numSamplesPerUpdateMax; - } else if ((numSamplesPerFrame / reverseUpdateIndex) <= - gAudioCtx.audioBufferParameters.numSamplesPerUpdateMin) { - numSamplesPerUpdate = gAudioCtx.audioBufferParameters.numSamplesPerUpdateMin; - } else { - numSamplesPerUpdate = gAudioCtx.audioBufferParameters.numSamplesPerUpdate; - } - - for (reverbIndex = 0; reverbIndex < gAudioCtx.numSynthesisReverbs; reverbIndex++) { - if (gAudioCtx.synthesisReverbs[reverbIndex].useReverb) { - AudioSynth_AddReverbBufferEntry(numSamplesPerUpdate, - gAudioCtx.audioBufferParameters.updatesPerFrame - reverseUpdateIndex, - reverbIndex); - } - } - - curCmd = AudioSynth_ProcessSamples(curAiBufPos, numSamplesPerUpdate, curCmd, - gAudioCtx.audioBufferParameters.updatesPerFrame - reverseUpdateIndex); - numSamplesPerFrame -= numSamplesPerUpdate; - curAiBufPos += numSamplesPerUpdate * SAMPLE_SIZE; - } - - // Update reverb frame info - for (reverbIndex = 0; reverbIndex < gAudioCtx.numSynthesisReverbs; reverbIndex++) { - if (gAudioCtx.synthesisReverbs[reverbIndex].framesToIgnore != 0) { - gAudioCtx.synthesisReverbs[reverbIndex].framesToIgnore--; - } - gAudioCtx.synthesisReverbs[reverbIndex].curFrame ^= 1; - } - - *numAbiCmds = curCmd - abiCmdStart; - return curCmd; -} - -void AudioSynth_DisableSampleStates(s32 updateIndex, s32 noteIndex) { - NoteSampleState* sampleState; - s32 i; - - for (i = updateIndex + 1; i < gAudioCtx.audioBufferParameters.updatesPerFrame; i++) { - sampleState = &gAudioCtx.sampleStateList[(gAudioCtx.numNotes * i) + noteIndex]; - if (sampleState->bitField0.needsInit) { - break; - } - sampleState->bitField0.enabled = false; - } -} - -/** - * Load reverb samples from a different reverb index - */ -Acmd* AudioSynth_LoadMixedReverbSamples(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) { - ReverbBufferEntry* entry = &reverb->bufEntry[reverb->curFrame][updateIndex]; - - cmd = AudioSynth_LoadReverbSamplesImpl(cmd, DMEM_WET_TEMP, entry->startPos, entry->size, reverb); - if (entry->wrappedSize != 0) { - // Ring buffer wrapped - cmd = AudioSynth_LoadReverbSamplesImpl(cmd, DMEM_WET_TEMP + entry->size, 0, entry->wrappedSize, reverb); - } - return cmd; -} - -/** - * Save reverb samples from a different reverb index - */ -Acmd* AudioSynth_SaveMixedReverbSamples(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) { - ReverbBufferEntry* entry = &reverb->bufEntry[reverb->curFrame][updateIndex]; - - cmd = AudioSynth_SaveReverbSamplesImpl(cmd, DMEM_WET_TEMP, entry->startPos, entry->size, reverb); - if (entry->wrappedSize != 0) { - // Ring buffer wrapped - cmd = AudioSynth_SaveReverbSamplesImpl(cmd, DMEM_WET_TEMP + entry->size, 0, entry->wrappedSize, reverb); - } - return cmd; -} - -void AudioSynth_Noop1(void) { -} - -void AudioSynth_ClearBuffer(Acmd* cmd, s32 dmem, s32 size) { - aClearBuffer(cmd, dmem, size); -} - -void AudioSynth_Noop2(void) { -} - -void AudioSynth_Noop3(void) { -} - -void AudioSynth_Noop4(void) { -} - -void AudioSynth_Mix(Acmd* cmd, size_t size, s32 gain, s32 dmemIn, s32 dmemOut) { - aMix(cmd, size, gain, dmemIn, dmemOut); -} - -void AudioSynth_Noop5(void) { -} - -void AudioSynth_Noop6(void) { -} - -void AudioSynth_Noop7(void) { -} - -void AudioSynth_SetBuffer(Acmd* cmd, s32 flags, s32 dmemIn, s32 dmemOut, size_t size) { - aSetBuffer(cmd, flags, dmemIn, dmemOut, size); -} - -void AudioSynth_Noop8(void) { -} - -void AudioSynth_Noop9(void) { -} - -void AudioSynth_DMemMove(Acmd* cmd, s32 dmemIn, s32 dmemOut, size_t size) { - // aDMEMMove(cmd, dmemIn, dmemOut, 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 AudioSynth_Noop10(void) { -} - -void AudioSynth_Noop11(void) { -} - -void AudioSynth_Noop12(void) { -} - -void AudioSynth_Noop13(void) { -} - -void AudioSynth_InterL(Acmd* cmd, s32 dmemIn, s32 dmemOut, s32 numSamples) { - // aInterl(cmd, dmemIn, dmemOut, 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 reverbVol, s32 rampReverb, s32 rampLeft, s32 rampRight) { - aEnvSetup1(cmd, reverbVol, rampReverb, rampLeft, rampRight); -} - -void AudioSynth_Noop14(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) { - // aEnvSetup2(cmd, volLeft, volRight); - cmd->words.w0 = _SHIFTL(A_ENVSETUP2, 24, 8); - cmd->words.w1 = _SHIFTL(volLeft, 16, 16) | _SHIFTL(volRight, 0, 16); -} - -void AudioSynth_Noop15(void) { -} - -void AudioSynth_Noop16(void) { -} - -void AudioSynth_Noop17(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) { - // aHiLoGain(cmd, gain, size, dmemIn, dmemOut); - 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); -} - -// Remnant of OoT -void AudioSynth_UnkCmd19(Acmd* cmd, s32 dmem1, s32 dmem2, s32 size, s32 arg4) { - cmd->words.w0 = _SHIFTL(A_SPNOOP, 24, 8) | _SHIFTL(arg4, 16, 8) | _SHIFTL(size, 0, 16); - cmd->words.w1 = _SHIFTL(dmem1, 16, 16) | _SHIFTL(dmem2, 0, 16); -} - -void AudioSynth_Noop18(void) { -} - -void AudioSynth_Noop19(void) { -} - -void AudioSynth_Noop20(void) { -} - -void AudioSynth_Noop21(void) { -} - -void AudioSynth_Noop22(void) { -} - -void AudioSynth_Noop23(void) { -} - -void AudioSynth_Noop24(void) { -} - -void AudioSynth_Noop25(void) { -} - -void AudioSynth_LoadFilterBuffer(Acmd* cmd, s32 flags, s32 buf, s16* addr) { - aFilter(cmd, flags, buf, addr); -} - -void AudioSynth_LoadFilterSize(Acmd* cmd, size_t size, s16* addr) { - aFilter(cmd, 2, size, addr); -} - -/** - * 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* AudioSynth_LoadDownsampledReverbSamples(Acmd* cmd, s32 numSamplesPerUpdate, SynthesisReverb* reverb, - s16 updateIndex) { - ReverbBufferEntry* entry = &reverb->bufEntry[reverb->curFrame][updateIndex]; - s16 offsetSize = (entry->startPos & 7) * SAMPLE_SIZE; - s16 wrappedOffsetSize = ALIGN16(offsetSize + entry->size); - - cmd = AudioSynth_LoadReverbSamplesImpl(cmd, DMEM_WET_TEMP, entry->startPos - (offsetSize / (s32)SAMPLE_SIZE), - DMEM_1CH_SIZE, reverb); - - if (entry->wrappedSize != 0) { - // Ring buffer wrapped - cmd = AudioSynth_LoadReverbSamplesImpl(cmd, DMEM_WET_TEMP + wrappedOffsetSize, 0, - DMEM_1CH_SIZE - wrappedOffsetSize, reverb); - } - - aSetBuffer(cmd++, 0, DMEM_WET_TEMP + offsetSize, DMEM_WET_LEFT_CH, numSamplesPerUpdate * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, reverb->downsamplePitch, reverb->leftLoadResampleBuf); - aSetBuffer(cmd++, 0, DMEM_WET_TEMP + DMEM_1CH_SIZE + offsetSize, DMEM_WET_RIGHT_CH, - numSamplesPerUpdate * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, reverb->downsamplePitch, reverb->rightLoadResampleBuf); - - return cmd; -} - -Acmd* AudioSynth_SaveResampledReverbSamples(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) { - ReverbBufferEntry* entry = &reverb->bufEntry[reverb->curFrame][updateIndex]; - s16 numSamples = entry->numSamples; - u32 size = numSamples * SAMPLE_SIZE; - - // Left Resample - aDMEMMove(cmd++, DMEM_WET_LEFT_CH, DMEM_WET_TEMP, size); - aSetBuffer(cmd++, 0, DMEM_WET_TEMP, DMEM_WET_SCRATCH, entry->saveResampleNumSamples * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, entry->saveResamplePitch, reverb->leftSaveResampleBuf); - - cmd = AudioSynth_SaveResampledReverbSamplesImpl(cmd, DMEM_WET_SCRATCH, entry->size, - &reverb->leftReverbBuf[entry->startPos]); - - if (entry->wrappedSize != 0) { - // Ring buffer wrapped - cmd = AudioSynth_SaveResampledReverbSamplesImpl(cmd, entry->size + DMEM_WET_SCRATCH, entry->wrappedSize, - reverb->leftReverbBuf); - } - - // Right Resample - aDMEMMove(cmd++, DMEM_WET_RIGHT_CH, DMEM_WET_TEMP, size); - aSetBuffer(cmd++, 0, DMEM_WET_TEMP, DMEM_WET_SCRATCH, entry->saveResampleNumSamples * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, entry->saveResamplePitch, reverb->rightSaveResampleBuf); - - cmd = AudioSynth_SaveResampledReverbSamplesImpl(cmd, DMEM_WET_SCRATCH, entry->size, - &reverb->rightReverbBuf[entry->startPos]); - - if (entry->wrappedSize != 0) { - // Ring buffer wrapped - cmd = AudioSynth_SaveResampledReverbSamplesImpl(cmd, entry->size + DMEM_WET_SCRATCH, entry->wrappedSize, - reverb->rightReverbBuf); - } - - return cmd; -} - -Acmd* AudioSynth_LoadResampledReverbSamples(Acmd* cmd, s32 numSamplesPerUpdate, SynthesisReverb* reverb, - s16 updateIndex) { - ReverbBufferEntry* entry = &reverb->bufEntry[reverb->curFrame][updateIndex]; - s16 offsetSize = (entry->startPos & 7) * SAMPLE_SIZE; - s16 wrappedOffsetSize = ALIGN16(offsetSize + entry->size); - - cmd = AudioSynth_LoadReverbSamplesImpl(cmd, DMEM_WET_TEMP, entry->startPos - (offsetSize / (s32)SAMPLE_SIZE), - DMEM_1CH_SIZE, reverb); - - if (entry->wrappedSize != 0) { - // Ring buffer wrapped - cmd = AudioSynth_LoadReverbSamplesImpl(cmd, wrappedOffsetSize + DMEM_WET_TEMP, 0, - DMEM_1CH_SIZE - wrappedOffsetSize, reverb); - } - - aSetBuffer(cmd++, 0, DMEM_WET_TEMP + offsetSize, DMEM_WET_LEFT_CH, numSamplesPerUpdate * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, entry->loadResamplePitch, reverb->leftLoadResampleBuf); - aSetBuffer(cmd++, 0, DMEM_WET_TEMP + DMEM_1CH_SIZE + offsetSize, DMEM_WET_RIGHT_CH, - numSamplesPerUpdate * SAMPLE_SIZE); - aResample(cmd++, reverb->resampleFlags, entry->loadResamplePitch, reverb->rightLoadResampleBuf); - - 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; -} - -/** - * Mix in reverb from a different reverb index - */ -Acmd* AudioSynth_MixOtherReverbIndex(Acmd* cmd, SynthesisReverb* reverb, s32 updateIndex) { - SynthesisReverb* mixReverb; - - if (reverb->mixReverbIndex >= gAudioCtx.numSynthesisReverbs) { - return cmd; - } - - mixReverb = &gAudioCtx.synthesisReverbs[reverb->mixReverbIndex]; - if (mixReverb->downsampleRate == 1) { - cmd = AudioSynth_LoadMixedReverbSamples(cmd, mixReverb, updateIndex); - aMix(cmd++, DMEM_2CH_SIZE >> 4, reverb->mixReverbStrength, DMEM_WET_LEFT_CH, DMEM_WET_TEMP); - cmd = AudioSynth_SaveMixedReverbSamples(cmd, mixReverb, updateIndex); - } - - return cmd; -} - -Acmd* AudioSynth_LoadDefaultReverbSamples(Acmd* cmd, s32 numSamplesPerUpdate, SynthesisReverb* reverb, - s16 updateIndex) { - ReverbBufferEntry* entry = &reverb->bufEntry[reverb->curFrame][updateIndex]; - - cmd = AudioSynth_LoadReverbSamplesImpl(cmd, DMEM_WET_LEFT_CH, entry->startPos, entry->size, reverb); - if (entry->wrappedSize != 0) { - // Ring buffer wrapped - cmd = AudioSynth_LoadReverbSamplesImpl(cmd, DMEM_WET_LEFT_CH + entry->size, 0, entry->wrappedSize, reverb); - } - - return cmd; -} - -Acmd* AudioSynth_LoadSubReverbSamples(Acmd* cmd, s32 numSamplesPerUpdate, SynthesisReverb* reverb, s16 updateIndex) { - ReverbBufferEntry* subEntry = &reverb->subBufEntry[reverb->curFrame][updateIndex]; - - cmd = AudioSynth_LoadReverbSamplesImpl(cmd, DMEM_WET_LEFT_CH, subEntry->startPos, subEntry->size, reverb); - if (subEntry->wrappedSize != 0) { - // Ring buffer wrapped - cmd = - AudioSynth_LoadReverbSamplesImpl(cmd, DMEM_WET_LEFT_CH + subEntry->size, 0, subEntry->wrappedSize, reverb); - } - - return cmd; -} - -Acmd* AudioSynth_SaveResampledReverbSamplesImpl(Acmd* cmd, u16 dmem, u16 size, uintptr_t startAddr) { - s32 startAddrAlignDropped; - u32 endAddr; - s32 endAddrAlignDropped; - - endAddr = startAddr + size; - - endAddrAlignDropped = endAddr & 0xF; - if (endAddrAlignDropped != 0) { - aLoadBuffer(cmd++, (endAddr - endAddrAlignDropped), DMEM_TEMP, 0x10); - aDMEMMove(cmd++, dmem, DMEM_TEMP2, size); - aDMEMMove(cmd++, DMEM_TEMP + endAddrAlignDropped, size + DMEM_TEMP2, 0x10 - endAddrAlignDropped); - - size += (0x10 - endAddrAlignDropped); - dmem = DMEM_TEMP2; - } - - startAddrAlignDropped = startAddr & 0xF; - if (startAddrAlignDropped != 0) { - aLoadBuffer(cmd++, startAddr - startAddrAlignDropped, DMEM_TEMP, 0x10); - aDMEMMove(cmd++, dmem, startAddrAlignDropped + DMEM_TEMP, size); - - size += startAddrAlignDropped; - dmem = DMEM_TEMP; - } - - aSaveBuffer(cmd++, dmem, startAddr - startAddrAlignDropped, size); - - return cmd; -} - -Acmd* AudioSynth_LoadReverbSamplesImpl(Acmd* cmd, u16 dmem, u16 startPos, s32 size, SynthesisReverb* reverb) { - aLoadBuffer(cmd++, &reverb->leftReverbBuf[startPos], dmem, size); - aLoadBuffer(cmd++, &reverb->rightReverbBuf[startPos], dmem + DMEM_1CH_SIZE, size); - - return cmd; -} - -Acmd* AudioSynth_SaveReverbSamplesImpl(Acmd* cmd, u16 dmem, u16 startPos, s32 size, SynthesisReverb* reverb) { - aSaveBuffer(cmd++, dmem, &reverb->leftReverbBuf[startPos], size); - aSaveBuffer(cmd++, dmem + DMEM_1CH_SIZE, &reverb->rightReverbBuf[startPos], size); - - return cmd; -} - -void AudioSynth_Noop26(void) { -} - -Acmd* AudioSynth_LoadSubReverbSamplesWithoutDownsample(Acmd* cmd, s32 numSamplesPerUpdate, SynthesisReverb* reverb, - s16 updateIndex) { - if (reverb->downsampleRate == 1) { - cmd = AudioSynth_LoadSubReverbSamples(cmd, numSamplesPerUpdate, reverb, updateIndex); - } - - return cmd; -} - -Acmd* AudioSynth_LoadReverbSamples(Acmd* cmd, s32 numSamplesPerUpdate, SynthesisReverb* reverb, s16 updateIndex) { - if (reverb->downsampleRate == 1) { - if (reverb->resampleEffectOn) { - cmd = AudioSynth_LoadResampledReverbSamples(cmd, numSamplesPerUpdate, reverb, updateIndex); - } else { - cmd = AudioSynth_LoadDefaultReverbSamples(cmd, numSamplesPerUpdate, reverb, updateIndex); - } - } else { - cmd = AudioSynth_LoadDownsampledReverbSamples(cmd, numSamplesPerUpdate, reverb, updateIndex); - } - - return cmd; -} - -Acmd* AudioSynth_SaveReverbSamples(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) { - ReverbBufferEntry* entry = &reverb->bufEntry[reverb->curFrame][updateIndex]; - s32 downsampleRate; - s32 numSamples; - - if (reverb->downsampleRate == 1) { - if (reverb->resampleEffectOn) { - cmd = AudioSynth_SaveResampledReverbSamples(cmd, reverb, updateIndex); - } else { - // Put the oldest samples in the ring buffer into the wet channels - cmd = AudioSynth_SaveReverbSamplesImpl(cmd, DMEM_WET_LEFT_CH, entry->startPos, entry->size, reverb); - if (entry->wrappedSize != 0) { - // Ring buffer wrapped - cmd = AudioSynth_SaveReverbSamplesImpl(cmd, DMEM_WET_LEFT_CH + entry->size, 0, entry->wrappedSize, - reverb); - } - } - } else { - //! FAKE: - if (1) {} - - downsampleRate = reverb->downsampleRate; - numSamples = 13 * SAMPLES_PER_FRAME; - - while (downsampleRate >= 2) { - aInterl(cmd++, DMEM_WET_LEFT_CH, DMEM_WET_LEFT_CH, numSamples); - aInterl(cmd++, DMEM_WET_RIGHT_CH, DMEM_WET_RIGHT_CH, numSamples); - downsampleRate >>= 1; - numSamples >>= 1; - } - - if (entry->size != 0) { - cmd = AudioSynth_SaveResampledReverbSamplesImpl(cmd, DMEM_WET_LEFT_CH, entry->size, - &reverb->leftReverbBuf[entry->startPos]); - cmd = AudioSynth_SaveResampledReverbSamplesImpl(cmd, DMEM_WET_RIGHT_CH, entry->size, - &reverb->rightReverbBuf[entry->startPos]); - } - - if (entry->wrappedSize != 0) { - cmd = AudioSynth_SaveResampledReverbSamplesImpl(cmd, entry->size + DMEM_WET_LEFT_CH, entry->wrappedSize, - reverb->leftReverbBuf); - cmd = AudioSynth_SaveResampledReverbSamplesImpl(cmd, entry->size + DMEM_WET_RIGHT_CH, entry->wrappedSize, - reverb->rightReverbBuf); - } - } - - reverb->resampleFlags = 0; - - return cmd; -} - -Acmd* AudioSynth_SaveSubReverbSamples(Acmd* cmd, SynthesisReverb* reverb, s16 updateIndex) { - ReverbBufferEntry* subEntry = &reverb->subBufEntry[reverb->curFrame][updateIndex]; - - cmd = AudioSynth_SaveReverbSamplesImpl(cmd, DMEM_WET_LEFT_CH, subEntry->startPos, subEntry->size, reverb); - if (subEntry->wrappedSize != 0) { - // Ring buffer wrapped - cmd = - AudioSynth_SaveReverbSamplesImpl(cmd, DMEM_WET_LEFT_CH + subEntry->size, 0, subEntry->wrappedSize, reverb); - } - - return cmd; -} - -/** - * Process all samples embedded in a note. Every sample has numSamplesPerUpdate processed, - * and each of those are mixed together into both DMEM_LEFT_CH and DMEM_RIGHT_CH - */ -Acmd* AudioSynth_ProcessSamples(s16* aiBuf, s32 numSamplesPerUpdate, Acmd* cmd, s32 updateIndex) { - s32 size; - u8 noteIndices[0x58]; - s16 noteCount = 0; - s16 reverbIndex; - SynthesisReverb* reverb; - s32 useReverb; - s32 sampleStateOffset = gAudioCtx.numNotes * updateIndex; - s32 i; - - if (gAudioCtx.numSynthesisReverbs == 0) { - for (i = 0; i < gAudioCtx.numNotes; i++) { - if (gAudioCtx.sampleStateList[sampleStateOffset + i].bitField0.enabled) { - noteIndices[noteCount++] = i; - } - } - } else { - NoteSampleState* sampleState; - - for (reverbIndex = 0; reverbIndex < gAudioCtx.numSynthesisReverbs; reverbIndex++) { - for (i = 0; i < gAudioCtx.numNotes; i++) { - sampleState = &gAudioCtx.sampleStateList[sampleStateOffset + i]; - if (sampleState->bitField0.enabled && (sampleState->bitField1.reverbIndex == reverbIndex)) { - noteIndices[noteCount++] = i; - } - } - } - - for (i = 0; i < gAudioCtx.numNotes; i++) { - sampleState = &gAudioCtx.sampleStateList[sampleStateOffset + i]; - if (sampleState->bitField0.enabled && - (sampleState->bitField1.reverbIndex >= gAudioCtx.numSynthesisReverbs)) { - noteIndices[noteCount++] = i; - } - } - } - - aClearBuffer(cmd++, DMEM_LEFT_CH, DMEM_2CH_SIZE); - - i = 0; - for (reverbIndex = 0; reverbIndex < gAudioCtx.numSynthesisReverbs; reverbIndex++) { - s32 subDelay; - NoteSampleState* sampleState; - - reverb = &gAudioCtx.synthesisReverbs[reverbIndex]; - useReverb = reverb->useReverb; - if (useReverb) { - - // Loads reverb samples from DRAM (ringBuffer) into DMEM (DMEM_WET_LEFT_CH) - cmd = AudioSynth_LoadReverbSamples(cmd, numSamplesPerUpdate, 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 reverbs. - // So 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); - - subDelay = reverb->subDelay; - if (subDelay != 0) { - 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); - - if (((reverb->leakRtl != 0) || (reverb->leakLtr != 0)) && (gAudioCtx.soundMode != SOUNDMODE_MONO)) { - cmd = AudioSynth_LeakReverb(cmd, reverb); - } - - if (subDelay != 0) { - if (reverb->mixReverbIndex != REVERB_INDEX_NONE) { - cmd = AudioSynth_MixOtherReverbIndex(cmd, reverb, updateIndex); - } - cmd = AudioSynth_SaveReverbSamples(cmd, reverb, updateIndex); - cmd = AudioSynth_LoadSubReverbSamplesWithoutDownsample(cmd, numSamplesPerUpdate, reverb, updateIndex); - aMix(cmd++, DMEM_2CH_SIZE >> 4, reverb->subVolume, DMEM_WET_TEMP, DMEM_WET_LEFT_CH); - } - } - - while (i < noteCount) { - sampleState = &gAudioCtx.sampleStateList[sampleStateOffset + noteIndices[i]]; - if (sampleState->bitField1.reverbIndex != reverbIndex) { - break; - } - cmd = AudioSynth_ProcessSample(noteIndices[i], sampleState, &gAudioCtx.notes[noteIndices[i]].synthesisState, - aiBuf, numSamplesPerUpdate, cmd, updateIndex); - i++; - } - - if (useReverb) { - if ((reverb->filterLeft != NULL) || (reverb->filterRight != NULL)) { - cmd = AudioSynth_FilterReverb(cmd, numSamplesPerUpdate * SAMPLE_SIZE, reverb); - } - - // Saves the wet channel sample from DMEM (DMEM_WET_LEFT_CH) into (ringBuffer) DRAM for future use - if (subDelay != 0) { - cmd = AudioSynth_SaveSubReverbSamples(cmd, reverb, updateIndex); - } else { - if (reverb->mixReverbIndex != REVERB_INDEX_NONE) { - cmd = AudioSynth_MixOtherReverbIndex(cmd, reverb, updateIndex); - } - cmd = AudioSynth_SaveReverbSamples(cmd, reverb, updateIndex); - } - } - } - - while (i < noteCount) { - cmd = AudioSynth_ProcessSample(noteIndices[i], &gAudioCtx.sampleStateList[sampleStateOffset + noteIndices[i]], - &gAudioCtx.notes[noteIndices[i]].synthesisState, aiBuf, numSamplesPerUpdate, cmd, - updateIndex); - i++; - } - - size = numSamplesPerUpdate * SAMPLE_SIZE; - aInterleave(cmd++, DMEM_TEMP, DMEM_LEFT_CH, DMEM_RIGHT_CH, size); - - if (gAudioCustomSynthFunction != NULL) { - cmd = gAudioCustomSynthFunction(cmd, 2 * size, updateIndex); - } - aSaveBuffer(cmd++, DMEM_TEMP, aiBuf, 2 * size); - - return cmd; -} - -Acmd* AudioSynth_ProcessSample(s32 noteIndex, NoteSampleState* sampleState, NoteSynthesisState* synthState, s16* aiBuf, - s32 numSamplesPerUpdate, Acmd* cmd, s32 updateIndex) { - s32 pad1[2]; - void* reverbAddrSrc; - Sample* sample; - AdpcmLoop* loopInfo; - s32 numSamplesUntilEnd; - s32 numSamplesInThisIteration; - s32 sampleFinished; - s32 loopToPoint; - s32 flags; - u16 frequencyFixedPoint; - s32 gain; - s32 frameIndex; - s32 skipBytes; - void* combFilterState; - s32 numSamplesToDecode; - s32 numFirstFrameSamplesToIgnore; - u8* sampleAddr; - u32 numSamplesToLoadFixedPoint; - s32 numSamplesToLoadAdj; - s32 numSamplesProcessed; - s32 sampleEndPos; - s32 numSamplesToProcess; - s32 dmemUncompressedAddrOffset2; - s32 pad2[3]; - s32 numSamplesInFirstFrame; - s32 numTrailingSamplesToIgnore; - s32 pad3[3]; - s32 frameSize; - s32 numFramesToDecode; - s32 skipInitialSamples; - s32 zeroOffset; - u8* samplesToLoadAddr; - s32 numParts; - s32 curPart; - s32 sampleDataChunkAlignPad; - s32 haasEffectDelaySide; - s32 numSamplesToLoadFirstPart; - u16 sampleDmemBeforeResampling; - s32 sampleAddrOffset; - s32 combFilterDmem; - s32 dmemUncompressedAddrOffset1; - Note* note; - u32 numSamplesToLoad; - u16 combFilterSize; - u16 combFilterGain; - s16* filter; - s32 bookOffset = sampleState->bitField1.bookOffset; - s32 finished = sampleState->bitField0.finished; - s32 sampleDataChunkSize; - s16 sampleDataDmemAddr; - - note = &gAudioCtx.notes[noteIndex]; - flags = A_CONTINUE; - - // Initialize the synthesis state - if (sampleState->bitField0.needsInit == true) { - flags = A_INIT; - synthState->atLoopPoint = false; - synthState->stopLoop = false; - synthState->samplePosInt = note->playbackState.startSamplePos; - synthState->samplePosFrac = 0; - synthState->curVolLeft = 0; - synthState->curVolRight = 0; - synthState->prevHaasEffectLeftDelaySize = 0; - synthState->prevHaasEffectRightDelaySize = 0; - synthState->curReverbVol = sampleState->targetReverbVol; - synthState->numParts = 0; - synthState->combFilterNeedsInit = true; - note->sampleState.bitField0.finished = false; - synthState->unk_1F = note->playbackState.unk_80; // Never set, never used - finished = false; - } - - // Process the sample in either one or two parts - numParts = sampleState->bitField1.hasTwoParts + 1; - - // Determine number of samples to load based on numSamplesPerUpdate and relative frequency - frequencyFixedPoint = sampleState->frequencyFixedPoint; - numSamplesToLoadFixedPoint = (frequencyFixedPoint * numSamplesPerUpdate * 2) + synthState->samplePosFrac; - numSamplesToLoad = numSamplesToLoadFixedPoint >> 16; - - if (numSamplesToLoad == 0) { - skipBytes = false; - } - - synthState->samplePosFrac = numSamplesToLoadFixedPoint & 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) && (numParts == 2)) { - } else if ((synthState->numParts == 2) && (numParts == 1)) { - } else { - } - - synthState->numParts = numParts; - - if (sampleState->bitField1.isSyntheticWave) { - cmd = AudioSynth_LoadWaveSamples(cmd, sampleState, synthState, numSamplesToLoad); - sampleDmemBeforeResampling = DMEM_UNCOMPRESSED_NOTE + (synthState->samplePosInt * 2); - synthState->samplePosInt += numSamplesToLoad; - } else { - sample = sampleState->tunedSample->sample; - loopInfo = sample->loop; - - if (note->playbackState.status != PLAYBACK_STATUS_0) { - synthState->stopLoop = true; - } - - if ((loopInfo->count == 2) && synthState->stopLoop) { - sampleEndPos = loopInfo->sampleEnd; - } else { - sampleEndPos = loopInfo->loopEnd; - } - - sampleAddr = sample->sampleAddr; - numSamplesToLoadFirstPart = 0; - - // If the frequency requested is more than double that of the raw sample, - // then the sample processing is split into two parts. - for (curPart = 0; curPart < numParts; curPart++) { - numSamplesProcessed = 0; - dmemUncompressedAddrOffset1 = 0; - - // Adjust the number of samples to load only if there are two parts and an odd number of samples - if (numParts == 1) { - numSamplesToLoadAdj = numSamplesToLoad; - } else if (numSamplesToLoad & 1) { - // round down for the first part - // round up for the second part - numSamplesToLoadAdj = (numSamplesToLoad & ~1) + (curPart * 2); - } else { - numSamplesToLoadAdj = numSamplesToLoad; - } - - // Load the ADPCM codeBook - if ((sample->codec == CODEC_ADPCM) || (sample->codec == CODEC_SMALL_ADPCM)) { - if (gAudioCtx.adpcmCodeBook != sample->book->codeBook) { - u32 numEntries; - - switch (bookOffset) { - case 1: - gAudioCtx.adpcmCodeBook = &gInvalidAdpcmCodeBook[1]; - break; - - case 2: - case 3: - default: - gAudioCtx.adpcmCodeBook = sample->book->codeBook; - break; - } - - numEntries = SAMPLES_PER_FRAME * sample->book->order * sample->book->numPredictors; - aLoadADPCM(cmd++, numEntries, gAudioCtx.adpcmCodeBook); - } - } - - // Continue processing samples until the number of samples needed to load is reached - while (numSamplesProcessed != numSamplesToLoadAdj) { - sampleFinished = false; - loopToPoint = false; - dmemUncompressedAddrOffset2 = 0; - - numFirstFrameSamplesToIgnore = synthState->samplePosInt & 0xF; - numSamplesUntilEnd = sampleEndPos - synthState->samplePosInt; - - // Calculate number of samples to process this loop - numSamplesToProcess = numSamplesToLoadAdj - numSamplesProcessed; - - if ((numFirstFrameSamplesToIgnore == 0) && !synthState->atLoopPoint) { - numFirstFrameSamplesToIgnore = SAMPLES_PER_FRAME; - } - numSamplesInFirstFrame = SAMPLES_PER_FRAME - numFirstFrameSamplesToIgnore; - - // Determine the number of samples to decode based on whether the end will be reached or not. - if (numSamplesToProcess < numSamplesUntilEnd) { - // The end will not be reached. - numFramesToDecode = - (s32)(numSamplesToProcess - numSamplesInFirstFrame + SAMPLES_PER_FRAME - 1) / SAMPLES_PER_FRAME; - numSamplesToDecode = numFramesToDecode * SAMPLES_PER_FRAME; - numTrailingSamplesToIgnore = numSamplesInFirstFrame + numSamplesToDecode - numSamplesToProcess; - } else { - // The end will be reached. - numSamplesToDecode = numSamplesUntilEnd - numSamplesInFirstFrame; - numTrailingSamplesToIgnore = 0; - if (numSamplesToDecode <= 0) { - numSamplesToDecode = 0; - numSamplesInFirstFrame = numSamplesUntilEnd; - } - numFramesToDecode = (numSamplesToDecode + SAMPLES_PER_FRAME - 1) / SAMPLES_PER_FRAME; - if (loopInfo->count != 0) { - if ((loopInfo->count == 2) && synthState->stopLoop) { - sampleFinished = true; - } else { - // Loop around and restart - loopToPoint = true; - } - } else { - sampleFinished = true; - } - } - - // Set parameters based on compression type - 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; - zeroOffset = 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; - zeroOffset = 0; - break; - - case CODEC_UNK7: - // 2 2-byte samples (4 bytes) processed without decompression - frameSize = 4; - skipInitialSamples = SAMPLES_PER_FRAME; - zeroOffset = 0; - break; - - case CODEC_S8: - // 16 2-byte samples (32 bytes) compressed into 8-bit samples (16 bytes) - frameSize = 16; - skipInitialSamples = SAMPLES_PER_FRAME; - zeroOffset = 0; - break; - - case CODEC_REVERB: - reverbAddrSrc = (void*)0xFFFFFFFF; - if (gAudioCustomReverbFunction != NULL) { - reverbAddrSrc = gAudioCustomReverbFunction(sample, numSamplesToLoadAdj, flags, noteIndex); - } - - if (reverbAddrSrc == (void*)0xFFFFFFFF) { - sampleFinished = true; - } else if (reverbAddrSrc == NULL) { - return cmd; - } else { - AudioSynth_LoadBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, - (numSamplesToLoadAdj + SAMPLES_PER_FRAME) * SAMPLE_SIZE, - reverbAddrSrc); - flags = A_CONTINUE; - skipBytes = 0; - numSamplesProcessed = numSamplesToLoadAdj; - dmemUncompressedAddrOffset1 = numSamplesToLoadAdj; - } - goto skip; - - case CODEC_S16_INMEMORY: - case CODEC_UNK6: - AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, - (numSamplesToLoadAdj + SAMPLES_PER_FRAME) * SAMPLE_SIZE); - flags = A_CONTINUE; - skipBytes = 0; - numSamplesProcessed = numSamplesToLoadAdj; - dmemUncompressedAddrOffset1 = numSamplesToLoadAdj; - goto skip; - - case CODEC_S16: - AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, - (numSamplesToLoadAdj + SAMPLES_PER_FRAME) * SAMPLE_SIZE); - flags = A_CONTINUE; - skipBytes = 0; - numSamplesProcessed = numSamplesToLoadAdj; - dmemUncompressedAddrOffset1 = numSamplesToLoadAdj; - goto skip; - - default: - break; - } - - // Move the compressed raw sample data from ram into the rsp (DMEM) - if (numFramesToDecode != 0) { - // Get the offset from the start of the sample to where the sample is currently playing from - frameIndex = (synthState->samplePosInt + skipInitialSamples - numFirstFrameSamplesToIgnore) / - SAMPLES_PER_FRAME; - sampleAddrOffset = frameIndex * frameSize; - - // Get the ram address of the requested sample chunk - if (sample->medium == MEDIUM_RAM) { - // Sample is already loaded into ram - samplesToLoadAddr = sampleAddr + (zeroOffset + sampleAddrOffset); - } else if (gAudioCtx.unk_29B8) { // always false - return cmd; - } else if (sample->medium == MEDIUM_UNK) { - // This medium is unsupported so terminate processing this note - return cmd; - } else { - // This medium is not in ram, so dma the requested sample into ram - samplesToLoadAddr = - AudioLoad_DmaSampleData(sampleAddr + (zeroOffset + sampleAddrOffset), - ALIGN16((numFramesToDecode * frameSize) + SAMPLES_PER_FRAME), flags, - &synthState->sampleDmaIndex, sample->medium); - } - - if (samplesToLoadAddr == NULL) { - // The ram address was unsuccessfully allocated - return cmd; - } - - // Move the raw sample chunk from ram to the rsp - // DMEM at the addresses before DMEM_COMPRESSED_ADPCM_DATA - sampleDataChunkAlignPad = (u32)samplesToLoadAddr & 0xF; - sampleDataChunkSize = ALIGN16((numFramesToDecode * frameSize) + SAMPLES_PER_FRAME); - sampleDataDmemAddr = DMEM_COMPRESSED_ADPCM_DATA - sampleDataChunkSize; - aLoadBuffer(cmd++, samplesToLoadAddr - sampleDataChunkAlignPad, sampleDataDmemAddr, - sampleDataChunkSize); - } else { - numSamplesToDecode = 0; - sampleDataChunkAlignPad = 0; - } - - if (synthState->atLoopPoint) { - aSetLoop(cmd++, sample->loop->predictorState); - flags = A_LOOP; - synthState->atLoopPoint = false; - } - - numSamplesInThisIteration = numSamplesToDecode + numSamplesInFirstFrame - numTrailingSamplesToIgnore; - - if (numSamplesProcessed == 0) { - //! FAKE: - if (1) {} - skipBytes = numFirstFrameSamplesToIgnore * SAMPLE_SIZE; - } else { - dmemUncompressedAddrOffset2 = ALIGN16(dmemUncompressedAddrOffset1 + 8 * SAMPLE_SIZE); - } - - // Decompress the raw sample chunks in the rsp - // Goes from adpcm (compressed) sample data to pcm (uncompressed) sample data - switch (sample->codec) { - case CODEC_ADPCM: - sampleDataChunkSize = ALIGN16((numFramesToDecode * frameSize) + SAMPLES_PER_FRAME); - sampleDataDmemAddr = DMEM_COMPRESSED_ADPCM_DATA - sampleDataChunkSize; - aSetBuffer(cmd++, 0, sampleDataDmemAddr + sampleDataChunkAlignPad, - DMEM_UNCOMPRESSED_NOTE + dmemUncompressedAddrOffset2, - numSamplesToDecode * SAMPLE_SIZE); - aADPCMdec(cmd++, flags, synthState->synthesisBuffers->adpcmState); - break; - - case CODEC_SMALL_ADPCM: - sampleDataChunkSize = ALIGN16((numFramesToDecode * frameSize) + SAMPLES_PER_FRAME); - sampleDataDmemAddr = DMEM_COMPRESSED_ADPCM_DATA - sampleDataChunkSize; - aSetBuffer(cmd++, 0, sampleDataDmemAddr + sampleDataChunkAlignPad, - DMEM_UNCOMPRESSED_NOTE + dmemUncompressedAddrOffset2, - numSamplesToDecode * SAMPLE_SIZE); - aADPCMdec(cmd++, flags | A_ADPCM_SHORT, synthState->synthesisBuffers->adpcmState); - break; - - case CODEC_S8: - sampleDataChunkSize = ALIGN16((numFramesToDecode * frameSize) + SAMPLES_PER_FRAME); - sampleDataDmemAddr = DMEM_COMPRESSED_ADPCM_DATA - sampleDataChunkSize; - AudioSynth_SetBuffer(cmd++, 0, sampleDataDmemAddr + sampleDataChunkAlignPad, - DMEM_UNCOMPRESSED_NOTE + dmemUncompressedAddrOffset2, - numSamplesToDecode * SAMPLE_SIZE); - AudioSynth_S8Dec(cmd++, flags, synthState->synthesisBuffers->adpcmState); - break; - - case CODEC_UNK7: - default: - // No decompression - break; - } - - if (numSamplesProcessed != 0) { - aDMEMMove(cmd++, - DMEM_UNCOMPRESSED_NOTE + dmemUncompressedAddrOffset2 + - (numFirstFrameSamplesToIgnore * SAMPLE_SIZE), - DMEM_UNCOMPRESSED_NOTE + dmemUncompressedAddrOffset1, - numSamplesInThisIteration * SAMPLE_SIZE); - } - - numSamplesProcessed += numSamplesInThisIteration; - - switch (flags) { - case A_INIT: - skipBytes = SAMPLES_PER_FRAME * SAMPLE_SIZE; - dmemUncompressedAddrOffset1 = (numSamplesToDecode + SAMPLES_PER_FRAME) * SAMPLE_SIZE; - break; - - case A_LOOP: - dmemUncompressedAddrOffset1 = - numSamplesInThisIteration * SAMPLE_SIZE + dmemUncompressedAddrOffset1; - break; - - default: - if (dmemUncompressedAddrOffset1 != 0) { - dmemUncompressedAddrOffset1 = - numSamplesInThisIteration * SAMPLE_SIZE + dmemUncompressedAddrOffset1; - } else { - dmemUncompressedAddrOffset1 = - (numFirstFrameSamplesToIgnore + numSamplesInThisIteration) * SAMPLE_SIZE; - } - break; - } - - flags = A_CONTINUE; - - skip: - - // Update what to do with the samples next - if (sampleFinished) { - if ((numSamplesToLoadAdj - numSamplesProcessed) != 0) { - AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE + dmemUncompressedAddrOffset1, - (numSamplesToLoadAdj - numSamplesProcessed) * SAMPLE_SIZE); - } - finished = true; - note->sampleState.bitField0.finished = true; - AudioSynth_DisableSampleStates(updateIndex, noteIndex); - break; // break out of the for-loop - } else if (loopToPoint) { - synthState->atLoopPoint = true; - synthState->samplePosInt = loopInfo->start; - } else { - synthState->samplePosInt += numSamplesToProcess; - } - } - - switch (numParts) { - 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(numSamplesToLoadAdj / 2)); - numSamplesToLoadFirstPart = numSamplesToLoadAdj; - sampleDmemBeforeResampling = DMEM_TEMP + (SAMPLES_PER_FRAME * SAMPLE_SIZE); - if (finished) { - AudioSynth_ClearBuffer(cmd++, sampleDmemBeforeResampling + numSamplesToLoadFirstPart, - numSamplesToLoadAdj + SAMPLES_PER_FRAME); - } - break; - - case 1: - AudioSynth_InterL(cmd++, DMEM_UNCOMPRESSED_NOTE + skipBytes, - DMEM_TEMP + (SAMPLES_PER_FRAME * SAMPLE_SIZE) + numSamplesToLoadFirstPart, - ALIGN8(numSamplesToLoadAdj / 2)); - break; - - default: - break; - } - break; - - default: - break; - } - if (finished) { - break; - } - } - } - - // Update the flags for the signal processing below - flags = A_CONTINUE; - if (sampleState->bitField0.needsInit == true) { - sampleState->bitField0.needsInit = false; - flags = A_INIT; - } - - // Resample the decompressed mono-signal to the correct pitch - cmd = AudioSynth_FinalResample(cmd, synthState, numSamplesPerUpdate * SAMPLE_SIZE, frequencyFixedPoint, - sampleDmemBeforeResampling, flags); - - // UnkCmd19 was removed from the audio microcode - // This block performs no operation - if (bookOffset == 3) { - AudioSynth_UnkCmd19(cmd++, DMEM_TEMP, DMEM_TEMP, numSamplesPerUpdate * (s32)SAMPLE_SIZE, 0); - } - - // Apply the gain to the mono-signal to adjust the volume - gain = sampleState->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, (numSamplesPerUpdate + SAMPLES_PER_FRAME) * SAMPLE_SIZE); - } - - // Apply the filter to the mono-signal - filter = sampleState->filter; - if (filter != 0) { - AudioSynth_LoadFilterSize(cmd++, numSamplesPerUpdate * SAMPLE_SIZE, filter); - AudioSynth_LoadFilterBuffer(cmd++, flags, DMEM_TEMP, synthState->synthesisBuffers->filterState); - } - - // Apply the comb filter to the mono-signal by taking the signal with a small temporal offset, - // and adding it back to itself - combFilterSize = sampleState->combFilterSize; - combFilterGain = sampleState->combFilterGain; - combFilterState = synthState->synthesisBuffers->combFilterState; - if ((combFilterSize != 0) && (sampleState->combFilterGain != 0)) { - AudioSynth_DMemMove(cmd++, DMEM_TEMP, DMEM_COMB_TEMP, numSamplesPerUpdate * SAMPLE_SIZE); - combFilterDmem = DMEM_COMB_TEMP - combFilterSize; - if (synthState->combFilterNeedsInit) { - AudioSynth_ClearBuffer(cmd++, combFilterDmem, combFilterSize); - synthState->combFilterNeedsInit = false; - } else { - AudioSynth_LoadBuffer(cmd++, combFilterDmem, combFilterSize, combFilterState); - } - AudioSynth_SaveBuffer(cmd++, DMEM_TEMP + (numSamplesPerUpdate * SAMPLE_SIZE) - combFilterSize, combFilterSize, - combFilterState); - AudioSynth_Mix(cmd++, (numSamplesPerUpdate * (s32)SAMPLE_SIZE) >> 4, combFilterGain, DMEM_COMB_TEMP, - combFilterDmem); - AudioSynth_DMemMove(cmd++, combFilterDmem, DMEM_TEMP, numSamplesPerUpdate * SAMPLE_SIZE); - } else { - synthState->combFilterNeedsInit = true; - } - - // Determine the behavior of the audio processing that leads to the haas effect - if ((sampleState->haasEffectLeftDelaySize != 0) || (synthState->prevHaasEffectLeftDelaySize != 0)) { - haasEffectDelaySide = HAAS_EFFECT_DELAY_LEFT; - } else if ((sampleState->haasEffectRightDelaySize != 0) || (synthState->prevHaasEffectRightDelaySize != 0)) { - haasEffectDelaySide = HAAS_EFFECT_DELAY_RIGHT; - } else { - haasEffectDelaySide = HAAS_EFFECT_DELAY_NONE; - } - - // Apply an unknown effect based on the surround sound-mode - if (gAudioCtx.soundMode == SOUNDMODE_SURROUND) { - sampleState->targetVolLeft = sampleState->targetVolLeft >> 1; - sampleState->targetVolRight = sampleState->targetVolRight >> 1; - if (sampleState->surroundEffectIndex != 0xFF) { - cmd = AudioSynth_ApplySurroundEffect(cmd, sampleState, synthState, numSamplesPerUpdate, DMEM_TEMP, flags); - } - } - - // Split the mono-signal into left and right channels: - // Both for dry signal (to go to the speakers now) - // and for wet signal (to go to a reverb buffer to be stored, and brought back later to produce an echo) - cmd = AudioSynth_ProcessEnvelope(cmd, sampleState, synthState, numSamplesPerUpdate, DMEM_TEMP, haasEffectDelaySide, - flags); - - // Apply the haas effect by delaying either the left or the right channel by a small amount - if (sampleState->bitField1.useHaasEffect) { - if (!(flags & A_INIT)) { - flags = A_CONTINUE; - } - cmd = AudioSynth_ApplyHaasEffect(cmd, sampleState, synthState, numSamplesPerUpdate * (s32)SAMPLE_SIZE, flags, - haasEffectDelaySide); - } - - return cmd; -} - -Acmd* AudioSynth_ApplySurroundEffect(Acmd* cmd, NoteSampleState* sampleState, NoteSynthesisState* synthState, - s32 numSamplesPerUpdate, s32 haasDmem, s32 flags) { - s32 wetGain; - u16 dryGain; - s64 dmem = DMEM_SURROUND_TEMP; - f32 decayGain; - - AudioSynth_DMemMove(cmd++, haasDmem, DMEM_HAAS_TEMP, numSamplesPerUpdate * SAMPLE_SIZE); - dryGain = synthState->surroundEffectGain; - - if (flags == A_INIT) { - aClearBuffer(cmd++, dmem, sizeof(synthState->synthesisBuffers->surroundEffectState)); - synthState->surroundEffectGain = 0; - } else { - aLoadBuffer(cmd++, synthState->synthesisBuffers->surroundEffectState, dmem, - sizeof(synthState->synthesisBuffers->surroundEffectState)); - aMix(cmd++, (numSamplesPerUpdate * (s32)SAMPLE_SIZE) >> 4, dryGain, dmem, DMEM_LEFT_CH); - aMix(cmd++, (numSamplesPerUpdate * (s32)SAMPLE_SIZE) >> 4, (dryGain ^ 0xFFFF), dmem, DMEM_RIGHT_CH); - - wetGain = (dryGain * synthState->curReverbVol) >> 7; - - aMix(cmd++, (numSamplesPerUpdate * (s32)SAMPLE_SIZE) >> 4, wetGain, dmem, DMEM_WET_LEFT_CH); - aMix(cmd++, (numSamplesPerUpdate * (s32)SAMPLE_SIZE) >> 4, (wetGain ^ 0xFFFF), dmem, DMEM_WET_RIGHT_CH); - } - - aSaveBuffer(cmd++, DMEM_SURROUND_TEMP + (numSamplesPerUpdate * SAMPLE_SIZE), - synthState->synthesisBuffers->surroundEffectState, - sizeof(synthState->synthesisBuffers->surroundEffectState)); - - decayGain = (sampleState->targetVolLeft + sampleState->targetVolRight) * (1.0f / 0x2000); - - if (decayGain > 1.0f) { - decayGain = 1.0f; - } - - decayGain = decayGain * gDefaultPanVolume[127 - sampleState->surroundEffectIndex]; - synthState->surroundEffectGain = ((decayGain * 0x7FFF) + synthState->surroundEffectGain) / 2; - - AudioSynth_DMemMove(cmd++, DMEM_HAAS_TEMP, haasDmem, numSamplesPerUpdate * SAMPLE_SIZE); - - 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, NoteSampleState* sampleState, NoteSynthesisState* synthState, - s32 numSamplesPerUpdate, u16 dmemSrc, s32 haasEffectDelaySide, s32 flags) { - u32 dmemDests; - u16 curVolLeft; - u16 targetVolLeft; - s32 curReverbVol; - u16 curVolRight; - s16 targetReverbVol; - s16 rampLeft; - s16 rampRight; - s16 rampReverb; - s16 curReverbVolAndFlags; - u16 targetVolRight; - f32 defaultPanVolume; - s32 pad; - - targetReverbVol = sampleState->targetReverbVol; - - curVolLeft = synthState->curVolLeft; - curVolRight = synthState->curVolRight; - - targetVolLeft = sampleState->targetVolLeft; - targetVolLeft <<= 4; - targetVolRight = sampleState->targetVolRight; - targetVolRight <<= 4; - - if ((gAudioCtx.soundMode == SOUNDMODE_SURROUND) && (sampleState->surroundEffectIndex != 0xFF)) { - defaultPanVolume = gDefaultPanVolume[sampleState->surroundEffectIndex]; - targetVolLeft *= defaultPanVolume; - targetVolRight *= defaultPanVolume; - } - - if (targetVolLeft != curVolLeft) { - rampLeft = (targetVolLeft - curVolLeft) / (numSamplesPerUpdate >> 3); - } else { - rampLeft = 0; - } - - if (targetVolRight != curVolRight) { - rampRight = (targetVolRight - curVolRight) / (numSamplesPerUpdate >> 3); - } else { - rampRight = 0; - } - - curReverbVolAndFlags = synthState->curReverbVol; - curReverbVol = curReverbVolAndFlags & 0x7F; - - if (curReverbVolAndFlags != targetReverbVol) { - rampReverb = (((targetReverbVol & 0x7F) - curReverbVol) << 9) / (numSamplesPerUpdate >> 3); - synthState->curReverbVol = targetReverbVol; - } else { - rampReverb = 0; - } - - synthState->curVolLeft = curVolLeft + (rampLeft * (numSamplesPerUpdate >> 3)); - synthState->curVolRight = curVolRight + (rampRight * (numSamplesPerUpdate >> 3)); - - if (sampleState->bitField1.useHaasEffect) { - AudioSynth_ClearBuffer(cmd++, DMEM_HAAS_TEMP, DMEM_1CH_SIZE); - AudioSynth_EnvSetup1(cmd++, curReverbVol * 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++, curReverbVol * 2, rampReverb, rampLeft, rampRight); - aEnvSetup2(cmd++, curVolLeft, curVolRight); - dmemDests = sEnvMixerDefaultDmemDests; - } - - aEnvMixer(cmd++, dmemSrc, numSamplesPerUpdate, (curReverbVolAndFlags & 0x80) >> 7, - sampleState->bitField0.strongReverbRight, sampleState->bitField0.strongReverbLeft, - sampleState->bitField0.strongRight, sampleState->bitField0.strongLeft, dmemDests, sEnvMixerOp); - - return cmd; -} - -Acmd* AudioSynth_LoadWaveSamples(Acmd* cmd, NoteSampleState* sampleState, NoteSynthesisState* synthState, - s32 numSamplesToLoad) { - s32 numSamplesAvailable; - s32 harmonicIndexCurAndPrev = sampleState->harmonicIndexCurAndPrev; - s32 samplePosInt = synthState->samplePosInt; - s32 numDuplicates; - - if (sampleState->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++, sampleState->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 - numSamplesAvailable = WAVE_SAMPLE_COUNT - samplePosInt; - - // Require duplicates if there are more samples to load than available - if (numSamplesToLoad > numSamplesAvailable) { - // Duplicate (copy) the WAVE_SAMPLE_COUNT samples as many times as needed to reach numSamplesToLoad. - // (numSamplesToLoad - numSamplesAvailable) is the number of samples missing. - // Divide by WAVE_SAMPLE_COUNT, rounding up, to get the amount of duplicates - numDuplicates = ((numSamplesToLoad - numSamplesAvailable + 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, NoteSampleState* sampleState, 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 = sampleState->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 = sampleState->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); - if (haasEffectDelaySize) { // != 0 - aClearBuffer(cmd++, DMEM_HAAS_TEMP, haasEffectDelaySize); - } - aDMEMMove(cmd++, DMEM_TEMP, DMEM_HAAS_TEMP + haasEffectDelaySize, size); - } - - if (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/audio/audio_thread.c b/src/code/audio/audio_thread.c deleted file mode 100644 index 2b06281cc..000000000 --- a/src/code/audio/audio_thread.c +++ /dev/null @@ -1,977 +0,0 @@ -/** - * @file audio_thread.c - * - * Top-level file that coordinates all audio code on the audio thread. - */ -#include "global.h" - -AudioTask* AudioThread_UpdateImpl(void); -void AudioThread_SetFadeOutTimer(s32 seqPlayerIndex, s32 fadeTimer); -void AudioThread_SetFadeInTimer(s32 seqPlayerIndex, s32 fadeTimer); -void AudioThread_ProcessCmds(u32 msg); -void AudioThread_ProcessSeqPlayerCmd(SequencePlayer* seqPlayer, AudioCmd* cmd); -void AudioThread_ProcessChannelCmd(SequenceChannel* channel, AudioCmd* cmd); -s32 AudioThread_GetSamplePos(s32 seqPlayerIndex, s32 channelIndex, s32 layerIndex, s32* loopEnd, s32* samplePosInt); -s32 AudioThread_CountAndReleaseNotes(s32 flags); - -AudioTask* AudioThread_Update(void) { - return AudioThread_UpdateImpl(); -} - -AudioTask* AudioThread_UpdateImpl(void) { - static AudioTask* sWaitingAudioTask = NULL; - u32 numSamplesRemainingInAi; - s32 numAbiCmds; - s32 pad; - s32 j; - s32 dmaCount; - s16* curAiBuffer; - OSTask_t* task; - s32 index; - u32 msg; - s32 validCount; - s32 i; - - gAudioCtx.totalTaskCount++; - if ((gAudioCtx.totalTaskCount % gAudioCtx.audioBufferParameters.specUnk4) != 0) { - if (gAudioCustomUpdateFunction != NULL) { - gAudioCustomUpdateFunction(); - } - - if (((gAudioCtx.totalTaskCount % gAudioCtx.audioBufferParameters.specUnk4) + 1) == - gAudioCtx.audioBufferParameters.specUnk4) { - return sWaitingAudioTask; - } - - return NULL; - } - - osSendMesg(gAudioCtx.taskStartQueueP, gAudioCtx.totalTaskCount, OS_MESG_NOBLOCK); - gAudioCtx.rspTaskIndex ^= 1; - gAudioCtx.curAiBufferIndex++; - gAudioCtx.curAiBufferIndex %= 3; - index = (gAudioCtx.curAiBufferIndex + 1) % 3; - - // Division converts size to numSamples: 2 channels (left/right) * 2 bytes per sample - numSamplesRemainingInAi = osAiGetLength() / (2 * SAMPLE_SIZE); - - if (gAudioCtx.resetTimer < 16) { - if (gAudioCtx.numSamplesPerFrame[index] != 0) { - osAiSetNextBuffer(gAudioCtx.aiBuffers[index], 2 * gAudioCtx.numSamplesPerFrame[index] * (s32)SAMPLE_SIZE); - if (gAudioCtx.aiBuffers[index]) {} - if (gAudioCtx.numSamplesPerFrame[index]) {} - } - } - - if (gAudioCustomUpdateFunction != NULL) { - gAudioCustomUpdateFunction(); - } - - dmaCount = gAudioCtx.curAudioFrameDmaCount; - for (i = 0; i < gAudioCtx.curAudioFrameDmaCount; i++) { - if (osRecvMesg(&gAudioCtx.curAudioFrameDmaQueue, NULL, OS_MESG_NOBLOCK) == 0) { - dmaCount--; - } - } - - if (dmaCount != 0) { - for (i = 0; i < dmaCount; i++) { - osRecvMesg(&gAudioCtx.curAudioFrameDmaQueue, NULL, OS_MESG_BLOCK); - } - } - - validCount = gAudioCtx.curAudioFrameDmaQueue.validCount; - if (validCount != 0) { - for (i = 0; i < validCount; 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, gAudioCtx.specId, 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.curAiBufferIndex; - curAiBuffer = gAudioCtx.aiBuffers[index]; - - gAudioCtx.numSamplesPerFrame[index] = - (s16)((((gAudioCtx.audioBufferParameters.numSamplesPerFrameTarget - numSamplesRemainingInAi) + - (8 * SAMPLES_PER_FRAME)) & - ~0xF) + - (1 * SAMPLES_PER_FRAME)); - - // Clamp numSamplesPerFrame between numSamplesPerFrameMin and numSamplesPerFrameMax - if (gAudioCtx.numSamplesPerFrame[index] < gAudioCtx.audioBufferParameters.numSamplesPerFrameMin) { - gAudioCtx.numSamplesPerFrame[index] = gAudioCtx.audioBufferParameters.numSamplesPerFrameMin; - } - if (gAudioCtx.numSamplesPerFrame[index] > gAudioCtx.audioBufferParameters.numSamplesPerFrameMax) { - gAudioCtx.numSamplesPerFrame[index] = gAudioCtx.audioBufferParameters.numSamplesPerFrameMax; - } - - j = 0; - if (gAudioCtx.resetStatus == 0) { - // msg = 0000RREE R = read pos, E = End Pos - while (osRecvMesg(gAudioCtx.threadCmdProcQueueP, (OSMesg*)&msg, OS_MESG_NOBLOCK) != -1) { - //! FAKE: - if (1) {} - AudioThread_ProcessCmds(msg); - j++; - } - if ((j == 0) && gAudioCtx.threadCmdQueueFinished) { - AudioThread_ScheduleProcessCmds(); - } - } - - if (gAudioSPDataPtr == (u64*)gAudioCtx.curAbiCmdBuf) { - return -1; - } - - gAudioCtx.curAbiCmdBuf = - AudioSynth_Update(gAudioCtx.curAbiCmdBuf, &numAbiCmds, curAiBuffer, gAudioCtx.numSamplesPerFrame[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 AudioThread_Update(), 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*)AudioThread_Update + (gAudioCtx.audioRandom & 0xFFF0)); - - index = gAudioCtx.rspTaskIndex; - gAudioCtx.curTask->taskQueue = NULL; - gAudioCtx.curTask->unk_44 = NULL; - - task = &gAudioCtx.curTask->task.t; - task->type = M_AUDTASK; - task->flags = 0; - task->ucodeBoot = aspMainTextStart; - task->ucodeBootSize = SP_UCODE_SIZE; - task->ucodeDataSize = ((aspMainDataEnd - aspMainDataStart) * sizeof(u64)) - 1; - task->ucode = aspMainTextStart; - task->ucodeData = aspMainDataStart; - task->ucodeSize = SP_UCODE_SIZE; - task->dramStack = (u64*)D_801D6200; - task->dramStackSize = 0; - task->outputBuff = NULL; - task->outputBuffSize = NULL; - if (1) {} - task->dataPtr = (u64*)gAudioCtx.abiCmdBufs[index]; - task->dataSize = numAbiCmds * sizeof(Acmd); - task->yieldDataPtr = NULL; - task->yieldDataSize = 0; - - if (gAudioCtx.numAbiCmdsMax < numAbiCmds) { - gAudioCtx.numAbiCmdsMax = numAbiCmds; - } - - if (gAudioCtx.audioBufferParameters.specUnk4 == 1) { - return gAudioCtx.curTask; - } else { - sWaitingAudioTask = gAudioCtx.curTask; - return NULL; - } -} - -void AudioThread_ProcessGlobalCmd(AudioCmd* cmd) { - s32 i; - s32 pad; - - switch (cmd->op) { - case AUDIOCMD_OP_GLOBAL_SYNC_LOAD_SEQ_PARTS: - AudioLoad_SyncLoadSeqParts(cmd->arg1, cmd->arg2, cmd->asInt, &gAudioCtx.externalLoadQueue); - break; - - case AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER: - AudioLoad_SyncInitSeqPlayer(cmd->arg0, cmd->arg1, cmd->arg2); - AudioThread_SetFadeInTimer(cmd->arg0, cmd->asInt); - break; - - case AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER_SKIP_TICKS: - AudioLoad_SyncInitSeqPlayerSkipTicks(cmd->arg0, cmd->arg1, cmd->asInt); - AudioThread_SetFadeInTimer(cmd->arg0, 500); - AudioSeq_SkipForwardSequence(&gAudioCtx.seqPlayers[cmd->arg0]); - break; - - case AUDIOCMD_OP_GLOBAL_DISABLE_SEQPLAYER: - if (gAudioCtx.seqPlayers[cmd->arg0].enabled) { - if (cmd->asInt == 0) { - AudioSeq_SequencePlayerDisableAsFinished(&gAudioCtx.seqPlayers[cmd->arg0]); - } else { - AudioThread_SetFadeOutTimer(cmd->arg0, cmd->asInt); - } - } - break; - - case AUDIOCMD_OP_GLOBAL_SET_SOUND_MODE: - gAudioCtx.soundMode = cmd->asInt; - break; - - case AUDIOCMD_OP_GLOBAL_MUTE: - if (cmd->arg0 == AUDIOCMD_ALL_SEQPLAYERS) { - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - gAudioCtx.seqPlayers[i].muted = true; - gAudioCtx.seqPlayers[i].recalculateVolume = true; - } - } else { - gAudioCtx.seqPlayers[cmd->arg0].muted = true; - gAudioCtx.seqPlayers[cmd->arg0].recalculateVolume = true; - } - break; - - case AUDIOCMD_OP_GLOBAL_UNMUTE: - if (cmd->asInt == true) { - for (i = 0; i < gAudioCtx.numNotes; i++) { - Note* note = &gAudioCtx.notes[i]; - NoteSampleState* noteSampleState = ¬e->sampleState; - - if (noteSampleState->bitField0.enabled && (note->playbackState.status == PLAYBACK_STATUS_0) && - (note->playbackState.parentLayer->channel->muteFlags & MUTE_FLAGS_STOP_SAMPLES)) { - noteSampleState->bitField0.finished = true; - } - } - } - - if (cmd->arg0 == AUDIOCMD_ALL_SEQPLAYERS) { - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - gAudioCtx.seqPlayers[i].muted = false; - gAudioCtx.seqPlayers[i].recalculateVolume = true; - } - } else { - gAudioCtx.seqPlayers[cmd->arg0].muted = false; - gAudioCtx.seqPlayers[cmd->arg0].recalculateVolume = true; - } - - break; - - case AUDIOCMD_OP_GLOBAL_SYNC_LOAD_INSTRUMENT: - AudioLoad_SyncLoadInstrument(cmd->arg0, cmd->arg1, cmd->arg2); - break; - - case AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SAMPLE_BANK: - AudioLoad_AsyncLoadSampleBank(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); - break; - - case AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_FONT: - AudioLoad_AsyncLoadFont(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); - break; - - case AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SEQ: - AudioLoad_AsyncLoadSeq(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); - break; - - case AUDIOCMD_OP_GLOBAL_DISCARD_SEQ_FONTS: - AudioLoad_DiscardSeqFonts(cmd->arg1); - break; - - case AUDIOCMD_OP_GLOBAL_SET_CHANNEL_MASK: - gAudioCtx.threadCmdChannelMask[cmd->arg0] = cmd->asUShort; - break; - - case AUDIOCMD_OP_GLOBAL_RESET_AUDIO_HEAP: - gAudioCtx.resetStatus = 5; - gAudioCtx.specId = cmd->asUInt; - break; - - case AUDIOCMD_OP_GLOBAL_SET_CUSTOM_UPDATE_FUNCTION: - gAudioCustomUpdateFunction = cmd->asUInt; - break; - - case AUDIOCMD_OP_GLOBAL_SET_CUSTOM_FUNCTION: - if (cmd->arg2 == AUDIO_CUSTOM_FUNCTION_REVERB) { - gAudioCustomReverbFunction = cmd->asUInt; - } else if (cmd->arg2 == AUDIO_CUSTOM_FUNCTION_SYNTH) { - gAudioCustomSynthFunction = cmd->asUInt; - } else { - gAudioCtx.customSeqFunctions[cmd->arg2] = cmd->asUInt; - } - break; - - case AUDIOCMD_OP_GLOBAL_SET_DRUM_FONT: - case AUDIOCMD_OP_GLOBAL_SET_SFX_FONT: - case AUDIOCMD_OP_GLOBAL_SET_INSTRUMENT_FONT: - if (AudioPlayback_SetFontInstrument(cmd->op - AUDIOCMD_OP_GLOBAL_SET_DRUM_FONT, cmd->arg1, cmd->arg2, - cmd->asInt)) {} - break; - - case AUDIOCMD_OP_GLOBAL_DISABLE_ALL_SEQPLAYERS: { - u32 flags = cmd->asUInt; - - if (flags == AUDIO_NOTE_RELEASE) { - for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { - if (gAudioCtx.seqPlayers[i].enabled) { - AudioSeq_SequencePlayerDisableAsFinished(&gAudioCtx.seqPlayers[i]); - } - } - } - AudioThread_CountAndReleaseNotes(flags); - break; - } - - case AUDIOCMD_OP_GLOBAL_POP_PERSISTENT_CACHE: - AudioHeap_PopPersistentCache(cmd->asInt); - break; - - case AUDIOCMD_OP_GLOBAL_E5: - func_8018FA60(cmd->arg0, cmd->arg1, cmd->arg2, cmd->asInt); - break; - - case AUDIOCMD_OP_GLOBAL_SET_REVERB_DATA: - AudioHeap_SetReverbData(cmd->arg1, cmd->arg0, cmd->asInt, false); - break; - - default: - break; - } -} - -void AudioThread_SetFadeOutTimer(s32 seqPlayerIndex, s32 fadeTimer) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex]; - - if (fadeTimer == 0) { - fadeTimer = 1; - } - - seqPlayer->fadeVelocity = -(seqPlayer->fadeVolume / fadeTimer); - seqPlayer->state = SEQPLAYER_STATE_FADE_OUT; - seqPlayer->fadeTimer = fadeTimer; -} - -void AudioThread_SetFadeInTimer(s32 seqPlayerIndex, s32 fadeTimer) { - SequencePlayer* seqPlayer; - - if (fadeTimer != 0) { - seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex]; - seqPlayer->state = SEQPLAYER_STATE_FADE_IN; - seqPlayer->storedFadeTimer = fadeTimer; - seqPlayer->fadeTimer = fadeTimer; - seqPlayer->fadeVolume = 0.0f; - seqPlayer->fadeVelocity = 0.0f; - } -} - -void AudioThread_InitMesgQueuesInternal(void) { - gAudioCtx.threadCmdWritePos = 0; - gAudioCtx.threadCmdReadPos = 0; - gAudioCtx.threadCmdQueueFinished = false; - - gAudioCtx.taskStartQueueP = &gAudioCtx.taskStartQueue; - gAudioCtx.threadCmdProcQueueP = &gAudioCtx.threadCmdProcQueue; - gAudioCtx.audioResetQueueP = &gAudioCtx.audioResetQueue; - - osCreateMesgQueue(gAudioCtx.taskStartQueueP, gAudioCtx.taskStartMsgs, ARRAY_COUNT(gAudioCtx.taskStartMsgs)); - osCreateMesgQueue(gAudioCtx.threadCmdProcQueueP, gAudioCtx.threadCmdProcMsgBuf, - ARRAY_COUNT(gAudioCtx.threadCmdProcMsgBuf)); - osCreateMesgQueue(gAudioCtx.audioResetQueueP, gAudioCtx.audioResetMesgs, ARRAY_COUNT(gAudioCtx.audioResetMesgs)); -} - -void AudioThread_QueueCmd(u32 opArgs, void** data) { - AudioCmd* cmd = &gAudioCtx.threadCmdBuf[gAudioCtx.threadCmdWritePos & 0xFF]; - - cmd->opArgs = opArgs; - cmd->data = *data; - - gAudioCtx.threadCmdWritePos++; - - if (gAudioCtx.threadCmdWritePos == gAudioCtx.threadCmdReadPos) { - gAudioCtx.threadCmdWritePos--; - } -} - -void AudioThread_QueueCmdF32(u32 opArgs, f32 data) { - AudioThread_QueueCmd(opArgs, (void**)&data); -} - -void AudioThread_QueueCmdS32(u32 opArgs, s32 data) { - AudioThread_QueueCmd(opArgs, (void**)&data); -} - -void AudioThread_QueueCmdS8(u32 opArgs, s8 data) { - u32 uData = data << 0x18; - - AudioThread_QueueCmd(opArgs, (void**)&uData); -} - -void AudioThread_QueueCmdU16(u32 opArgs, u16 data) { - u32 uData = data << 0x10; - - AudioThread_QueueCmd(opArgs, (void**)&uData); -} - -s32 AudioThread_ScheduleProcessCmds(void) { - static s32 sMaxWriteReadDiff = 0; - s32 ret; - - if (sMaxWriteReadDiff < (u8)((gAudioCtx.threadCmdWritePos - gAudioCtx.threadCmdReadPos) + 0x100)) { - sMaxWriteReadDiff = (u8)((gAudioCtx.threadCmdWritePos - gAudioCtx.threadCmdReadPos) + 0x100); - } - - ret = osSendMesg(gAudioCtx.threadCmdProcQueueP, - (void*)(((gAudioCtx.threadCmdReadPos & 0xFF) << 8) | (gAudioCtx.threadCmdWritePos & 0xFF)), - OS_MESG_NOBLOCK); - if (ret != -1) { - gAudioCtx.threadCmdReadPos = gAudioCtx.threadCmdWritePos; - ret = 0; - } else { - return -1; - } - - return ret; -} - -void AudioThread_ResetCmdQueue(void) { - gAudioCtx.threadCmdQueueFinished = false; - gAudioCtx.threadCmdReadPos = gAudioCtx.threadCmdWritePos; -} - -void AudioThread_ProcessCmd(AudioCmd* cmd) { - SequencePlayer* seqPlayer; - u16 threadCmdChannelMask; - s32 channelIndex; - - if ((cmd->op & 0xF0) >= 0xE0) { - AudioThread_ProcessGlobalCmd(cmd); - return; - } - - if (cmd->arg0 < gAudioCtx.audioBufferParameters.numSequencePlayers) { - seqPlayer = &gAudioCtx.seqPlayers[cmd->arg0]; - if (cmd->op & 0x80) { - AudioThread_ProcessGlobalCmd(cmd); - return; - } - - if (cmd->op & 0x40) { - AudioThread_ProcessSeqPlayerCmd(seqPlayer, cmd); - return; - } - - if (cmd->arg1 < SEQ_NUM_CHANNELS) { - AudioThread_ProcessChannelCmd(seqPlayer->channels[cmd->arg1], cmd); - return; - } - - if (cmd->arg1 == AUDIOCMD_ALL_CHANNELS) { - threadCmdChannelMask = gAudioCtx.threadCmdChannelMask[cmd->arg0]; - for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) { - if (threadCmdChannelMask & 1) { - AudioThread_ProcessChannelCmd(seqPlayer->channels[channelIndex], cmd); - } - threadCmdChannelMask = threadCmdChannelMask >> 1; - } - } - } -} - -void AudioThread_ProcessCmds(u32 msg) { - static u8 sCurCmdRdPos = 0; - AudioCmd* cmd; - u8 endPos; - - if (!gAudioCtx.threadCmdQueueFinished) { - sCurCmdRdPos = msg >> 8; - } - - while (true) { - endPos = msg & 0xFF; - if (sCurCmdRdPos == endPos) { - gAudioCtx.threadCmdQueueFinished = false; - break; - } - - cmd = &gAudioCtx.threadCmdBuf[sCurCmdRdPos++ & 0xFF]; - if (cmd->op == AUDIOCMD_OP_GLOBAL_STOP_AUDIOCMDS) { - gAudioCtx.threadCmdQueueFinished = true; - break; - } - - AudioThread_ProcessCmd(cmd); - cmd->op = AUDIOCMD_OP_NOOP; - } -} - -u32 AudioThread_GetExternalLoadQueueMsg(u32* retMsg) { - u32 msg; - - if (osRecvMesg(&gAudioCtx.externalLoadQueue, (OSMesg*)&msg, OS_MESG_NOBLOCK) == -1) { - *retMsg = 0; - return 0; - } - - *retMsg = msg & 0xFFFFFF; - return msg >> 0x18; -} - -u8* AudioThread_GetFontsForSequence(s32 seqId, u32* outNumFonts) { - return AudioLoad_GetFontsForSequence(seqId, outNumFonts); -} - -void AudioThread_GetSampleBankIdsOfFont(s32 fontId, u32* sampleBankId1, u32* sampleBankId2) { - *sampleBankId1 = gAudioCtx.soundFontList[fontId].sampleBankId1; - *sampleBankId2 = gAudioCtx.soundFontList[fontId].sampleBankId2; -} - -s32 func_80193C5C(void) { - s32 pad; - s32 specId; - - if (osRecvMesg(gAudioCtx.audioResetQueueP, (OSMesg*)&specId, OS_MESG_NOBLOCK) == -1) { - return 0; - } else if (gAudioCtx.specId != specId) { - return -1; - } else { - return 1; - } -} - -void AudioThread_WaitForAudioResetQueueP(void) { - // macro? - // clang-format off - s32 chk = -1; s32 msg; do {} while (osRecvMesg(gAudioCtx.audioResetQueueP, (OSMesg*)&msg, OS_MESG_NOBLOCK) != chk); - // clang-format on -} - -s32 AudioThread_ResetAudioHeap(s32 specId) { - s32 resetStatus; - OSMesg msg; - s32 pad; - - AudioThread_WaitForAudioResetQueueP(); - resetStatus = gAudioCtx.resetStatus; - if (resetStatus != 0) { - AudioThread_ResetCmdQueue(); - if (gAudioCtx.specId == specId) { - return -2; - } else if (resetStatus > 2) { - gAudioCtx.specId = specId; - return -3; - } else { - osRecvMesg(gAudioCtx.audioResetQueueP, &msg, OS_MESG_BLOCK); - } - } - - AudioThread_WaitForAudioResetQueueP(); - AUDIOCMD_GLOBAL_RESET_AUDIO_HEAP(specId); - - return AudioThread_ScheduleProcessCmds(); -} - -void AudioThread_PreNMIInternal(void) { - gAudioCtx.resetTimer = 1; - if (gAudioCtxInitalized) { - AudioThread_ResetAudioHeap(0); - gAudioCtx.resetStatus = 0; - } -} - -// Unused -s8 AudioThread_GetChannelIO(s32 seqPlayerIndex, s32 channelIndex, s32 ioPort) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex]; - SequenceChannel* channel; - - if (seqPlayer->enabled) { - channel = seqPlayer->channels[channelIndex]; - return channel->seqScriptIO[ioPort]; - } else { - return SEQ_IO_VAL_NONE; - } -} - -// Unused -s8 AudioThread_GetSeqPlayerIO(s32 seqPlayerIndex, s32 ioPort) { - return gAudioCtx.seqPlayers[seqPlayerIndex].seqScriptIO[ioPort]; -} - -// Unused -void AudioThread_InitExternalPool(void* addr, size_t size) { - AudioHeap_InitPool(&gAudioCtx.externalPool, addr, size); -} - -// Unused -void AudioThread_ResetExternalPool(void) { - gAudioCtx.externalPool.startAddr = NULL; -} - -void AudioThread_ProcessSeqPlayerCmd(SequencePlayer* seqPlayer, AudioCmd* cmd) { - f32 fadeVolume; - - switch (cmd->op) { - case AUDIOCMD_OP_SEQPLAYER_FADE_VOLUME_SCALE: - if (seqPlayer->fadeVolumeScale != cmd->asFloat) { - seqPlayer->fadeVolumeScale = cmd->asFloat; - seqPlayer->recalculateVolume = true; - } - break; - - case AUDIOCMD_OP_SEQPLAYER_SET_TEMPO: - seqPlayer->tempo = cmd->asInt * TATUMS_PER_BEAT; - break; - - case AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO: - seqPlayer->tempoChange = cmd->asInt * TATUMS_PER_BEAT; - break; - - case AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO_TICKS: - seqPlayer->tempoChange = cmd->asInt; - break; - - case AUDIOCMD_OP_SEQPLAYER_SET_TRANSPOSITION: - seqPlayer->transposition = cmd->asSbyte; - break; - - case AUDIOCMD_OP_SEQPLAYER_SET_IO: - seqPlayer->seqScriptIO[cmd->arg2] = cmd->asSbyte; - break; - - case AUDIOCMD_OP_SEQPLAYER_FADE_TO_SET_VOLUME: - fadeVolume = (s32)cmd->arg1 / 127.0f; - goto apply_fade; - - case AUDIOCMD_OP_SEQPLAYER_FADE_TO_SCALED_VOLUME: - fadeVolume = ((s32)cmd->arg1 / 100.0f) * seqPlayer->fadeVolume; - apply_fade: - if (seqPlayer->state != SEQPLAYER_STATE_FADE_OUT) { - seqPlayer->volume = seqPlayer->fadeVolume; - if (cmd->asInt == 0) { - seqPlayer->fadeVolume = fadeVolume; - } else { - s32 fadeTimer = cmd->asInt; - - seqPlayer->state = SEQPLAYER_STATE_0; - seqPlayer->fadeTimer = fadeTimer; - seqPlayer->fadeVelocity = (fadeVolume - seqPlayer->fadeVolume) / fadeTimer; - } - } - break; - - case AUDIOCMD_OP_SEQPLAYER_RESET_VOLUME: - if (seqPlayer->state != SEQPLAYER_STATE_FADE_OUT) { - if (cmd->asInt == 0) { - seqPlayer->fadeVolume = seqPlayer->volume; - } else { - s32 fadeTimer = cmd->asInt; - - seqPlayer->state = SEQPLAYER_STATE_0; - seqPlayer->fadeTimer = fadeTimer; - seqPlayer->fadeVelocity = (seqPlayer->volume - seqPlayer->fadeVolume) / fadeTimer; - } - } - break; - - case AUDIOCMD_OP_SEQPLAYER_SET_BEND: - seqPlayer->bend = cmd->asFloat; - if (seqPlayer->bend == 1.0f) { - seqPlayer->applyBend = false; - } else { - seqPlayer->applyBend = true; - } - break; - - default: - break; - } -} - -void AudioThread_ProcessChannelCmd(SequenceChannel* channel, AudioCmd* cmd) { - u8 filterCutoff; - - switch (cmd->op) { - case AUDIOCMD_OP_CHANNEL_SET_VOL_SCALE: - if (channel->volumeScale != cmd->asFloat) { - channel->volumeScale = cmd->asFloat; - channel->changes.s.volume = true; - } - break; - - case AUDIOCMD_OP_CHANNEL_SET_VOL: - if (channel->volume != cmd->asFloat) { - channel->volume = cmd->asFloat; - channel->changes.s.volume = true; - } - break; - - case AUDIOCMD_OP_CHANNEL_SET_PAN: - if (channel->newPan != cmd->asSbyte) { - channel->newPan = cmd->asSbyte; - channel->changes.s.pan = true; - } - break; - - case AUDIOCMD_OP_CHANNEL_SET_PAN_WEIGHT: - if (channel->newPan != cmd->asSbyte) { - channel->panChannelWeight = cmd->asSbyte; - channel->changes.s.pan = true; - } - break; - - case AUDIOCMD_OP_CHANNEL_SET_FREQ_SCALE: - if (channel->freqScale != cmd->asFloat) { - channel->freqScale = cmd->asFloat; - channel->changes.s.freqScale = true; - } - break; - - case AUDIOCMD_OP_CHANNEL_SET_REVERB_VOLUME: - if (channel->targetReverbVol != cmd->asSbyte) { - channel->targetReverbVol = cmd->asSbyte; - } - break; - - case AUDIOCMD_OP_CHANNEL_SET_REVERB_INDEX: - if (channel->reverbIndex != cmd->asSbyte) { - channel->reverbIndex = cmd->asSbyte; - } - break; - - case AUDIOCMD_OP_CHANNEL_SET_SURROUND_EFFECT_INDEX: - channel->surroundEffectIndex = cmd->asSbyte; - break; - - case AUDIOCMD_OP_CHANNEL_SET_IO: - if (cmd->arg2 < ARRAY_COUNT(channel->seqScriptIO)) { - channel->seqScriptIO[cmd->arg2] = cmd->asSbyte; - } - break; - - case AUDIOCMD_OP_CHANNEL_SET_MUTE: - channel->muted = cmd->asSbyte; - break; - - case AUDIOCMD_OP_CHANNEL_SET_MUTE_FLAGS: - channel->muteFlags = cmd->asSbyte; - break; - - case AUDIOCMD_OP_CHANNEL_SET_VIBRATO_DEPTH: - channel->vibrato.vibratoDepthTarget = cmd->asUbyte * 8; - channel->vibrato.vibratoDepthChangeDelay = 1; - break; - - case AUDIOCMD_OP_CHANNEL_SET_VIBRATO_RATE: - channel->vibrato.vibratoRateTarget = cmd->asUbyte * 32; - channel->vibrato.vibratoRateChangeDelay = 1; - break; - - case AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_SIZE: - channel->combFilterSize = cmd->asUbyte; - break; - - case AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_GAIN: - channel->combFilterGain = cmd->asUShort; - break; - - case AUDIOCMD_OP_CHANNEL_SET_STEREO: - channel->stereoData.asByte = cmd->asUbyte; - break; - - case AUDIOCMD_OP_CHANNEL_SET_SET_START_POS: - channel->startSamplePos = cmd->asInt; - break; - - case AUDIOCMD_OP_CHANNEL_SET_SFX_STATE: - channel->sfxState = cmd->asUInt; - break; - - case AUDIOCMD_OP_CHANNEL_SET_FILTER: - filterCutoff = cmd->arg2; - if (cmd->asUInt != 0) { - channel->filter = cmd->asUInt; - } - if (channel->filter != NULL) { - AudioHeap_LoadFilter(channel->filter, filterCutoff >> 4, filterCutoff & 0xF); - } - break; - - case AUDIOCMD_OP_CHANNEL_SET_GAIN: - channel->gain = cmd->asUbyte; - break; - - default: - break; - } -} - -/** - * Call an audio-thread command that has no code to process it. Unused. - */ -void AudioThread_Noop1Cmd(s32 arg0, s32 arg1, s32 arg2) { - AUDIOCMD_GLOBAL_NOOP_1(arg0, arg1, arg2, 1); -} - -/** - * Call an audio-thread command that has no code to process it. Unused. - */ -void AudioThread_Noop1CmdZeroed(void) { - AUDIOCMD_GLOBAL_NOOP_1(0, 0, 0, 0); -} - -/** - * Call an audio-thread command that has no code to process it. Unused. - */ -void AudioThread_Noop2Cmd(u32 arg0, s32 arg1) { - AUDIOCMD_GLOBAL_NOOP_2(0, 0, arg1, arg0); -} - -// Unused -void AudioThread_WaitForAudioTask(void) { - osRecvMesg(gAudioCtx.taskStartQueueP, NULL, OS_MESG_NOBLOCK); - osRecvMesg(gAudioCtx.taskStartQueueP, NULL, OS_MESG_BLOCK); -} - -/** - * Get the number of s16-samples from the start of the sample to the current sample position. - * Unused - */ -s32 AudioThread_GetSamplePosFromStart(s32 seqPlayerIndex, s32 channelIndex, s32 layerIndex) { - s32 pad; - s32 loopEnd; - s32 samplePosInt; - - if (!AudioThread_GetSamplePos(seqPlayerIndex, channelIndex, layerIndex, &loopEnd, &samplePosInt)) { - return 0; - } - return samplePosInt; -} - -/** - * Get the number of s16-samples from the current sample position to the end of the sample. - * Unused - */ -s32 AudioThread_GetSamplePosUntilEnd(s32 seqPlayerIndex, s32 channelIndex, s32 layerIndex) { - s32 pad; - s32 loopEnd; - s32 samplePosInt; - - if (!AudioThread_GetSamplePos(seqPlayerIndex, channelIndex, layerIndex, &loopEnd, &samplePosInt)) { - return 0; - } - return loopEnd - samplePosInt; -} - -// Only used in unused functions -s32 AudioThread_GetSamplePos(s32 seqPlayerIndex, s32 channelIndex, s32 layerIndex, s32* loopEnd, s32* samplePosInt) { - SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex]; - SequenceLayer* layer; - Note* note; - TunedSample* tunedSample; - - if (seqPlayer->enabled && seqPlayer->channels[channelIndex]->enabled) { - layer = seqPlayer->channels[channelIndex]->layers[layerIndex]; - if (layer == NULL) { - return false; - } - - if (layer->enabled) { - if (layer->note == NULL) { - return false; - } - - if (!layer->bit3) { - return false; - } - - note = layer->note; - if (layer == note->playbackState.parentLayer) { - - if (note->sampleState.bitField1.isSyntheticWave == true) { - return false; - } - - tunedSample = note->sampleState.tunedSample; - if (tunedSample == NULL) { - return false; - } - *loopEnd = tunedSample->sample->loop->loopEnd; - *samplePosInt = note->synthesisState.samplePosInt; - return true; - } - return false; - } - } - return false; -} - -s32 AudioThread_GetEnabledNotesCount(void) { - return AudioThread_CountAndReleaseNotes(0); -} - -s32 AudioThread_GetEnabledSampledNotesCount(void) { - return AudioThread_CountAndReleaseNotes(AUDIO_NOTE_SAMPLE_NOTES); -} - -/** - * @param flags 0: count notes. 1: release all notes. 2: count sample notes 3: release sample notes - * @return s32 number of notes - */ -s32 AudioThread_CountAndReleaseNotes(s32 flags) { - s32 noteCount; - NotePlaybackState* playbackState; - NoteSampleState* noteSampleState; - s32 i; - Note* note; - TunedSample* tunedSample; - - noteCount = 0; - for (i = 0; i < gAudioCtx.numNotes; i++) { - note = &gAudioCtx.notes[i]; - playbackState = ¬e->playbackState; - if (note->sampleState.bitField0.enabled) { - noteSampleState = ¬e->sampleState; - if (playbackState->adsr.action.s.state != ADSR_STATE_DISABLED) { - if (flags >= AUDIO_NOTE_SAMPLE_NOTES) { - tunedSample = noteSampleState->tunedSample; - if ((tunedSample == NULL) || noteSampleState->bitField1.isSyntheticWave) { - continue; - } - if (tunedSample->sample->medium == MEDIUM_RAM) { - continue; - } - } - - noteCount++; - if ((flags & AUDIO_NOTE_RELEASE) == AUDIO_NOTE_RELEASE) { - playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; - playbackState->adsr.action.s.release = true; - } - } - } - } - return noteCount; -} - -u32 AudioThread_NextRandom(void) { - static u32 sAudioRandom = 0x12345678; - static u32 sAudioOsCount = 0x11111111; - u32 count = osGetCount(); - - sAudioRandom = (gAudioCtx.totalTaskCount + sAudioRandom + count) * (gAudioCtx.audioRandom + 0x1234567); - sAudioRandom = (sAudioRandom & 1) + (sAudioRandom * 2) + sAudioOsCount; - sAudioOsCount = count; - - return sAudioRandom; -} - -void AudioThread_InitMesgQueues(void) { - AudioThread_InitMesgQueuesInternal(); -} diff --git a/src/code/audio/code_8019AF00.c b/src/code/audio/code_8019AF00.c deleted file mode 100644 index 801e2b076..000000000 --- a/src/code/audio/code_8019AF00.c +++ /dev/null @@ -1,5176 +0,0 @@ -#include "global.h" - -typedef struct { - /* 0x0 */ s8 x; - /* 0x1 */ s8 y; -} OcarinaControlStick; // size = 0x2 - -typedef struct { - /* 0x0 */ Vec3f* pos; - /* 0x4 */ f32 freqScale; - /* 0x8 */ s8 reverbAdd; -} SfxSettings; // size = 0x9 - -typedef struct { - /* 0x0 */ f32 volume; - /* 0x4 */ f32 freqScale; - /* 0x8 */ s8 reverb; - /* 0x9 */ s8 panSigned; - /* 0xA */ s8 stereoBits; - /* 0xB */ u8 filter; - /* 0xC */ u8 combFilterGain; - /* 0xD */ u8 zVolume; -} SfxChannelState; // size = 0xE - -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; // playerIndex = 2 - -// Global IO ports for sequences, 8 global ports per seqPlayer -typedef enum { - /* 0x0 */ SEQ_PLAYER_IO_PORT_0, - /* 0x1 */ SEQ_PLAYER_IO_PORT_1, - /* 0x2 */ SEQ_PLAYER_IO_PORT_2, - /* 0x3 */ SEQ_PLAYER_IO_PORT_3, - /* 0x4 */ SEQ_PLAYER_IO_PORT_4, - /* 0x5 */ SEQ_PLAYER_IO_PORT_5, - /* 0x6 */ SEQ_PLAYER_IO_PORT_6, - /* 0x7 */ SEQ_PLAYER_IO_PORT_7, -} SeqPlayerIOPort; - -typedef struct { - /* 0x0 */ f32 value; - /* 0x4 */ f32 target; - /* 0x8 */ f32 step; - /* 0xC */ s32 remainingFrames; -} FreqLerp; // size = 0x10 - -s32 AudioOcarina_MemoryGameNextNote(void); - -void AudioSfx_ProcessSfxSettings(void); -void func_8019FEDC(void); -void Audio_StepFreqLerp(FreqLerp* lerp); - -s32 Audio_SetGanonsTowerBgmVolume(u8 targetVolume); - -void Audio_StartMorningSceneSequence(u16 seqId); -void Audio_StartSceneSequence(u16 seqId); -void Audio_PlaySequenceWithSeqPlayerIO(s8 playerIndex, u16 seqId, u8 fadeInDuration, s8 ioPort, u8 ioData); -void func_801A4428(u8 reverbIndex); -void func_801A3038(void); -void Audio_PlayAmbience(u8 ambienceId); -void Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(u8 volume); - -void Audio_UpdateRiverSoundVolumes(void); -void func_801A1290(void); -void func_801A1904(void); -void func_801A1E0C(void); -void func_801A2090(void); -void Audio_UpdateSceneSequenceResumePoint(void); -void func_801A312C(void); -void func_801A3AC0(void); -void Audio_ResetRequestedSceneSeqId(void); - -// Sfx bss -SfxSettings sSfxSettings[8]; -u8 sSfxSettingsFlags; -f32 sTwoSemitonesLoweredFreq; -s8 sSfxIncreasedReverb; -f32 sSfxSyncedVolume; -f32 sSfxSyncedVolumeForMetalEffects; -f32 sSfxSyncedFreq; -FreqLerp sRiverFreqScaleLerp; -FreqLerp sWaterfallFreqScaleLerp; -f32 sSfxAdjustedFreq; -s8 sSfxCustomReverb; -u8 sRiverSoundMainBgmVol; -u8 sRiverSoundMainBgmCurrentVol; -u8 sRiverSoundMainBgmLower; -u8 sRiverSoundMainBgmRestore; -u8 sGanonsTowerVol; -f32* sSfxVolumeCur; -f32 sSfxVolumeTarget; -f32 sSfxVolumeRate; -u16 sRequestedSceneSeqId; -SfxChannelState sSfxChannelState[16]; - -// Sequence bss -u8 D_801FD3A8; -u8 D_801FD3A9; -u8 sRiverSoundBgmTimer; -u8 sFanfareState; -u16 sFanfareSeqId; -u8 sMuteOnlySfxAndAmbienceSeq; -u8 sAllPlayersMutedExceptOcaAndSys; -u8 sAudioPauseState; -u8 sSpatialSeqIsActive[4]; -u8 sSequenceFilter[8 * 4]; -u8 sIsFinalHoursOrSoaring; -u8 sObjSoundFanfareSeqId; -u8 sObjSoundFanfareRequested; -Vec3f sObjSoundFanfarePos; -u8 sObjSoundPlayerIndex; -Vec3f sObjSoundPos; -s16 sObjSoundFlags; -f32 sObjSoundMinDist; -f32 sObjSoundMaxDist; -f32 sObjSoundMaxVol; -f32 sObjSoundMinVol; -Vec3f sSpatialSeqNoFilterPos; -Vec3f sSpatialSeqFilterPos; -f32 sSpatialSeqMaxDist; -u8 sSpatialSeqSeqId; -u8 sSpatialSeqFlags; -u8 D_801FD432; -u8 sSpatialSubBgmFadeTimer; -u8 D_801FD434; -u8 sSpatialSeqPlayerIndex; -u8 sSpatialSeqFadeTimer; -u16 sPrevAmbienceSeqId; - -// AudioOcarina bss -OcarinaStaff sPlayingStaff; -OcarinaStaff sPlaybackStaff; -OcarinaStaff sRecordingStaff; -u32 sOcarinaUpdateTaskStart; -OcarinaControlStick sOcarinaInputStickRel; -u32 sOcarinaInputButtonCur; -u32 sOcarinaInputButtonStart; -u32 sOcarinaInputButtonPrev; -s32 sOcarinaInputButtonPress; -u8 sOcarinaDisableTimer; -u8 sOcarinaUnused; -u8 sOcarinaHasStartedSong; -u8 sFirstOcarinaSongIndex; -u8 sLastOcarinaSongIndex; -u32 sOcarinaAvailableSongFlags; -u8 sOcarinaStaffPlayingPos; -u16 sMusicStaffPos[OCARINA_SONG_MAX]; -u16 sMusicStaffCurHeldLength[OCARINA_SONG_MAX]; -u16 sMusicStaffExpectedLength[OCARINA_SONG_MAX]; -u8 sMusicStaffExpectedPitch[OCARINA_SONG_MAX]; // Next required pitch in song playback -u8 D_801FD518[OCARINA_SONG_MAX]; -u32 D_801FD530[OCARINA_SONG_MAX]; -OcarinaNote sScarecrowsLongSongSecondNote; -u16 sCustomSequencePc; - -// Sfx Data -// If the Sfx Bank has more than 255 values (max value of u8) -u8 gIsLargeSfxBank[] = { - true, false, true, true, false, false, true, -}; -u8 D_801D6608[] = { - true, true, true, true, true, false, true, -}; -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 sGiantsMaskFreq = 0.89167805f; // Around 2 semitones down in pitch -s8 sGiantsMaskReverbAdd = 0x40; -f32 sWaterWheelVolume = 0.65f; -f32 gSfxVolume = 1.0f; -s8 sSfxTimer = 20; -s8 sSfxTimerLerpRange2 = 30; -s8 sSfxTimerLerpRange1 = 20; -f32 sBehindScreenZ[2] = { -15.0f, -65.0f }; // Unused Remnant of OoT -u8 sAudioIncreasingTranspose = 0; // Remnant of OoT, only unsed in unused functions -u8 gMorphaTransposeTable[16] = { 0, 0, 0, 1, 1, 2, 4, 6, 8, 8, 8, 8, 8, 8, 8, 8 }; // Unused Remnant of OoT -u8 sPrevChargeLevel = 0; -f32 sChargeLevelsSfxFreq[] = { 1.0f, 1.12246f, 1.33484f, 1.33484f }; -f32 sCurChargeLevelSfxFreq = 1.0f; -u8 sGanonsTowerLevelsVol[] = { - 127, 80, 75, 73, 70, 68, 65, 60 // volumes -}; -u8 sEnterGanonsTowerTimer = 0; -u16 sSfxVolumeDuration = 0; - -// System Data -s8 sSoundMode = SOUNDMODE_STEREO; -s8 sAudioIsWindowOpen = false; -s8 sAudioCutsceneFlag = false; -s8 sSpecReverb = 0; -s8 sAudioEnvReverb = 0; -s8 sAudioCodeReverb = 0; - -// Sequence Data -u8 sPrevSeqMode = 0; -f32 sBgmEnemyDist = 0.0f; -s8 sBgmEnemyVolume = 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; -s8 gUnderwaterSfxReverbAdd = 0; -Vec3f* sRiverSoundBgmPos = NULL; -f32 sRiverSoundXZDistToPlayer = 2000.0f; -u8 sObjSoundMainBgmSeqId = NA_BGM_GENERAL_SFX; - -// Allows enemy bgm -#define SEQ_FLAG_ENEMY (1 << 0) - -#define SEQ_FLAG_FANFARE (1 << 1) -#define SEQ_FLAG_FANFARE_KAMARO (1 << 2) - -// required for Audio_RestorePrevBgm to restore a sequence after Audio_PlayBgm_StorePrevBgm -#define SEQ_FLAG_RESTORE (1 << 3) - -/** - * 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. - * - * TODO: Confirm which sequences properly implement this system after sequence extraction - */ -#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_FILE_SELECT - ioPort 7 skips the harp intro when a value of 1 is written to it. - */ -#define SEQ_FLAG_SKIP_HARP_INTRO (1 << 6) - -// Unused, repurposed for SubBgm -#define SEQ_FLAG_NO_AMBIENCE (1 << 7) - -u8 sSeqFlags[] = { - SEQ_FLAG_FANFARE | SEQ_FLAG_ENEMY, // NA_BGM_GENERAL_SFX - SEQ_FLAG_ENEMY, // NA_BGM_AMBIENCE - SEQ_FLAG_ENEMY, // NA_BGM_TERMINA_FIELD - SEQ_FLAG_RESTORE, // NA_BGM_CHASE - 0, // NA_BGM_MAJORAS_THEME - 0, // NA_BGM_CLOCK_TOWER - SEQ_FLAG_ENEMY, // NA_BGM_STONE_TOWER_TEMPLE - SEQ_FLAG_ENEMY, // NA_BGM_INV_STONE_TOWER_TEMPLE - SEQ_FLAG_FANFARE, // NA_BGM_FAILURE_0 - SEQ_FLAG_FANFARE, // NA_BGM_FAILURE_1 - 0, // NA_BGM_HAPPY_MASK_SALESMAN - 0, // NA_BGM_SONG_OF_HEALING - SEQ_FLAG_ENEMY, // NA_BGM_SWAMP_REGION - 0, // NA_BGM_ALIEN_INVASION - SEQ_FLAG_FANFARE, // NA_BGM_SWAMP_CRUISE - 0, // NA_BGM_SHARPS_CURSE - SEQ_FLAG_ENEMY, // NA_BGM_GREAT_BAY_REGION - SEQ_FLAG_ENEMY, // NA_BGM_IKANA_REGION - 0, // NA_BGM_DEKU_KING - SEQ_FLAG_ENEMY, // NA_BGM_MOUNTAIN_REGION - 0, // NA_BGM_PIRATES_FORTRESS - 0, // NA_BGM_CLOCK_TOWN_DAY_1 - 0, // NA_BGM_CLOCK_TOWN_DAY_2 - 0, // NA_BGM_CLOCK_TOWN_DAY_3 - SEQ_FLAG_SKIP_HARP_INTRO, // NA_BGM_FILE_SELECT - SEQ_FLAG_RESUME, // NA_BGM_CLEAR_EVENT - 0, // NA_BGM_ENEMY - SEQ_FLAG_RESTORE, // NA_BGM_BOSS - SEQ_FLAG_ENEMY, // NA_BGM_WOODFALL_TEMPLE - 0, // NA_BGM_MARKET - 0, // NA_BGM_OPENING - SEQ_FLAG_RESUME_PREV, // NA_BGM_INSIDE_A_HOUSE - SEQ_FLAG_FANFARE, // NA_BGM_GAME_OVER - 0, // NA_BGM_CLEAR_BOSS - SEQ_FLAG_FANFARE, // NA_BGM_GET_ITEM - SEQ_FLAG_FANFARE, // NA_BGM_GATE_OPEN - SEQ_FLAG_FANFARE, // NA_BGM_GET_HEART - SEQ_FLAG_RESTORE, // NA_BGM_TIMED_MINI_GAME - 0, // NA_BGM_GORON_RACE - 0, // NA_BGM_MUSIC_BOX_HOUSE - 0, // NA_BGM_FAIRY_FOUNTAIN - 0, // NA_BGM_ZELDAS_LULLABY - 0, // NA_BGM_ROSA_SISTERS - SEQ_FLAG_FANFARE, // NA_BGM_OPEN_CHEST - 0, // NA_BGM_MARINE_RESEARCH_LAB - SEQ_FLAG_SKIP_HARP_INTRO, // NA_BGM_GIANTS_THEME - 0, // NA_BGM_SONG_OF_STORMS - 0, // NA_BGM_ROMANI_RANCH - 0, // NA_BGM_GORON_VILLAGE - 0, // NA_BGM_MAYORS_OFFICE - SEQ_FLAG_FANFARE, // NA_BGM_OCA_EPONA - SEQ_FLAG_FANFARE, // NA_BGM_OCA_SUNS - SEQ_FLAG_FANFARE, // NA_BGM_OCA_TIME - SEQ_FLAG_FANFARE, // NA_BGM_OCA_STORM - SEQ_FLAG_RESUME, // NA_BGM_ZORA_HALL - SEQ_FLAG_FANFARE, // NA_BGM_GET_NEW_MASK - SEQ_FLAG_RESTORE, // NA_BGM_MINI_BOSS - SEQ_FLAG_FANFARE, // NA_BGM_GET_SMALL_ITEM - 0, // NA_BGM_ASTRAL_OBSERVATORY - SEQ_FLAG_ENEMY, // NA_BGM_CAVERN - SEQ_FLAG_RESUME | SEQ_FLAG_ENEMY, // NA_BGM_MILK_BAR - SEQ_FLAG_FANFARE, // NA_BGM_ZELDA_APPEAR - 0, // NA_BGM_SARIAS_SONG - 0, // NA_BGM_GORON_GOAL - 0, // NA_BGM_HORSE - 0, // NA_BGM_HORSE_GOAL - 0, // NA_BGM_INGO - 0, // NA_BGM_KOTAKE_POTION_SHOP - SEQ_FLAG_RESUME_PREV, // NA_BGM_SHOP - SEQ_FLAG_FANFARE, // NA_BGM_OWL - SEQ_FLAG_RESUME_PREV, // NA_BGM_MINI_GAME - SEQ_FLAG_FANFARE, // NA_BGM_OCA_SOARING - SEQ_FLAG_FANFARE, // NA_BGM_OCA_HEALING - SEQ_FLAG_FANFARE, // NA_BGM_INVERTED_SONG_OF_TIME - SEQ_FLAG_FANFARE, // NA_BGM_SONG_OF_DOUBLE_TIME - SEQ_FLAG_FANFARE, // NA_BGM_SONATA_OF_AWAKENING - SEQ_FLAG_FANFARE, // NA_BGM_GORON_LULLABY - SEQ_FLAG_FANFARE, // NA_BGM_NEW_WAVE_BOSSA_NOVA - SEQ_FLAG_FANFARE, // NA_BGM_ELEGY_OF_EMPTINESS - SEQ_FLAG_FANFARE, // NA_BGM_OATH_TO_ORDER - 0, // NA_BGM_SWORD_TRAINING_HALL - SEQ_FLAG_FANFARE, // NA_BGM_GORON_LULLABY_INTRO - SEQ_FLAG_FANFARE, // NA_BGM_OCA_FAIRY - SEQ_FLAG_FANFARE, // NA_BGM_BREMEN_MARCH - SEQ_FLAG_FANFARE, // NA_BGM_BALLAD_OF_THE_WIND_FISH - SEQ_FLAG_RESTORE, // NA_BGM_SONG_OF_SOARING - 0, // NA_BGM_MILK_BAR_DUPLICATE - 0, // NA_BGM_FINAL_HOURS - SEQ_FLAG_FANFARE, // NA_BGM_MIKAU_RIFF - SEQ_FLAG_FANFARE, // NA_BGM_MIKAU_FINALE - 0, // NA_BGM_FROG_SONG - SEQ_FLAG_FANFARE, // NA_BGM_OCA_SONATA - SEQ_FLAG_FANFARE, // NA_BGM_OCA_LULLABY - SEQ_FLAG_FANFARE, // NA_BGM_OCA_NEW_WAVE - SEQ_FLAG_FANFARE, // NA_BGM_OCA_ELEGY - SEQ_FLAG_FANFARE, // NA_BGM_OCA_OATH - 0, // NA_BGM_MAJORAS_LAIR - SEQ_FLAG_FANFARE, // NA_BGM_OCA_LULLABY_INTRO - SEQ_FLAG_FANFARE, // NA_BGM_OCA_GUITAR_BASS_SESSION - SEQ_FLAG_FANFARE, // NA_BGM_PIANO_SESSION - SEQ_FLAG_FANFARE, // NA_BGM_INDIGO_GO_SESSION - SEQ_FLAG_ENEMY, // NA_BGM_SNOWHEAD_TEMPLE - SEQ_FLAG_ENEMY, // NA_BGM_GREAT_BAY_TEMPLE - SEQ_FLAG_FANFARE, // NA_BGM_NEW_WAVE_SAXOPHONE - SEQ_FLAG_FANFARE, // NA_BGM_NEW_WAVE_VOCAL - 0, // NA_BGM_MAJORAS_WRATH - 0, // NA_BGM_MAJORAS_INCARNATION - 0, // NA_BGM_MAJORAS_MASK - SEQ_FLAG_FANFARE, // NA_BGM_BASS_PLAY - SEQ_FLAG_FANFARE, // NA_BGM_DRUMS_PLAY - SEQ_FLAG_FANFARE, // NA_BGM_PIANO_PLAY - SEQ_FLAG_ENEMY, // NA_BGM_IKANA_CASTLE - 0, // NA_BGM_GATHERING_GIANTS - SEQ_FLAG_FANFARE_KAMARO, // NA_BGM_KAMARO_DANCE - 0, // NA_BGM_CREMIA_CARRIAGE - SEQ_FLAG_FANFARE, // NA_BGM_KEATON_QUIZ - 0, // NA_BGM_END_CREDITS_1 - 0, // NA_BGM_OPENING_LOOP - 0, // NA_BGM_TITLE_THEME - SEQ_FLAG_FANFARE, // NA_BGM_DUNGEON_APPEAR - SEQ_FLAG_FANFARE, // NA_BGM_WOODFALL_CLEAR - SEQ_FLAG_FANFARE, // NA_BGM_SNOWHEAD_CLEAR - 0, // - 0, // NA_BGM_INTO_THE_MOON - 0, // NA_BGM_GOODBYE_GIANT - 0, // NA_BGM_TATL_AND_TAEL - 0, // NA_BGM_MOONS_DESTRUCTION - 0, // NA_BGM_END_CREDITS_2 -}; - -s8 sSpecReverbs[] = { - 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -#define AMBIENCE_CHANNEL_PROPERTIES_ENTRIES_MAX 33 - -typedef struct { - /* 0x0 */ u16 initChannelMask; // bitwise flag for 16 channels, channels to initialize - /* 0x2 */ u16 initMuteChannelMask; // bitwise flag for 16 channels, channels to mute upon initialization - /* 0x4 */ u8 channelProperties[3 * AMBIENCE_CHANNEL_PROPERTIES_ENTRIES_MAX + 1]; -} AmbienceDataIO; // size = 0x68 - -AmbienceDataIO sAmbienceData[20] = { - // AMBIENCE_ID_00 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | - (1 << AMBIENCE_CHANNEL_CRITTER_2) | (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | - (1 << AMBIENCE_CHANNEL_CRITTER_5) | (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | (1 << AMBIENCE_CHANNEL_CRITTER_2) | - (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | (1 << AMBIENCE_CHANNEL_CRITTER_5) | - (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_09), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_0_PORT5(32), - - // Channel 2 - AMBIENCE_IO_CRITTER_1_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_1_BEND_PITCH(0), - AMBIENCE_IO_CRITTER_1_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_1_PORT5(16), - - // Channel 3 - AMBIENCE_IO_CRITTER_2_TYPE(AMBIENCE_CRITTER_10), - AMBIENCE_IO_CRITTER_2_BEND_PITCH(112), - AMBIENCE_IO_CRITTER_2_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_2_PORT5(48), - - // Channel 4 - AMBIENCE_IO_CRITTER_3_TYPE(AMBIENCE_CRITTER_03), - AMBIENCE_IO_CRITTER_3_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_3_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_3_PORT5(16), - - // Channel 5 - AMBIENCE_IO_CRITTER_4_TYPE(AMBIENCE_CRITTER_00), - AMBIENCE_IO_CRITTER_4_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_4_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_4_PORT5(16), - - // Channel 6 - AMBIENCE_IO_CRITTER_5_TYPE(AMBIENCE_CRITTER_01), - AMBIENCE_IO_CRITTER_5_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_5_NUM_LAYERS(3), - AMBIENCE_IO_CRITTER_5_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_01 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | - (1 << AMBIENCE_CHANNEL_CRITTER_2) | (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | - (1 << AMBIENCE_CHANNEL_CRITTER_5) | (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | (1 << AMBIENCE_CHANNEL_CRITTER_2) | - (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | (1 << AMBIENCE_CHANNEL_CRITTER_5) | - (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_0_PORT5(32), - - // Channel 2 - AMBIENCE_IO_CRITTER_1_TYPE(AMBIENCE_CRITTER_16), - AMBIENCE_IO_CRITTER_1_BEND_PITCH(0), - AMBIENCE_IO_CRITTER_1_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_1_PORT5(16), - - // Channel 3 - AMBIENCE_IO_CRITTER_2_TYPE(AMBIENCE_CRITTER_12), - AMBIENCE_IO_CRITTER_2_BEND_PITCH(112), - AMBIENCE_IO_CRITTER_2_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_2_PORT5(48), - - // Channel 4 - AMBIENCE_IO_CRITTER_3_TYPE(AMBIENCE_CRITTER_15), - AMBIENCE_IO_CRITTER_3_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_3_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_3_PORT5(16), - - // Channel 5 - AMBIENCE_IO_CRITTER_4_TYPE(AMBIENCE_CRITTER_06), - AMBIENCE_IO_CRITTER_4_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_4_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_4_PORT5(16), - - // Channel 6 - AMBIENCE_IO_CRITTER_5_TYPE(AMBIENCE_CRITTER_01), - AMBIENCE_IO_CRITTER_5_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_5_NUM_LAYERS(3), - AMBIENCE_IO_CRITTER_5_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_02 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | - (1 << AMBIENCE_CHANNEL_CRITTER_2) | (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | - (1 << AMBIENCE_CHANNEL_CRITTER_5) | (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | (1 << AMBIENCE_CHANNEL_CRITTER_2) | - (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | (1 << AMBIENCE_CHANNEL_CRITTER_5) | - (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_0_PORT5(48), - - // Channel 2 - AMBIENCE_IO_CRITTER_1_TYPE(AMBIENCE_CRITTER_10), - AMBIENCE_IO_CRITTER_1_BEND_PITCH(0), - AMBIENCE_IO_CRITTER_1_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_1_PORT5(16), - - // Channel 3 - AMBIENCE_IO_CRITTER_2_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_2_BEND_PITCH(48), - AMBIENCE_IO_CRITTER_2_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_2_PORT5(32), - - // Channel 4 - AMBIENCE_IO_CRITTER_3_TYPE(AMBIENCE_CRITTER_03), - AMBIENCE_IO_CRITTER_3_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_3_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_3_PORT5(16), - - // Channel 5 - AMBIENCE_IO_CRITTER_4_TYPE(AMBIENCE_CRITTER_01), - AMBIENCE_IO_CRITTER_4_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_4_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_4_PORT5(0), - - // Channel 6 - AMBIENCE_IO_CRITTER_5_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_5_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_5_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_5_PORT5(63), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_03 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | - (1 << AMBIENCE_CHANNEL_CRITTER_2) | (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | - (1 << AMBIENCE_CHANNEL_CRITTER_5) | (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | (1 << AMBIENCE_CHANNEL_CRITTER_2) | - (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | (1 << AMBIENCE_CHANNEL_CRITTER_5) | - (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_09), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_0_PORT5(32), - - // Channel 2 - AMBIENCE_IO_CRITTER_1_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_1_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_1_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_1_PORT5(48), - - // Channel 3 - AMBIENCE_IO_CRITTER_2_TYPE(AMBIENCE_CRITTER_10), - AMBIENCE_IO_CRITTER_2_BEND_PITCH(32), - AMBIENCE_IO_CRITTER_2_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_2_PORT5(32), - - // Channel 4 - AMBIENCE_IO_CRITTER_3_TYPE(AMBIENCE_CRITTER_14), - AMBIENCE_IO_CRITTER_3_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_3_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_3_PORT5(16), - - // Channel 5 - AMBIENCE_IO_CRITTER_4_TYPE(AMBIENCE_CRITTER_00), - AMBIENCE_IO_CRITTER_4_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_4_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_4_PORT5(16), - - // Channel 6 - AMBIENCE_IO_CRITTER_5_TYPE(AMBIENCE_CRITTER_01), - AMBIENCE_IO_CRITTER_5_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_5_NUM_LAYERS(3), - AMBIENCE_IO_CRITTER_5_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_04 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | - (1 << AMBIENCE_CHANNEL_CRITTER_2) | (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | - (1 << AMBIENCE_CHANNEL_CRITTER_5) | (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | (1 << AMBIENCE_CHANNEL_CRITTER_2) | - (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | (1 << AMBIENCE_CHANNEL_CRITTER_5) | - (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_0_PORT5(32), - - // Channel 2 - AMBIENCE_IO_CRITTER_1_TYPE(AMBIENCE_CRITTER_02), - AMBIENCE_IO_CRITTER_1_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_1_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_1_PORT5(16), - - // Channel 3 - AMBIENCE_IO_CRITTER_2_TYPE(AMBIENCE_CRITTER_12), - AMBIENCE_IO_CRITTER_2_BEND_PITCH(112), - AMBIENCE_IO_CRITTER_2_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_2_PORT5(48), - - // Channel 4 - AMBIENCE_IO_CRITTER_3_TYPE(AMBIENCE_CRITTER_13), - AMBIENCE_IO_CRITTER_3_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_3_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_3_PORT5(16), - - // Channel 5 - AMBIENCE_IO_CRITTER_4_TYPE(AMBIENCE_CRITTER_01), - AMBIENCE_IO_CRITTER_4_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_4_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_4_PORT5(16), - - // Channel 6 - AMBIENCE_IO_CRITTER_5_TYPE(AMBIENCE_CRITTER_02), - AMBIENCE_IO_CRITTER_5_BEND_PITCH(112), - AMBIENCE_IO_CRITTER_5_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_5_PORT5(48), - - // Channel 14 - AMBIENCE_IO_RAIN_PORT4(63), - - // End - AMBIENCE_IO_ENTRIES_END, - - }, - }, - - // AMBIENCE_ID_05 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | - (1 << AMBIENCE_CHANNEL_CRITTER_2) | (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | - (1 << AMBIENCE_CHANNEL_CRITTER_5) | (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | (1 << AMBIENCE_CHANNEL_CRITTER_2) | - (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | (1 << AMBIENCE_CHANNEL_CRITTER_5) | - (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_09), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(64), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_0_PORT5(32), - - // Channel 2 - AMBIENCE_IO_CRITTER_1_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_1_BEND_PITCH(0), - AMBIENCE_IO_CRITTER_1_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_1_PORT5(16), - - // Channel 3 - AMBIENCE_IO_CRITTER_2_TYPE(AMBIENCE_CRITTER_10), - AMBIENCE_IO_CRITTER_2_BEND_PITCH(112), - AMBIENCE_IO_CRITTER_2_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_2_PORT5(48), - - // Channel 4 - AMBIENCE_IO_CRITTER_3_TYPE(AMBIENCE_CRITTER_13), - AMBIENCE_IO_CRITTER_3_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_3_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_3_PORT5(63), - - // Channel 5 - AMBIENCE_IO_CRITTER_4_TYPE(AMBIENCE_CRITTER_00), - AMBIENCE_IO_CRITTER_4_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_4_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_4_PORT5(16), - - // Channel 6 - AMBIENCE_IO_CRITTER_5_TYPE(AMBIENCE_CRITTER_01), - AMBIENCE_IO_CRITTER_5_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_5_NUM_LAYERS(3), - AMBIENCE_IO_CRITTER_5_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_06 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | - (1 << AMBIENCE_CHANNEL_CRITTER_2) | (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | - (1 << AMBIENCE_CHANNEL_CRITTER_5) | (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | (1 << AMBIENCE_CHANNEL_CRITTER_2) | - (1 << AMBIENCE_CHANNEL_CRITTER_3) | (1 << AMBIENCE_CHANNEL_CRITTER_4) | (1 << AMBIENCE_CHANNEL_CRITTER_5) | - (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_11), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(112), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_0_PORT5(48), - - // Channel 2 - AMBIENCE_IO_CRITTER_1_TYPE(AMBIENCE_CRITTER_15), - AMBIENCE_IO_CRITTER_1_BEND_PITCH(112), - AMBIENCE_IO_CRITTER_1_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_1_PORT5(63), - - // Channel 3 - AMBIENCE_IO_CRITTER_2_TYPE(AMBIENCE_CRITTER_11), - AMBIENCE_IO_CRITTER_2_BEND_PITCH(48), - AMBIENCE_IO_CRITTER_2_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_2_PORT5(16), - - // Channel 4 - AMBIENCE_IO_CRITTER_3_TYPE(AMBIENCE_CRITTER_14), - AMBIENCE_IO_CRITTER_3_BEND_PITCH(48), - AMBIENCE_IO_CRITTER_3_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_3_PORT5(16), - - // Channel 5 - AMBIENCE_IO_CRITTER_4_TYPE(AMBIENCE_CRITTER_11), - AMBIENCE_IO_CRITTER_4_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_4_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_4_PORT5(32), - - // Channel 6 - AMBIENCE_IO_CRITTER_5_TYPE(AMBIENCE_CRITTER_02), - AMBIENCE_IO_CRITTER_5_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_5_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_5_PORT5(48), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_07 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_08 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_01), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(3), - AMBIENCE_IO_CRITTER_0_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_09 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | - (1 << AMBIENCE_CHANNEL_CRITTER_2) | (1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_16), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(0), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(2), - AMBIENCE_IO_CRITTER_0_PORT5(16), - - // Channel 2 - AMBIENCE_IO_CRITTER_1_TYPE(AMBIENCE_CRITTER_12), - AMBIENCE_IO_CRITTER_1_BEND_PITCH(112), - AMBIENCE_IO_CRITTER_1_NUM_LAYERS(0), - AMBIENCE_IO_CRITTER_1_PORT5(48), - - // Channel 3 - AMBIENCE_IO_CRITTER_2_TYPE(AMBIENCE_CRITTER_15), - AMBIENCE_IO_CRITTER_2_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_2_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_2_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_0A - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_6) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_1), - AMBIENCE_IO_STREAM_0_PORT3(8), - - // Channel 7 - AMBIENCE_IO_CRITTER_6_TYPE(AMBIENCE_CRITTER_11), - AMBIENCE_IO_CRITTER_6_BEND_PITCH(112), - AMBIENCE_IO_CRITTER_6_NUM_LAYERS(2), - AMBIENCE_IO_CRITTER_6_PORT5(32), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_0B - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | - (1 << AMBIENCE_CHANNEL_CRITTER_2) | (1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_3), - AMBIENCE_IO_STREAM_0_PORT3(8), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_01), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(3), - AMBIENCE_IO_CRITTER_0_PORT5(16), - - // Channel 2 - AMBIENCE_IO_CRITTER_1_TYPE(AMBIENCE_CRITTER_00), - AMBIENCE_IO_CRITTER_1_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_1_NUM_LAYERS(2), - AMBIENCE_IO_CRITTER_1_PORT5(16), - - // Channel 3 - AMBIENCE_IO_CRITTER_2_TYPE(AMBIENCE_CRITTER_06), - AMBIENCE_IO_CRITTER_2_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_2_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_2_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_0C - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_CRITTER_1) | - (1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_00), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_0_PORT5(16), - - // Channel 2 - AMBIENCE_IO_CRITTER_1_TYPE(AMBIENCE_CRITTER_01), - AMBIENCE_IO_CRITTER_1_BEND_PITCH(127), - AMBIENCE_IO_CRITTER_1_NUM_LAYERS(3), - AMBIENCE_IO_CRITTER_1_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_0D - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(0), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_0_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_0E - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(0), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_0_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_0F - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(0), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_0_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_10 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(0), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_0_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_11 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(0), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_0_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_12 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - // Channel 0 - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - - // End - AMBIENCE_IO_ENTRIES_END, - }, - }, - - // AMBIENCE_ID_13 - { - // Init channel mask - ((1 << AMBIENCE_CHANNEL_STREAM_0) | (1 << AMBIENCE_CHANNEL_CRITTER_0) | (1 << AMBIENCE_CHANNEL_RAIN) | - (1 << AMBIENCE_CHANNEL_LIGHTNING)), - // Init mute channel mask - ((1 << AMBIENCE_CHANNEL_RAIN) | (1 << AMBIENCE_CHANNEL_LIGHTNING)), - { - AMBIENCE_IO_STREAM_0_TYPE(AMBIENCE_STREAM_0), - AMBIENCE_IO_STREAM_0_PORT3(0), - - // Channel 1 - AMBIENCE_IO_CRITTER_0_TYPE(AMBIENCE_CRITTER_04), - AMBIENCE_IO_CRITTER_0_BEND_PITCH(0), - AMBIENCE_IO_CRITTER_0_NUM_LAYERS(1), - AMBIENCE_IO_CRITTER_0_PORT5(16), - - // End - AMBIENCE_IO_ENTRIES_END, - - }, - }, -}; - -// AudioOcarina Data -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 sDefaultOcarinaVolume = 87.0f / 127.0f; -s8 sCurOcarinaBendIndex = 0; -s8 sCurOcarinaVolume = 87; -s8 sCurOcarinaVibrato = 0; -u8 sPlaybackState = 0; -u8 sPlaybackStaffStopPos = 0xFF; -u8 sPlaybackStaffStartPos = 0xFF; -u32 sOcarinaFlags = 0; -s32 sPlaybackNoteTimer = 0; -u16 sPlaybackNotePos = 0; -u16 sPlaybackStaffPos = 0; -u32 sPrevOcarinaWithMusicStaffFlags = 0; // Stores sOcarinaFlags but never used -u8 sPlaybackPitch = OCARINA_PITCH_NONE; // Pitch + PitchFlags -u8 sNotePlaybackVolume = 0; -u8 sNotePlaybackVibrato = 0; -s8 sNotePlaybackBend = 0; -f32 sRelativeNotePlaybackBend = 1.0f; -f32 sRelativeNotePlaybackVolume = 1.0f; -u32 sOcarinaPlaybackTaskStart = 0; -u32 sOcarinaWallCounter = 0; -u8 sCurOcarinaSongWithoutMusicStaff[8] = { - OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, - OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, -}; -u8 sOcarinaWithoutMusicStaffPos = 0; -u8 sOcarinaSongStartingPos = 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 sOcarinaMemoryGameAppendPos = 0; -u8 sOcarinaMemoryGameEndPos = 0; -u8 sOcarinaMemoryGameNumNotes[] = { 5, 6, 8 }; -OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { - // OCARINA_SONG_SONATA - { - { OCARINA_PITCH_D5, 19, 92, 0, 0, 0 }, - { OCARINA_PITCH_B4, 19, 90, 0, 0, 0 }, - { OCARINA_PITCH_D5, 19, 90, 0, 0, 0 }, - { OCARINA_PITCH_B4, 38, 90, 0, 0, 0 }, - { OCARINA_PITCH_D4, 39, 92, 0, 0, 0 }, - { OCARINA_PITCH_A4, 76, 89, 0, 0, 0 }, - { OCARINA_PITCH_D4, 77, 82, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 86, 0, 0, 0 }, - }, - - // OCARINA_SONG_GORON_LULLABY - { - { OCARINA_PITCH_D4, 41, 80, 0, 0, 0 }, - { OCARINA_PITCH_A4, 40, 72, 0, 0, 0 }, - { OCARINA_PITCH_B4, 39, 84, 0, 0, 0 }, - { OCARINA_PITCH_D4, 42, 76, 0, 0, 0 }, - { OCARINA_PITCH_A4, 40, 84, 0, 0, 0 }, - { OCARINA_PITCH_B4, 39, 76, 0, 0, 0 }, - { OCARINA_PITCH_A4, 41, 84, 0, 0, 0 }, - { OCARINA_PITCH_D4, 80, 76, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 40, 76, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, - }, - - // OCARINA_SONG_NEW_WAVE - { - { OCARINA_PITCH_B4, 64, 74, 0, 0, 0 }, - { OCARINA_PITCH_D5, 13, 88, 0, 0, 0 }, - { OCARINA_PITCH_B4, 12, 90, 0, 0, 0 }, - { OCARINA_PITCH_A4, 78, 88, 0, 0, 0 }, - { OCARINA_PITCH_F4, 12, 76, 0, 0, 0 }, - { OCARINA_PITCH_B4, 13, 76, 0, 0, 0 }, - { OCARINA_PITCH_A4, 114, 76, 6, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, - }, - - // OCARINA_SONG_ELEGY - { - { OCARINA_PITCH_A4, 85, 93, 0, 0, 0 }, - { OCARINA_PITCH_B4, 43, 91, 0, 0, 0 }, - { OCARINA_PITCH_A4, 43, 93, 0, 0, 0 }, - { OCARINA_PITCH_F4, 21, 88, 0, 0, 0 }, - { OCARINA_PITCH_A4, 21, 88, 0, 0, 0 }, - { OCARINA_PITCH_D5, 43, 101, 0, 0, 0 }, - { OCARINA_PITCH_B4, 85, 95, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 94, 0, 0, 0 }, - }, - - // OCARINA_SONG_OATH - { - { OCARINA_PITCH_A4, 97, 104, 0, 0, 0 }, - { OCARINA_PITCH_F4, 48, 88, 0, 0, 0 }, - { OCARINA_PITCH_D4, 49, 78, 0, 0, 0 }, - { OCARINA_PITCH_F4, 49, 78, 0, 0, 0 }, - { OCARINA_PITCH_A4, 48, 94, 0, 0, 0 }, - { OCARINA_PITCH_D5, 97, 100, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 96, 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_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_HEALING - { - { OCARINA_PITCH_B4, 32, 88, 0, 0, 0 }, - { OCARINA_PITCH_A4, 33, 88, 0, 0, 0 }, - { OCARINA_PITCH_F4, 33, 69, 0, 0, 0 }, - { OCARINA_PITCH_B4, 32, 94, 0, 0, 0 }, - { OCARINA_PITCH_A4, 33, 88, 0, 0, 0 }, - { OCARINA_PITCH_F4, 121, 86, 2, 0, 0 }, - { OCARINA_PITCH_NONE, 10, 84, 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_SOARING - { - { OCARINA_PITCH_F4, 18, 84, 0, 0, 0 }, - { OCARINA_PITCH_B4, 18, 80, 0, 0, 0 }, - { OCARINA_PITCH_D5, 36, 94, 0, 0, 0 }, - { OCARINA_PITCH_F4, 18, 73, 0, 0, 0 }, - { OCARINA_PITCH_B4, 18, 76, 0, 0, 0 }, - { OCARINA_PITCH_D5, 108, 96, 2, 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_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_INVERTED_TIME - { - { OCARINA_PITCH_F4, 32, 84, 0, 0, 0 }, - { OCARINA_PITCH_D4, 65, 88, 0, 0, 0 }, - { OCARINA_PITCH_A4, 33, 80, 0, 0, 0 }, - { OCARINA_PITCH_F4, 32, 84, 0, 0, 0 }, - { OCARINA_PITCH_D4, 65, 88, 0, 0, 0 }, - { OCARINA_PITCH_A4, 99, 80, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, - }, - - // OCARINA_SONG_DOUBLE_TIME - { - { OCARINA_PITCH_A4, 29, 84, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, - { OCARINA_PITCH_A4, 30, 84, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, - { OCARINA_PITCH_D4, 29, 84, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, - { OCARINA_PITCH_D4, 30, 84, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, - { OCARINA_PITCH_F4, 29, 84, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, - { OCARINA_PITCH_F4, 99, 84, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 }, - }, - - // OCARINA_SONG_GORON_LULLABY_INTRO - { - { OCARINA_PITCH_D4, 32, 78, 0, 0, 0 }, - { OCARINA_PITCH_A4, 33, 90, 0, 0, 0 }, - { OCARINA_PITCH_B4, 33, 87, 0, 0, 0 }, - { OCARINA_PITCH_D4, 32, 92, 0, 0, 0 }, - { OCARINA_PITCH_A4, 33, 86, 0, 0, 0 }, - { OCARINA_PITCH_B4, 130, 80, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, - }, - - // OCARINA_SONG_WIND_FISH_HUMAN - { - { OCARINA_PITCH_D5, 89, 80, 0, 0, 0 }, - { OCARINA_PITCH_A4, 41, 72, 0, 0, 0 }, - { OCARINA_PITCH_B4, 22, 84, 0, 0, 0 }, - { OCARINA_PITCH_A4, 91, 76, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 30, 66, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, - }, - - // OCARINA_SONG_WIND_FISH_GORON - { - { OCARINA_PITCH_D4, 52, 80, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, - { OCARINA_PITCH_D4, 8, 72, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, - { OCARINA_PITCH_D4, 30, 84, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, - { OCARINA_PITCH_F4, 34, 76, 0, 0, 0 }, - { OCARINA_PITCH_D4, 52, 80, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, - { OCARINA_PITCH_D4, 8, 72, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, - { OCARINA_PITCH_D4, 30, 84, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, - { OCARINA_PITCH_A4, 34, 76, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, - }, - - // OCARINA_SONG_WIND_FISH_ZORA - { - { OCARINA_PITCH_D5, 11, 80, 0, 0, 0 }, - { OCARINA_PITCH_A4, 11, 72, 0, 0, 0 }, - { OCARINA_PITCH_F4, 11, 84, 0, 0, 0 }, - { OCARINA_PITCH_D4, 100, 76, 0, 0, 0 }, - { OCARINA_PITCH_D5, 11, 84, 0, 0, 0 }, - { OCARINA_PITCH_B4, 11, 76, 0, 0, 0 }, - { OCARINA_PITCH_A4, 11, 72, 0, 0, 0 }, - { OCARINA_PITCH_F4, 100, 84, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, - }, - - // OCARINA_SONG_WIND_FISH_DEKU - { - { OCARINA_PITCH_A4, 54, 80, 0, 0, 0 }, - { OCARINA_PITCH_D4, 77, 72, 0, 0, 0 }, - { OCARINA_PITCH_F4, 19, 84, 0, 0, 0 }, - { OCARINA_PITCH_B4, 20, 76, 0, 0, 0 }, - { OCARINA_PITCH_A4, 78, 84, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, - }, - - // OCARINA_SONG_EVAN_PART1 - { - { OCARINA_PITCH_A4, 33, 100, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 92, 0, 0, 0 }, - { OCARINA_PITCH_A4, 37, 104, 0, 0, 0 }, - { OCARINA_PITCH_F4, 24, 100, 0, 0, 0 }, - { OCARINA_PITCH_D4, 70, 97, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 96, 0, 0, 0 }, - { OCARINA_PITCH_D4, 12, 93, 0, 0, 0 }, - { OCARINA_PITCH_F4, 12, 100, 0, 0, 0 }, - { OCARINA_PITCH_A4, 12, 62, 0, 0, 0 }, - { OCARINA_PITCH_D4, 170, 91, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, - }, - - // OCARINA_SONG_EVAN_PART2 - { - { OCARINA_PITCH_B4, 33, 107, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 100, 0, 0, 0 }, - { OCARINA_PITCH_B4, 37, 104, 0, 0, 0 }, - { OCARINA_PITCH_A4, 24, 97, 0, 0, 0 }, - { OCARINA_PITCH_F4, 70, 104, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 3, 104, 0, 0, 0 }, - { OCARINA_PITCH_F4, 12, 90, 0, 0, 0 }, - { OCARINA_PITCH_A4, 12, 96, 0, 0, 0 }, - { OCARINA_PITCH_B4, 12, 81, 0, 0, 0 }, - { OCARINA_PITCH_F4, 170, 66, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, - }, - - // OCARINA_SONG_ZELDAS_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_SCARECROW_SPAWN - { - { OCARINA_PITCH_D4, 3, 0, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 255, 0, 0, 0 }, - }, - - // OCARINA_SONG_TERMINA_WALL - { - { OCARINA_PITCH_D4, 3, 0, 0, 0, 0 }, - { OCARINA_PITCH_NONE, 0, 255, 0, 0, 0 }, - }, -}; - -OcarinaNote sOoTOcarinaSongNotes[9][20] = { - // 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 }, - }, - - // 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 }, - }, - - // 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 }, - }, - - // 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 }, - }, - - // 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 }, - }, - - // 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 }, - }, - - // 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 }, - }, - - // Zeldas 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 }, - }, - - // Suns Song - { - { 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 }, - }, -}; - -u8 sOoTOcarinaSongsNumNotes[] = { - 6, // Minuet - 8, // Bolero - 5, // Serenade - 6, // Requiem - 7, // Nocturne - 6, // Prelude - 6, // Sarias - 6, // Zeldas Lullaby - 6, // Suns Song -}; - -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 D_801D8530 = false; -u32 D_801D8534 = 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* sTerminaWallSongPtr = sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL]; - -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 -}; - -// seqData written in the music macro language -// Only used in unused functions -// clang-format off -u8 sCustomSequenceScript[400] = { - /* 0 */ 0xFE, // delay1 - /* 1 */ 0xFE, // delay1 - /* 2 */ 0xD3, 0x20, // mutebhv 0x20 - /* 4 */ 0xD7, 0x00, 0x01, // initchan 0x0001 - /* 7 */ 0xCC, 0x00, // ldi 0 - /* 9 */ 0x70, // stio 0 - /* 10 */ 0x90, 0x00, 22, // ldchan 0, chan0 - /* 13 */ 0xDB, 100, // vol 100 - /* 15 */ 0xDD, 120, // tempo 120 - - // .sequence seq_loop - /* 17 */ 0xFE, // delay1 - /* 18 */ 0x00, // testchan 0 - /* 19 */ 0xF3, -4, // rbeqz seq_loop - /* 21 */ 0xFF, // end - - // .channel chan0 - /* 22 */ 0xC3, // short - /* 23 */ 0x88, 0x00, 41, // ldlayer 0, layer0 - /* 26 */ 0x89, 0x00, 43, // ldlayer 1, layer1 - /* 29 */ 0xDF, 127, // vol 127 - /* 31 */ 0xE9, 0x0F, // notepri 0x0F - /* 33 */ 0xDD, 55, // pan 55 - /* 35 */ 0xD4, 64, // reverb 64 - /* 37 */ 0xC1, 82, // instr 82 - - // .channel chan_loop - /* 39 */ 0xFE, // delay1 - /* 40 */ 0x80, // testlayer 0 - - // (no end or loop; channel script seems to run into the note layers?) - - // .layer layer0 - /* 41 */ 0xF3, -4, // rbeqz chan_loop - - // .layer layer1 - /* 43 */ 0xFF, // end - - // .layer layer2? - /* 44 */ 0xC2, -5, // transpose -5 - /* 46 */ 0xC0, 0, // ldelay 0 - /* 48 */ 0xC1, 87, // shortvel 87 - /* 50 */ 0xC9, 0, // shortgate 0 - /* 52 */ 0, // empty until the end -}; -// clang-format on - -OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { - // OCARINA_SONG_SONATA - { - 7, - { - OCARINA_BTN_C_UP, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_A, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_A, - }, - }, - - // OCARINA_SONG_GORON_LULLABY - { - 8, - { - OCARINA_BTN_A, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_A, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_A, - }, - }, - - // OCARINA_SONG_NEW_WAVE - { - 7, - { - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - }, - }, - - // OCARINA_SONG_ELEGY - { - 7, - { - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_LEFT, - }, - }, - - // OCARINA_SONG_OATH - { - 6, - { - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_RIGHT, - 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_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_HEALING - { - 6, - { - 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_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_SOARING - { - 6, - { - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_UP, - }, - }, - - // 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_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_INVERTED_TIME - { - 6, - { - OCARINA_BTN_C_DOWN, - OCARINA_BTN_A, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_A, - OCARINA_BTN_C_RIGHT, - }, - }, - - // OCARINA_SONG_DOUBLE_TIME - { - 6, - { - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_DOWN, - }, - }, - - // OCARINA_SONG_GORON_LULLABY_INTRO - { - 6, - { - OCARINA_BTN_A, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_A, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - }, - }, - - // OCARINA_SONG_WIND_FISH_HUMAN - { - 4, - { - OCARINA_BTN_C_UP, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - }, - }, - - // OCARINA_SONG_WIND_FISH_GORON - { - 8, - { - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_C_RIGHT, - }, - }, - - // OCARINA_SONG_WIND_FISH_ZORA - { - 8, - { - OCARINA_BTN_C_UP, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_A, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - }, - }, - - // OCARINA_SONG_WIND_FISH_DEKU - { - 5, - { - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - }, - }, - - // OCARINA_SONG_EVAN_PART1 - { - 8, - { - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_A, - }, - }, - - // OCARINA_SONG_EVAN_PART2 - { - 8, - { - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_DOWN, - }, - }, - - // OCARINA_SONG_ZELDAS_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_SCARECROW_SPAWN - { - 8, - { - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_A, - OCARINA_BTN_A, - }, - }, - - // OCARINA_SONG_TERMINA_WALL - { - 8, - { - OCARINA_BTN_A, - OCARINA_BTN_C_DOWN, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_UP, - OCARINA_BTN_C_LEFT, - OCARINA_BTN_C_RIGHT, - OCARINA_BTN_C_DOWN, - }, - }, -}; - -const u16 gAudioEnvironmentalSfx[] = { - NA_SE_EV_RIVER_STREAM - SFX_FLAG, NA_SE_EV_WAVE - SFX_FLAG, - NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, NA_SE_EV_WATER_WALL - SFX_FLAG, - NA_SE_EV_MAGMA_LEVEL - SFX_FLAG, NA_SE_EV_MAGMA_LEVEL_M - SFX_FLAG, - NA_SE_EV_MAGMA_LEVEL_L - SFX_FLAG, NA_SE_EV_TORCH - SFX_FLAG, - NA_SE_EV_FOUNTAIN - SFX_FLAG, NA_SE_EV_DRAIN - SFX_FLAG, - NA_SE_EV_CROWD - SFX_FLAG, NA_SE_EV_WATER_CONVECTION - SFX_FLAG, - NA_SE_EV_GORON_CHEER - SFX_FLAG, NA_SE_EV_WATER_WALL_BIG_SILENT - SFX_FLAG, - NA_SE_EV_WATER_BUBBLE - SFX_FLAG, NA_SE_EV_COW_CRY_LV - SFX_FLAG, - NA_SE_EV_MAKE_TURRET - SFX_FLAG, NA_SE_EV_BOILED_WATER_S - SFX_FLAG, - NA_SE_EV_BOILED_WATER_L - SFX_FLAG, NA_SE_EV_WAVE_S - SFX_FLAG, - NA_SE_EV_WAVE_S - SFX_FLAG, NA_SE_EV_WAVE_S - SFX_FLAG, -}; - -const u8 sIsOcarinaSongReserved[OCARINA_SONG_MAX] = { - true, // OCARINA_SONG_SONATA - true, // OCARINA_SONG_GORON_LULLABY - true, // OCARINA_SONG_NEW_WAVE - true, // OCARINA_SONG_ELEGY - true, // OCARINA_SONG_OATH - false, // OCARINA_SONG_SARIAS - true, // OCARINA_SONG_TIME - true, // OCARINA_SONG_HEALING - true, // OCARINA_SONG_EPONAS - true, // OCARINA_SONG_SOARING - true, // OCARINA_SONG_STORMS - false, // OCARINA_SONG_SUNS - true, // OCARINA_SONG_INVERTED_TIME - true, // OCARINA_SONG_DOUBLE_TIME - true, // OCARINA_SONG_GORON_LULLABY_INTRO - false, // OCARINA_SONG_WIND_FISH_HUMAN - false, // OCARINA_SONG_WIND_FISH_GORON - false, // OCARINA_SONG_WIND_FISH_ZORA - false, // OCARINA_SONG_WIND_FISH_DEKU - true, // OCARINA_SONG_EVAN_PART1 - true, // OCARINA_SONG_EVAN_PART2 - false, // OCARINA_SONG_ZELDAS_LULLABY - true, // OCARINA_SONG_SCARECROW_SPAWN - false, // OCARINA_SONG_TERMINA_WALL -}; - -const char sAudioOcarinaUnusedText0[] = "key step is too long !!! %d:%d>%d\n"; -const char sAudioOcarinaUnusedText1[] = "You played %d Melody !!! (last step:%d)\n"; -const char sAudioOcarinaUnusedText2[] = "pass 0\n"; -const char sAudioOcarinaUnusedText3[] = "pass 1\n"; -const char sAudioOcarinaUnusedText4[] = "pass 2\n"; -const char sAudioOcarinaUnusedText5[] = "last key is bad !!! %d %d %02X %02X\n"; -const char sAudioOcarinaUnusedText6[] = "last key step is too short !!! %d:%d %d<%d\n"; -const char sAudioOcarinaUnusedText7[] = "check is over!!! %d %d %d\n"; - -void AudioOcarina_ReadControllerInput(void) { - Input inputs[4]; - Input* input = &inputs[0]; - u32 ocarinaInputButtonPrev = sOcarinaInputButtonCur; - - Padmgr_GetInput2(inputs, 0); - sOcarinaInputButtonCur = input->cur.button; - sOcarinaInputButtonPrev = ocarinaInputButtonPrev; - sOcarinaInputStickRel.x = input->rel.stick_x; - sOcarinaInputStickRel.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_MapPitchToButton(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 pitch 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 & OCARINA_BUTTON_FLAG_BFLAT_RAISE) { - return OCARINA_BTN_C_RIGHT; - } - // OCARINA_BUTTON_FLAG_BFLAT_LOWER - return OCARINA_BTN_C_LEFT; - } - - return buttonIndex; -} - -void AudioOcarina_MapSongFromPitchToButton(u8 noteSongIndex, u8 buttonSongIndex, u8 numButtons) { - u8 buttonSongPos = 0; - u8 noteSongPos = 0; - u8 pitch; - - while ((buttonSongPos < numButtons) && (noteSongPos < 16)) { - pitch = sOcarinaSongNotes[noteSongIndex][noteSongPos++].pitch; - - if (pitch != OCARINA_PITCH_NONE) { - gOcarinaSongButtons[buttonSongIndex].buttonIndex[buttonSongPos++] = sPitchToButtonMap[pitch]; - } - } - - gOcarinaSongButtons[buttonSongIndex].numButtons = numButtons; -} - -/** - * 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) - */ - -// The ocarina songs that can be performed at any time = 0x3FFF -#define OCARINA_SONGS_PLAYABLE_FLAGS \ - ((1 << OCARINA_SONG_SONATA) | (1 << OCARINA_SONG_GORON_LULLABY) | (1 << OCARINA_SONG_NEW_WAVE) | \ - (1 << OCARINA_SONG_ELEGY) | (1 << OCARINA_SONG_OATH) | (1 << OCARINA_SONG_SARIAS) | (1 << OCARINA_SONG_TIME) | \ - (1 << OCARINA_SONG_HEALING) | (1 << OCARINA_SONG_EPONAS) | (1 << OCARINA_SONG_SOARING) | \ - (1 << OCARINA_SONG_STORMS) | (1 << OCARINA_SONG_SUNS) | (1 << OCARINA_SONG_INVERTED_TIME) | \ - (1 << OCARINA_SONG_DOUBLE_TIME)) - -void AudioOcarina_Start(u32 ocarinaFlags) { - u8 songIndex; - - if ((sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF) && - ((ocarinaFlags & OCARINA_SONGS_PLAYABLE_FLAGS) == OCARINA_SONGS_PLAYABLE_FLAGS)) { - ocarinaFlags |= (1 << OCARINA_SONG_SCARECROW_SPAWN); - } - - if ((ocarinaFlags == (0xC0000000 | OCARINA_SONGS_PLAYABLE_FLAGS)) && - (sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF)) { - ocarinaFlags = (0xC0000000 | OCARINA_SONGS_PLAYABLE_FLAGS); - } - - if ((ocarinaFlags == OCARINA_SONGS_PLAYABLE_FLAGS) && - (sOcarinaSongNotes[OCARINA_SONG_SCARECROW_SPAWN][1].volume != 0xFF)) { - ocarinaFlags = OCARINA_SONGS_PLAYABLE_FLAGS; - } - - if (ocarinaFlags != 0xFFFF) { - sOcarinaFlags = 0x80000000 + ocarinaFlags; - sFirstOcarinaSongIndex = 0; - sLastOcarinaSongIndex = OCARINA_SONG_MAX; - sOcarinaAvailableSongFlags = ocarinaFlags & 0xFFFFFF; - sMusicStaffNumNotesPerTest = 8; // Ocarina Check - sOcarinaHasStartedSong = false; - sPlayedOcarinaSongIndexPlusOne = 0; - sOcarinaStaffPlayingPos = 0; - sPlayingStaff.state = AudioOcarina_GetPlayingState(); - sIsOcarinaInputEnabled = true; - sPrevOcarinaWithMusicStaffFlags = 0; - - // Reset music staff song check - for (songIndex = OCARINA_SONG_SONATA; songIndex <= OCARINA_SONG_EVAN_PART2; songIndex++) { - for (sMusicStaffPos[songIndex] = 0; - sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]].pitch == OCARINA_PITCH_NONE;) { - sMusicStaffPos[songIndex]++; - } - - sMusicStaffCurHeldLength[songIndex] = 0; - sMusicStaffExpectedLength[songIndex] = 0; - sMusicStaffExpectedPitch[songIndex] = 0; - - if (D_801D8530) { - if ((1 << songIndex) & ocarinaFlags) { - D_801FD518[songIndex] = 0; - } else { - D_801FD518[songIndex] = 0xFF; - } - } - } - - if (ocarinaFlags & 0x80000000) { - sMusicStaffNumNotesPerTest = 0; // Ocarina Playback - } - - if (ocarinaFlags & 0x40000000) { - sOcarinaWithoutMusicStaffPos = 0; - } - - if (ocarinaFlags & 0xC0400000) { - AudioOcarina_MapSongFromPitchToButton(OCARINA_SONG_SCARECROW_SPAWN, OCARINA_SONG_SCARECROW_SPAWN, 8); - } - } else { - sOcarinaFlags = 0; - sIsOcarinaInputEnabled = false; - } -} - -#undef OCARINA_SONGS_PLAYABLE_FLAGS - -void AudioOcarina_SetSongStartingPos(void) { - sOcarinaSongStartingPos = sOcarinaWithoutMusicStaffPos; -} - -void AudioOcarina_StartAtSongStartingPos(u32 ocarinaFlags) { - D_801D8530 = false; - AudioOcarina_Start(ocarinaFlags); - if (sOcarinaSongStartingPos != 0) { - sOcarinaWithoutMusicStaffPos = sOcarinaSongStartingPos; - sOcarinaSongStartingPos = 0; - } -} - -void AudioOcarina_StartForSongCheck(u32 ocarinaFlags, u8 ocarinaStaffPlayingPosStart) { - u8 songIndex; - u8 j; - - AudioOcarina_Start(ocarinaFlags); - sMusicStaffNumNotesPerTest = 8; - sOcarinaStaffPlayingPos = ocarinaStaffPlayingPosStart; - - for (songIndex = 0; songIndex <= OCARINA_SONG_EVAN_PART2; songIndex++) { - for (j = 0; j < ocarinaStaffPlayingPosStart;) { - if (sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]].pitch != OCARINA_PITCH_NONE) { - j++; - } - sMusicStaffPos[songIndex]++; - } - - if (sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]].pitch == OCARINA_PITCH_NONE) { - sMusicStaffPos[songIndex]++; - } - } -} - -void AudioOcarina_StartWithSongNoteLengths(u32 ocarinaFlags) { - u8 songIndex; - - for (songIndex = 0; songIndex < OCARINA_SONG_MAX; songIndex++) { - if ((1 << songIndex) & ocarinaFlags) { - D_801FD530[songIndex] = 0; - } else { - D_801FD530[songIndex] = 0xFF; - } - } - - D_801D8530 = true; - D_801D8534 = ocarinaFlags; - AudioOcarina_Start(ocarinaFlags); -} - -void AudioOcarina_StartDefault(u32 ocarinaFlags) { - D_801D8530 = false; - AudioOcarina_Start(ocarinaFlags); -} - -u8 func_8019B568(void) { - u32 temp_v0 = D_801D8534; - u8 songIndex; - - for (songIndex = OCARINA_SONG_SONATA; !((temp_v0 >> songIndex) & 1) && (songIndex < OCARINA_SONG_MAX); - songIndex++) {} - - return songIndex; -} - -u8 func_8019B5AC(void) { - u8 songIndex = func_8019B568(); - - if (songIndex < OCARINA_SONG_MAX) { - return D_801FD518[songIndex]; - } - - return 0xFF; -} - -u8 func_8019B5EC(void) { - return D_801FD530[func_8019B568()]; -} - -void AudioOcarina_CheckIfStartedSong(void) { - if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && !sOcarinaHasStartedSong) { - sOcarinaHasStartedSong = true; - sMusicStaffPrevPitch = OCARINA_PITCH_NONE; - } -} - -void AudioOcarina_UpdateCurOcarinaSong(void) { - u8 i; - - if (sOcarinaWithoutMusicStaffPos == 8) { - for (i = 0; i < ARRAY_COUNT(sCurOcarinaSongWithoutMusicStaff) - 1; i++) { - sCurOcarinaSongWithoutMusicStaff[i] = sCurOcarinaSongWithoutMusicStaff[i + 1]; - } - } else { - sOcarinaWithoutMusicStaffPos++; - } -} - -/** - * 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) { - u32 curOcarinaSongFlag; - s32 pad; - u8 noNewValidInput = false; - s16 pad2; - s8 staffOcarinaPlayingPosOffset = 0; - u8 songIndex; - OcarinaNote* curNote; - OcarinaNote* nextNote; - - AudioOcarina_CheckIfStartedSong(); - - if (!sOcarinaHasStartedSong) { - return; - } - - if (ABS_ALT(sCurOcarinaBendIndex) > 20) { - sOcarinaFlags = 0; - for (songIndex = OCARINA_SONG_SONATA; songIndex < OCARINA_SONG_MAX; songIndex++) { - D_801FD518[songIndex] = 4; - } - sIsOcarinaInputEnabled = false; - return; - } - - if ((sPrevOcarinaPitch == sCurOcarinaPitch) || (sCurOcarinaPitch == OCARINA_PITCH_NONE)) { - noNewValidInput = true; - } else { - AudioOcarina_UpdateCurOcarinaSong(); - sCurOcarinaSongWithoutMusicStaff[sOcarinaWithoutMusicStaffPos - 1] = sCurOcarinaPitch; - } - - for (songIndex = sFirstOcarinaSongIndex; songIndex < sLastOcarinaSongIndex; songIndex++) { - curOcarinaSongFlag = 1 << songIndex; - - if (sOcarinaAvailableSongFlags & curOcarinaSongFlag) { - if (D_801D8530) { - sMusicStaffCurHeldLength[songIndex] += sOcarinaUpdateTaskStart - sOcarinaPlaybackTaskStart; - } else { - sMusicStaffCurHeldLength[songIndex] = sMusicStaffExpectedLength[songIndex] + 9; - } - - if (noNewValidInput) { - if ((sMusicStaffCurHeldLength[songIndex] > 8) && - (sMusicStaffPrevPitch != sMusicStaffExpectedPitch[songIndex])) { - sOcarinaAvailableSongFlags ^= curOcarinaSongFlag; - if (D_801D8530) { - D_801FD518[songIndex] = 1; - } - } - - if (D_801D8530 && ((sMusicStaffExpectedLength[songIndex] + 9) < sMusicStaffCurHeldLength[songIndex])) { - sOcarinaAvailableSongFlags ^= curOcarinaSongFlag; - D_801FD518[songIndex] = 3; - } else if ((sMusicStaffCurHeldLength[songIndex] >= (sMusicStaffExpectedLength[songIndex] - 9)) && - (sMusicStaffCurHeldLength[songIndex] >= sMusicStaffExpectedLength[songIndex]) && - (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; - if (D_801D8530) { - D_801FD518[songIndex] = 5; - } - } - } else if (sMusicStaffCurHeldLength[songIndex] >= (sMusicStaffExpectedLength[songIndex] - 9)) { - // 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 (D_801D8530) { - D_801FD530[songIndex] += - ABS_ALT(sMusicStaffExpectedLength[songIndex] - sMusicStaffCurHeldLength[songIndex]); - } - sMusicStaffCurHeldLength[songIndex] = 0; - } else { - // Note is not part of expected song, so this song is no longer available as an option in this - // playback - sOcarinaAvailableSongFlags ^= curOcarinaSongFlag; - if (D_801D8530) { - D_801FD518[songIndex] = 1; - } - } - } - - curNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]]; - nextNote = &sOcarinaSongNotes[songIndex][++sMusicStaffPos[songIndex]]; - sMusicStaffExpectedLength[songIndex] = curNote->length; - sMusicStaffExpectedPitch[songIndex] = curNote->pitch; - - while ((curNote->pitch == nextNote->pitch) || - ((nextNote->pitch == OCARINA_PITCH_NONE) && (nextNote->length != 0))) { - sMusicStaffExpectedLength[songIndex] += nextNote->length; - curNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]]; - nextNote = &sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex] + 1]; - sMusicStaffPos[songIndex]++; - } - } else if (sMusicStaffCurHeldLength[songIndex] < 9) { - // case never taken - staffOcarinaPlayingPosOffset = -1; - sMusicStaffCurHeldLength[songIndex] = 0; - sMusicStaffPrevPitch = sCurOcarinaPitch; - } else { - // case never taken - if (sOcarinaSongNotes[songIndex][sMusicStaffPos[songIndex]].length == 0) { - D_801FD518[songIndex] = 1; - } else if (D_801D8530) { - D_801FD518[songIndex] = 2; - } - sOcarinaAvailableSongFlags ^= 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 ((sOcarinaAvailableSongFlags == 0) && (sOcarinaStaffPlayingPos >= sMusicStaffNumNotesPerTest)) { - sIsOcarinaInputEnabled = false; - if (!D_801D8530) { - if ((sOcarinaFlags & 0x40000000) && (sCurOcarinaPitch == sOcarinaSongNotes[songIndex][0].pitch)) { - // case never taken, this function is not called if (sOcarinaFlags & 0x40000000) is set - sPrevOcarinaWithMusicStaffFlags = sOcarinaFlags; - } - } - sOcarinaFlags = 0; - return; - } - } - - if (!noNewValidInput) { - sMusicStaffPrevPitch = sCurOcarinaPitch; - sOcarinaStaffPlayingPos += 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 ocarinaStaffPlayingPosStart; - u8 songIndex; - u8 j; - u8 k; - - if (CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_L) && - CHECK_BTN_ANY(sOcarinaInputButtonCur, BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP)) { - AudioOcarina_StartDefault(sOcarinaFlags); - return; - } - - AudioOcarina_CheckIfStartedSong(); - - if (!sOcarinaHasStartedSong) { - return; - } - - ocarinaStaffPlayingPosStart = sOcarinaStaffPlayingPos; - if ((sPrevOcarinaPitch != sCurOcarinaPitch) && (sCurOcarinaPitch != OCARINA_PITCH_NONE)) { - sOcarinaStaffPlayingPos++; - if (sOcarinaStaffPlayingPos > ARRAY_COUNT(sCurOcarinaSongWithoutMusicStaff)) { - sOcarinaStaffPlayingPos = 1; - } - - AudioOcarina_UpdateCurOcarinaSong(); - - if ((ABS_ALT(sCurOcarinaBendIndex) > 20) && (ocarinaStaffPlayingPosStart != sOcarinaStaffPlayingPos)) { - 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 (songIndex = sFirstOcarinaSongIndex; songIndex < sLastOcarinaSongIndex; songIndex++) { - // Checks to see if the song is available to be played - if ((u32)sOcarinaAvailableSongFlags & (1 << songIndex)) { - // Loops through all possible starting indices? - // Loops through the notes of the song? - for (j = 0, k = 0; j < gOcarinaSongButtons[songIndex].numButtons && k == 0 && - sOcarinaWithoutMusicStaffPos >= gOcarinaSongButtons[songIndex].numButtons;) { - - pitch = sCurOcarinaSongWithoutMusicStaff[(sOcarinaWithoutMusicStaffPos - - gOcarinaSongButtons[songIndex].numButtons) + - j]; - - if (pitch == sButtonToPitchMap[gOcarinaSongButtons[songIndex].buttonIndex[j]]) { - j++; - } else { - k++; - } - } - - // This conditional is true if songIndex = i is detected - if (j == gOcarinaSongButtons[songIndex].numButtons) { - sPlayedOcarinaSongIndexPlusOne = songIndex + 1; - sIsOcarinaInputEnabled = false; - sOcarinaFlags = 0; - } - } - } - } -} - -void AudioOcarina_PlayControllerInput(u8 isOcarinaSfxSuppressedWhenCancelled) { - 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 & (BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP)) != - (sOcarinaInputButtonCur & (BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP)))) { - sOcarinaInputButtonStart = 0; - if (1) {} - sCurOcarinaPitch = OCARINA_PITCH_NONE; - sCurOcarinaButtonIndex = OCARINA_BTN_INVALID; - ocarinaBtnsHeld = (sOcarinaInputButtonCur & (BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP)) & - (sOcarinaInputButtonPrev & (BTN_A | BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP)); - - 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, BTN_A)) { - sCurOcarinaPitch = OCARINA_PITCH_D4; - sCurOcarinaButtonIndex = OCARINA_BTN_A; - - } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CDOWN)) { - sCurOcarinaPitch = OCARINA_PITCH_F4; - sCurOcarinaButtonIndex = OCARINA_BTN_C_DOWN; - - } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CRIGHT)) { - sCurOcarinaPitch = OCARINA_PITCH_A4; - sCurOcarinaButtonIndex = OCARINA_BTN_C_RIGHT; - - } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CLEFT)) { - sCurOcarinaPitch = OCARINA_PITCH_B4; - sCurOcarinaButtonIndex = OCARINA_BTN_C_LEFT; - - } else if (CHECK_BTN_ANY(sOcarinaInputButtonPress, BTN_CUP)) { - sCurOcarinaPitch = OCARINA_PITCH_D5; - sCurOcarinaButtonIndex = OCARINA_BTN_C_UP; - } - - if (sOcarinaInputButtonCur) {} - - // 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 += OCARINA_BUTTON_FLAG_BFLAT_RAISE; // 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 += OCARINA_BUTTON_FLAG_BFLAT_LOWER; // 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 = sOcarinaInputStickRel.y; - sCurOcarinaBendFreq = AudioOcarina_BendPitchTwoSemitones(sCurOcarinaBendIndex); - - // Add vibrato of the ocarina note based on the x control stick - sCurOcarinaVibrato = ABS_ALT(sOcarinaInputStickRel.x) >> 2; - // Sets vibrato to io port 6 - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, SFX_CHANNEL_OCARINA, 6, sCurOcarinaVibrato); - } else { - // no bending or vibrato for recording state OCARINA_RECORD_SCARECROW_SPAWN - sCurOcarinaBendIndex = 0; - sCurOcarinaVibrato = 0; - sCurOcarinaBendFreq = 1.0f; // No bend - } - - // Processes new and valid notes - if ((sCurOcarinaPitch != OCARINA_PITCH_NONE) && (sPrevOcarinaPitch != sCurOcarinaPitch)) { - // Sets ocarina instrument Id to io port 7, which is used - // as an index in seq 0 to get the true instrument Id - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, SFX_CHANNEL_OCARINA, 7, sOcarinaInstrumentId - 1); - // Sets pitch to io port 5 - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, SFX_CHANNEL_OCARINA, 5, sCurOcarinaPitch); - AudioSfx_PlaySfx(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sCurOcarinaBendFreq, &sDefaultOcarinaVolume, - &gSfxDefaultReverb); - } else if ((sPrevOcarinaPitch != OCARINA_PITCH_NONE) && (sCurOcarinaPitch == OCARINA_PITCH_NONE) && - !isOcarinaSfxSuppressedWhenCancelled) { - // Stops ocarina sound when transitioning from playing to not playing a note - AudioSfx_StopById(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 - */ -void AudioOcarina_ResetAndMute(void) { - sOcarinaInputButtonCur = 0; - sOcarinaInputButtonPrev = 0; - sOcarinaInputButtonPress = 0; - - sOcarinaInputButtonStart = 0xFFFF; - - AudioOcarina_PlayControllerInput(false); - AudioSfx_StopById(NA_SE_OC_OCARINA); - - if (gAudioSpecId != 12) { - AudioSfx_MuteBanks(0); - } - - sPlaybackState = 0; - sPlaybackStaffPos = 0; - sIsOcarinaInputEnabled = false; - - sOcarinaFlags = 0; - - // return to full volume for both bgm players after ocarina is finished - AudioSfx_RestoreBgmVolume(SFX_CHANNEL_OCARINA); - // return to full volume for all sfx channels except system & ocarina banks - Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(0x7F); -} - -void AudioOcarina_ResetAndReadInput(void) { - sOcarinaInputButtonCur = 0; - sOcarinaInputButtonPrev = 0; - sOcarinaInputButtonPress = 0; - - sOcarinaInputButtonStart = 0xFFFF; - - AudioOcarina_PlayControllerInput(true); - - sPlaybackState = 0; - sPlaybackStaffPos = 0; - sIsOcarinaInputEnabled = false; - - sOcarinaFlags = 0; - - sOcarinaInputButtonCur = 0; - - AudioOcarina_ReadControllerInput(); - sOcarinaInputButtonStart = sOcarinaInputButtonCur; -} - -/** - * Set a timer that will disable the ocarina once the timer reaches 0 - */ -void AudioOcarina_SetOcarinaDisableTimer(u8 unused, u8 timer) { - sOcarinaDisableTimer = timer; - sOcarinaUnused = unused; -} - -void AudioOcarina_SetInstrument(u8 ocarinaInstrumentId) { - if ((sOcarinaInstrumentId != ocarinaInstrumentId) || (ocarinaInstrumentId == OCARINA_INSTRUMENT_DEFAULT)) { - Audio_QueueSeqCmd(0x80000000 | ((u32)(SEQ_PLAYER_SFX) << 24) | ((u32)(1) << 16) | - ((u32)(SFX_CHANNEL_OCARINA) << 8) | (u32)(ocarinaInstrumentId)); - sOcarinaInstrumentId = ocarinaInstrumentId; - - if (ocarinaInstrumentId == OCARINA_INSTRUMENT_OFF) { - AudioOcarina_ResetAndMute(); - } else { - sOcarinaInputButtonCur = 0; - AudioOcarina_ReadControllerInput(); - sOcarinaInputButtonStart = sOcarinaInputButtonCur; - // lowers volume of all sfx channels except system & ocarina banks - Audio_SetSfxVolumeExceptSystemAndOcarinaBanks(0x40); - // lowers volume of bgm players while playing ocarina - AudioSfx_LowerBgmVolume(SFX_CHANNEL_OCARINA); - } - } -} - -void AudioOcarina_SetPlaybackSong(s8 songIndexPlusOne, u8 playbackState) { - u8 i = 0; - - if (songIndexPlusOne == 0) { - sPlaybackState = 0; - AudioSfx_StopById(NA_SE_OC_OCARINA); - return; - } - - if (songIndexPlusOne < (OCARINA_SONG_MAX + 1)) { - sPlaybackSong = sOcarinaSongNotes[songIndexPlusOne - 1]; - } else { - sPlaybackSong = sScarecrowsLongSongNotes; - } - - sPlaybackNotePos = 0; - if (playbackState & 0x80) { - sPlaybackState = 1; - sPlaybackStaffStopPos = playbackState & 0xF; - sPlaybackStaffStartPos = 0xFF; - } else if (playbackState & 0x40) { - sPlaybackState = 1; - sPlaybackStaffStartPos = playbackState & 0xF; - sPlaybackStaffStopPos = 0xFF; - while (i < sPlaybackStaffStartPos) { - if (sOcarinaSongNotes[songIndexPlusOne - 1][sPlaybackNotePos].pitch != OCARINA_PITCH_NONE) { - i++; - } - sPlaybackNotePos++; - } - } else { - sPlaybackState = playbackState; - sPlaybackStaffStopPos = 0xFF; - sPlaybackStaffStartPos = 0xFF; - } - - sPlaybackNoteTimer = 0; - sPlaybackPitch = OCARINA_PITCH_NONE; - sPlaybackStaffPos = 0; - - if (sPlaybackStaffStartPos == 0xFF) { - while ((sPlaybackSong[sPlaybackNotePos].pitch == OCARINA_PITCH_NONE) && - (songIndexPlusOne > (OCARINA_SONG_EVAN_PART2 + 1))) { - sPlaybackNotePos++; - } - } -} - -/** - * Play a song with the ocarina to the user that is - * based on OcarinaNote data and not user input - */ -void AudioOcarina_PlaybackSong(void) { - s32 noteTimerStep; - s32 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) { - - if (sPlaybackStaffPos == sPlaybackStaffStopPos) { - sPlaybackState = 0; - return; - } - - sPlaybackNoteTimer = sPlaybackSong[sPlaybackNotePos].length; - - if (sPlaybackNotePos == 1) { - sPlaybackNoteTimer++; - } - - if (sPlaybackNoteTimer == 0) { - sPlaybackState--; - if (sPlaybackState != 0) { - sPlaybackNotePos = 0; - sPlaybackStaffPos = 0; - sPlaybackPitch = OCARINA_PITCH_NONE; - } else { - AudioSfx_StopById(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 - sNotePlaybackVibrato = sPlaybackSong[sPlaybackNotePos].vibrato; - // Sets vibrato to io port 6 - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, SFX_CHANNEL_OCARINA, 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 io port 7, which is used - // as an index in seq 0 to get the true instrument Id - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, SFX_CHANNEL_OCARINA, 7, sOcarinaInstrumentId - 1); - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, SFX_CHANNEL_OCARINA, 5, - sPlaybackPitch & OCARINA_BUTTON_MASK_PITCH); - AudioSfx_PlaySfx(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sRelativeNotePlaybackBend, - &sRelativeNotePlaybackVolume, &gSfxDefaultReverb); - } else { - AudioSfx_StopById(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 termina - * wall 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 = sTerminaWallSongPtr; - } - - 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 & OCARINA_BUTTON_MASK_FLAG; - - 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 (sRecordSongPos != (i + 1)) { - sRecordSongPos = i + 2; - recordedSong[sRecordSongPos - 1].length = 0; - } - - recordedSong[sRecordSongPos].length = 0; - - if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) { - if (sOcarinaStaffPlayingPos >= 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_MapSongFromPitchToButton(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_SCARECROW_SPAWN, 8); - - // Tests to see if the notes from the scarecrow song contain identical - // notes within its song to any of the reserved songIndex from 0 to 21 - - // Loop through each of the songs - for (i = 0; i < OCARINA_SONG_SCARECROW_SPAWN; i++) { - // Checks to see if the song is reserved - if (sIsOcarinaSongReserved[i]) { - // Loops through all possible starting indices - for (j = 0; (j < 9 - gOcarinaSongButtons[i].numButtons); j++) { - // Loops through the notes of the song - for (k = 0; (k < gOcarinaSongButtons[i].numButtons) && (k + j < 8) && - (gOcarinaSongButtons[i].buttonIndex[k] == - gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonIndex[k + j]); - k++) { - ; - } - - // This conditional is true if the recorded song contains a reserved song - // recorded song is cancelled - 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].buttonIndex[0] != - gOcarinaSongButtons[OCARINA_SONG_SCARECROW_SPAWN].buttonIndex[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_TERMINA_WALL][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; - sOcarinaStaffPlayingPos = 0; - sScarecrowsLongSongSecondNote = sScarecrowsLongSongNotes[1]; - } else { - if (sRecordSongPos == 0) { - sScarecrowsLongSongNotes[1] = sScarecrowsLongSongSecondNote; - } else { - if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) { - sOcarinaStaffPlayingPos = 1; - } - - AudioOcarina_SetRecordingSong(true); - } - - sIsOcarinaInputEnabled = false; - sOcarinaStaffPlayingPos = 0; - } - - sRecordingState = recordingState; -} - -void AudioOcarina_UpdateRecordingStaff(void) { - sRecordingStaff.state = sRecordingState; - sRecordingStaff.pos = sOcarinaStaffPlayingPos; - if (sRecordingState == OCARINA_RECORD_REJECTED) { - sRecordingState = OCARINA_RECORD_OFF; - } -} - -void AudioOcarina_UpdatePlayingStaff(void) { - if (sCurOcarinaButtonIndex != OCARINA_BTN_INVALID) { - sPlayingStaff.buttonIndex = sCurOcarinaButtonIndex & OCARINA_BUTTON_MASK_PITCH; - } - sPlayingStaff.state = AudioOcarina_GetPlayingState(); - sPlayingStaff.pos = sOcarinaStaffPlayingPos; -} - -void AudioOcarina_UpdatePlaybackStaff(void) { - if ((sPlaybackPitch & OCARINA_BUTTON_MASK_PITCH) <= OCARINA_PITCH_EFLAT5) { - sPlaybackStaff.buttonIndex = AudioOcarina_MapPitchToButton(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 & OCARINA_BUTTON_MASK_PITCH; - sOcarinaStaffPlayingPos++; - } else if ((sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) && (sOcarinaStaffPlayingPos == 8)) { - AudioOcarina_SetRecordingSong(true); - return; - } - - if (sOcarinaStaffPlayingPos > 8) { - if (sRecordingState == OCARINA_RECORD_SCARECROW_SPAWN) { - // notes played are over 8 and in recording mode. - AudioOcarina_SetRecordingSong(true); - return; - } - sOcarinaStaffPlayingPos = 1; - } - noteChanged = true; - } else if (sRecordOcarinaVolume != sCurOcarinaVolume) { - noteChanged = true; - } else if (sRecordOcarinaVibrato != sCurOcarinaVibrato) { - if (sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN) { - noteChanged = true; - } - } else if ((sRecordOcarinaBendIndex != sCurOcarinaBendIndex) && - (sRecordingState != OCARINA_RECORD_SCARECROW_SPAWN)) { - noteChanged = true; - } - - if (noteChanged) { - AudioOcarina_SetRecordingSong(false); - sOcarinaRecordTaskStart = sOcarinaUpdateTaskStart; - } - } -} - -/** - * Tests to see if the notes from songIndex contain identical notes - * within its song to any of the reserved songIndex from 0 up to maxSongIndex - */ -s32 AudioOcarina_TerminaWallValidateNotes(u8 songIndex, u8 maxSongIndex) { - u8 curSongIndex; - u8 j; - u8 k; - - // loop through all possible songs up to maxSongIndex - for (curSongIndex = 0; curSongIndex < maxSongIndex; curSongIndex++) { - // check to see if the song is reserved or not - if (sIsOcarinaSongReserved[curSongIndex]) { - // starting index to test the song - for (j = 0; j < (9 - gOcarinaSongButtons[curSongIndex].numButtons); j++) { - // loop through each note in the song - for (k = 0; (k < gOcarinaSongButtons[curSongIndex].numButtons) && ((k + j) < 8) && - (gOcarinaSongButtons[curSongIndex].buttonIndex[k] == - gOcarinaSongButtons[songIndex].buttonIndex[(k + j)]); - k++) { - continue; - } - - if (k == gOcarinaSongButtons[curSongIndex].numButtons) { - // failure: songIndex is identical to curSongIndex. - return -1; - } - } - } - } - - // success: notes are accepted and used - return 0; -} - -/** - * Generates the notes displayed on the Termina Field wall of musical notes - * Song generation loop alternates between 8 random notes and a random song from Ocarina of Time (OoT). - * Will check to see that the notes are valid by ensuring no playable song is within the selected notes - * All OoT songs are valid, so the outer loop will run a maxiumum of two times. - * i.e. if random notes fails, then the next set of notes will be from a valid OoT song - */ -void AudioOcarina_TerminaWallGenerateNotes(void) { - OcarinaNote* ocarinaNote; - u8 randomButtonIndex; - u8 i; - u8 j; - - do { - i = 0; - if (sOcarinaWallCounter++ % 2) { - j = 0; - - for (; i < 8; i++) { - randomButtonIndex = AudioThread_NextRandom() % ARRAY_COUNT(sButtonToPitchMap); - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].pitch = sButtonToPitchMap[randomButtonIndex]; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].length = 19; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].volume = 80; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].vibrato = 0; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].bend = 0; - j++; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].pitch = OCARINA_PITCH_NONE; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].length = 3; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].volume = 0; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].vibrato = 0; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].bend = 0; - j++; - } - - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j - 2].length = 90; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j - 1].length = 22; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j + 1].pitch = OCARINA_PITCH_NONE; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j + 1].length = 0; - AudioOcarina_MapSongFromPitchToButton(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL, 8); - } else { - j = AudioThread_NextRandom() % ARRAY_COUNT(sOoTOcarinaSongNotes); - ocarinaNote = sOoTOcarinaSongNotes[j]; - - for (; ocarinaNote[i].length != 0; i++) { - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][i] = ocarinaNote[i]; - } - - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][i].pitch = OCARINA_PITCH_NONE; - sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][i].length = 0; - AudioOcarina_MapSongFromPitchToButton(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL, - sOoTOcarinaSongsNumNotes[j]); - } - } while (AudioOcarina_TerminaWallValidateNotes(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL) != 0); -} - -/** - * Unused remnant of OoT - */ -void AudioOcarina_MemoryGameInit(u8 minigameRound) { - u8 i; - - if (minigameRound > 2) { - minigameRound = 2; - } - - sOcarinaMemoryGameAppendPos = 0; - sOcarinaMemoryGameEndPos = sOcarinaMemoryGameNumNotes[minigameRound]; - - for (i = 0; i < 3; i++) { - AudioOcarina_MemoryGameNextNote(); - } -} - -/** - * Unused remnant of OoT, Id 14 now represent Goron Lullaby Intro instead of the OoT ocarina memory game - * //! @bug calling this function in MM will overwrite Goron Lullaby Intro - */ -#define OCARINA_SONG_MEMORY_GAME 14 -s32 AudioOcarina_MemoryGameNextNote(void) { - u32 randomButtonIndex; - u8 randomPitch; - - if (sOcarinaMemoryGameAppendPos == sOcarinaMemoryGameEndPos) { - return true; - } - - randomButtonIndex = AudioThread_NextRandom(); - randomPitch = sButtonToPitchMap[randomButtonIndex % ARRAY_COUNT(sButtonToPitchMap)]; - - if (sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos - 1].pitch == randomPitch) { - randomPitch = sButtonToPitchMap[(randomButtonIndex + 1) % ARRAY_COUNT(sButtonToPitchMap)]; - } - - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].pitch = randomPitch; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].length = 45; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].volume = 0x50; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].vibrato = 0; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].bend = 0; - - sOcarinaMemoryGameAppendPos++; - - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].pitch = OCARINA_PITCH_NONE; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos].length = 0; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos + 1].pitch = OCARINA_PITCH_NONE; - sOcarinaSongNotes[OCARINA_SONG_MEMORY_GAME][sOcarinaMemoryGameAppendPos + 1].length = 0; - if (1) {} - return false; -} -#undef OCARINA_SONG_MEMORY_GAME - -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 & 0x40000000) { - 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; - - if (sOcarinaDisableTimer != 0) { - sOcarinaDisableTimer--; - if (sOcarinaDisableTimer == 0) { - AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF); - } - } - } - - AudioOcarina_UpdatePlayingStaff(); - AudioOcarina_UpdatePlaybackStaff(); - AudioOcarina_UpdateRecordingStaff(); -} - -#define OCARINA_INSTRUMENT_OOT_MAX 7 - -void AudioOcarina_PlayLongScarecrowAfterCredits(void) { - static u8 sScarecrowAfterCreditsState = 0; - static u8 sScarecrowAfterCreditsIntrumentId = OCARINA_INSTRUMENT_DEFAULT; - static u16 sScarecrowAfterCreditsTimer = 1200; - - switch (sScarecrowAfterCreditsState) { - case 0: - if (sScarecrowAfterCreditsTimer-- == 0) { - // OoT originally had 7 Ocarina instruments - // MM has more so this does not go all the way to the max - if (sScarecrowAfterCreditsIntrumentId < OCARINA_INSTRUMENT_OOT_MAX) { - // set next ocarina instrument and restart - sScarecrowAfterCreditsState++; - } else { - // finished - sScarecrowAfterCreditsState = 3; - AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF); - } - sScarecrowAfterCreditsTimer = 1200; - } - break; - - case 1: - AudioSfx_MuteBanks(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; - } -} - -u8 sRequestCustomSequence = false; - -void AudioOcarina_SetCustomSequence(void) { - // Never passes true as sRequestCustomSequence is never set true - if (sRequestCustomSequence && gAudioCtx.seqPlayers[SEQ_PLAYER_FANFARE].enabled && - ((u8)gAudioCtx.seqPlayers[SEQ_PLAYER_FANFARE].seqScriptIO[0] == (u8)SEQ_IO_VAL_NONE)) { - gAudioCtx.seqPlayers[SEQ_PLAYER_FANFARE].seqData = sCustomSequenceScript; - sRequestCustomSequence = false; - } -} - -// Called by unused function -void AudioOcarina_PlayCustomSequence(void) { - sRequestCustomSequence = true; - Audio_QueueSeqCmd(0x00000000 | ((u32)(SEQ_PLAYER_FANFARE) << 24) | ((u32)(0) << 0x10) | - (u32)(NA_BGM_DUNGEON_APPEAR)); -} - -// Unused -// Regalloc Swap https://decomp.me/scratch/QEovr -#ifdef NON_MATCHING -s32 AudioOcarina_CreateCustomSequence(void) { - OcarinaNote* prevNote; - u16 i; - u16 phi_s4; - u16 temp_a0; // delay1 - u16 phi_a2; // delay2 - u8 absPitch; - s8 phi_a0; // adjBendIndex - s8 phi_s2; // prevBend - u8 phi_t1; // vibrato - u8 phi_t5; // isLegato - u16 temp_t4; // prevNoteLength - - phi_a2 = 0; - phi_t1 = 0; - phi_s2 = 0; - phi_t5 = 0; - phi_s4 = 0; - - sCustomSequencePc = 39; // .channel chan_loop - - prevNote = &sScarecrowsLongSongNotes[0]; - for (i = 1; ((prevNote->pitch == OCARINA_PITCH_NONE) && (prevNote->length != 0)); i++) { - prevNote = &sScarecrowsLongSongNotes[i]; - } - - for (; (prevNote->length != 0) && (sCustomSequencePc < 394); i++) { - - temp_a0 = ((prevNote->length * 48) / 30); - - if (phi_t1 != prevNote->vibrato) { - sCustomSequenceScript[sCustomSequencePc++] = 0xFD; // delay cmd - - if (phi_a2 >= 0x80) { - // Store as compressed u16 - sCustomSequenceScript[sCustomSequencePc++] = (((phi_a2 >> 8) & 0xFF) & 0x7F) + 0x80; // delay arg - sCustomSequenceScript[sCustomSequencePc++] = phi_a2 & 0xFF; // delay arg - } else { - // Store as u8 - sCustomSequenceScript[sCustomSequencePc++] = phi_a2; // delay arg - } - - sCustomSequenceScript[sCustomSequencePc++] = 0xD8; // vibdepth cmd - sCustomSequenceScript[sCustomSequencePc++] = prevNote->vibrato; // vibdepth arg - - phi_a2 = temp_a0; - phi_t1 = prevNote->vibrato; - } else { - phi_a2 += temp_a0; - } - - prevNote = &sScarecrowsLongSongNotes[i]; - } - - if (phi_a2 != 0) { - sCustomSequenceScript[sCustomSequencePc++] = 0xFD; // delay cmd - if (phi_a2 >= 0x80) { - // Store as compressed u16 - sCustomSequenceScript[sCustomSequencePc++] = (((phi_a2 >> 8) & 0xFF) & 0x7F) + 0x80; // delay arg - sCustomSequenceScript[sCustomSequencePc++] = phi_a2 & 0xFF; // delay arg - } else { - // Store as u8 - sCustomSequenceScript[sCustomSequencePc++] = phi_a2; // delay arg - } - } - - sCustomSequenceScript[sCustomSequencePc++] = 0xFF; // end cmd - - // ldlayer 0, layer0 - sCustomSequenceScript[24] = sCustomSequencePc >> 8; - sCustomSequenceScript[25] = sCustomSequencePc & 0xFF; - - // ldlayer 1, layer1 - sCustomSequenceScript[27] = (sCustomSequencePc + 4) >> 8; - sCustomSequenceScript[28] = (sCustomSequencePc + 4) & 0xFF; - - sCustomSequenceScript[sCustomSequencePc++] = 0xC2; // transpose cmd - sCustomSequenceScript[sCustomSequencePc++] = -5; // transpose arg - - sCustomSequenceScript[sCustomSequencePc++] = 0xC0; // ldelay cmd - sCustomSequenceScript[sCustomSequencePc++] = 8; // ldelay arg - - sCustomSequenceScript[sCustomSequencePc++] = 0xC1; // shortvel cmd - sCustomSequenceScript[sCustomSequencePc++] = 87; // shortvel arg - - sCustomSequenceScript[sCustomSequencePc++] = 0xC9; // shortgate cmd - sCustomSequenceScript[sCustomSequencePc++] = 0; // shortgate arg - - if (1) {} - if (1) {} // TODO: Needed? - - prevNote = &sScarecrowsLongSongNotes[0]; - - for (i = 1; ((prevNote->pitch == OCARINA_PITCH_NONE) && (prevNote->length != 0)); i++) { - prevNote = &sScarecrowsLongSongNotes[i]; - } - - for (; ((temp_t4 = prevNote->length) != 0) && (sCustomSequencePc < 394); i++) { - - if (prevNote->pitch == sScarecrowsLongSongNotes[i].pitch) { - if ((sScarecrowsLongSongNotes[i].length != 0) && (phi_t5 == 0)) { - sCustomSequenceScript[sCustomSequencePc++] = 0xC4; // legato cmd - phi_t5 = 1; - } - } else if ((phi_t5 == 1) && (sScarecrowsLongSongNotes[i].pitch != OCARINA_PITCH_NONE) && - (sScarecrowsLongSongNotes[i].pitch != OCARINA_PITCH_C4)) { - sCustomSequenceScript[sCustomSequencePc++] = 0xC5; // nolegato cmd - phi_t5 = 0; - } - - if (phi_s2 != prevNote->bend) { - sCustomSequenceScript[sCustomSequencePc++] = 0xCE; // bendfine cmd - - if (ABS_ALT(prevNote->bend) > 64) { - phi_a0 = 127; - } else if (prevNote->bend < 0) { - phi_a0 = -prevNote->bend; - } else { - phi_a0 = ((prevNote->bend * 127) / 64); - } - - if (prevNote->bend < 0) { - phi_a0 *= -1; - } - - sCustomSequenceScript[sCustomSequencePc++] = phi_a0; // bendfine arg - - phi_s2 = prevNote->bend; - } - - absPitch = prevNote->pitch + 39; // convert ocarina pitch to absolute pitch, + PITCH_C4 (Middle C) - if (prevNote->pitch != OCARINA_PITCH_NONE) { - sCustomSequenceScript[sCustomSequencePc++] = absPitch; // shortdvg cmd, shortdvg arg - } else { - sCustomSequenceScript[sCustomSequencePc++] = 0xC0; // ldelay cmd - } - - // delay/duration - temp_a0 = ((temp_t4 * 48) + phi_s4) / 30; - - if (temp_a0 < 0x80) { - // Store as u8 - sCustomSequenceScript[sCustomSequencePc++] = temp_a0; // shortdvg/ldelay arg - } else { - // Store as compressed u16 - sCustomSequenceScript[sCustomSequencePc++] = (((temp_a0 >> 8) & 0xFF) & 0x7F) + 0x80; // shortdvg/ldelay arg - sCustomSequenceScript[sCustomSequencePc++] = temp_a0 & 0xFF; // shortdvg/ldelay arg - } - - if (1) {} - - phi_s4 = ((temp_t4 * 48) + phi_s4) - (temp_a0 * 30); - - prevNote = &sScarecrowsLongSongNotes[i]; - } - - sCustomSequenceScript[sCustomSequencePc++] = 0xFF; // end cmd - - AudioOcarina_PlayCustomSequence(); - - if (i >= 394) { - return -1; - } - - return 0; -} -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_CreateCustomSequence.s") -#endif - -void AudioOcarina_ResetInstrument(void) { - if (sOcarinaInstrumentId != OCARINA_INSTRUMENT_OFF) { - Audio_QueueSeqCmd(0x80000000 | ((u32)(SEQ_PLAYER_SFX) << 24) | ((u32)(1) << 16) | - ((u32)(SFX_CHANNEL_OCARINA) << 8) | (u32)(0)); - sOcarinaInstrumentId = OCARINA_INSTRUMENT_OFF; - AudioOcarina_ResetAndMute(); - } -} - -void AudioOcarina_ResetStaffs(void) { - u8 songIndex; - - 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 = 0xFF; - sRecordingStaff.pos = 0; - - sOcarinaDisableTimer = 0; - sOcarinaDropInputTimer = 0; - - for (songIndex = OCARINA_SONG_SONATA; songIndex < OCARINA_SONG_MAX; songIndex++) { - D_801FD518[songIndex] = 0xFF; - D_801FD530[songIndex] = 0; - } - - D_801D8534 = 0; -} - -void Audio_Noop1(s32 arg0) { -} - -void Audio_Noop2(s32 arg0, s32 arg1) { -} - -void Audio_Noop3(void) { -} - -void Audio_Update(void) { - if ((func_801A9768() == 0) && (func_801A982C() == 0)) { - AudioOcarina_SetCustomSequence(); - AudioOcarina_Update(); - func_801A5118(); - Audio_StepFreqLerp(&sRiverFreqScaleLerp); - Audio_StepFreqLerp(&sWaterfallFreqScaleLerp); - Audio_UpdateRiverSoundVolumes(); - Audio_UpdateSceneSequenceResumePoint(); - func_801A312C(); - func_8019FEDC(); - func_801A1E0C(); - func_801A1904(); - func_801A2090(); - func_801A3AC0(); - func_801A1290(); - Audio_ResetRequestedSceneSeqId(); - AudioSfx_ProcessRequests(); - func_801A89D0(); - AudioSfx_ProcessActiveSfx(); - func_801A8D5C(); - AudioSfx_ProcessSfxSettings(); - AudioThread_ScheduleProcessCmds(); - } -} - -void Audio_Noop4(s32 arg0) { -} - -void Audio_Noop5(s32 arg0, s32 arg1) { -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E110.s") - -f32 AudioSfx_ComputeVolume(u8 bankId, u8 entryIndex) { - SfxBankEntry* bankEntry = &gSfxBanks[bankId][entryIndex]; - f32 minDist; - f32 phi_f14; - f32 baseDist; - f32 phi_f12; - f32 volume; // Also acts as intermediate volumeSquared - s32 pad[3]; - - if (bankEntry->sfxParams & SFX_FLAG_VOLUME_NO_DIST) { - return 1.0f; - } - - if (bankEntry->dist > 10000.0f) { - volume = 0.0f; - } else { - if (bankEntry->sfxParams & SFX_PARAM_DIST_RANGE_MASK_UPPER) { - phi_f12 = 0.35f; - phi_f14 = 0.65f; - } else { - phi_f12 = 0.81f; - phi_f14 = 0.19f; - } - - switch (bankEntry->sfxParams & SFX_PARAM_DIST_RANGE_MASK) { - case 0: - baseDist = 500.0f; - break; - - case 1: - baseDist = 666.6667f; - break; - - case 2: - baseDist = 952.381f; - break; - - case 3: - baseDist = 3846.154f; - break; - - case 4: - baseDist = 1000.0f; - break; - - case 5: - baseDist = 666.6667f; - break; - - case 6: - baseDist = 500.0f; - break; - - case 7: - baseDist = 400.0f; - break; - } - - minDist = baseDist / 5.0f; - - if (bankEntry->dist < minDist) { - volume = 1.0f; - } else if (bankEntry->dist < baseDist) { - volume = - ((((baseDist - minDist) - (bankEntry->dist - minDist)) / (baseDist - minDist)) * phi_f14) + phi_f12; - } else { - volume = (1.0f - ((bankEntry->dist - baseDist) / (10000.0f - baseDist))) * phi_f12; - } - - volume = SQ(volume); - } - - return volume; -} - -s8 AudioSfx_ComputeReverb(u8 bankId, u8 entryIndex, u8 channelIndex) { - s8 distAdd = 0; - s32 scriptAdd = 0; - SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex]; - s32 reverb; - - if (!(entry->sfxParams & SFX_FLAG_REVERB_NO_DIST)) { - 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[channelIndex])) { - scriptAdd = gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[channelIndex]->seqScriptIO[1]; - if (gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[channelIndex]->seqScriptIO[1] <= SEQ_IO_VAL_NONE) { - scriptAdd = 0; - } - } - - reverb = (*entry->reverbAdd & 0x7F) + distAdd; - - if (entry->state != SFX_STATE_READY) { - reverb += scriptAdd; - } - - if ((bankId != BANK_OCARINA) || (SFX_INDEX(entry->sfxId) >= 2)) { - reverb += sAudioEnvReverb + (sAudioCodeReverb & 0x3F) + sSpecReverb; - } - - if (reverb > 0x7F) { - reverb = 0x7F; - } - - return reverb; -} - -s8 AudioSfx_ComputePanSigned(f32 x, f32 z, u8 token) { - f32 absX = ABS_ALT(x); - f32 absZ = ABS_ALT(z); - f32 pan; - - 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) / (4.5f * (16000.0f - absZ)); - if (x >= 0.0f) { - pan = 1.0f - pan; - } - } else { - pan = (x / (3.6f * absZ)) + 0.5f; - } - - if ((absZ < 50.0f) && (absX < 50.0f)) { - pan = ((pan - 0.5f) * SQ(absX / 50.0f)) + 0.5f; - } - - return (pan * 127.0f) + 0.5f; -} - -f32 AudioSfx_ComputeFreqScale(u8 bankId, u8 entryIndex) { - s32 applyRandScaling = false; - SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex]; - f32 dist; - f32 freq = 1.0f; - - if (entry->sfxParams & SFX_PARAM_RAND_FREQ_LOWER) { - freq = 1.0f - ((gAudioCtx.audioRandom & 0xF) / 192.0f); - } - - switch (bankId) { - case BANK_VOICE: - if (((entry->sfxId & 0xFF) < 0x40) && (sAudioBaseFilter2 != 0)) { - applyRandScaling = true; - } else if (((entry->sfxId & 0xFF) >= 0x40) && (sAudioExtraFilter2 != 0)) { - applyRandScaling = true; - } - break; - - case BANK_PLAYER: - case BANK_ITEM: - if (sAudioBaseFilter2 != 0) { - applyRandScaling = true; - } - break; - - case BANK_ENV: - case BANK_ENEMY: - if (((*entry->reverbAdd & 0x80) != 0) | (sAudioExtraFilter2 != 0)) { - applyRandScaling = true; - } - break; - - case BANK_SYSTEM: - case BANK_OCARINA: - break; - - default: - break; - } - - if ((applyRandScaling == true) && !(entry->sfxParams & SFX_PARAM_RAND_FREQ_SCALE)) { - freq *= 1.0293 - ((gAudioCtx.audioRandom & 0xF) / 144.0f); - } - - dist = entry->dist; - if (!(entry->sfxParams & SFX_FLAG_VOLUME_NO_DIST) && !(entry->sfxParams & SFX_FLAG_FREQ_NO_DIST)) { - if (dist >= 10000.0f) { - freq += 0.2f; - } else { - freq += (0.2f * (dist / 10000.0f)); - } - } - - if ((entry->sfxParams & SFX_PARAM_RAND_FREQ_RAISE_MASK) != (0 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT)) { - freq += (entry->randFreq / 192.0f); - } - - return freq; -} - -u8 AudioSfx_ComputeSurroundSoundFilter(f32 behindScreenZ, SfxBankEntry* entry, s8 panSigned) { - u8 lowPassCutoff; - u8 highPassCutoff; - u16* sfxParams; - f32 distParam; - f32 dist; - - // Remnant of OoT - if (*entry->posZ < behindScreenZ) { - lowPassCutoff = 0; - } else { - lowPassCutoff = 0; - } - - sfxParams = &entry->sfxParams; - - if (*sfxParams & SFX_FLAG_SURROUND_LOWPASS_FILTER) { - lowPassCutoff = 0xF; - } - - switch ((*sfxParams & SFX_PARAM_DIST_RANGE_MASK)) { - case 0: - distParam = 15.0f; - break; - - case 1: - distParam = 12.0f; - break; - - case 2: - distParam = 9.0f; - break; - - case 3: - distParam = 6.0f; - break; - - case 4: - distParam = 18.0f; - break; - - case 5: - distParam = 21.0f; - break; - - case 6: - distParam = 24.0f; - break; - - case 7: - distParam = 27.0f; - break; - - default: - break; - } - - if (!(entry->sfxFlags & SFX_FLAG2_SURROUND_NO_HIGHPASS_FILTER)) { - if (entry->dist > 1923.077f) { - dist = 1923.077f; - } else { - dist = entry->dist; - } - - highPassCutoff = (distParam * dist) / (2 * 1923.077f); - } else { - highPassCutoff = 0; - } - - return (lowPassCutoff << 4) + highPassCutoff; -} - -s8 AudioSfx_ComputeCombFilter(f32 posY, u16 sfxParams) { - s8 combFilterGain; - - if (posY < 0.0f) { - if (posY < -625.0f) { - combFilterGain = -32; - } else { - combFilterGain = (s8)(((625.0f + posY) / 625.0f) * 31.0f) + 0xE0; - } - } else if (posY > 1250.0f) { - combFilterGain = 127; - } else { - combFilterGain = (posY / 1250.0f) * 126.0f; - } - - return combFilterGain | 1; -} - -void AudioSfx_SetProperties(u8 bankId, u8 entryIndex, u8 channelIndex) { - static s8 sZVolumes[] = { - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, - 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, - }; - f32 volume = 1.0f; - s8 volumeS8; - s8 reverb = 0; - f32 freqScale = 1.0f; - s8 panSigned = 0x40; - u8 pad; - u8 filter = 0; - s8 combFilterGain = 0; - s8 zVolume = -1; - f32 behindScreenZ; - u8 baseFilter = 0; - SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex]; - s32 pad2; - - switch (bankId) { - case BANK_PLAYER: - case BANK_ITEM: - case BANK_ENV: - case BANK_ENEMY: - case BANK_VOICE: - if (sSoundMode == SOUNDMODE_SURROUND_EXTERNAL) { - combFilterGain = AudioSfx_ComputeCombFilter(*entry->posY, entry->sfxParams); - } - // fallthrough - case BANK_OCARINA: - entry->dist = sqrtf(entry->dist * 10.0f); - volume = AudioSfx_ComputeVolume(bankId, entryIndex) * *entry->volume; - reverb = AudioSfx_ComputeReverb(bankId, entryIndex, channelIndex); - panSigned = AudioSfx_ComputePanSigned(*entry->posX, *entry->posZ, entry->token); - freqScale = AudioSfx_ComputeFreqScale(bankId, entryIndex) * *entry->freqScale; - - if (sSoundMode == SOUNDMODE_SURROUND_EXTERNAL) { - if (*entry->posZ >= 0.0f) { - if (*entry->posZ < 200.0f) { - zVolume = 32.0f - ((*entry->posZ / 300.0f) * 32.0f); - } else { - zVolume = 0; - } - } else if (*entry->posZ < 0.0f) { - if (*entry->posZ > -300.0f) { - zVolume = 32.0f - ((*entry->posZ / 300.0f) * 95.0f); - } else { - zVolume = 127; - } - } - zVolume = sZVolumes[zVolume]; - } - - if (sAudioBaseFilter != 0) { - if ((bankId == BANK_PLAYER) || (bankId == BANK_ITEM) || - ((bankId == BANK_VOICE) && (((entry->sfxId & 0xFF) < 0x40) || ((entry->sfxId & 0xFF) >= 0x80)))) { - baseFilter = sAudioBaseFilter; - if (sAudioExtraFilter) { - reverb >>= 2; - } - } - } - - if (((*entry->reverbAdd & 0x80) | baseFilter | sAudioExtraFilter | - (entry->sfxFlags & SFX_FLAG2_APPLY_LOWPASS_FILTER)) != 0) { - filter = ((((*entry->reverbAdd & 0x80) >> 2) | baseFilter | sAudioExtraFilter | - ((entry->sfxFlags & SFX_FLAG2_APPLY_LOWPASS_FILTER) >> 2)) * - 2); - filter &= 0xFF; - } else if ((sSoundMode == SOUNDMODE_SURROUND_EXTERNAL) && !(entry->sfxParams & SFX_FLAG_VOLUME_NO_DIST)) { - filter = AudioSfx_ComputeSurroundSoundFilter(behindScreenZ, entry, panSigned); - } - break; - - case BANK_SYSTEM: - break; - } - - if (sSfxChannelState[channelIndex].volume != volume) { - volumeS8 = (u8)(volume * 127.0f); - sSfxChannelState[channelIndex].volume = volume; - } else { - volumeS8 = -1; - } - - //! FAKE: - if (1) {} - - // ioPort 2, sets volume - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, channelIndex, 2, volumeS8); - - if (sSfxChannelState[channelIndex].reverb != reverb) { - sSfxChannelState[channelIndex].reverb = reverb; - } - if (sSfxChannelState[channelIndex].freqScale != freqScale) { - sSfxChannelState[channelIndex].freqScale = freqScale; - } - if (sSfxChannelState[channelIndex].stereoBits != 0) { - sSfxChannelState[channelIndex].stereoBits = 0; - } - if (sSfxChannelState[channelIndex].filter != filter) { - sSfxChannelState[channelIndex].filter = filter; - } - if (sSfxChannelState[channelIndex].combFilterGain != combFilterGain) { - sSfxChannelState[channelIndex].combFilterGain = combFilterGain; - } - if (sSfxChannelState[channelIndex].zVolume != zVolume) { - sSfxChannelState[channelIndex].zVolume = zVolume; - } - if (sSfxChannelState[channelIndex].panSigned != panSigned) { - sSfxChannelState[channelIndex].panSigned = panSigned; - } -} - -u32 AudioSfx_SetFreqAndStereoBits(u8 seqScriptValIn, SequenceChannel* channel) { - channel->stereoData.asByte = sSfxChannelState[seqScriptValIn].stereoBits; - channel->freqScale = sSfxChannelState[seqScriptValIn].freqScale; - channel->changes.s.freqScale = true; - - return seqScriptValIn; -} - -void AudioSfx_ResetSfxChannelState(void) { - SfxChannelState* state; - u8 i; - - for (i = 0; i < ARRAY_COUNT(sSfxChannelState); i++) { - state = &sSfxChannelState[i]; - state->volume = 1.0f; - state->freqScale = 1.0f; - state->reverb = 0; - state->panSigned = 0x40; - state->stereoBits = 0; - state->filter = 0xFF; - state->combFilterGain = 0xFF; - state->zVolume = 0xFF; - } - - sSfxChannelState[SFX_CHANNEL_OCARINA].combFilterGain = 0; - sPrevSeqMode = SEQ_MODE_DEFAULT; - sAudioCodeReverb = 0; -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/play_sound.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F128.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F170.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_PlaySfxAtPos.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F208.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F230.s") - -SfxSettings* AudioSfx_AddSfxSetting(Vec3f* pos) { - SfxSettings* sfxSettings; - u8 i = 0; - u8 sfxSettingIndex = 0xFF; - - for (; i < ARRAY_COUNT(sSfxSettings); i++) { - sfxSettings = &sSfxSettings[i]; - - if ((sfxSettings->pos == NULL) && (sfxSettingIndex == 0xFF)) { - sfxSettingIndex = i; - } - - if (sfxSettings->pos == pos) { - return sfxSettings; - } - } - - if (sfxSettingIndex != 0xFF) { - sSfxSettingsFlags |= 1 << sfxSettingIndex; - sfxSettings = &sSfxSettings[sfxSettingIndex]; - sfxSettings->pos = pos; - return sfxSettings; - } - - return NULL; -} - -void AudioSfx_ProcessSfxSettings(void) { - SfxBankEntry* entry; - u8 sfxSettingsFlags; - u8 sfxSettingIndex = 0; - u8 bankId; - u8 entryIndex; - s32 found; - - if (sSfxSettingsFlags != 0) { - sfxSettingsFlags = sSfxSettingsFlags; - - while (sfxSettingsFlags != 0) { - bankId = BANK_ENV; - if ((sfxSettingsFlags & (1 << sfxSettingIndex))) { - - found = false; - while ((bankId <= BANK_ENEMY) && !found) { - entryIndex = gSfxBanks[bankId]->next; - - while (entryIndex != 0xFF) { - entry = &gSfxBanks[bankId][entryIndex]; - entryIndex = 0xFF; - if (entry->posX == &sSfxSettings[sfxSettingIndex].pos->x) { - found = true; - } else { - entryIndex = entry->next; - } - } - bankId++; - } - - if (!found) { - sSfxSettingsFlags ^= (1 << sfxSettingIndex); - sSfxSettings[sfxSettingIndex].pos = NULL; - } - - sfxSettingsFlags ^= (1 << sfxSettingIndex); - } - sfxSettingIndex++; - } - } -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F420.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F4AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F540.s") - -void AudioSfx_LowerSfxSettingsReverb(Vec3f* pos, s8 isReverbLowered) { - SfxSettings* sfxSettings = AudioSfx_AddSfxSetting(pos); - - if (sfxSettings != NULL) { - if (isReverbLowered) { - sfxSettings->reverbAdd = -0x80; - } else { - sfxSettings->reverbAdd = 0; - } - } -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F5AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F638.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F780.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F7D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F830.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F88C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F900.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FA18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FAD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FB0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FC20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FCB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FD90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FDC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FE1C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FE74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FEDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FF38.s") - -/** - * Used for EnRiverSound - */ -void Audio_PlaySfxForRiver(Vec3f* pos, f32 freqScale) { - if (!AudioSfx_IsPlaying(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; - } - AudioSfx_PlaySfx(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultReverb); -} - -/** - * Unused remnant of OoT's EnRiverSound - * Used for Zora's River Waterfall - */ -void Audio_PlaySfxForWaterfall(Vec3f* pos, f32 freqScale) { - if (!AudioSfx_IsPlaying(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; - } - AudioSfx_PlaySfx(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, pos, 4, &sWaterfallFreqScaleLerp.value, - &sWaterfallFreqScaleLerp.value, &gSfxDefaultReverb); -} - -/** - * Used for EnRiverSound variables - */ -void Audio_StepFreqLerp(FreqLerp* lerp) { - if (lerp->remainingFrames != 0) { - lerp->remainingFrames--; - if (lerp->remainingFrames != 0) { - lerp->value += lerp->step; - } else { - lerp->value = lerp->target; - } - } -} - -f32 sBigBellsVolume[8] = { - 1.0f, 0.9f, 0.8f, 0.7f, 0.6f, 0.5f, 0.4f, 0.3f, -}; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0124.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0184.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A01C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0204.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0238.s") - -/** - * Unused remnant from OoT's EnRiverSound - * Was designed to 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 channelIndex; - s8 panChannelWeight = 0; - - // Ganondorfs's Lair - if (ganonsTowerLevel == 0) { - // Pan comes entirely from the SequenceChannel - panChannelWeight = 0x7F; - } - - for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) { - AUDIOCMD_CHANNEL_SET_PAN_WEIGHT(SEQ_PLAYER_BGM_MAIN, channelIndex, panChannelWeight); - } - - // 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)]); - } -} - -/** - * Unused remnant from OoT's EnRiverSound - * 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 targetVolume) { - u8 lowPassFilterCutoff; - u8 channelIndex; - u16 reverb; - - if (sGanonsTowerVol != targetVolume) { - // Sets the volume - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 0, targetVolume, 2); - - // Sets the filter cutoff of the form (lowPassFilterCutoff << 4) | (highPassFilter & 0xF). highPassFilter is - // always set to 0 - if (targetVolume < 0x40) { - // Only the first room - lowPassFilterCutoff = 0x10; - } else { - // Higher volume leads to a higher cut-off frequency in the low-pass filtering - lowPassFilterCutoff = (((targetVolume - 0x40) >> 2) + 1) << 4; - } - - Audio_QueueSeqCmd((8 << 28) | ((u8)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u8)(4) << 16) | ((u8)(15) << 8) | - (u8)(lowPassFilterCutoff)); - - // Sets the reverb - for (channelIndex = 0; channelIndex < ARRAY_COUNT(gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels); - channelIndex++) { - if (&gAudioCtx.sequenceChannelNone != gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIndex]) { - // seqScriptIO[5] was originally set to 0x40 in channels 0, 1, and 4 by OoT's Ganon's Tower BGM, - // which was removed in MM - if ((u8)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIndex]->seqScriptIO[5] != - (u8)SEQ_IO_VAL_NONE) { - // Higher volume leads to lower reverb - reverb = (((u16)gAudioCtx.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIndex]->seqScriptIO[5] - - targetVolume) + - 0x7F); - - if (reverb > 0x7F) { - reverb = 0x7F; - } - - AUDIOCMD_CHANNEL_SET_REVERB_VOLUME(SEQ_PLAYER_BGM_MAIN, channelIndex, (u8)reverb); - } - } - } - - sGanonsTowerVol = targetVolume; - } - return -1; -} - -/** - * Unused remnant from OoT's EnRiverSound - * 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; -} - -/** - * Unused remnant from OoT's EnRiverSound - * Still called by Audio_Update every frame, but none of these processes get initialized - */ -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, 0, sRiverSoundMainBgmVol, 10); - sRiverSoundMainBgmCurrentVol = sRiverSoundMainBgmVol; - sRiverSoundMainBgmRestore = true; - } - sRiverSoundMainBgmLower = false; - } else if ((sRiverSoundMainBgmRestore == true) && !sAudioIsWindowOpen) { - // restores the volume every frame - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 0, 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]); - } - } -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0554.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A05E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A05F0.s") - -void AudioSfx_SetChannelIO(Vec3f* pos, u16 sfxId, u8 ioData) { - u8 channelIndex = 0; - u8 bankId = SFX_BANK_SHIFT(sfxId); - u8 entryIndex; - u8 i; - - for (i = 0; i < bankId; i++) { - channelIndex += gChannelsPerBank[gSfxChannelLayout][i]; - } - - for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) { - entryIndex = gActiveSfx[bankId][i].entryIndex; - - if (entryIndex != 0xFF) { - if ((sfxId == gSfxBanks[bankId][entryIndex].sfxId) && (&pos->x == gSfxBanks[bankId][entryIndex].posX)) { - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, channelIndex, 6, ioData); - } - } - channelIndex++; - } -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0810.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0868.s") - -/** - * Unused remnant of OoT's EnRiverSound (func_800F4E30) - */ -void func_801A09D4(Vec3f* pos, f32 xzDistToPlayer) { - f32 volumeRel; - s8 pan; - u8 channelIndex; - - if (sRiverSoundBgmPos == NULL) { - sRiverSoundBgmPos = pos; - sRiverSoundXZDistToPlayer = xzDistToPlayer; - } else if (sRiverSoundBgmPos != pos) { - if (sRiverSoundXZDistToPlayer > xzDistToPlayer) { - sRiverSoundBgmPos = pos; - sRiverSoundXZDistToPlayer = xzDistToPlayer; - } - } else { - sRiverSoundXZDistToPlayer = xzDistToPlayer; - } - - if (sRiverSoundBgmPos->x > 100.0f) { - pan = 0x7F; - } else if (sRiverSoundBgmPos->x < -100.0f) { - pan = 0; - } else { - pan = ((sRiverSoundBgmPos->x / 100.0f) * 64.0f) + 64.0f; - } - - if (sRiverSoundXZDistToPlayer > 400.0f) { - volumeRel = 0.1f; - } else if (sRiverSoundXZDistToPlayer < 120.0f) { - volumeRel = 1.0f; - } else { - volumeRel = ((1.0f - ((sRiverSoundXZDistToPlayer - 120.0f) / 280.0f)) * 0.9f) + 0.1f; - } - - for (channelIndex = 0; channelIndex < 16; channelIndex++) { - if (channelIndex != 9) { - Audio_QueueSeqCmd(((u32)(6) << 28) | ((u32)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u32)(2) << 16) | - ((u32)(channelIndex) << 8) | ((u8)(127.0f * volumeRel))); - AUDIOCMD_CHANNEL_SET_PAN(SEQ_PLAYER_BGM_MAIN, channelIndex, pan); - } - } -} - -/** - * Unused remnant of OoT's EnRiverSound - */ -void Audio_ClearSariaBgm(void) { - if (sRiverSoundBgmPos != NULL) { - sRiverSoundBgmPos = NULL; - } -} - -/** - * Unused remnant of OoT's EnRiverSound - */ -void Audio_ClearSariaBgmAtPos(Vec3f* pos) { - if (sRiverSoundBgmPos == pos) { - sRiverSoundBgmPos = 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 volumeSplit) { - u8 volume; - u8 notePriority; - u16 channelBits; - u8 sBgmPlayers[2] = { SEQ_PLAYER_BGM_MAIN, SEQ_PLAYER_BGM_SUB }; - u8 i; - u8 channelIndex; - - if ((Audio_GetActiveSequence(SEQ_PLAYER_FANFARE) == NA_BGM_DISABLED) && - (Audio_GetActiveSequence(SEQ_PLAYER_BGM_SUB) != NA_BGM_ROMANI_RANCH)) { - for (i = 0; i < ARRAY_COUNT(sBgmPlayers); i++) { - if (i == 0) { - // Main Bgm SeqPlayer - volume = volumeSplit; - } else { - // Sub Bgm SeqPlayer - volume = 0x7F - volumeSplit; - } - - if (volume > 100) { - notePriority = 11; - } else if (volume < 20) { - notePriority = 2; - } else { - notePriority = ((volume - 20) / 10) + 2; - } - - channelBits = 0; - for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) { - if (gAudioCtx.seqPlayers[sBgmPlayers[i]].channels[channelIndex]->notePriority < 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 << channelIndex); - } - } - - Audio_QueueSeqCmd(0xA0000000 | ((u32)(sBgmPlayers[i]) << 24) | ((u32)(channelBits))); - } - } -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0E44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1290.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1348.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A13BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A153C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A17F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1904.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1A10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1A8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1D44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1DB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1E0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1F00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1F88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1FB4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2090.s") - -/** - * Unused remnant of OoT's EnRiverSound - */ -void Audio_PlaySariaBgm(Vec3f* pos, u16 seqId, u16 distMax) { - f32 absY; - f32 dist; - u8 targetVolume; - f32 prevDist; - - if (sRiverSoundBgmTimer != 0) { - sRiverSoundBgmTimer--; - return; - } - - dist = sqrtf(SQ(pos->z) + (SQ(pos->x) + SQ(pos->y))); - - if (sRiverSoundBgmPos == NULL) { - sRiverSoundBgmPos = pos; - Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_SUB, seqId, 0, 7, 2); - } else { - prevDist = sqrtf(SQ(sRiverSoundBgmPos->z) + SQ(sRiverSoundBgmPos->x)); - if (dist < prevDist) { - sRiverSoundBgmPos = pos; - } else { - dist = prevDist; - } - } - - absY = ABS_ALT(pos->y); - - if ((distMax / 15.0f) < absY) { - targetVolume = 0; - } else if (dist < distMax) { - targetVolume = (1.0f - (dist / distMax)) * 127.0f; - } else { - targetVolume = 0; - } - - if (seqId != NA_BGM_FAIRY_FOUNTAIN) { - Audio_SplitBgmChannels(targetVolume); - } - - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, 3, targetVolume, 0); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 3, 0x7F - targetVolume, 0); -} - -/** - * Unused remnant of OoT's EnRiverSound - */ -void Audio_ClearSariaBgm2(void) { - sRiverSoundBgmPos = NULL; -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A246C.s") - -void Audio_PlayMorningSceneSequence(u16 seqId, u8 dayMinusOne) { - Audio_StartMorningSceneSequence(seqId); - Audio_QueueSeqCmd(0x70000000 | ((u32)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u32)(4) << 0x10) | (u32)(dayMinusOne)); -} - -void Audio_StartMorningSceneSequence(u16 seqId) { - if (seqId != NA_BGM_AMBIENCE) { - Audio_QueueSeqCmd(0x100000FF | ((u8)(SEQ_PLAYER_AMBIENCE) << 24) | ((0) << 16)); - Audio_StartSceneSequence(seqId); - Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_MAIN, seqId, 0, 0, 1); - } else { - Audio_PlayAmbience(AMBIENCE_ID_08); - } -} - -void Audio_PlaySceneSequence(u16 seqId, u8 dayMinusOne) { - if (sRequestedSceneSeqId != seqId) { - if (seqId == NA_BGM_AMBIENCE) { - Audio_PlayAmbience(AMBIENCE_ID_08); - } else if ((seqId != NA_BGM_FINAL_HOURS) || (sPrevMainBgmSeqId == NA_BGM_DISABLED)) { - Audio_StartSceneSequence(seqId); - Audio_QueueSeqCmd(0x70000000 | ((u32)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u32)(4) << 0x10) | - (u32)(dayMinusOne)); - } - sRequestedSceneSeqId = seqId; - } -} - -void Audio_StartSceneSequence(u16 seqId) { - u8 fadeInDuration = 0; - u8 skipHarpIntro; - - 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 resume 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. - if (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_SKIP_HARP_INTRO) { - skipHarpIntro = 1; - } else { - skipHarpIntro = (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_GetActiveSequence(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].seqScriptIO[3]; - } else { - // Initialize the point to resume from to the start of the sequence - sSeqResumePoint = 0; - } - } -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A27E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A281C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A29D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2BB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2C20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2C44.s") - -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_KAMARO) { - Audio_QueueSeqCmd(0x00000000 | ((u32)(SEQ_PLAYER_FANFARE) << 24) | ((u32)(0) << 0x10) | (u32)(seqId)); - } else if (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_NO_AMBIENCE) { - Audio_QueueSeqCmd(0x00000000 | ((u32)(SEQ_PLAYER_BGM_SUB) << 24) | ((u32)(0) << 0x10) | (u32)(seqId)); - } else { - Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_MAIN, seqId, 0, 7, SEQ_IO_VAL_NONE); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 1, 0x7F, 0); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 3, 0x7F, 0); - Audio_QueueSeqCmd(0x100000FF | ((u8)(SEQ_PLAYER_FANFARE) << 24) | ((0) << 16)); - } -} - -void Audio_StopSequenceInCutscene(u16 seqId) { - if (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_FANFARE) { - Audio_QueueSeqCmd(0x100000FF | ((u8)(SEQ_PLAYER_FANFARE) << 24) | ((0) << 16)); - } else if (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_FANFARE_KAMARO) { - Audio_QueueSeqCmd(0x100000FF | ((u8)(SEQ_PLAYER_FANFARE) << 24) | ((0) << 16)); - } else if (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_NO_AMBIENCE) { - Audio_QueueSeqCmd(0x100000FF | ((u8)(SEQ_PLAYER_BGM_SUB) << 24) | ((0) << 16)); - } else { - Audio_QueueSeqCmd(0x100000FF | ((u8)(SEQ_PLAYER_BGM_MAIN) << 24) | ((0) << 16)); - } -} - -s32 Audio_IsSequencePlaying(u8 seqId) { - u8 playerIndex = SEQ_PLAYER_BGM_MAIN; - - if (sSeqFlags[seqId & 0xFF] & SEQ_FLAG_FANFARE) { - playerIndex = SEQ_PLAYER_FANFARE; - } else if (sSeqFlags[seqId & 0xFF] & SEQ_FLAG_FANFARE_KAMARO) { - playerIndex = SEQ_PLAYER_FANFARE; - } - - if (seqId == (Audio_GetActiveSequence(playerIndex) & 0xFF)) { - return true; - } else { - return false; - } -} - -void Audio_PlayBgm_StorePrevBgm(u16 seqId) { - u16 curSeqId = Audio_GetActiveSequence(SEQ_PLAYER_BGM_MAIN); - - if (curSeqId == NA_BGM_DISABLED) { - curSeqId = NA_BGM_GENERAL_SFX; - } - - if (curSeqId != seqId) { - Audio_SetSequenceMode(SEQ_MODE_IGNORE); - - // Ensure the sequence about to be stored isn't also storing a separate sequence - if (!(sSeqFlags[curSeqId] & SEQ_FLAG_RESTORE)) { - sPrevMainBgmSeqId = curSeqId; - } - - Audio_QueueSeqCmd(0x00000000 | ((u32)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u32)(0) << 0x10) | (u32)(seqId + 0x8000)); - } -} - -/** - * To be used in conjunction with Audio_PlayBgm_StorePrevBgm - */ -void Audio_RestorePrevBgm(void) { - if ((Audio_GetActiveSequence(SEQ_PLAYER_BGM_MAIN) != NA_BGM_DISABLED) && - (sSeqFlags[Audio_GetActiveSequence(SEQ_PLAYER_BGM_MAIN) & 0xFF] & SEQ_FLAG_RESTORE)) { - if ((sPrevMainBgmSeqId == NA_BGM_DISABLED) || (sPrevMainBgmSeqId == NA_BGM_GENERAL_SFX)) { - Audio_QueueSeqCmd(0x100000FF | ((u8)(SEQ_PLAYER_BGM_MAIN) << 24) | ((0) << 16)); - } else { - if (sPrevMainBgmSeqId == NA_BGM_AMBIENCE) { - sPrevMainBgmSeqId = sPrevAmbienceSeqId; - } - Audio_QueueSeqCmd(0x00000000 | ((u32)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u32)(0) << 0x10) | - (u32)(sPrevMainBgmSeqId + 0x8000)); - } - sPrevMainBgmSeqId = NA_BGM_DISABLED; - } -} - -// Unused -void Audio_PlayAmbience_StorePrevBgm(u8 ambienceId) { - u16 seqId = Audio_GetActiveSequence(SEQ_PLAYER_BGM_MAIN); - - if (seqId != NA_BGM_AMBIENCE) { - sPrevMainBgmSeqId = seqId; - } - - Audio_PlayAmbience(ambienceId); -} - -// Unused -void Audio_ForceRestorePreviousBgm(void) { - if (sPrevMainBgmSeqId != NA_BGM_DISABLED) { - Audio_QueueSeqCmd(0x00000000 | ((u32)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u32)(0) << 0x10) | - (u32)(sPrevMainBgmSeqId + 0x8000)); - } - - sPrevMainBgmSeqId = NA_BGM_DISABLED; -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3000.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3038.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_PlayFanfare.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A312C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A31EC.s") - -void Audio_PlaySequenceWithSeqPlayerIO(s8 playerIndex, u16 seqId, u8 fadeInDuration, s8 ioPort, u8 ioData) { - u16 flaggedSeqId; - - Audio_QueueSeqCmd(0x70000000 | ((u32)(playerIndex) << 24) | ((u32)(ioPort) << 0x10) | (u32)(ioData)); - if ((seqId & 0xFF) < 2) { - flaggedSeqId = seqId; - } else { - flaggedSeqId = seqId | 0x8000; - } - Audio_QueueSeqCmd(0x00000000 | ((u32)(playerIndex) << 24) | ((u32)(fadeInDuration) << 0x10) | (u32)(flaggedSeqId)); -} - -void Audio_SetSequenceMode(u8 seqMode) { - s32 volumeFadeInTimer; - u16 seqId; - u8 volumeFadeOutTimer; - - if ((sPrevMainBgmSeqId == NA_BGM_DISABLED) && (sPrevMainBgmSeqId == NA_BGM_DISABLED)) { - // clang-format off - if (sAudioCutsceneFlag || sSpatialSeqIsActive[SEQ_PLAYER_BGM_SUB]) { \ - seqMode = SEQ_MODE_IGNORE; - } - // clang-format on - - seqId = gActiveSeqs[SEQ_PLAYER_BGM_MAIN].seqId; - - if ((seqId == NA_BGM_DISABLED) || (sSeqFlags[(u8)(seqId & 0xFF)] & SEQ_FLAG_ENEMY) || - ((sPrevSeqMode & 0x7F) == SEQ_MODE_ENEMY)) { - if (seqMode != (sPrevSeqMode & 0x7F)) { - if (seqMode == SEQ_MODE_ENEMY) { - // If only seqMode = SEQ_MODE_ENEMY (Start) - if (gActiveSeqs[SEQ_PLAYER_BGM_SUB].volScales[1] - sBgmEnemyVolume < 0) { - volumeFadeInTimer = -(gActiveSeqs[SEQ_PLAYER_BGM_SUB].volScales[1] - sBgmEnemyVolume); - } else { - volumeFadeInTimer = gActiveSeqs[SEQ_PLAYER_BGM_SUB].volScales[1] - sBgmEnemyVolume; - } - - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, 3, sBgmEnemyVolume, volumeFadeInTimer); - Audio_QueueSeqCmd(0x00000000 | ((u32)(SEQ_PLAYER_BGM_SUB) << 24) | ((u32)(10) << 0x10) | - (u32)(NA_BGM_ENEMY | 0x800)); - - if (seqId >= NA_BGM_TERMINA_FIELD) { - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 3, 0x7F - sBgmEnemyVolume, 10); - Audio_SplitBgmChannels(sBgmEnemyVolume); - } - } else if ((sPrevSeqMode & 0x7F) == SEQ_MODE_ENEMY) { - // If only sPrevSeqMode = SEQ_MODE_ENEMY (End) - Audio_QueueSeqCmd(0x100000FF | ((u8)(SEQ_PLAYER_BGM_SUB) << 24) | ((10) << 16)); - - if (seqMode == SEQ_MODE_IGNORE) { - volumeFadeOutTimer = 0; - } else { - volumeFadeOutTimer = 10; - } - - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 3, 0x7F, volumeFadeOutTimer); - Audio_SplitBgmChannels(0); - } - - sPrevSeqMode = seqMode + 0x80; - } else { - if (seqMode == SEQ_MODE_ENEMY) { - // If both seqMode = sPrevSeqMode = SEQ_MODE_ENEMY - if ((Audio_GetActiveSequence(SEQ_PLAYER_BGM_SUB) == NA_BGM_DISABLED) && - (seqId != NA_BGM_DISABLED) && (sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_ENEMY)) { - Audio_QueueSeqCmd(0x00000000 | ((u32)(SEQ_PLAYER_BGM_SUB) << 24) | ((u32)(10) << 0x10) | - (u32)(NA_BGM_ENEMY | 0x800)); - sPrevSeqMode = seqMode + 0x80; - } - } - } - } else { - // Remnant of OoT's Hyrule Field Sequence - 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; - Audio_QueueSeqCmd(0x70000000 | ((u32)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u32)(2) << 0x10) | (u32)(seqMode)); - } - } -} - -void Audio_UpdateEnemyBgmVolume(f32 dist) { - f32 adjDist; - u16 seqId = gActiveSeqs[SEQ_PLAYER_BGM_MAIN].seqId; - - if (sPrevSeqMode == (SEQ_MODE_ENEMY | 0x80)) { - if (dist != sBgmEnemyDist) { - // clamp (dist - 150.0f) between 0 and 350 - if (dist < 150.0f) { - adjDist = 0.0f; - } else if (dist > 500.0f) { - adjDist = 350.0f; - } else { - adjDist = dist - 150.0f; - } - - sBgmEnemyVolume = ((350.0f - adjDist) * 127.0f) / 350.0f; - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, 3, sBgmEnemyVolume, 10); - - if ((seqId >= NA_BGM_TERMINA_FIELD) && !(sSeqFlags[seqId & 0xFF & 0xFF] & SEQ_FLAG_FANFARE_KAMARO)) { - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 3, (0x7F - sBgmEnemyVolume), 10); - } - } - - Audio_SplitBgmChannels(sBgmEnemyVolume); - } - sBgmEnemyDist = dist; -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A36F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3950.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A39F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3A7C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3AC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3AEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3B48.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3B90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3CD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3CF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3D54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3D98.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3E38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3EC0.s") - -void Audio_SetCutsceneFlag(s8 flag) { - sAudioCutsceneFlag = flag; -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3F6C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3FB4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3FFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_SetSpec.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4058.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A41C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A41F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A429C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A42C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4324.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4348.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_SetSfxVolumeExceptSystemAndOcarinaBanks.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4428.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_PreNMI.s") - -void Audio_ResetRequestedSceneSeqId(void) { - sRequestedSceneSeqId = NA_BGM_DISABLED; -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A44D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A46F8.s") - -f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4748.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A479C.s") - -void Audio_SetAmbienceChannelIO(u8 channelIndexRange, u8 ioPort, u8 ioData) { - u8 firstChannelIndex; - u8 lastChannelIndex; - u8 channelIndex; - - if ((gActiveSeqs[SEQ_PLAYER_AMBIENCE].seqId != NA_BGM_AMBIENCE) && func_801A8ABC(NA_BGM_AMBIENCE, 0xF00000FF)) { - return; - } - - // channelIndexRange = 01 on ioPort 1 - if ((((channelIndexRange << 8) + (u32)ioPort) == ((1 << 8) | (u32)1)) && - (Audio_GetActiveSequence(SEQ_PLAYER_BGM_SUB) != NA_BGM_ROMANI_RANCH)) { - D_801FD3A8 = 0; - } - - firstChannelIndex = channelIndexRange >> 4; - lastChannelIndex = channelIndexRange & 0xF; - - if (firstChannelIndex == 0) { - firstChannelIndex = channelIndexRange & 0xF; - } - - for (channelIndex = firstChannelIndex; channelIndex <= lastChannelIndex; channelIndex++) { - Audio_QueueSeqCmd(0x80000000 | ((u32)(SEQ_PLAYER_AMBIENCE) << 24) | ((u32)(ioPort) << 16) | - ((u32)(channelIndex) << 8) | (u32)(ioData)); - } -} - -void Audio_StartAmbience(u16 initChannelMask, u16 initMuteChannelMask) { - u8 channelIndex; - - Audio_QueueSeqCmd(0x70000000 | ((u32)(SEQ_PLAYER_AMBIENCE) << 24) | ((u32)(SEQ_PLAYER_IO_PORT_0) << 0x10) | - (u32)(1)); - Audio_QueueSeqCmd(0x70000000 | ((u32)(SEQ_PLAYER_AMBIENCE) << 24) | ((u32)(SEQ_PLAYER_IO_PORT_4) << 0x10) | - (u32)((u8)(initChannelMask >> 8))); - Audio_QueueSeqCmd(0x70000000 | ((u32)(SEQ_PLAYER_AMBIENCE) << 24) | ((u32)(SEQ_PLAYER_IO_PORT_5) << 0x10) | - (u32)((u8)(initChannelMask & 0xFF))); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 0, 0x7F, 1); - - if ((Audio_GetActiveSequence(SEQ_PLAYER_AMBIENCE) != NA_BGM_DISABLED) && - (Audio_GetActiveSequence(SEQ_PLAYER_AMBIENCE) != NA_BGM_AMBIENCE)) { - Audio_StopSequence(SEQ_PLAYER_AMBIENCE, 0); - AUDIOCMD_GLOBAL_STOP_AUDIOCMDS(); - } - - if (Audio_GetActiveSequence(SEQ_PLAYER_BGM_SUB) == (NA_BGM_ENEMY | 0x800)) { - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 3, 0x7F, 1); - } - - Audio_QueueSeqCmd(0x00000000 | ((u32)(SEQ_PLAYER_AMBIENCE) << 24) | ((u32)(0) << 0x10) | (u32)(NA_BGM_AMBIENCE)); - - for (channelIndex = 0; channelIndex < 16; channelIndex++) { - if (!(initMuteChannelMask & (1 << channelIndex)) && (initChannelMask & (1 << channelIndex))) { - Audio_QueueSeqCmd(0x80000000 | ((u32)(SEQ_PLAYER_AMBIENCE) << 24) | ((u32)(CHANNEL_IO_PORT_1) << 16) | - ((u32)(channelIndex) << 8) | (u32)(1)); - } - } -} - -void Audio_PlayAmbience(u8 ambienceId) { - u8 i = 0; - u8 channelIndex; - u8 ioPort; - u8 ioData; - - if (!((gActiveSeqs[SEQ_PLAYER_AMBIENCE].seqId != NA_BGM_DISABLED) && - (sSeqFlags[gActiveSeqs[SEQ_PLAYER_AMBIENCE].seqId & 0xFF & 0xFF] & SEQ_FLAG_NO_AMBIENCE))) { - if (gActiveSeqs[SEQ_PLAYER_AMBIENCE].seqId != NA_BGM_AMBIENCE) { - sPrevAmbienceSeqId = gActiveSeqs[SEQ_PLAYER_AMBIENCE].seqId; - } - - Audio_StartAmbience(sAmbienceData[ambienceId].initChannelMask, sAmbienceData[ambienceId].initMuteChannelMask); - - while ((sAmbienceData[ambienceId].channelProperties[i] != 0xFF) && - (i < ARRAY_COUNT(sAmbienceData[ambienceId].channelProperties))) { - channelIndex = sAmbienceData[ambienceId].channelProperties[i++]; - ioPort = sAmbienceData[ambienceId].channelProperties[i++]; - ioData = sAmbienceData[ambienceId].channelProperties[i++]; - Audio_QueueSeqCmd(0x80000000 | ((u32)(SEQ_PLAYER_AMBIENCE) << 24) | ((u32)(ioPort) << 16) | - ((u32)(channelIndex) << 8) | (u32)(ioData)); - } - - Audio_QueueSeqCmd(0x80000000 | ((u32)(SEQ_PLAYER_AMBIENCE) << 24) | ((u32)(CHANNEL_IO_PORT_7) << 16) | - ((u32)(AMBIENCE_CHANNEL_SOUND_MODE) << 8) | (u32)(sSoundMode)); - } -} - -u32 Audio_SetAmbienceRandomBend(u8 seqScriptValIn, SequenceChannel* channel) { - u32 seqScriptValOut = seqScriptValIn; - - gAudioCtx.seqPlayers[SEQ_PLAYER_AMBIENCE].applyBend = true; - - if ((seqScriptValIn == 0) || (seqScriptValIn == 0xFF)) { - gAudioCtx.seqPlayers[SEQ_PLAYER_AMBIENCE].bend = 1.0f; - } else { - seqScriptValOut = AudioThread_NextRandom(); - gAudioCtx.seqPlayers[SEQ_PLAYER_AMBIENCE].bend = 1.0293 - ((gAudioCtx.audioRandom & 0xF) / 144.0f); - - return seqScriptValOut; - } - -#ifdef AVOID_UB - return seqScriptValOut; -#endif -} - -void Audio_Init(void) { - AudioLoad_Init(NULL, 0); -} - -void AudioSfx_Init(u16 fadeTimer) { - u8 channelIndex; - - AudioThread_ScheduleProcessCmds(); - Audio_StartSequence(SEQ_PLAYER_SFX, NA_BGM_GENERAL_SFX, 0x70, fadeTimer); - - for (channelIndex = 0; channelIndex < ARRAY_COUNT(sSfxChannelState); channelIndex++) { - AUDIOCMD_CHANNEL_SET_SFX_STATE(SEQ_PLAYER_SFX, channelIndex, &sSfxChannelState[channelIndex]); - } - - AUDIOCMD_GLOBAL_SET_CUSTOM_FUNCTION(AUDIO_CUSTOM_FUNCTION_SEQ_0, AudioSfx_SetFreqAndStereoBits); - AUDIOCMD_GLOBAL_SET_CUSTOM_FUNCTION(AUDIO_CUSTOM_FUNCTION_SEQ_1, Audio_SetAmbienceRandomBend); -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4D00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4D50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4DA4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4DF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4E64.s") diff --git a/src/code/audio/code_801A4EB0.c b/src/code/audio/code_801A4EB0.c deleted file mode 100644 index d3461c8f5..000000000 --- a/src/code/audio/code_801A4EB0.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A4EB0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A4EB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A4FD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A5080.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A50C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A5100.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A510C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A5118.s") diff --git a/src/code/audio/code_801A51F0.c b/src/code/audio/code_801A51F0.c deleted file mode 100644 index 6a40bf23a..000000000 --- a/src/code/audio/code_801A51F0.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/D_801E0EC0.s") - -UNK_TYPE func_801A51F0(UNK_TYPE arg0) { - switch (arg0) { - case 1: - case 4: - case 5: - case 11: - case 13: - case 14: - case 15: - return -1; - default: - return 0; - } -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A5228.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A5390.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A53DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A53E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A541C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A5488.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A54C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A54D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A5680.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A5808.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A5A10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A51F0/func_801A5A1C.s") diff --git a/src/code/audio/code_801A5BD0.c b/src/code/audio/code_801A5BD0.c deleted file mode 100644 index 76597f5f3..000000000 --- a/src/code/audio/code_801A5BD0.c +++ /dev/null @@ -1,944 +0,0 @@ -#include "global.h" - -typedef struct { - /* 0x00 */ u16 sfxId; - /* 0x02 */ u8 token; - /* 0x04 */ s8* reverbAdd; - /* 0x08 */ Vec3f* pos; - /* 0x0C */ f32* freqScale; - /* 0x10 */ f32* volume; -} SfxRequest; // size = 0x14 - -typedef struct { - /* 0x0 */ f32 value; - /* 0x4 */ f32 target; - /* 0x8 */ f32 step; - /* 0xC */ u16 remainingFrames; -} SfxBankLerp; // size = 0x10 - -typedef enum { - /* 0 */ SFX_RM_REQ_BY_BANK, - /* 1 */ SFX_RM_REQ_BY_POS_AND_BANK, - /* 2 */ SFX_RM_REQ_BY_POS, - /* 3 */ SFX_RM_REQ_BY_POS_AND_ID, - /* 4 */ SFX_RM_REQ_BY_TOKEN_AND_ID, - /* 5 */ SFX_RM_REQ_BY_ID -} SfxRemoveRequest; - -SfxBankEntry sSfxPlayerBank[9]; -SfxBankEntry sSfxItemBank[12]; -SfxBankEntry sSfxEnvironmentBank[32]; -SfxBankEntry sSfxEnemyBank[20]; -SfxBankEntry sSfxSystemBank[8]; -SfxBankEntry sSfxOcarinaBank[3]; -SfxBankEntry sSfxVoiceBank[5]; -SfxRequest sSfxRequests[0x100]; -u8 sSfxBankListEnd[7]; -u8 sSfxBankFreeListStart[7]; -u8 sSfxBankUnused[7]; -ActiveSfx gActiveSfx[7][3]; -u8 sCurSfxPlayerChannelIndex; -u8 gSfxBankMuted[7]; -SfxBankLerp sSfxBankLerp[7]; - -// sSfxRequests ring buffer endpoints. read index <= write index, wrapping around mod 256. -u8 sSfxRequestWriteIndex = 0; -u8 sSfxRequestReadIndex = 0; - -/** - * Array of pointers to arrays of SfxBankEntry of sizes: 9, 12, 32, 20, 8, 3, 5 - * - * 0 : Player Bank size 9 - * 1 : Item Bank size 12 - * 2 : Environment Bank size 32 - * 3 : Enemy Bank size 20 - * 4 : System Bank size 8 - * 5 : Ocarina Bank size 3 - * 6 : Voice Bank size 5 - */ -SfxBankEntry* gSfxBanks[7] = { - sSfxPlayerBank, sSfxItemBank, sSfxEnvironmentBank, sSfxEnemyBank, sSfxSystemBank, sSfxOcarinaBank, sSfxVoiceBank, -}; - -u8 sSfxBankSizes[ARRAY_COUNT(gSfxBanks)] = { - ARRAY_COUNT(sSfxPlayerBank), ARRAY_COUNT(sSfxItemBank), ARRAY_COUNT(sSfxEnvironmentBank), - ARRAY_COUNT(sSfxEnemyBank), ARRAY_COUNT(sSfxSystemBank), ARRAY_COUNT(sSfxOcarinaBank), - ARRAY_COUNT(sSfxVoiceBank), -}; - -u8 gSfxChannelLayout = 0; -u16 sSfxChannelLowVolumeFlag = 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_801DB4B4 = 0; // unused - -// Adds no reverb to the existing reverb -s8 gSfxDefaultReverb = 0; - -void AudioSfx_MuteBanks(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; - } -} - -/** - * Lowers volumes of both bgm players so that sfx can be more pronounced. - * Each sfx channel stores its own bit to lower the volume. - * Only a single channel needs to request this to lower the volume. - */ -void AudioSfx_LowerBgmVolume(u8 channelIndex) { - sSfxChannelLowVolumeFlag |= (1 << channelIndex); - - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 2, 0x40, 0xF); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, 2, 0x40, 0xF); -} - -/** - * Clears the flag for the specific channel to lower volume. - * If all flags are cleared, then both bgm players return to full volume - */ -void AudioSfx_RestoreBgmVolume(u8 channelIndex) { - sSfxChannelLowVolumeFlag &= ((1 << channelIndex) ^ 0xFFFF); - - if (sSfxChannelLowVolumeFlag == 0) { - Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 2, 0x7F, 0xF); - Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, 2, 0x7F, 0xF); - } -} - -/** - * The main function to request a sfx. All sfx requests begin here. - */ -void AudioSfx_PlaySfx(u16 sfxId, Vec3f* pos, u8 token, f32* freqScale, f32* volume, s8* reverbAdd) { - u8 i; - SfxRequest* reqWrite; - SfxRequest* reqRead; - - if (!gSfxBankMuted[SFX_BANK_SHIFT(sfxId)]) { - reqWrite = &sSfxRequests[sSfxRequestWriteIndex]; - - for (i = sSfxRequestReadIndex; sSfxRequestWriteIndex != i; i++) { - reqRead = &sSfxRequests[i]; - if ((reqRead->pos == pos) && (reqRead->sfxId == sfxId)) { - return; - } - } - - reqWrite->sfxId = sfxId; - reqWrite->pos = pos; - reqWrite->token = token; - reqWrite->freqScale = freqScale; - reqWrite->volume = volume; - reqWrite->reverbAdd = reverbAdd; - sSfxRequestWriteIndex++; - } -} - -void AudioSfx_RemoveMatchingRequests(u8 aspect, SfxBankEntry* entry) { - SfxRequest* req; - s32 remove; - u8 i = sSfxRequestReadIndex; - - for (; i != sSfxRequestWriteIndex; i++) { - remove = false; - req = &sSfxRequests[i]; - - switch (aspect) { - case SFX_RM_REQ_BY_BANK: - if (SFX_BANK_MASK(req->sfxId) == SFX_BANK_MASK(entry->sfxId)) { - remove = true; - } - break; - - case SFX_RM_REQ_BY_POS_AND_BANK: - if ((SFX_BANK_MASK(req->sfxId) == SFX_BANK_MASK(entry->sfxId)) && (&req->pos->x == entry->posX)) { - remove = true; - } - break; - - case SFX_RM_REQ_BY_POS: - if (&req->pos->x == entry->posX) { - remove = true; - } - break; - - case SFX_RM_REQ_BY_POS_AND_ID: - if ((&req->pos->x == entry->posX) && (req->sfxId == entry->sfxId)) { - remove = true; - } - break; - - case SFX_RM_REQ_BY_TOKEN_AND_ID: - if ((req->token == entry->token) && (req->sfxId == entry->sfxId)) { - remove = true; - } - break; - - case SFX_RM_REQ_BY_ID: - if (req->sfxId == entry->sfxId) { - remove = true; - } - break; - - default: - break; - } - - if (remove) { - req->sfxId = 0; - } - } -} - -void AudioSfx_ProcessRequest(void) { - u16 sfxId; - u8 channelCount; - u8 index; - SfxRequest* req = &sSfxRequests[sSfxRequestReadIndex]; - SfxBankEntry* entry; - SfxParams* sfxParams; - s32 bankId; - u8 evictImportance; - u8 evictIndex = 0x80; - - if (req->sfxId == 0) { - return; - } - - bankId = SFX_BANK(req->sfxId); - channelCount = 0; - index = gSfxBanks[bankId][0].next; - - // Compare the sfx request to all sfx bank entries - while ((index != 0xFF) && (index != 0)) { - - // If an existing sfx from the same source exists in the bank, then we should either: - // renew if it is the same sfx, check if any sfx channels are available for that bank, - // interrupt that sfx and replace it with the new sfx request, or drop the new sfx request. - if (gSfxBanks[bankId][index].posX == &req->pos->x) { - - // If the new sfx has equal importance to the existing sfx, - // drop the request if the existing sfx has the "SFX_FLAG_BLOCK_EQUAL_IMPORTANCE" flag. - // Otherwise, keep processing the new sfx request - if ((gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].params & - SFX_FLAG_BLOCK_EQUAL_IMPORTANCE) && - (gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].importance == - gSfxBanks[bankId][index].sfxImportance)) { - // Drop the new request - return; - } - - if (gSfxBanks[bankId][index].sfxId == req->sfxId) { - // The new sfx is the same as the existing sfx - // Set channelCount to max value to reprocess the sfx - channelCount = gUsedChannelsPerBank[gSfxChannelLayout][bankId]; - } else { - // Determine which sfx to evict based on importance if there are no more channels available - if (channelCount == 0) { - // If this is the first sfx at the same source, than store the existing sfx info into evict temps - 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) { - // If a different existing sfx is at the same source, than update the evict temps if the next - // existing src has lower importance than the previous existing source - evictIndex = index; - sfxId = gSfxBanks[bankId][index].sfxId & 0xFFFF; - evictImportance = gSfxParams[SFX_BANK_SHIFT(sfxId)][SFX_INDEX(sfxId)].importance; - } - - channelCount++; - - // There are no channels available, evict the lowest importance - if (channelCount == gUsedChannelsPerBank[gSfxChannelLayout][bankId]) { - if (gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)].importance >= evictImportance) { - index = evictIndex; - } else { - index = 0; - } - } - } - - // Process this sfx by refreshing or replacing and existing sfx - if (channelCount == gUsedChannelsPerBank[gSfxChannelLayout][bankId]) { - sfxParams = &gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)]; - - // Interrupt existing sfx and play the new sfx instead. - if ((req->sfxId & SFX_FLAG_MASK) || (sfxParams->flags & SFX_FLAG2_FORCE_RESET) || - (index == evictIndex)) { - - // Restore bgm if the sfx about to be replaced has the right flag - if ((gSfxBanks[bankId][index].sfxParams & SFX_FLAG_LOWER_VOLUME_BGM) && - (gSfxBanks[bankId][index].state != SFX_STATE_QUEUED)) { - AudioSfx_RestoreBgmVolume(gSfxBanks[bankId][index].channelIndex); - } - - 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].volume = req->volume; - gSfxBanks[bankId][index].reverbAdd = req->reverbAdd; - gSfxBanks[bankId][index].sfxParams = sfxParams->params; - gSfxBanks[bankId][index].sfxFlags = sfxParams->flags; - gSfxBanks[bankId][index].sfxImportance = sfxParams->importance; - } else if (gSfxBanks[bankId][index].state == SFX_STATE_PLAYING_ONE_FRAME) { - // The new sfx is "one-frame" and equals the existing sfx, - // continue playing the "one-frame" sfx by setting "SFX_STATE_PLAYING". - // This will avoid triggering deletion and get "SFX_STATE_REFRESH" - // The state will be set back to "SFX_STATE_PLAYING_ONE_FRAME" at the end of the cycle - gSfxBanks[bankId][index].state = SFX_STATE_PLAYING; - } - // Terminate loop, function is finished (nothing more is processed) - index = 0; - } - } - - if (index != 0) { - index = gSfxBanks[bankId][index].next; - } - } - - if ((gSfxBanks[bankId][sSfxBankFreeListStart[bankId]].next != 0xFF) && (index != 0)) { - // Allocate from free list - 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->volume = req->volume; - entry->reverbAdd = req->reverbAdd; - - sfxParams = &gSfxParams[SFX_BANK_SHIFT(req->sfxId)][SFX_INDEX(req->sfxId)]; - - entry->sfxParams = sfxParams->params; - entry->sfxFlags = sfxParams->flags; - 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 AudioSfx_RemoveBankEntry(u8 bankId, u8 entryIndex) { - SfxBankEntry* entry = &gSfxBanks[bankId][entryIndex]; - u8 i; - - if (entry->sfxParams & SFX_FLAG_LOWER_VOLUME_BGM) { - AudioSfx_RestoreBgmVolume(entry->channelIndex); - } - - 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 AudioSfx_ChooseActiveSfx(u8 bankId) { - u8 numChosenSfx = 0; - u8 numChannels; - u8 entryIndex; - u8 i; - u8 j; - u8 k; - u8 sfxImportance; - u8 needNewSfx; - u8 chosenEntryIndex; - s32 pad; - SfxBankEntry* entry; - ActiveSfx chosenSfx[MAX_CHANNELS_PER_BANK]; - ActiveSfx* activeSfx; - f32 entryPosY; - f32 entryPosX; - - for (i = 0; i < MAX_CHANNELS_PER_BANK; i++) { - chosenSfx[i].priority = 0x7FFFFFFF; - chosenSfx[i].entryIndex = 0xFF; - } - - entryIndex = gSfxBanks[bankId][0].next; - k = 0; - - // Delete stale sfx and prioritize remaining sfx into the gActiveSfx arrays - while (entryIndex != 0xFF) { - - // Update the freshness for an "all-frame" sfx if it is still queued - if ((gSfxBanks[bankId][entryIndex].state == SFX_STATE_QUEUED) && - (gSfxBanks[bankId][entryIndex].sfxId & SFX_FLAG_MASK)) { - gSfxBanks[bankId][entryIndex].freshness--; - - // If a "one-frame" sfx is still in "SFX_STATE_PLAYING_ONE_FRAME", then remove the sfx - } else if (!(gSfxBanks[bankId][entryIndex].sfxId & SFX_FLAG_MASK) && - (gSfxBanks[bankId][entryIndex].state == SFX_STATE_PLAYING_ONE_FRAME)) { - // ioPort 0, force stop sfx in seq 0 - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, gSfxBanks[bankId][entryIndex].channelIndex, 0, 0); - AudioSfx_RemoveBankEntry(bankId, entryIndex); - } - - // If a "all-frame" sfx goes 2 frames in the "queued" state - // (because it is too low priority), then remove the sfx - if (gSfxBanks[bankId][entryIndex].freshness == 0) { - AudioSfx_RemoveBankEntry(bankId, entryIndex); - } else if (gSfxBanks[bankId][entryIndex].state != SFX_STATE_EMPTY) { - // process the entry - entry = &gSfxBanks[bankId][entryIndex]; - - // Recompute distSq each frame since the sound's position may have changed - // (later converted into dist) - if (&gSfxDefaultPos.x == entry[0].posX) { - entry->dist = 0.0f; - } else { - entryPosY = *entry->posY * 1; - entryPosX = *entry->posX * 0.5f; - entry->dist = (SQ(entryPosX) + SQ(entryPosY) + SQ(*entry->posZ)) / 10.0f; - } - - // Recompute priority, possibly based on sfx position relative to the camera. - // (Note that the priority is the opposite of importance; lower is more preserved) - sfxImportance = entry->sfxImportance; - - if (entry->sfxParams & SFX_FLAG_PRIORITY_NO_DIST) { - // Priority is independent of distance - entry->priority = SQ(0xFF - sfxImportance) * SQ(76); - } else { - // Priority value increases with distance (more likely to eject) - if (entry->dist > 0x7FFFFFD0) { - // max distance - entry->dist = 0x70000008; - } - - entry->priority = (u32)entry->dist + (SQ(0xFF - sfxImportance) * SQ(76)); - if (*entry->posZ < 0.0f) { - entry->priority += (s32)(-*entry->posZ * 6.0f); - } - } - - // Sfx is too far away, do not consider for chosen sfx - if (entry->dist > SQ(1e5f)) { - - // If too far away and also playing, stop playing - if (entry->state == SFX_STATE_PLAYING) { - // ioPort 0, force stop sfx in seq 0 - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0); - if (entry->sfxId & SFX_FLAG_MASK) { - AudioSfx_RemoveBankEntry(bankId, entryIndex); - entryIndex = k; - } - } - } else { - // Loop through all channels allocated to a specific bank - // Choose which sfx from gSfxBanks to play - // This includes all sfx requests and sfx already playing - // Sort all current sfx entries in gSfxBanks by priority - // This is where the "active" sfx are chosen - numChannels = gChannelsPerBank[gSfxChannelLayout][bankId]; - - for (i = 0; i < numChannels; i++) { - // Sort all sfx entries by priority - if (chosenSfx[i].priority >= entry->priority) { - // Update the number of sfx to attampt to play - 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; // make this the last pass through the loop, here equivalent to "break" - } - } - } - - k = entryIndex; - } - - entryIndex = gSfxBanks[bankId][k].next; - } - - // If a sfx is chosen, update its state - for (i = 0; i < numChosenSfx; i++) { - entry = &gSfxBanks[bankId][chosenSfx[i].entryIndex]; - - if (entry->state == SFX_STATE_QUEUED) { - // sfx is a new entry - entry->state = SFX_STATE_READY; - } else if (entry->state == SFX_STATE_PLAYING) { - // sfx is already playing - entry->state = SFX_STATE_PLAYING_REFRESH; - } - } - - // Apply the chosenSfx to the activeSfx in each channel - numChannels = gChannelsPerBank[gSfxChannelLayout][bankId]; - for (i = 0; i < numChannels; i++) { - needNewSfx = false; - activeSfx = &gActiveSfx[bankId][i]; - - // Check if a sfx is already in the channel - if (activeSfx->entryIndex == 0xFF) { - // No sfx playing in the channel - // Available for use - needNewSfx = true; - } else { - // The channel is already playing a sfx - // Get the entry of the sfx playing - entry = &gSfxBanks[bankId][activeSfx[0].entryIndex]; - - // Check the state of the sfx playing - if (entry->state == SFX_STATE_PLAYING) { - if (entry->sfxId & SFX_FLAG_MASK) { - // For "all-frames" sfx, remove the entry - AudioSfx_RemoveBankEntry(bankId, activeSfx->entryIndex); - } else { - // For "one-frame" sfx, reset the state to queued - entry->state = SFX_STATE_QUEUED; - entry->freshness = 0x80; - } - needNewSfx = true; - } else if (entry->state == SFX_STATE_EMPTY) { - // The sfx already in the channel is empty - // Can replace the sfx - 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--; - } - } - - // enter the new sfx into the activeSfx - 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; i.e. force for-loop to end" - } - } - - if (needNewSfx == true) { - activeSfx->entryIndex = chosenEntryIndex; - chosenSfx[j].entryIndex = 0xFF; - j = numChannels + 1; - numChosenSfx--; - } - } - } - if (j == numChannels) { - // nothing found - activeSfx->entryIndex = 0xFF; - } - } - } -} - -void AudioSfx_PlayActiveSfx(u8 bankId) { - u8 entryIndex; - SequenceChannel* channel; - SfxBankEntry* entry; - u8 i; - u8 ioPort5Data; - - for (i = 0; i < gChannelsPerBank[gSfxChannelLayout][bankId]; i++) { - entryIndex = gActiveSfx[bankId][i].entryIndex; - // If entry is not empty - if (entryIndex != 0xFF) { - entry = &gSfxBanks[bankId][entryIndex]; - channel = gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[sCurSfxPlayerChannelIndex]; - - if (entry->state == SFX_STATE_READY) { - // Initialize a sfx (new sfx request) - entry->channelIndex = sCurSfxPlayerChannelIndex; - if (entry->sfxParams & SFX_FLAG_LOWER_VOLUME_BGM) { - AudioSfx_LowerBgmVolume(sCurSfxPlayerChannelIndex); - } - - // Add noise that will offset the frequency of the sfx - if ((entry->sfxParams & SFX_PARAM_RAND_FREQ_RAISE_MASK) != (0 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT)) { - switch (entry->sfxParams & SFX_PARAM_RAND_FREQ_RAISE_MASK) { - case (1 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT): - entry->randFreq = AudioThread_NextRandom() & 0xF; - break; - - case (2 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT): - entry->randFreq = AudioThread_NextRandom() & 0x1F; - break; - - case (3 << SFX_PARAM_RAND_FREQ_RAISE_SHIFT): - entry->randFreq = AudioThread_NextRandom() & 0x3F; - break; - - default: - entry->randFreq = 0; - break; - } - } - - // Calculate all the properties of sfx - AudioSfx_SetProperties(bankId, entryIndex, sCurSfxPlayerChannelIndex); - - // ioPort 0, enable the sfx to play in `NA_BGM_GENERAL_SFX` - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sCurSfxPlayerChannelIndex, 0, 1); - - // ioPort 4, write the lower bits sfx index for `NA_BGM_GENERAL_SFX` to find the right code to execute - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sCurSfxPlayerChannelIndex, 4, entry->sfxId & 0xFF); - - // If the sfx bank has more than 255 entries (greater than a u8 can store), - // then store the Id in upper and lower bits - if (gIsLargeSfxBank[bankId]) { - // Store upper bits - ioPort5Data = ((u8)((entry->sfxId & 0x300) >> 7) + (u8)((entry->sfxId & 0xFF) >> 7)); - } else { - ioPort5Data = 0; - } - - if ((entry->sfxParams & SFX_FLAG_8) && (entry->freshness == 0x80)) { - ioPort5Data += 0x80; - } - - if (D_801D6608[bankId]) { - // ioPort 5, write the upper bits sfx index and a flag for `NA_BGM_GENERAL_SFX`, - // for banks with > 0xFF entries - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sCurSfxPlayerChannelIndex, 5, ioPort5Data); - } - - // Update playing state - if (entry->sfxId & SFX_FLAG_MASK) { - // "all-frames" sfx - entry->state = SFX_STATE_PLAYING; - } else { - // "one-frame" sfx - entry->state = SFX_STATE_PLAYING_ONE_FRAME; - } - } else if ((u8)channel->seqScriptIO[1] == (u8)SEQ_IO_VAL_NONE) { - // Signal from seq 0 that the sfx is finished playing. Remove entry - AudioSfx_RemoveBankEntry(bankId, entryIndex); - } else if (entry->state == SFX_STATE_PLAYING_REFRESH) { - // Sfx is playing but a refresh is requested - AudioSfx_SetProperties(bankId, entryIndex, sCurSfxPlayerChannelIndex); - - // Update playing state - if (entry->sfxId & SFX_FLAG_MASK) { - // "all-frames" sfx - entry->state = SFX_STATE_PLAYING; - } else { - // "one-frame" sfx - entry->state = SFX_STATE_PLAYING_ONE_FRAME; - } - } - } - - sCurSfxPlayerChannelIndex++; - } -} - -void AudioSfx_StopByBank(u8 bankId) { - SfxBankEntry* entry; - s32 pad; - SfxBankEntry entryToRemove; - u8 entryIndex = gSfxBanks[bankId][0].next; - - while (entryIndex != 0xFF) { - entry = &gSfxBanks[bankId][entryIndex]; - if (entry->state >= SFX_STATE_PLAYING_REFRESH) { - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0); - } - - if (entry->state != SFX_STATE_EMPTY) { - AudioSfx_RemoveBankEntry(bankId, entryIndex); - } - entryIndex = gSfxBanks[bankId][0].next; - } - - entryToRemove.sfxId = bankId << 12; - AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_BANK, &entryToRemove); -} - -void AudioSfx_StopByPosAndBankImpl(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) { - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0); - } - - if (entry->state != SFX_STATE_EMPTY) { - AudioSfx_RemoveBankEntry(bankId, entryIndex); - } - } else { - prevEntryIndex = entryIndex; - } - - entryIndex = gSfxBanks[bankId][prevEntryIndex].next; - } -} - -void AudioSfx_StopByPosAndBank(u8 bankId, Vec3f* pos) { - SfxBankEntry entryToRemove; - - AudioSfx_StopByPosAndBankImpl(bankId, pos); - entryToRemove.sfxId = bankId << 12; - entryToRemove.posX = &pos->x; - AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_POS_AND_BANK, &entryToRemove); -} - -void AudioSfx_StopByPos(Vec3f* pos) { - u8 bankId; - SfxBankEntry entryToRemove; - - for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) { - AudioSfx_StopByPosAndBankImpl(bankId, pos); - } - - entryToRemove.posX = &pos->x; - AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_POS, &entryToRemove); -} - -void AudioSfx_StopByPosAndId(Vec3f* pos, u16 sfxId) { - SfxBankEntry* entry; - u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next; - u8 prevEntryIndex = 0; - SfxBankEntry entryToRemove; - - while (entryIndex != 0xFF) { - entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex]; - if ((entry->posX == &pos->x) && (entry->sfxId == sfxId)) { - if (entry->state >= SFX_STATE_PLAYING_REFRESH) { - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0); - } - - if (entry->state != SFX_STATE_EMPTY) { - AudioSfx_RemoveBankEntry(SFX_BANK(sfxId), entryIndex); - } - entryIndex = 0xFF; - } else { - prevEntryIndex = entryIndex; - } - - if (entryIndex != 0xFF) { - entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next; - } - } - - entryToRemove.posX = &pos->x; - entryToRemove.sfxId = sfxId; - AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_POS_AND_ID, &entryToRemove); -} - -void AudioSfx_StopByTokenAndId(u8 token, u16 sfxId) { - SfxBankEntry* entry; - u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next; - u8 prevEntryIndex = 0; - SfxBankEntry entryToRemove; - - while (entryIndex != 0xFF) { - entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex]; - if ((entry->token == token) && (entry->sfxId == sfxId)) { - if (entry->state >= SFX_STATE_PLAYING_REFRESH) { - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0); - } - - if (entry->state != SFX_STATE_EMPTY) { - AudioSfx_RemoveBankEntry(SFX_BANK(sfxId), entryIndex); - } - } else { - prevEntryIndex = entryIndex; - } - - if (entryIndex != 0xFF) { - entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next; - } - } - - entryToRemove.token = token; - entryToRemove.sfxId = sfxId; - AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_TOKEN_AND_ID, &entryToRemove); -} - -void AudioSfx_StopById(u32 sfxId) { - SfxBankEntry* entry; - u8 entryIndex = gSfxBanks[SFX_BANK(sfxId)][0].next; - u8 prevEntryIndex = 0; - SfxBankEntry entryToRemove; - - while (entryIndex != 0xFF) { - entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex]; - if (entry->sfxId == sfxId) { - if (entry->state >= SFX_STATE_PLAYING_REFRESH) { - AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0); - } - if (entry->state != SFX_STATE_EMPTY) { - AudioSfx_RemoveBankEntry(SFX_BANK(sfxId), entryIndex); - } - } else { - prevEntryIndex = entryIndex; - } - - entryIndex = gSfxBanks[SFX_BANK(sfxId)][prevEntryIndex].next; - } - - entryToRemove.sfxId = sfxId; - AudioSfx_RemoveMatchingRequests(SFX_RM_REQ_BY_ID, &entryToRemove); -} - -void AudioSfx_ProcessRequests(void) { - if (gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].enabled) { - while (sSfxRequestWriteIndex != sSfxRequestReadIndex) { - AudioSfx_ProcessRequest(); - sSfxRequestReadIndex++; - } - } -} - -/** - * Unused - */ -void AudioSfx_SetBankLerp(u8 bankId, u8 target, u16 delay) { - if (delay == 0) { - delay++; - } - - sSfxBankLerp[bankId].target = target / 127.0f; - sSfxBankLerp[bankId].remainingFrames = delay; - sSfxBankLerp[bankId].step = ((sSfxBankLerp[bankId].value - sSfxBankLerp[bankId].target) / delay); -} - -/** - * Unused - */ -void AudioSfx_StepBankLerp(u8 bankId) { - if (sSfxBankLerp[bankId].remainingFrames != 0) { - sSfxBankLerp[bankId].remainingFrames--; - - if (sSfxBankLerp[bankId].remainingFrames != 0) { - sSfxBankLerp[bankId].value -= sSfxBankLerp[bankId].step; - } else { - sSfxBankLerp[bankId].value = sSfxBankLerp[bankId].target; - } - } -} - -void AudioSfx_ProcessActiveSfx(void) { - u8 bankId; - - if (gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].enabled) { - sCurSfxPlayerChannelIndex = 0; - - for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) { - AudioSfx_ChooseActiveSfx(bankId); - AudioSfx_PlayActiveSfx(bankId); - AudioSfx_StepBankLerp(bankId); - } - } -} - -u8 AudioSfx_IsPlaying(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 AudioSfx_Reset(void) { - u8 bankId; - u8 i; - u8 entryIndex; - - sSfxRequestWriteIndex = 0; - sSfxRequestReadIndex = 0; - sSfxChannelLowVolumeFlag = 0; - - for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) { - sSfxBankListEnd[bankId] = 0; - sSfxBankFreeListStart[bankId] = 1; - sSfxBankUnused[bankId] = 0; - gSfxBankMuted[bankId] = false; - sSfxBankLerp[bankId].value = 1.0f; - sSfxBankLerp[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 < sSfxBankSizes[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; - } -} diff --git a/src/code/audio/code_801A7B10.c b/src/code/audio/code_801A7B10.c deleted file mode 100644 index 3f8446036..000000000 --- a/src/code/audio/code_801A7B10.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/Audio_StartSequence.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/Audio_StopSequence.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A7D84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/Audio_QueueSeqCmd.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A89D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/Audio_GetActiveSequence.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A8ABC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A8B14.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A8B2C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/Audio_SetVolumeScale.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A8D5C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A9768.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A982C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A99B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A9A74.s") diff --git a/src/code/code_80172BC0.c b/src/code/audio_stop_all_sfx.c index 94b55d4df..94b55d4df 100644 --- a/src/code/code_80172BC0.c +++ b/src/code/audio_stop_all_sfx.c diff --git a/src/code/audioMgr.c b/src/code/audio_thread_manager.c index eca7ddd83..eca7ddd83 100644 --- a/src/code/audioMgr.c +++ b/src/code/audio_thread_manager.c |
