Commit | Line | Data |
---|---|---|
5fd68266 | 1 | /* Copyright 2016 Jack Humbert |
2 | * | |
3 | * This program is free software: you can redistribute it and/or modify | |
4 | * it under the terms of the GNU General Public License as published by | |
5 | * the Free Software Foundation, either version 2 of the License, or | |
6 | * (at your option) any later version. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU General Public License | |
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
15 | */ | |
16 | ||
17 | #include "audio.h" | |
18 | #include "ch.h" | |
19 | #include "hal.h" | |
20 | ||
5fd68266 | 21 | #include <string.h> |
22 | #include "print.h" | |
23 | #include "keymap.h" | |
24 | ||
25 | #include "eeconfig.h" | |
26 | ||
27 | // ----------------------------------------------------------------------------- | |
28 | ||
b624f32f | 29 | int voices = 0; |
30 | int voice_place = 0; | |
31 | float frequency = 0; | |
5fd68266 | 32 | float frequency_alt = 0; |
b624f32f | 33 | int volume = 0; |
34 | long position = 0; | |
5fd68266 | 35 | |
36 | float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | |
b624f32f | 37 | int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; |
38 | bool sliding = false; | |
5fd68266 | 39 | |
40 | float place = 0; | |
41 | ||
b624f32f | 42 | uint8_t *sample; |
5fd68266 | 43 | uint16_t sample_length = 0; |
44 | ||
b624f32f | 45 | bool playing_notes = false; |
46 | bool playing_note = false; | |
5fd68266 | 47 | float note_frequency = 0; |
b624f32f | 48 | float note_length = 0; |
49 | uint8_t note_tempo = TEMPO_DEFAULT; | |
50 | float note_timbre = TIMBRE_DEFAULT; | |
51 | uint16_t note_position = 0; | |
52 | float (*notes_pointer)[][2]; | |
5fd68266 | 53 | uint16_t notes_count; |
54 | bool notes_repeat; | |
55 | bool note_resting = false; | |
56 | ||
73d85933 | 57 | uint16_t current_note = 0; |
b624f32f | 58 | uint8_t rest_counter = 0; |
5fd68266 | 59 | |
60 | #ifdef VIBRATO_ENABLE | |
b624f32f | 61 | float vibrato_counter = 0; |
5fd68266 | 62 | float vibrato_strength = .5; |
b624f32f | 63 | float vibrato_rate = 0.125; |
5fd68266 | 64 | #endif |
65 | ||
66 | float polyphony_rate = 0; | |
67 | ||
68 | static bool audio_initialized = false; | |
69 | ||
70 | audio_config_t audio_config; | |
71 | ||
72 | uint16_t envelope_index = 0; | |
b624f32f | 73 | bool glissando = true; |
5fd68266 | 74 | |
75 | #ifndef STARTUP_SONG | |
b624f32f | 76 | # define STARTUP_SONG SONG(STARTUP_SOUND) |
5fd68266 | 77 | #endif |
78 | float startup_song[][2] = STARTUP_SONG; | |
79 | ||
5fd68266 | 80 | static void gpt_cb8(GPTDriver *gptp); |
81 | ||
fa4052c2 | 82 | #define DAC_BUFFER_SIZE 100 |
3a0f3a5b | 83 | #ifndef DAC_SAMPLE_MAX |
b624f32f | 84 | # define DAC_SAMPLE_MAX 65535U |
3a0f3a5b | 85 | #endif |
63c16f4b | 86 | |
b624f32f | 87 | #define START_CHANNEL_1() \ |
88 | gptStart(&GPTD6, &gpt6cfg1); \ | |
63c16f4b | 89 | gptStartContinuous(&GPTD6, 2U) |
b624f32f | 90 | #define START_CHANNEL_2() \ |
91 | gptStart(&GPTD7, &gpt7cfg1); \ | |
63c16f4b JH |
92 | gptStartContinuous(&GPTD7, 2U) |
93 | #define STOP_CHANNEL_1() gptStopTimer(&GPTD6) | |
94 | #define STOP_CHANNEL_2() gptStopTimer(&GPTD7) | |
b624f32f | 95 | #define RESTART_CHANNEL_1() \ |
96 | STOP_CHANNEL_1(); \ | |
63c16f4b | 97 | START_CHANNEL_1() |
b624f32f | 98 | #define RESTART_CHANNEL_2() \ |
99 | STOP_CHANNEL_2(); \ | |
63c16f4b | 100 | START_CHANNEL_2() |
b624f32f | 101 | #define UPDATE_CHANNEL_1_FREQ(freq) \ |
102 | gpt6cfg1.frequency = freq * DAC_BUFFER_SIZE; \ | |
63c16f4b | 103 | RESTART_CHANNEL_1() |
b624f32f | 104 | #define UPDATE_CHANNEL_2_FREQ(freq) \ |
105 | gpt7cfg1.frequency = freq * DAC_BUFFER_SIZE; \ | |
63c16f4b | 106 | RESTART_CHANNEL_2() |
fa4052c2 JH |
107 | #define GET_CHANNEL_1_FREQ (uint16_t)(gpt6cfg1.frequency * DAC_BUFFER_SIZE) |
108 | #define GET_CHANNEL_2_FREQ (uint16_t)(gpt7cfg1.frequency * DAC_BUFFER_SIZE) | |
63c16f4b | 109 | |
5fd68266 | 110 | /* |
111 | * GPT6 configuration. | |
112 | */ | |
63c16f4b JH |
113 | // static const GPTConfig gpt6cfg1 = { |
114 | // .frequency = 1000000U, | |
115 | // .callback = NULL, | |
116 | // .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ | |
117 | // .dier = 0U | |
118 | // }; | |
119 | ||
b624f32f | 120 | GPTConfig gpt6cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, |
121 | .callback = NULL, | |
122 | .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ | |
123 | .dier = 0U}; | |
5fd68266 | 124 | |
b624f32f | 125 | GPTConfig gpt7cfg1 = {.frequency = 440U * DAC_BUFFER_SIZE, |
126 | .callback = NULL, | |
127 | .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ | |
128 | .dier = 0U}; | |
5fd68266 | 129 | |
b624f32f | 130 | GPTConfig gpt8cfg1 = {.frequency = 10, |
131 | .callback = gpt_cb8, | |
132 | .cr2 = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event. */ | |
133 | .dier = 0U}; | |
63c16f4b JH |
134 | |
135 | /* | |
136 | * DAC test buffer (sine wave). | |
137 | */ | |
138 | // static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = { | |
139 | // 2047, 2082, 2118, 2154, 2189, 2225, 2260, 2296, 2331, 2367, 2402, 2437, | |
140 | // 2472, 2507, 2542, 2576, 2611, 2645, 2679, 2713, 2747, 2780, 2813, 2846, | |
141 | // 2879, 2912, 2944, 2976, 3008, 3039, 3070, 3101, 3131, 3161, 3191, 3221, | |
142 | // 3250, 3278, 3307, 3335, 3362, 3389, 3416, 3443, 3468, 3494, 3519, 3544, | |
143 | // 3568, 3591, 3615, 3637, 3660, 3681, 3703, 3723, 3744, 3763, 3782, 3801, | |
144 | // 3819, 3837, 3854, 3870, 3886, 3902, 3917, 3931, 3944, 3958, 3970, 3982, | |
145 | // 3993, 4004, 4014, 4024, 4033, 4041, 4049, 4056, 4062, 4068, 4074, 4078, | |
146 | // 4082, 4086, 4089, 4091, 4092, 4093, 4094, 4093, 4092, 4091, 4089, 4086, | |
147 | // 4082, 4078, 4074, 4068, 4062, 4056, 4049, 4041, 4033, 4024, 4014, 4004, | |
148 | // 3993, 3982, 3970, 3958, 3944, 3931, 3917, 3902, 3886, 3870, 3854, 3837, | |
149 | // 3819, 3801, 3782, 3763, 3744, 3723, 3703, 3681, 3660, 3637, 3615, 3591, | |
150 | // 3568, 3544, 3519, 3494, 3468, 3443, 3416, 3389, 3362, 3335, 3307, 3278, | |
151 | // 3250, 3221, 3191, 3161, 3131, 3101, 3070, 3039, 3008, 2976, 2944, 2912, | |
152 | // 2879, 2846, 2813, 2780, 2747, 2713, 2679, 2645, 2611, 2576, 2542, 2507, | |
153 | // 2472, 2437, 2402, 2367, 2331, 2296, 2260, 2225, 2189, 2154, 2118, 2082, | |
154 | // 2047, 2012, 1976, 1940, 1905, 1869, 1834, 1798, 1763, 1727, 1692, 1657, | |
155 | // 1622, 1587, 1552, 1518, 1483, 1449, 1415, 1381, 1347, 1314, 1281, 1248, | |
156 | // 1215, 1182, 1150, 1118, 1086, 1055, 1024, 993, 963, 933, 903, 873, | |
157 | // 844, 816, 787, 759, 732, 705, 678, 651, 626, 600, 575, 550, | |
158 | // 526, 503, 479, 457, 434, 413, 391, 371, 350, 331, 312, 293, | |
159 | // 275, 257, 240, 224, 208, 192, 177, 163, 150, 136, 124, 112, | |
160 | // 101, 90, 80, 70, 61, 53, 45, 38, 32, 26, 20, 16, | |
161 | // 12, 8, 5, 3, 2, 1, 0, 1, 2, 3, 5, 8, | |
162 | // 12, 16, 20, 26, 32, 38, 45, 53, 61, 70, 80, 90, | |
163 | // 101, 112, 124, 136, 150, 163, 177, 192, 208, 224, 240, 257, | |
164 | // 275, 293, 312, 331, 350, 371, 391, 413, 434, 457, 479, 503, | |
165 | // 526, 550, 575, 600, 626, 651, 678, 705, 732, 759, 787, 816, | |
166 | // 844, 873, 903, 933, 963, 993, 1024, 1055, 1086, 1118, 1150, 1182, | |
167 | // 1215, 1248, 1281, 1314, 1347, 1381, 1415, 1449, 1483, 1518, 1552, 1587, | |
168 | // 1622, 1657, 1692, 1727, 1763, 1798, 1834, 1869, 1905, 1940, 1976, 2012 | |
169 | // }; | |
170 | ||
ade22f8e JH |
171 | // static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = { |
172 | // 12, 8, 5, 3, 2, 1, 0, 1, 2, 3, 5, 8, | |
173 | // 12, 16, 20, 26, 32, 38, 45, 53, 61, 70, 80, 90, | |
174 | // 101, 112, 124, 136, 150, 163, 177, 192, 208, 224, 240, 257, | |
175 | // 275, 293, 312, 331, 350, 371, 391, 413, 434, 457, 479, 503, | |
176 | // 526, 550, 575, 600, 626, 651, 678, 705, 732, 759, 787, 816, | |
177 | // 844, 873, 903, 933, 963, 993, 1024, 1055, 1086, 1118, 1150, 1182, | |
178 | // 1215, 1248, 1281, 1314, 1347, 1381, 1415, 1449, 1483, 1518, 1552, 1587, | |
179 | // 1622, 1657, 1692, 1727, 1763, 1798, 1834, 1869, 1905, 1940, 1976, 2012, | |
180 | // 2047, 2082, 2118, 2154, 2189, 2225, 2260, 2296, 2331, 2367, 2402, 2437, | |
181 | // 2472, 2507, 2542, 2576, 2611, 2645, 2679, 2713, 2747, 2780, 2813, 2846, | |
182 | // 2879, 2912, 2944, 2976, 3008, 3039, 3070, 3101, 3131, 3161, 3191, 3221, | |
183 | // 3250, 3278, 3307, 3335, 3362, 3389, 3416, 3443, 3468, 3494, 3519, 3544, | |
184 | // 3568, 3591, 3615, 3637, 3660, 3681, 3703, 3723, 3744, 3763, 3782, 3801, | |
185 | // 3819, 3837, 3854, 3870, 3886, 3902, 3917, 3931, 3944, 3958, 3970, 3982, | |
186 | // 3993, 4004, 4014, 4024, 4033, 4041, 4049, 4056, 4062, 4068, 4074, 4078, | |
187 | // 4082, 4086, 4089, 4091, 4092, 4093, 4094, 4093, 4092, 4091, 4089, 4086, | |
188 | // 4082, 4078, 4074, 4068, 4062, 4056, 4049, 4041, 4033, 4024, 4014, 4004, | |
189 | // 3993, 3982, 3970, 3958, 3944, 3931, 3917, 3902, 3886, 3870, 3854, 3837, | |
190 | // 3819, 3801, 3782, 3763, 3744, 3723, 3703, 3681, 3660, 3637, 3615, 3591, | |
191 | // 3568, 3544, 3519, 3494, 3468, 3443, 3416, 3389, 3362, 3335, 3307, 3278, | |
192 | // 3250, 3221, 3191, 3161, 3131, 3101, 3070, 3039, 3008, 2976, 2944, 2912, | |
193 | // 2879, 2846, 2813, 2780, 2747, 2713, 2679, 2645, 2611, 2576, 2542, 2507, | |
194 | // 2472, 2437, 2402, 2367, 2331, 2296, 2260, 2225, 2189, 2154, 2118, 2082, | |
195 | // 2047, 2012, 1976, 1940, 1905, 1869, 1834, 1798, 1763, 1727, 1692, 1657, | |
196 | // 1622, 1587, 1552, 1518, 1483, 1449, 1415, 1381, 1347, 1314, 1281, 1248, | |
197 | // 1215, 1182, 1150, 1118, 1086, 1055, 1024, 993, 963, 933, 903, 873, | |
198 | // 844, 816, 787, 759, 732, 705, 678, 651, 626, 600, 575, 550, | |
199 | // 526, 503, 479, 457, 434, 413, 391, 371, 350, 331, 312, 293, | |
200 | // 275, 257, 240, 224, 208, 192, 177, 163, 150, 136, 124, 112, | |
201 | // 101, 90, 80, 70, 61, 53, 45, 38, 32, 26, 20, 16 | |
202 | // }; | |
203 | ||
63c16f4b JH |
204 | // squarewave |
205 | static const dacsample_t dac_buffer[DAC_BUFFER_SIZE] = { | |
b624f32f | 206 | // First half is max, second half is 0 |
207 | [0 ... DAC_BUFFER_SIZE / 2 - 1] = DAC_SAMPLE_MAX, | |
208 | [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = 0, | |
63c16f4b JH |
209 | }; |
210 | ||
211 | // squarewave | |
212 | static const dacsample_t dac_buffer_2[DAC_BUFFER_SIZE] = { | |
b624f32f | 213 | // opposite of dac_buffer above |
214 | [0 ... DAC_BUFFER_SIZE / 2 - 1] = 0, | |
215 | [DAC_BUFFER_SIZE / 2 ... DAC_BUFFER_SIZE - 1] = DAC_SAMPLE_MAX, | |
63c16f4b JH |
216 | }; |
217 | ||
218 | /* | |
219 | * DAC streaming callback. | |
220 | */ | |
26eef35f JY |
221 | size_t nz = 0; |
222 | static void end_cb1(DACDriver *dacp) { | |
b624f32f | 223 | (void)dacp; |
63c16f4b | 224 | |
b624f32f | 225 | nz++; |
b624f32f | 226 | if ((nz % 1000) == 0) { |
227 | // palTogglePad(GPIOD, GPIOD_LED3); | |
228 | } | |
5fd68266 | 229 | } |
230 | ||
63c16f4b JH |
231 | /* |
232 | * DAC error callback. | |
233 | */ | |
234 | static void error_cb1(DACDriver *dacp, dacerror_t err) { | |
b624f32f | 235 | (void)dacp; |
236 | (void)err; | |
63c16f4b | 237 | |
b624f32f | 238 | chSysHalt("DAC failure"); |
5fd68266 | 239 | } |
240 | ||
b624f32f | 241 | static const DACConfig dac1cfg1 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; |
63c16f4b | 242 | |
b624f32f | 243 | static const DACConversionGroup dacgrpcfg1 = {.num_channels = 1U, .end_cb = end_cb1, .error_cb = error_cb1, .trigger = DAC_TRG(0)}; |
63c16f4b | 244 | |
b624f32f | 245 | static const DACConfig dac1cfg2 = {.init = DAC_SAMPLE_MAX, .datamode = DAC_DHRM_12BIT_RIGHT}; |
63c16f4b | 246 | |
b624f32f | 247 | static const DACConversionGroup dacgrpcfg2 = {.num_channels = 1U, .end_cb = end_cb1, .error_cb = error_cb1, .trigger = DAC_TRG(0)}; |
63c16f4b | 248 | |
85022f8b | 249 | void audio_init() { |
b624f32f | 250 | if (audio_initialized) { |
251 | return; | |
252 | } | |
85022f8b | 253 | |
b624f32f | 254 | // Check EEPROM |
d13ada11 | 255 | #ifdef EEPROM_ENABLE |
85022f8b | 256 | if (!eeconfig_is_enabled()) { |
b624f32f | 257 | eeconfig_init(); |
85022f8b DJ |
258 | } |
259 | audio_config.raw = eeconfig_read_audio(); | |
b624f32f | 260 | #else // ARM EEPROM |
261 | audio_config.enable = true; | |
262 | # ifdef AUDIO_CLICKY_ON | |
85022f8b | 263 | audio_config.clicky_enable = true; |
b624f32f | 264 | # endif |
265 | #endif // ARM EEPROM | |
266 | ||
267 | /* | |
268 | * Starting DAC1 driver, setting up the output pin as analog as suggested | |
269 | * by the Reference Manual. | |
270 | */ | |
271 | palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); | |
272 | palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); | |
273 | dacStart(&DACD1, &dac1cfg1); | |
274 | dacStart(&DACD2, &dac1cfg2); | |
275 | ||
276 | /* | |
277 | * Starting GPT6/7 driver, it is used for triggering the DAC. | |
278 | */ | |
279 | START_CHANNEL_1(); | |
280 | START_CHANNEL_2(); | |
281 | ||
282 | /* | |
283 | * Starting a continuous conversion. | |
284 | */ | |
285 | dacStartConversion(&DACD1, &dacgrpcfg1, (dacsample_t *)dac_buffer, DAC_BUFFER_SIZE); | |
286 | dacStartConversion(&DACD2, &dacgrpcfg2, (dacsample_t *)dac_buffer_2, DAC_BUFFER_SIZE); | |
287 | ||
288 | audio_initialized = true; | |
289 | ||
290 | if (audio_config.enable) { | |
291 | PLAY_SONG(startup_song); | |
292 | } else { | |
293 | stop_all_notes(); | |
294 | } | |
5fd68266 | 295 | } |
296 | ||
85022f8b | 297 | void stop_all_notes() { |
5fd68266 | 298 | dprintf("audio stop all notes"); |
299 | ||
300 | if (!audio_initialized) { | |
301 | audio_init(); | |
302 | } | |
303 | voices = 0; | |
304 | ||
305 | gptStopTimer(&GPTD6); | |
306 | gptStopTimer(&GPTD7); | |
307 | gptStopTimer(&GPTD8); | |
308 | ||
309 | playing_notes = false; | |
b624f32f | 310 | playing_note = false; |
311 | frequency = 0; | |
5fd68266 | 312 | frequency_alt = 0; |
b624f32f | 313 | volume = 0; |
5fd68266 | 314 | |
b624f32f | 315 | for (uint8_t i = 0; i < 8; i++) { |
5fd68266 | 316 | frequencies[i] = 0; |
b624f32f | 317 | volumes[i] = 0; |
5fd68266 | 318 | } |
319 | } | |
320 | ||
85022f8b | 321 | void stop_note(float freq) { |
b624f32f | 322 | dprintf("audio stop note freq=%d", (int)freq); |
5fd68266 | 323 | |
b624f32f | 324 | if (playing_note) { |
325 | if (!audio_initialized) { | |
326 | audio_init(); | |
327 | } | |
328 | for (int i = 7; i >= 0; i--) { | |
329 | if (frequencies[i] == freq) { | |
330 | frequencies[i] = 0; | |
331 | volumes[i] = 0; | |
332 | for (int j = i; (j < 7); j++) { | |
333 | frequencies[j] = frequencies[j + 1]; | |
334 | frequencies[j + 1] = 0; | |
335 | volumes[j] = volumes[j + 1]; | |
336 | volumes[j + 1] = 0; | |
337 | } | |
338 | break; | |
339 | } | |
340 | } | |
341 | voices--; | |
342 | if (voices < 0) { | |
343 | voices = 0; | |
344 | } | |
345 | if (voice_place >= voices) { | |
346 | voice_place = 0; | |
347 | } | |
348 | if (voices == 0) { | |
349 | STOP_CHANNEL_1(); | |
350 | STOP_CHANNEL_2(); | |
351 | gptStopTimer(&GPTD8); | |
352 | frequency = 0; | |
353 | frequency_alt = 0; | |
354 | volume = 0; | |
355 | playing_note = false; | |
5fd68266 | 356 | } |
357 | } | |
358 | } | |
359 | ||
360 | #ifdef VIBRATO_ENABLE | |
361 | ||
85022f8b | 362 | float mod(float a, int b) { |
b624f32f | 363 | float r = fmod(a, b); |
364 | return r < 0 ? r + b : r; | |
5fd68266 | 365 | } |
366 | ||
367 | float vibrato(float average_freq) { | |
b624f32f | 368 | # ifdef VIBRATO_STRENGTH_ENABLE |
85022f8b | 369 | float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); |
b624f32f | 370 | # else |
85022f8b | 371 | float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter]; |
b624f32f | 372 | # endif |
373 | vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0 / average_freq)), VIBRATO_LUT_LENGTH); | |
374 | return vibrated_freq; | |
5fd68266 | 375 | } |
376 | ||
377 | #endif | |
378 | ||
5fd68266 | 379 | static void gpt_cb8(GPTDriver *gptp) { |
b624f32f | 380 | float freq; |
5fd68266 | 381 | |
b624f32f | 382 | if (playing_note) { |
383 | if (voices > 0) { | |
384 | float freq_alt = 0; | |
385 | if (voices > 1) { | |
386 | if (polyphony_rate == 0) { | |
387 | if (glissando) { | |
388 | if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440 / frequencies[voices - 2] / 12 / 2)) { | |
389 | frequency_alt = frequency_alt * pow(2, 440 / frequency_alt / 12 / 2); | |
390 | } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440 / frequencies[voices - 2] / 12 / 2)) { | |
391 | frequency_alt = frequency_alt * pow(2, -440 / frequency_alt / 12 / 2); | |
392 | } else { | |
393 | frequency_alt = frequencies[voices - 2]; | |
394 | } | |
395 | } else { | |
396 | frequency_alt = frequencies[voices - 2]; | |
397 | } | |
5fd68266 | 398 | |
b624f32f | 399 | #ifdef VIBRATO_ENABLE |
400 | if (vibrato_strength > 0) { | |
401 | freq_alt = vibrato(frequency_alt); | |
402 | } else { | |
403 | freq_alt = frequency_alt; | |
404 | } | |
405 | #else | |
406 | freq_alt = frequency_alt; | |
407 | #endif | |
408 | } | |
5fd68266 | 409 | |
b624f32f | 410 | if (envelope_index < 65535) { |
411 | envelope_index++; | |
412 | } | |
5fd68266 | 413 | |
b624f32f | 414 | freq_alt = voice_envelope(freq_alt); |
85022f8b | 415 | |
b624f32f | 416 | if (freq_alt < 30.517578125) { |
417 | freq_alt = 30.52; | |
418 | } | |
5fd68266 | 419 | |
b624f32f | 420 | if (GET_CHANNEL_2_FREQ != (uint16_t)freq_alt) { |
421 | UPDATE_CHANNEL_2_FREQ(freq_alt); | |
422 | } else { | |
423 | RESTART_CHANNEL_2(); | |
424 | } | |
425 | // note_timbre; | |
426 | } | |
5fd68266 | 427 | |
b624f32f | 428 | if (polyphony_rate > 0) { |
429 | if (voices > 1) { | |
430 | voice_place %= voices; | |
431 | if (place++ > (frequencies[voice_place] / polyphony_rate)) { | |
432 | voice_place = (voice_place + 1) % voices; | |
433 | place = 0.0; | |
434 | } | |
435 | } | |
5fd68266 | 436 | |
b624f32f | 437 | #ifdef VIBRATO_ENABLE |
438 | if (vibrato_strength > 0) { | |
439 | freq = vibrato(frequencies[voice_place]); | |
440 | } else { | |
441 | freq = frequencies[voice_place]; | |
442 | } | |
443 | #else | |
444 | freq = frequencies[voice_place]; | |
445 | #endif | |
446 | } else { | |
447 | if (glissando) { | |
448 | if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440 / frequencies[voices - 1] / 12 / 2)) { | |
449 | frequency = frequency * pow(2, 440 / frequency / 12 / 2); | |
450 | } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440 / frequencies[voices - 1] / 12 / 2)) { | |
451 | frequency = frequency * pow(2, -440 / frequency / 12 / 2); | |
452 | } else { | |
453 | frequency = frequencies[voices - 1]; | |
454 | } | |
455 | } else { | |
456 | frequency = frequencies[voices - 1]; | |
457 | } | |
5fd68266 | 458 | |
b624f32f | 459 | #ifdef VIBRATO_ENABLE |
460 | if (vibrato_strength > 0) { | |
461 | freq = vibrato(frequency); | |
462 | } else { | |
463 | freq = frequency; | |
464 | } | |
465 | #else | |
466 | freq = frequency; | |
467 | #endif | |
468 | } | |
5fd68266 | 469 | |
b624f32f | 470 | if (envelope_index < 65535) { |
471 | envelope_index++; | |
472 | } | |
5fd68266 | 473 | |
b624f32f | 474 | freq = voice_envelope(freq); |
5fd68266 | 475 | |
b624f32f | 476 | if (freq < 30.517578125) { |
477 | freq = 30.52; | |
478 | } | |
5fd68266 | 479 | |
b624f32f | 480 | if (GET_CHANNEL_1_FREQ != (uint16_t)freq) { |
481 | UPDATE_CHANNEL_1_FREQ(freq); | |
482 | } else { | |
483 | RESTART_CHANNEL_1(); | |
484 | } | |
485 | // note_timbre; | |
85022f8b | 486 | } |
85022f8b | 487 | } |
5fd68266 | 488 | |
b624f32f | 489 | if (playing_notes) { |
490 | if (note_frequency > 0) { | |
491 | #ifdef VIBRATO_ENABLE | |
492 | if (vibrato_strength > 0) { | |
493 | freq = vibrato(note_frequency); | |
494 | } else { | |
495 | freq = note_frequency; | |
496 | } | |
497 | #else | |
498 | freq = note_frequency; | |
499 | #endif | |
5fd68266 | 500 | |
b624f32f | 501 | if (envelope_index < 65535) { |
502 | envelope_index++; | |
503 | } | |
504 | freq = voice_envelope(freq); | |
505 | ||
506 | if (GET_CHANNEL_1_FREQ != (uint16_t)freq) { | |
507 | UPDATE_CHANNEL_1_FREQ(freq); | |
508 | UPDATE_CHANNEL_2_FREQ(freq); | |
509 | } | |
510 | // note_timbre; | |
85022f8b | 511 | } else { |
b624f32f | 512 | // gptStopTimer(&GPTD6); |
513 | // gptStopTimer(&GPTD7); | |
85022f8b | 514 | } |
b624f32f | 515 | |
516 | note_position++; | |
517 | bool end_of_note = false; | |
518 | if (GET_CHANNEL_1_FREQ > 0) { | |
519 | if (!note_resting) | |
520 | end_of_note = (note_position >= (note_length * 8 - 1)); | |
521 | else | |
522 | end_of_note = (note_position >= (note_length * 8)); | |
85022f8b | 523 | } else { |
b624f32f | 524 | end_of_note = (note_position >= (note_length * 8)); |
5fd68266 | 525 | } |
526 | ||
b624f32f | 527 | if (end_of_note) { |
528 | current_note++; | |
529 | if (current_note >= notes_count) { | |
530 | if (notes_repeat) { | |
531 | current_note = 0; | |
532 | } else { | |
533 | STOP_CHANNEL_1(); | |
534 | STOP_CHANNEL_2(); | |
535 | // gptStopTimer(&GPTD8); | |
536 | playing_notes = false; | |
537 | return; | |
538 | } | |
539 | } | |
540 | if (!note_resting) { | |
541 | note_resting = true; | |
542 | current_note--; | |
543 | if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) { | |
544 | note_frequency = 0; | |
545 | note_length = 1; | |
546 | } else { | |
547 | note_frequency = (*notes_pointer)[current_note][0]; | |
548 | note_length = 1; | |
549 | } | |
550 | } else { | |
551 | note_resting = false; | |
552 | envelope_index = 0; | |
553 | note_frequency = (*notes_pointer)[current_note][0]; | |
554 | note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); | |
555 | } | |
556 | ||
557 | note_position = 0; | |
558 | } | |
5fd68266 | 559 | } |
560 | ||
b624f32f | 561 | if (!audio_config.enable) { |
562 | playing_notes = false; | |
563 | playing_note = false; | |
564 | } | |
5fd68266 | 565 | } |
566 | ||
85022f8b | 567 | void play_note(float freq, int vol) { |
b624f32f | 568 | dprintf("audio play note freq=%d vol=%d", (int)freq, vol); |
5fd68266 | 569 | |
b624f32f | 570 | if (!audio_initialized) { |
571 | audio_init(); | |
5fd68266 | 572 | } |
573 | ||
b624f32f | 574 | if (audio_config.enable && voices < 8) { |
575 | // Cancel notes if notes are playing | |
576 | if (playing_notes) { | |
577 | stop_all_notes(); | |
578 | } | |
5fd68266 | 579 | |
b624f32f | 580 | playing_note = true; |
5fd68266 | 581 | |
b624f32f | 582 | envelope_index = 0; |
5fd68266 | 583 | |
b624f32f | 584 | if (freq > 0) { |
585 | frequencies[voices] = freq; | |
586 | volumes[voices] = vol; | |
587 | voices++; | |
588 | } | |
5fd68266 | 589 | |
b624f32f | 590 | gptStart(&GPTD8, &gpt8cfg1); |
591 | gptStartContinuous(&GPTD8, 2U); | |
592 | RESTART_CHANNEL_1(); | |
593 | RESTART_CHANNEL_2(); | |
594 | } | |
85022f8b | 595 | } |
5fd68266 | 596 | |
85022f8b | 597 | void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat) { |
b624f32f | 598 | if (!audio_initialized) { |
599 | audio_init(); | |
5fd68266 | 600 | } |
601 | ||
b624f32f | 602 | if (audio_config.enable) { |
603 | // Cancel note if a note is playing | |
604 | if (playing_note) { | |
605 | stop_all_notes(); | |
606 | } | |
85022f8b | 607 | |
b624f32f | 608 | playing_notes = true; |
85022f8b | 609 | |
b624f32f | 610 | notes_pointer = np; |
611 | notes_count = n_count; | |
612 | notes_repeat = n_repeat; | |
85022f8b | 613 | |
b624f32f | 614 | place = 0; |
615 | current_note = 0; | |
85022f8b | 616 | |
b624f32f | 617 | note_frequency = (*notes_pointer)[current_note][0]; |
618 | note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); | |
619 | note_position = 0; | |
5fd68266 | 620 | |
b624f32f | 621 | gptStart(&GPTD8, &gpt8cfg1); |
622 | gptStartContinuous(&GPTD8, 2U); | |
623 | RESTART_CHANNEL_1(); | |
624 | RESTART_CHANNEL_2(); | |
625 | } | |
5fd68266 | 626 | } |
627 | ||
b624f32f | 628 | bool is_playing_notes(void) { return playing_notes; } |
629 | ||
630 | bool is_audio_on(void) { return (audio_config.enable != 0); } | |
5fd68266 | 631 | |
632 | void audio_toggle(void) { | |
b624f32f | 633 | audio_config.enable ^= 1; |
634 | eeconfig_update_audio(audio_config.raw); | |
635 | if (audio_config.enable) { | |
636 | audio_on_user(); | |
637 | } | |
5fd68266 | 638 | } |
639 | ||
640 | void audio_on(void) { | |
b624f32f | 641 | audio_config.enable = 1; |
642 | eeconfig_update_audio(audio_config.raw); | |
643 | audio_on_user(); | |
5fd68266 | 644 | } |
645 | ||
646 | void audio_off(void) { | |
b624f32f | 647 | stop_all_notes(); |
648 | audio_config.enable = 0; | |
649 | eeconfig_update_audio(audio_config.raw); | |
5fd68266 | 650 | } |
651 | ||
652 | #ifdef VIBRATO_ENABLE | |
653 | ||
654 | // Vibrato rate functions | |
655 | ||
b624f32f | 656 | void set_vibrato_rate(float rate) { vibrato_rate = rate; } |
5fd68266 | 657 | |
b624f32f | 658 | void increase_vibrato_rate(float change) { vibrato_rate *= change; } |
5fd68266 | 659 | |
b624f32f | 660 | void decrease_vibrato_rate(float change) { vibrato_rate /= change; } |
5fd68266 | 661 | |
b624f32f | 662 | # ifdef VIBRATO_STRENGTH_ENABLE |
5fd68266 | 663 | |
b624f32f | 664 | void set_vibrato_strength(float strength) { vibrato_strength = strength; } |
5fd68266 | 665 | |
b624f32f | 666 | void increase_vibrato_strength(float change) { vibrato_strength *= change; } |
5fd68266 | 667 | |
b624f32f | 668 | void decrease_vibrato_strength(float change) { vibrato_strength /= change; } |
5fd68266 | 669 | |
b624f32f | 670 | # endif /* VIBRATO_STRENGTH_ENABLE */ |
5fd68266 | 671 | |
672 | #endif /* VIBRATO_ENABLE */ | |
673 | ||
674 | // Polyphony functions | |
675 | ||
b624f32f | 676 | void set_polyphony_rate(float rate) { polyphony_rate = rate; } |
5fd68266 | 677 | |
b624f32f | 678 | void enable_polyphony() { polyphony_rate = 5; } |
5fd68266 | 679 | |
b624f32f | 680 | void disable_polyphony() { polyphony_rate = 0; } |
5fd68266 | 681 | |
b624f32f | 682 | void increase_polyphony_rate(float change) { polyphony_rate *= change; } |
5fd68266 | 683 | |
b624f32f | 684 | void decrease_polyphony_rate(float change) { polyphony_rate /= change; } |
5fd68266 | 685 | |
686 | // Timbre function | |
687 | ||
b624f32f | 688 | void set_timbre(float timbre) { note_timbre = timbre; } |
5fd68266 | 689 | |
690 | // Tempo functions | |
691 | ||
b624f32f | 692 | void set_tempo(uint8_t tempo) { note_tempo = tempo; } |
5fd68266 | 693 | |
b624f32f | 694 | void decrease_tempo(uint8_t tempo_change) { note_tempo += tempo_change; } |
5fd68266 | 695 | |
696 | void increase_tempo(uint8_t tempo_change) { | |
b624f32f | 697 | if (note_tempo - tempo_change < 10) { |
698 | note_tempo = 10; | |
699 | } else { | |
700 | note_tempo -= tempo_change; | |
701 | } | |
5fd68266 | 702 | } |