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