1 /* Copyright 2016 Jack Humbert
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.
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.
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/>.
21 #include <avr/pgmspace.h>
22 #include <avr/interrupt.h>
32 #define CPU_PRESCALER 8
34 // -----------------------------------------------------------------------------
36 // -----------------------------------------------------------------------------
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
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
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
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
79 #define BPIN_SET_DIRECTION DDRB |= _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
91 #define BPIN_SET_DIRECTION DDRB |= _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
101 #if defined(B7_AUDIO)
103 #define BPIN_SET_DIRECTION DDRB |= _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
113 // -----------------------------------------------------------------------------
119 float frequency_alt = 0;
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;
130 uint16_t sample_length = 0;
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;
142 bool note_resting = false;
144 uint8_t current_note = 0;
145 uint8_t rest_counter = 0;
147 #ifdef VIBRATO_ENABLE
148 float vibrato_counter = 0;
149 float vibrato_strength = .5;
150 float vibrato_rate = 0.125;
153 float polyphony_rate = 0;
155 static bool audio_initialized = false;
157 audio_config_t audio_config;
159 uint16_t envelope_index = 0;
160 bool glissando = true;
163 #define STARTUP_SONG SONG(STARTUP_SOUND)
165 #ifndef AUDIO_ON_SONG
166 #define AUDIO_ON_SONG SONG(AUDIO_ON_SOUND)
168 #ifndef AUDIO_OFF_SONG
169 #define AUDIO_OFF_SONG SONG(AUDIO_OFF_SOUND)
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;
179 if (!eeconfig_is_enabled())
183 audio_config.raw = eeconfig_read_audio();
185 if (!audio_initialized) {
187 // Set audio ports as output
190 DISABLE_AUDIO_COUNTER_3_ISR;
194 DISABLE_AUDIO_COUNTER_1_ISR;
197 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers TCCR3A/TCCR3B, TCCR1A/TCCR1B
198 // Compare Output Mode (COM3An and COM1An) = 0b00 = Normal port operation
206 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14. Period = ICR3, Duty Cycle OCR3A)
214 // Clock Select (CS3n) = 0b010 = Clock / 8
217 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
218 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));
219 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre);
223 TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
224 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));
225 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre);
228 audio_initialized = true;
231 if (audio_config.enable) {
232 PLAY_SONG(startup_song);
237 void stop_all_notes()
239 dprintf("audio stop all notes");
241 if (!audio_initialized) {
247 DISABLE_AUDIO_COUNTER_3_ISR;
248 DISABLE_AUDIO_COUNTER_3_OUTPUT;
252 DISABLE_AUDIO_COUNTER_1_ISR;
253 DISABLE_AUDIO_COUNTER_1_OUTPUT;
256 playing_notes = false;
257 playing_note = false;
262 for (uint8_t i = 0; i < 8; i++)
269 void stop_note(float freq)
271 dprintf("audio stop note freq=%d", (int)freq);
274 if (!audio_initialized) {
277 for (int i = 7; i >= 0; i--) {
278 if (frequencies[i] == freq) {
281 for (int j = i; (j < 7); j++) {
282 frequencies[j] = frequencies[j+1];
283 frequencies[j+1] = 0;
284 volumes[j] = volumes[j+1];
293 if (voice_place >= voices) {
298 DISABLE_AUDIO_COUNTER_3_ISR;
299 DISABLE_AUDIO_COUNTER_3_OUTPUT;
302 DISABLE_AUDIO_COUNTER_1_ISR;
303 DISABLE_AUDIO_COUNTER_1_OUTPUT;
308 playing_note = false;
313 #ifdef VIBRATO_ENABLE
315 float mod(float a, int b)
317 float r = fmod(a, b);
318 return r < 0 ? r + b : r;
321 float vibrato(float average_freq) {
322 #ifdef VIBRATO_STRENGTH_ENABLE
323 float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength);
325 float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter];
327 vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH);
328 return vibrated_freq;
334 ISR(TIMER3_AUDIO_vect)
344 if (polyphony_rate == 0) {
346 if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440/frequencies[voices - 2]/12/2)) {
347 frequency_alt = frequency_alt * pow(2, 440/frequency_alt/12/2);
348 } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440/frequencies[voices - 2]/12/2)) {
349 frequency_alt = frequency_alt * pow(2, -440/frequency_alt/12/2);
351 frequency_alt = frequencies[voices - 2];
354 frequency_alt = frequencies[voices - 2];
357 #ifdef VIBRATO_ENABLE
358 if (vibrato_strength > 0) {
359 freq_alt = vibrato(frequency_alt);
361 freq_alt = frequency_alt;
364 freq_alt = frequency_alt;
368 if (envelope_index < 65535) {
372 freq_alt = voice_envelope(freq_alt);
374 if (freq_alt < 30.517578125) {
378 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER));
379 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre);
383 if (polyphony_rate > 0) {
385 voice_place %= voices;
386 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
387 voice_place = (voice_place + 1) % voices;
392 #ifdef VIBRATO_ENABLE
393 if (vibrato_strength > 0) {
394 freq = vibrato(frequencies[voice_place]);
396 freq = frequencies[voice_place];
399 freq = frequencies[voice_place];
403 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
404 frequency = frequency * pow(2, 440/frequency/12/2);
405 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
406 frequency = frequency * pow(2, -440/frequency/12/2);
408 frequency = frequencies[voices - 1];
411 frequency = frequencies[voices - 1];
414 #ifdef VIBRATO_ENABLE
415 if (vibrato_strength > 0) {
416 freq = vibrato(frequency);
425 if (envelope_index < 65535) {
429 freq = voice_envelope(freq);
431 if (freq < 30.517578125) {
435 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
436 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
441 if (note_frequency > 0) {
442 #ifdef VIBRATO_ENABLE
443 if (vibrato_strength > 0) {
444 freq = vibrato(note_frequency);
446 freq = note_frequency;
449 freq = note_frequency;
452 if (envelope_index < 65535) {
455 freq = voice_envelope(freq);
457 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
458 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
461 TIMER_3_DUTY_CYCLE = 0;
465 bool end_of_note = false;
466 if (TIMER_3_PERIOD > 0) {
468 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1));
470 end_of_note = (note_position >= (note_length));
472 end_of_note = (note_position >= (note_length));
477 if (current_note >= notes_count) {
481 DISABLE_AUDIO_COUNTER_3_ISR;
482 DISABLE_AUDIO_COUNTER_3_OUTPUT;
483 playing_notes = false;
490 if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
494 note_frequency = (*notes_pointer)[current_note][0];
498 note_resting = false;
500 note_frequency = (*notes_pointer)[current_note][0];
501 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
508 if (!audio_config.enable) {
509 playing_notes = false;
510 playing_note = false;
516 ISR(TIMER1_AUDIO_vect)
518 #if defined(BPIN_AUDIO) && !defined(CPIN_AUDIO)
523 if (polyphony_rate > 0) {
525 voice_place %= voices;
526 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
527 voice_place = (voice_place + 1) % voices;
532 #ifdef VIBRATO_ENABLE
533 if (vibrato_strength > 0) {
534 freq = vibrato(frequencies[voice_place]);
536 freq = frequencies[voice_place];
539 freq = frequencies[voice_place];
543 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
544 frequency = frequency * pow(2, 440/frequency/12/2);
545 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
546 frequency = frequency * pow(2, -440/frequency/12/2);
548 frequency = frequencies[voices - 1];
551 frequency = frequencies[voices - 1];
554 #ifdef VIBRATO_ENABLE
555 if (vibrato_strength > 0) {
556 freq = vibrato(frequency);
565 if (envelope_index < 65535) {
569 freq = voice_envelope(freq);
571 if (freq < 30.517578125) {
575 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
576 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
581 if (note_frequency > 0) {
582 #ifdef VIBRATO_ENABLE
583 if (vibrato_strength > 0) {
584 freq = vibrato(note_frequency);
586 freq = note_frequency;
589 freq = note_frequency;
592 if (envelope_index < 65535) {
595 freq = voice_envelope(freq);
597 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
598 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
601 TIMER_1_DUTY_CYCLE = 0;
605 bool end_of_note = false;
606 if (TIMER_1_PERIOD > 0) {
608 end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1));
610 end_of_note = (note_position >= (note_length));
612 end_of_note = (note_position >= (note_length));
617 if (current_note >= notes_count) {
621 DISABLE_AUDIO_COUNTER_1_ISR;
622 DISABLE_AUDIO_COUNTER_1_OUTPUT;
623 playing_notes = false;
630 if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
634 note_frequency = (*notes_pointer)[current_note][0];
638 note_resting = false;
640 note_frequency = (*notes_pointer)[current_note][0];
641 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
648 if (!audio_config.enable) {
649 playing_notes = false;
650 playing_note = false;
656 void play_note(float freq, int vol) {
658 dprintf("audio play note freq=%d vol=%d", (int)freq, vol);
660 if (!audio_initialized) {
664 if (audio_config.enable && voices < 8) {
666 DISABLE_AUDIO_COUNTER_3_ISR;
669 DISABLE_AUDIO_COUNTER_1_ISR;
672 // Cancel notes if notes are playing
681 frequencies[voices] = freq;
682 volumes[voices] = vol;
687 ENABLE_AUDIO_COUNTER_3_ISR;
688 ENABLE_AUDIO_COUNTER_3_OUTPUT;
693 ENABLE_AUDIO_COUNTER_1_ISR;
694 ENABLE_AUDIO_COUNTER_1_OUTPUT;
697 ENABLE_AUDIO_COUNTER_1_ISR;
698 ENABLE_AUDIO_COUNTER_1_OUTPUT;
705 void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
708 if (!audio_initialized) {
712 if (audio_config.enable) {
715 DISABLE_AUDIO_COUNTER_3_ISR;
718 DISABLE_AUDIO_COUNTER_1_ISR;
721 // Cancel note if a note is playing
725 playing_notes = true;
728 notes_count = n_count;
729 notes_repeat = n_repeat;
734 note_frequency = (*notes_pointer)[current_note][0];
735 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
740 ENABLE_AUDIO_COUNTER_3_ISR;
741 ENABLE_AUDIO_COUNTER_3_OUTPUT;
745 ENABLE_AUDIO_COUNTER_1_ISR;
746 ENABLE_AUDIO_COUNTER_1_OUTPUT;
753 bool is_playing_notes(void) {
754 return playing_notes;
757 bool is_audio_on(void) {
758 return (audio_config.enable != 0);
761 void audio_toggle(void) {
762 audio_config.enable ^= 1;
763 eeconfig_update_audio(audio_config.raw);
764 if (audio_config.enable)
768 void audio_on(void) {
769 audio_config.enable = 1;
770 eeconfig_update_audio(audio_config.raw);
772 PLAY_SONG(audio_on_song);
775 void audio_off(void) {
776 PLAY_SONG(audio_off_song);
779 audio_config.enable = 0;
780 eeconfig_update_audio(audio_config.raw);
783 #ifdef VIBRATO_ENABLE
785 // Vibrato rate functions
787 void set_vibrato_rate(float rate) {
791 void increase_vibrato_rate(float change) {
792 vibrato_rate *= change;
795 void decrease_vibrato_rate(float change) {
796 vibrato_rate /= change;
799 #ifdef VIBRATO_STRENGTH_ENABLE
801 void set_vibrato_strength(float strength) {
802 vibrato_strength = strength;
805 void increase_vibrato_strength(float change) {
806 vibrato_strength *= change;
809 void decrease_vibrato_strength(float change) {
810 vibrato_strength /= change;
813 #endif /* VIBRATO_STRENGTH_ENABLE */
815 #endif /* VIBRATO_ENABLE */
817 // Polyphony functions
819 void set_polyphony_rate(float rate) {
820 polyphony_rate = rate;
823 void enable_polyphony() {
827 void disable_polyphony() {
831 void increase_polyphony_rate(float change) {
832 polyphony_rate *= change;
835 void decrease_polyphony_rate(float change) {
836 polyphony_rate /= change;
841 void set_timbre(float timbre) {
842 note_timbre = timbre;
847 void set_tempo(uint8_t tempo) {
851 void decrease_tempo(uint8_t tempo_change) {
852 note_tempo += tempo_change;
855 void increase_tempo(uint8_t tempo_change) {
856 if (note_tempo - tempo_change < 10) {
859 note_tempo -= tempo_change;