From f32eda6df8e1df42e06eae55d28d9a45a92e7ecd Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Thu, 27 May 2021 11:57:08 +0200 Subject: Update pitch_table LUT to avoid divisions This also unifies both the 44100 and variable pitch tables, reducing the amount of space needed. --- src/main.c | 19 +++++++-------- src/uxn/devices/apu.c | 67 ++++++++++++++++----------------------------------- 2 files changed, 30 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 222ffd4..cbf781d 100644 --- a/src/main.c +++ b/src/main.c @@ -134,10 +134,9 @@ audio_talk(Device *d, u8 b0, u8 w) { c->length <<= 12; // fixed point. c->data = &d->mem[mempeek16(d->dat, 0xc)]; - // TODO: Volume. - c->vol = 12; // 0-64 - // c->volume[0] = d->dat[0xe] >> 4; - // c->volume[1] = d->dat[0xe] & 0xf; + // Volume (Mono only for now). + c->vol = MAX(d->dat[0xe] >> 4, d->dat[0xe] & 0xf); // 0-64 + c->vol *= 4 / 3; // Looping. if (!(d->dat[0xf] & 0x80)) { @@ -150,16 +149,16 @@ audio_talk(Device *d, u8 b0, u8 w) { c->pitch = d->dat[0xf] & 0x7f; // Initialization. + u32 sampling_rate = length; if (length > 256) { - c->inc = pitch_table_44100[c->pitch]; - } else { - c->inc = pitch_table_variable[c->pitch] * length / AUDIO_FREQ; + sampling_rate = 44100; } + c->inc = (pitch_table[c->pitch] * sampling_rate) >> 5; txt_position(0, 0); - txt_printf("note: %d \n", c->pitch); - txt_printf("inc: %ld \n", c->inc); - txt_printf("length: %ld \n", c->length >> 12); + txt_printf("note: %d \n", c->pitch); + txt_printf("inc: %ld \n", c->inc); + txt_printf("length: %ld \n", c->length >> 12); } } diff --git a/src/uxn/devices/apu.c b/src/uxn/devices/apu.c index 15eed20..4447e12 100644 --- a/src/uxn/devices/apu.c +++ b/src/uxn/devices/apu.c @@ -1,38 +1,22 @@ -// Calculated as (44100 << 12) / 18157 for C4 -static u32 pitch_table_44100[] = { - 310, 329, 348, 369, 391, 414, 439, 465, - 493, 522, 553, 586, 621, 658, 697, 739, - 783, 829, 879, 931, 987, 1045, 1107, 1173, - 1243, 1317, 1395, 1478, 1566, 1659, 1758, 1863, - 1974, 2091, 2215, 2347, 2487, 2634, 2791, 2957, - 3133, 3319, 3517, 3726, 3948, 4182, 4431, 4695, - 4974, 5269, 5583, 5915, 6267, 6639, 7034, 7452, - 7896, 8365, 8863, 9390, 9948, 10539, 11166, 11830, - 12534, 13279, 14069, 14905, 15792, 16731, 17726, 18780, - 19896, 21079, 22333, 23661, 25068, 26559, 28138, 29811, - 31584, 33462, 35452, 37560, 39793, 42159, 44666, 47322, - 50136, 53118, 56276, 59623, 63168, 66924, 70904, 75120, - 79587, 84319, 89333, 94645, 100273, 106236, 112553, 119246, - 126337, 133849, 141808, 150241, 159174, 168639, 178667, 189291, - 200547, 212472, 225107, 238492, 252674, 267699, 283617, 300482, -}; - -static u32 pitch_table_variable[] = { - 33484, 35475, 37585, 39820, 42188, 44696, 47354, 50170, - 53153, 56314, 59663, 63210, 66969, 70951, 75170, 79640, - 84376, 89393, 94709, 100341, 106307, 112628, 119326, 126421, - 133939, 141903, 150341, 159281, 168752, 178787, 189418, 200682, - 212615, 225257, 238652, 252843, 267878, 283807, 300683, 318562, - 337505, 357574, 378837, 401364, 425230, 450515, 477305, 505687, - 535756, 567614, 601366, 637125, 675011, 715149, 757674, 802728, - 850460, 901031, 954610, 1011374, 1071513, 1135229, 1202733, 1274251, - 1350022, 1430299, 1515349, 1605456, 1700921, 1802063, 1909220, 2022748, - 2143027, 2270458, 2405466, 2548503, 2700045, 2860598, 3030698, 3210912, - 3401843, 3604127, 3818440, 4045496, 4286054, 4540916, 4810933, 5097006, - 5400090, 5721196, 6061396, 6421825, 6803687, 7208255, 7636880, 8090993, - 8572108, 9081832, 9621866, 10194012, 10800180, 11442392, 12122792, 12843651, - 13607374, 14416511, 15273761, 16181986, 17144217, 18163665, 19243733, 20388025, - 21600360, 22884784, 24245585, 25687302, 27214749, 28833022, 30547522, 32363973, +// Calculated as ((261.6 / 18157) << 17) for C4. If multiplied by sampling rate +// we will have a u32 (15.17) fixed-point number. This should be enough to +// accurately portray samples up to 75300 Hz. +static u32 pitch_table[120] = { + 59, 62, 66, 70, 74, 78, 83, 88, + 93, 99, 105, 111, 118, 125, 132, 140, + 148, 157, 166, 176, 187, 198, 210, 222, + 236, 250, 264, 280, 297, 315, 333, 353, + 374, 396, 420, 445, 472, 500, 529, 561, + 594, 630, 667, 707, 749, 793, 841, 891, + 944, 1000, 1059, 1122, 1189, 1260, 1335, 1414, + 1498, 1587, 1682, 1782, 1888, 2000, 2119, 2245, + 2379, 2520, 2670, 2829, 2997, 3175, 3364, 3564, + 3776, 4001, 4239, 4491, 4758, 5041, 5341, 5658, + 5995, 6351, 6729, 7129, 7553, 8002, 8478, 8982, + 9517, 10083, 10682, 11317, 11990, 12703, 13459, 14259, + 15107, 16005, 16957, 17965, 19034, 20166, 21365, 22635, + 23981, 25407, 26918, 28519, 30215, 32011, 33915, 35931, + 38068, 40332, 42730, 45271, 47963, 50815, 53837, 57038, }; // @@ -75,7 +59,7 @@ typedef struct AudioChannel { u32 length; // Length of looped portion (20.12 fixed-point, 0 to disable looping). u32 loop_length; - // TODO: this should be different? + // Pitch encoded as a MIDI note. u8 pitch; } AudioChannel; @@ -92,15 +76,6 @@ init_sound(void) { channels[i] = (AudioChannel){0}; } - // DEBUG: testing channel 0 with square wave - // channels[0].data = samples; - // channels[0].length = (LEN(samples) - 1) << 12; - // channels[0].pos = 0; - // channels[0].inc = (44100 << 12) / AUDIO_FREQ; - // channels[0].vol = 32; - // channels[0].loop_length = channels[0].length; - // channels[0].loop_length = 0; - // Enable the sound chip. SOUND_STATUS = SOUND_ENABLE; @@ -111,7 +86,6 @@ init_sound(void) { | SOUND_DSOUND_RIGHT_A | SOUND_DSOUND_RESET_A; - // TODO: No pitch selection yet. TIMER_DATA_0 = AUDIO_TIMER; TIMER_CTRL_0 = TIMER_CTRL_ENABLE; } @@ -135,6 +109,7 @@ void sound_vsync() { } } +IWRAM_CODE void sound_mix() { // Initialize and clear mix_buffer. s16 mix_buffer[AUDIO_BUF_LEN]; -- cgit v1.2.1