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