Added support for audio using pins C4, C5, B6, B7
[jackhill/qmk/firmware.git] / quantum / audio / audio.c
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 <stdio.h>
18 #include <string.h>
19 //#include <math.h>
20 #if defined(__AVR__)
21 #include <avr/pgmspace.h>
22 #include <avr/interrupt.h>
23 #include <avr/io.h>
24 #endif
25 #include "print.h"
26 #include "audio.h"
27 #include "keymap.h"
28 #include "wait.h"
29
30 #include "eeconfig.h"
31
32 #define CPU_PRESCALER 8
33
34 // -----------------------------------------------------------------------------
35 // Timer Abstractions
36 // -----------------------------------------------------------------------------
37
38 //Currently we support timers 1 and 3 used at the sime time, channels A-C,
39 //pins PB5, PB6, PB7, PC4, PC5, and PC6
40 #if defined(C6_AUDIO)
41 #define CPIN_AUDIO
42 #define CPIN_SET_DIRECTION DDRC |= _BV(PORTC6);
43 #define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
44 #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A)
45 #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A)
46 #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1);
47 #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0));
48 #define TIMER_3_PERIOD ICR3
49 #define TIMER_3_DUTY_CYCLE OCR3A
50 #define TIMER3_AUDIO_vect TIMER3_COMPA_vect
51 #endif
52 #if defined(C5_AUDIO)
53 #define CPIN_AUDIO
54 #define CPIN_SET_DIRECTION DDRC |= _BV(PORTC5);
55 #define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3B1) | (0 << COM3B0) | (1 << WGM31) | (0 << WGM30);
56 #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3B)
57 #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3B)
58 #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3B1);
59 #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3B1) | _BV(COM3B0));
60 #define TIMER_3_PERIOD ICR3
61 #define TIMER_3_DUTY_CYCLE OCR3B
62 #define TIMER3_AUDIO_vect TIMER3_COMPB_vect
63 #endif
64 #if defined(C4_AUDIO)
65 #define CPIN_AUDIO
66 #define CPIN_SET_DIRECTION DDRC |= _BV(PORTC4);
67 #define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3C1) | (0 << COM3C0) | (1 << WGM31) | (0 << WGM30);
68 #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3C)
69 #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3C)
70 #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3C1);
71 #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3C1) | _BV(COM3C0));
72 #define TIMER_3_PERIOD ICR3
73 #define TIMER_3_DUTY_CYCLE OCR3C
74 #define TIMER3_AUDIO_vect TIMER3_COMPC_vect
75 #endif
76
77 #if defined(B5_AUDIO)
78 #define BPIN_AUDIO
79 #define BPIN_SET_DIRECTION DDRC |= _BV(PORTB5);
80 #define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
81 #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A)
82 #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A)
83 #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1);
84 #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0));
85 #define TIMER_1_PERIOD ICR1
86 #define TIMER_1_DUTY_CYCLE OCR1A
87 #define TIMER1_AUDIO_vect TIMER1_COMPA_vect
88 #endif
89 #if defined(B6_AUDIO)
90 #define BPIN_AUDIO
91 #define BPIN_SET_DIRECTION DDRC |= _BV(PORTB6);
92 #define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1B1) | (0 << COM1B0) | (1 << WGM11) | (0 << WGM10);
93 #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1B)
94 #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1B)
95 #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1B1);
96 #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1B1) | _BV(COM1B0));
97 #define TIMER_1_PERIOD ICR1
98 #define TIMER_1_DUTY_CYCLE OCR1B
99 #define TIMER1_AUDIO_vect TIMER1_COMPB_vect
100 #endif
101 #if defined(B7_AUDIO)
102 #define BPIN_AUDIO
103 #define BPIN_SET_DIRECTION DDRC |= _BV(PORTB7);
104 #define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1C1) | (0 << COM1C0) | (1 << WGM11) | (0 << WGM10);
105 #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1C)
106 #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1C)
107 #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1C1);
108 #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1C1) | _BV(COM1C0));
109 #define TIMER_1_PERIOD ICR1
110 #define TIMER_1_DUTY_CYCLE OCR1C
111 #define TIMER1_AUDIO_vect TIMER1_COMPC_vect
112 #endif
113 // -----------------------------------------------------------------------------
114
115
116 int voices = 0;
117 int voice_place = 0;
118 float frequency = 0;
119 float frequency_alt = 0;
120 int volume = 0;
121 long position = 0;
122
123 float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
124 int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
125 bool sliding = false;
126
127 float place = 0;
128
129 uint8_t * sample;
130 uint16_t sample_length = 0;
131
132 bool playing_notes = false;
133 bool playing_note = false;
134 float note_frequency = 0;
135 float note_length = 0;
136 uint8_t note_tempo = TEMPO_DEFAULT;
137 float note_timbre = TIMBRE_DEFAULT;
138 uint16_t note_position = 0;
139 float (* notes_pointer)[][2];
140 uint16_t notes_count;
141 bool notes_repeat;
142 bool note_resting = false;
143
144 uint8_t current_note = 0;
145 uint8_t rest_counter = 0;
146
147 #ifdef VIBRATO_ENABLE
148 float vibrato_counter = 0;
149 float vibrato_strength = .5;
150 float vibrato_rate = 0.125;
151 #endif
152
153 float polyphony_rate = 0;
154
155 static bool audio_initialized = false;
156
157 audio_config_t audio_config;
158
159 uint16_t envelope_index = 0;
160 bool glissando = true;
161
162 #ifndef STARTUP_SONG
163 #define STARTUP_SONG SONG(STARTUP_SOUND)
164 #endif
165 #ifndef AUDIO_ON_SONG
166 #define AUDIO_ON_SONG SONG(AUDIO_ON_SOUND)
167 #endif
168 #ifndef AUDIO_OFF_SONG
169 #define AUDIO_OFF_SONG SONG(AUDIO_OFF_SOUND)
170 #endif
171 float startup_song[][2] = STARTUP_SONG;
172 float audio_on_song[][2] = AUDIO_ON_SONG;
173 float audio_off_song[][2] = AUDIO_OFF_SONG;
174
175 void audio_init()
176 {
177
178 // Check EEPROM
179 if (!eeconfig_is_enabled())
180 {
181 eeconfig_init();
182 }
183 audio_config.raw = eeconfig_read_audio();
184
185 if (!audio_initialized) {
186
187 // Set audio ports as output
188 #ifdef CPIN_AUDIO
189 CPIN_SET_DIRECTION
190 #endif
191 #ifdef BPIN_AUDIO
192 BPIN_SET_DIRECTION
193 #endif
194
195 #ifdef CPIN_AUDIO
196 DISABLE_AUDIO_COUNTER_3_ISR;
197 #endif
198 #ifdef BPIN_AUDIO
199 DISABLE_AUDIO_COUNTER_1_ISR;
200 #endif
201
202 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers TCCR3A/TCCR3B, TCCR1A/TCCR1B
203 // Compare Output Mode (COM3An and COM1An) = 0b00 = Normal port operation
204 // OC3A -- PC6
205 // OC3B -- PC5
206 // OC3C -- PC4
207 // OC1A -- PB5
208 // OC1B -- PB6
209 // OC1C -- PB7
210
211 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14. Period = ICR3, Duty Cycle OCR3A)
212 // OCR3A - PC6
213 // OCR3B - PC5
214 // OCR3C - PC4
215 // OCR1A - PB5
216 // OCR1B - PB6
217 // OCR1C - PB7
218
219 // Clock Select (CS3n) = 0b010 = Clock / 8
220 #ifdef CPIN_AUDIO
221 INIT_AUDIO_COUNTER_3
222 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
223 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));
224 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre);
225 #endif
226 #ifdef BPIN_AUDIO
227 INIT_AUDIO_COUNTER_1
228 TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
229 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));
230 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre);
231 #endif
232
233 audio_initialized = true;
234 }
235
236 if (audio_config.enable) {
237 PLAY_SONG(startup_song);
238 }
239
240 }
241
242 void stop_all_notes()
243 {
244 dprintf("audio stop all notes");
245
246 if (!audio_initialized) {
247 audio_init();
248 }
249 voices = 0;
250
251 #ifdef CPIN_AUDIO
252 DISABLE_AUDIO_COUNTER_3_ISR;
253 DISABLE_AUDIO_COUNTER_3_OUTPUT;
254 #endif
255
256 #ifdef BPIN_AUDIO
257 DISABLE_AUDIO_COUNTER_1_ISR;
258 DISABLE_AUDIO_COUNTER_1_OUTPUT;
259 #endif
260
261 playing_notes = false;
262 playing_note = false;
263 frequency = 0;
264 frequency_alt = 0;
265 volume = 0;
266
267 for (uint8_t i = 0; i < 8; i++)
268 {
269 frequencies[i] = 0;
270 volumes[i] = 0;
271 }
272 }
273
274 void stop_note(float freq)
275 {
276 dprintf("audio stop note freq=%d", (int)freq);
277
278 if (playing_note) {
279 if (!audio_initialized) {
280 audio_init();
281 }
282 for (int i = 7; i >= 0; i--) {
283 if (frequencies[i] == freq) {
284 frequencies[i] = 0;
285 volumes[i] = 0;
286 for (int j = i; (j < 7); j++) {
287 frequencies[j] = frequencies[j+1];
288 frequencies[j+1] = 0;
289 volumes[j] = volumes[j+1];
290 volumes[j+1] = 0;
291 }
292 break;
293 }
294 }
295 voices--;
296 if (voices < 0)
297 voices = 0;
298 if (voice_place >= voices) {
299 voice_place = 0;
300 }
301 if (voices == 0) {
302 #ifdef CPIN_AUDIO
303 DISABLE_AUDIO_COUNTER_3_ISR;
304 DISABLE_AUDIO_COUNTER_3_OUTPUT;
305 #endif
306 #ifdef BPIN_AUDIO
307 DISABLE_AUDIO_COUNTER_1_ISR;
308 DISABLE_AUDIO_COUNTER_1_OUTPUT;
309 #endif
310 frequency = 0;
311 frequency_alt = 0;
312 volume = 0;
313 playing_note = false;
314 }
315 }
316 }
317
318 #ifdef VIBRATO_ENABLE
319
320 float mod(float a, int b)
321 {
322 float r = fmod(a, b);
323 return r < 0 ? r + b : r;
324 }
325
326 float vibrato(float average_freq) {
327 #ifdef VIBRATO_STRENGTH_ENABLE
328 float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength);
329 #else
330 float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter];
331 #endif
332 vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH);
333 return vibrated_freq;
334 }
335
336 #endif
337
338 #ifdef CPIN_AUDIO
339 ISR(TIMER3_AUDIO_vect)
340 {
341 float freq;
342
343 if (playing_note) {
344 if (voices > 0) {
345
346 #ifdef BPIN_AUDIO
347 float freq_alt = 0;
348 if (voices > 1) {
349 if (polyphony_rate == 0) {
350 if (glissando) {
351 if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440/frequencies[voices - 2]/12/2)) {
352 frequency_alt = frequency_alt * pow(2, 440/frequency_alt/12/2);
353 } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440/frequencies[voices - 2]/12/2)) {
354 frequency_alt = frequency_alt * pow(2, -440/frequency_alt/12/2);
355 } else {
356 frequency_alt = frequencies[voices - 2];
357 }
358 } else {
359 frequency_alt = frequencies[voices - 2];
360 }
361
362 #ifdef VIBRATO_ENABLE
363 if (vibrato_strength > 0) {
364 freq_alt = vibrato(frequency_alt);
365 } else {
366 freq_alt = frequency_alt;
367 }
368 #else
369 freq_alt = frequency_alt;
370 #endif
371 }
372
373 if (envelope_index < 65535) {
374 envelope_index++;
375 }
376
377 freq_alt = voice_envelope(freq_alt);
378
379 if (freq_alt < 30.517578125) {
380 freq_alt = 30.52;
381 }
382
383 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER));
384 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre);
385 }
386 #endif
387
388 if (polyphony_rate > 0) {
389 if (voices > 1) {
390 voice_place %= voices;
391 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
392 voice_place = (voice_place + 1) % voices;
393 place = 0.0;
394 }
395 }
396
397 #ifdef VIBRATO_ENABLE
398 if (vibrato_strength > 0) {
399 freq = vibrato(frequencies[voice_place]);
400 } else {
401 freq = frequencies[voice_place];
402 }
403 #else
404 freq = frequencies[voice_place];
405 #endif
406 } else {
407 if (glissando) {
408 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
409 frequency = frequency * pow(2, 440/frequency/12/2);
410 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
411 frequency = frequency * pow(2, -440/frequency/12/2);
412 } else {
413 frequency = frequencies[voices - 1];
414 }
415 } else {
416 frequency = frequencies[voices - 1];
417 }
418
419 #ifdef VIBRATO_ENABLE
420 if (vibrato_strength > 0) {
421 freq = vibrato(frequency);
422 } else {
423 freq = frequency;
424 }
425 #else
426 freq = frequency;
427 #endif
428 }
429
430 if (envelope_index < 65535) {
431 envelope_index++;
432 }
433
434 freq = voice_envelope(freq);
435
436 if (freq < 30.517578125) {
437 freq = 30.52;
438 }
439
440 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
441 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
442 }
443 }
444
445 if (playing_notes) {
446 if (note_frequency > 0) {
447 #ifdef VIBRATO_ENABLE
448 if (vibrato_strength > 0) {
449 freq = vibrato(note_frequency);
450 } else {
451 freq = note_frequency;
452 }
453 #else
454 freq = note_frequency;
455 #endif
456
457 if (envelope_index < 65535) {
458 envelope_index++;
459 }
460 freq = voice_envelope(freq);
461
462 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
463 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
464 } else {
465 TIMER_3_PERIOD = 0;
466 TIMER_3_DUTY_CYCLE = 0;
467 }
468
469 note_position++;
470 bool end_of_note = false;
471 if (TIMER_3_PERIOD > 0) {
472 if (!note_resting)
473 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1));
474 else
475 end_of_note = (note_position >= (note_length));
476 } else {
477 end_of_note = (note_position >= (note_length));
478 }
479
480 if (end_of_note) {
481 current_note++;
482 if (current_note >= notes_count) {
483 if (notes_repeat) {
484 current_note = 0;
485 } else {
486 DISABLE_AUDIO_COUNTER_3_ISR;
487 DISABLE_AUDIO_COUNTER_3_OUTPUT;
488 playing_notes = false;
489 return;
490 }
491 }
492 if (!note_resting) {
493 note_resting = true;
494 current_note--;
495 if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
496 note_frequency = 0;
497 note_length = 1;
498 } else {
499 note_frequency = (*notes_pointer)[current_note][0];
500 note_length = 1;
501 }
502 } else {
503 note_resting = false;
504 envelope_index = 0;
505 note_frequency = (*notes_pointer)[current_note][0];
506 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
507 }
508
509 note_position = 0;
510 }
511 }
512
513 if (!audio_config.enable) {
514 playing_notes = false;
515 playing_note = false;
516 }
517 }
518 #endif
519
520 #ifdef BPIN_AUDIO
521 ISR(TIMER1_AUDIO_vect)
522 {
523 #if defined(BPIN_AUDIO) && !defined(CPIN_AUDIO)
524 float freq = 0;
525
526 if (playing_note) {
527 if (voices > 0) {
528 if (polyphony_rate > 0) {
529 if (voices > 1) {
530 voice_place %= voices;
531 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
532 voice_place = (voice_place + 1) % voices;
533 place = 0.0;
534 }
535 }
536
537 #ifdef VIBRATO_ENABLE
538 if (vibrato_strength > 0) {
539 freq = vibrato(frequencies[voice_place]);
540 } else {
541 freq = frequencies[voice_place];
542 }
543 #else
544 freq = frequencies[voice_place];
545 #endif
546 } else {
547 if (glissando) {
548 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
549 frequency = frequency * pow(2, 440/frequency/12/2);
550 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
551 frequency = frequency * pow(2, -440/frequency/12/2);
552 } else {
553 frequency = frequencies[voices - 1];
554 }
555 } else {
556 frequency = frequencies[voices - 1];
557 }
558
559 #ifdef VIBRATO_ENABLE
560 if (vibrato_strength > 0) {
561 freq = vibrato(frequency);
562 } else {
563 freq = frequency;
564 }
565 #else
566 freq = frequency;
567 #endif
568 }
569
570 if (envelope_index < 65535) {
571 envelope_index++;
572 }
573
574 freq = voice_envelope(freq);
575
576 if (freq < 30.517578125) {
577 freq = 30.52;
578 }
579
580 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
581 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
582 }
583 }
584
585 if (playing_notes) {
586 if (note_frequency > 0) {
587 #ifdef VIBRATO_ENABLE
588 if (vibrato_strength > 0) {
589 freq = vibrato(note_frequency);
590 } else {
591 freq = note_frequency;
592 }
593 #else
594 freq = note_frequency;
595 #endif
596
597 if (envelope_index < 65535) {
598 envelope_index++;
599 }
600 freq = voice_envelope(freq);
601
602 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
603 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
604 } else {
605 TIMER_1_PERIOD = 0;
606 TIMER_1_DUTY_CYCLE = 0;
607 }
608
609 note_position++;
610 bool end_of_note = false;
611 if (TIMER_1_PERIOD > 0) {
612 if (!note_resting)
613 end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1));
614 else
615 end_of_note = (note_position >= (note_length));
616 } else {
617 end_of_note = (note_position >= (note_length));
618 }
619
620 if (end_of_note) {
621 current_note++;
622 if (current_note >= notes_count) {
623 if (notes_repeat) {
624 current_note = 0;
625 } else {
626 DISABLE_AUDIO_COUNTER_1_ISR;
627 DISABLE_AUDIO_COUNTER_1_OUTPUT;
628 playing_notes = false;
629 return;
630 }
631 }
632 if (!note_resting) {
633 note_resting = true;
634 current_note--;
635 if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
636 note_frequency = 0;
637 note_length = 1;
638 } else {
639 note_frequency = (*notes_pointer)[current_note][0];
640 note_length = 1;
641 }
642 } else {
643 note_resting = false;
644 envelope_index = 0;
645 note_frequency = (*notes_pointer)[current_note][0];
646 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
647 }
648
649 note_position = 0;
650 }
651 }
652
653 if (!audio_config.enable) {
654 playing_notes = false;
655 playing_note = false;
656 }
657 #endif
658 }
659 #endif
660
661 void play_note(float freq, int vol) {
662
663 dprintf("audio play note freq=%d vol=%d", (int)freq, vol);
664
665 if (!audio_initialized) {
666 audio_init();
667 }
668
669 if (audio_config.enable && voices < 8) {
670 #ifdef CPIN_AUDIO
671 DISABLE_AUDIO_COUNTER_3_ISR;
672 #endif
673 #ifdef BPIN_AUDIO
674 DISABLE_AUDIO_COUNTER_1_ISR;
675 #endif
676
677 // Cancel notes if notes are playing
678 if (playing_notes)
679 stop_all_notes();
680
681 playing_note = true;
682
683 envelope_index = 0;
684
685 if (freq > 0) {
686 frequencies[voices] = freq;
687 volumes[voices] = vol;
688 voices++;
689 }
690
691 #ifdef CPIN_AUDIO
692 ENABLE_AUDIO_COUNTER_3_ISR;
693 ENABLE_AUDIO_COUNTER_3_OUTPUT;
694 #endif
695 #ifdef BPIN_AUDIO
696 #ifdef CPIN_AUDIO
697 if (voices > 1) {
698 ENABLE_AUDIO_COUNTER_1_ISR;
699 ENABLE_AUDIO_COUNTER_1_OUTPUT;
700 }
701 #else
702 ENABLE_AUDIO_COUNTER_1_ISR;
703 ENABLE_AUDIO_COUNTER_1_OUTPUT;
704 #endif
705 #endif
706 }
707
708 }
709
710 void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
711 {
712
713 if (!audio_initialized) {
714 audio_init();
715 }
716
717 if (audio_config.enable) {
718
719 #ifdef CPIN_AUDIO
720 DISABLE_AUDIO_COUNTER_3_ISR;
721 #endif
722 #ifdef BPIN_AUDIO
723 DISABLE_AUDIO_COUNTER_1_ISR;
724 #endif
725
726 // Cancel note if a note is playing
727 if (playing_note)
728 stop_all_notes();
729
730 playing_notes = true;
731
732 notes_pointer = np;
733 notes_count = n_count;
734 notes_repeat = n_repeat;
735
736 place = 0;
737 current_note = 0;
738
739 note_frequency = (*notes_pointer)[current_note][0];
740 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
741 note_position = 0;
742
743
744 #ifdef CPIN_AUDIO
745 ENABLE_AUDIO_COUNTER_3_ISR;
746 ENABLE_AUDIO_COUNTER_3_OUTPUT;
747 #endif
748 #ifdef BPIN_AUDIO
749 #ifndef CPIN_AUDIO
750 ENABLE_AUDIO_COUNTER_1_ISR;
751 ENABLE_AUDIO_COUNTER_1_OUTPUT;
752 #endif
753 #endif
754 }
755
756 }
757
758 bool is_playing_notes(void) {
759 return playing_notes;
760 }
761
762 bool is_audio_on(void) {
763 return (audio_config.enable != 0);
764 }
765
766 void audio_toggle(void) {
767 audio_config.enable ^= 1;
768 eeconfig_update_audio(audio_config.raw);
769 if (audio_config.enable)
770 audio_on_user();
771 }
772
773 void audio_on(void) {
774 audio_config.enable = 1;
775 eeconfig_update_audio(audio_config.raw);
776 audio_on_user();
777 PLAY_SONG(audio_on_song);
778 }
779
780 void audio_off(void) {
781 PLAY_SONG(audio_off_song);
782 wait_ms(100);
783 stop_all_notes();
784 audio_config.enable = 0;
785 eeconfig_update_audio(audio_config.raw);
786 }
787
788 #ifdef VIBRATO_ENABLE
789
790 // Vibrato rate functions
791
792 void set_vibrato_rate(float rate) {
793 vibrato_rate = rate;
794 }
795
796 void increase_vibrato_rate(float change) {
797 vibrato_rate *= change;
798 }
799
800 void decrease_vibrato_rate(float change) {
801 vibrato_rate /= change;
802 }
803
804 #ifdef VIBRATO_STRENGTH_ENABLE
805
806 void set_vibrato_strength(float strength) {
807 vibrato_strength = strength;
808 }
809
810 void increase_vibrato_strength(float change) {
811 vibrato_strength *= change;
812 }
813
814 void decrease_vibrato_strength(float change) {
815 vibrato_strength /= change;
816 }
817
818 #endif /* VIBRATO_STRENGTH_ENABLE */
819
820 #endif /* VIBRATO_ENABLE */
821
822 // Polyphony functions
823
824 void set_polyphony_rate(float rate) {
825 polyphony_rate = rate;
826 }
827
828 void enable_polyphony() {
829 polyphony_rate = 5;
830 }
831
832 void disable_polyphony() {
833 polyphony_rate = 0;
834 }
835
836 void increase_polyphony_rate(float change) {
837 polyphony_rate *= change;
838 }
839
840 void decrease_polyphony_rate(float change) {
841 polyphony_rate /= change;
842 }
843
844 // Timbre function
845
846 void set_timbre(float timbre) {
847 note_timbre = timbre;
848 }
849
850 // Tempo functions
851
852 void set_tempo(uint8_t tempo) {
853 note_tempo = tempo;
854 }
855
856 void decrease_tempo(uint8_t tempo_change) {
857 note_tempo += tempo_change;
858 }
859
860 void increase_tempo(uint8_t tempo_change) {
861 if (note_tempo - tempo_change < 10) {
862 note_tempo = 10;
863 } else {
864 note_tempo -= tempo_change;
865 }
866 }