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