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