aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-27 11:57:08 +0200
committerBad Diode <bd@badd10de.dev>2021-05-27 11:57:08 +0200
commitf32eda6df8e1df42e06eae55d28d9a45a92e7ecd (patch)
tree98a04c2e031038bcfe1d210049ca64af720959e2 /src
parent8fc709cc1d69c911ac36d18ea3fd6e3da3efc3f4 (diff)
downloaduxngba-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.c19
-rw-r--r--src/uxn/devices/apu.c67
2 files changed, 30 insertions, 56 deletions
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) {
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
2static 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, 4static 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,
20static 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
112IWRAM_CODE
138void sound_mix() { 113void 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];