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 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
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
101 #if defined(B7_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
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
196 DISABLE_AUDIO_COUNTER_3_ISR;
199 DISABLE_AUDIO_COUNTER_1_ISR;
202 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers TCCR3A/TCCR3B, TCCR1A/TCCR1B
203 // Compare Output Mode (COM3An and COM1An) = 0b00 = Normal port operation
211 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14. Period = ICR3, Duty Cycle OCR3A)
219 // Clock Select (CS3n) = 0b010 = Clock / 8
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);
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);
233 audio_initialized = true;
236 if (audio_config.enable) {
237 PLAY_SONG(startup_song);
242 void stop_all_notes()
244 dprintf("audio stop all notes");
246 if (!audio_initialized) {
252 DISABLE_AUDIO_COUNTER_3_ISR;
253 DISABLE_AUDIO_COUNTER_3_OUTPUT;
257 DISABLE_AUDIO_COUNTER_1_ISR;
258 DISABLE_AUDIO_COUNTER_1_OUTPUT;
261 playing_notes = false;
262 playing_note = false;
267 for (uint8_t i = 0; i < 8; i++)
274 void stop_note(float freq)
276 dprintf("audio stop note freq=%d", (int)freq);
279 if (!audio_initialized) {
282 for (int i = 7; i >= 0; i--) {
283 if (frequencies[i] == freq) {
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];
298 if (voice_place >= voices) {
303 DISABLE_AUDIO_COUNTER_3_ISR;
304 DISABLE_AUDIO_COUNTER_3_OUTPUT;
307 DISABLE_AUDIO_COUNTER_1_ISR;
308 DISABLE_AUDIO_COUNTER_1_OUTPUT;
313 playing_note = false;
318 #ifdef VIBRATO_ENABLE
320 float mod(float a, int b)
322 float r = fmod(a, b);
323 return r < 0 ? r + b : r;
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);
330 float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter];
332 vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH);
333 return vibrated_freq;
339 ISR(TIMER3_AUDIO_vect)
349 if (polyphony_rate == 0) {
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);
356 frequency_alt = frequencies[voices - 2];
359 frequency_alt = frequencies[voices - 2];
362 #ifdef VIBRATO_ENABLE
363 if (vibrato_strength > 0) {
364 freq_alt = vibrato(frequency_alt);
366 freq_alt = frequency_alt;
369 freq_alt = frequency_alt;
373 if (envelope_index < 65535) {
377 freq_alt = voice_envelope(freq_alt);
379 if (freq_alt < 30.517578125) {
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);
388 if (polyphony_rate > 0) {
390 voice_place %= voices;
391 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
392 voice_place = (voice_place + 1) % voices;
397 #ifdef VIBRATO_ENABLE
398 if (vibrato_strength > 0) {
399 freq = vibrato(frequencies[voice_place]);
401 freq = frequencies[voice_place];
404 freq = frequencies[voice_place];
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);
413 frequency = frequencies[voices - 1];
416 frequency = frequencies[voices - 1];
419 #ifdef VIBRATO_ENABLE
420 if (vibrato_strength > 0) {
421 freq = vibrato(frequency);
430 if (envelope_index < 65535) {
434 freq = voice_envelope(freq);
436 if (freq < 30.517578125) {
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);
446 if (note_frequency > 0) {
447 #ifdef VIBRATO_ENABLE
448 if (vibrato_strength > 0) {
449 freq = vibrato(note_frequency);
451 freq = note_frequency;
454 freq = note_frequency;
457 if (envelope_index < 65535) {
460 freq = voice_envelope(freq);
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);
466 TIMER_3_DUTY_CYCLE = 0;
470 bool end_of_note = false;
471 if (TIMER_3_PERIOD > 0) {
473 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1));
475 end_of_note = (note_position >= (note_length));
477 end_of_note = (note_position >= (note_length));
482 if (current_note >= notes_count) {
486 DISABLE_AUDIO_COUNTER_3_ISR;
487 DISABLE_AUDIO_COUNTER_3_OUTPUT;
488 playing_notes = false;
495 if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
499 note_frequency = (*notes_pointer)[current_note][0];
503 note_resting = false;
505 note_frequency = (*notes_pointer)[current_note][0];
506 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
513 if (!audio_config.enable) {
514 playing_notes = false;
515 playing_note = false;
521 ISR(TIMER1_AUDIO_vect)
523 #if defined(BPIN_AUDIO) && !defined(CPIN_AUDIO)
528 if (polyphony_rate > 0) {
530 voice_place %= voices;
531 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
532 voice_place = (voice_place + 1) % voices;
537 #ifdef VIBRATO_ENABLE
538 if (vibrato_strength > 0) {
539 freq = vibrato(frequencies[voice_place]);
541 freq = frequencies[voice_place];
544 freq = frequencies[voice_place];
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);
553 frequency = frequencies[voices - 1];
556 frequency = frequencies[voices - 1];
559 #ifdef VIBRATO_ENABLE
560 if (vibrato_strength > 0) {
561 freq = vibrato(frequency);
570 if (envelope_index < 65535) {
574 freq = voice_envelope(freq);
576 if (freq < 30.517578125) {
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);
586 if (note_frequency > 0) {
587 #ifdef VIBRATO_ENABLE
588 if (vibrato_strength > 0) {
589 freq = vibrato(note_frequency);
591 freq = note_frequency;
594 freq = note_frequency;
597 if (envelope_index < 65535) {
600 freq = voice_envelope(freq);
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);
606 TIMER_1_DUTY_CYCLE = 0;
610 bool end_of_note = false;
611 if (TIMER_1_PERIOD > 0) {
613 end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1));
615 end_of_note = (note_position >= (note_length));
617 end_of_note = (note_position >= (note_length));
622 if (current_note >= notes_count) {
626 DISABLE_AUDIO_COUNTER_1_ISR;
627 DISABLE_AUDIO_COUNTER_1_OUTPUT;
628 playing_notes = false;
635 if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
639 note_frequency = (*notes_pointer)[current_note][0];
643 note_resting = false;
645 note_frequency = (*notes_pointer)[current_note][0];
646 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
653 if (!audio_config.enable) {
654 playing_notes = false;
655 playing_note = false;
661 void play_note(float freq, int vol) {
663 dprintf("audio play note freq=%d vol=%d", (int)freq, vol);
665 if (!audio_initialized) {
669 if (audio_config.enable && voices < 8) {
671 DISABLE_AUDIO_COUNTER_3_ISR;
674 DISABLE_AUDIO_COUNTER_1_ISR;
677 // Cancel notes if notes are playing
686 frequencies[voices] = freq;
687 volumes[voices] = vol;
692 ENABLE_AUDIO_COUNTER_3_ISR;
693 ENABLE_AUDIO_COUNTER_3_OUTPUT;
698 ENABLE_AUDIO_COUNTER_1_ISR;
699 ENABLE_AUDIO_COUNTER_1_OUTPUT;
702 ENABLE_AUDIO_COUNTER_1_ISR;
703 ENABLE_AUDIO_COUNTER_1_OUTPUT;
710 void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
713 if (!audio_initialized) {
717 if (audio_config.enable) {
720 DISABLE_AUDIO_COUNTER_3_ISR;
723 DISABLE_AUDIO_COUNTER_1_ISR;
726 // Cancel note if a note is playing
730 playing_notes = true;
733 notes_count = n_count;
734 notes_repeat = n_repeat;
739 note_frequency = (*notes_pointer)[current_note][0];
740 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
745 ENABLE_AUDIO_COUNTER_3_ISR;
746 ENABLE_AUDIO_COUNTER_3_OUTPUT;
750 ENABLE_AUDIO_COUNTER_1_ISR;
751 ENABLE_AUDIO_COUNTER_1_OUTPUT;
758 bool is_playing_notes(void) {
759 return playing_notes;
762 bool is_audio_on(void) {
763 return (audio_config.enable != 0);
766 void audio_toggle(void) {
767 audio_config.enable ^= 1;
768 eeconfig_update_audio(audio_config.raw);
769 if (audio_config.enable)
773 void audio_on(void) {
774 audio_config.enable = 1;
775 eeconfig_update_audio(audio_config.raw);
777 PLAY_SONG(audio_on_song);
780 void audio_off(void) {
781 PLAY_SONG(audio_off_song);
784 audio_config.enable = 0;
785 eeconfig_update_audio(audio_config.raw);
788 #ifdef VIBRATO_ENABLE
790 // Vibrato rate functions
792 void set_vibrato_rate(float rate) {
796 void increase_vibrato_rate(float change) {
797 vibrato_rate *= change;
800 void decrease_vibrato_rate(float change) {
801 vibrato_rate /= change;
804 #ifdef VIBRATO_STRENGTH_ENABLE
806 void set_vibrato_strength(float strength) {
807 vibrato_strength = strength;
810 void increase_vibrato_strength(float change) {
811 vibrato_strength *= change;
814 void decrease_vibrato_strength(float change) {
815 vibrato_strength /= change;
818 #endif /* VIBRATO_STRENGTH_ENABLE */
820 #endif /* VIBRATO_ENABLE */
822 // Polyphony functions
824 void set_polyphony_rate(float rate) {
825 polyphony_rate = rate;
828 void enable_polyphony() {
832 void disable_polyphony() {
836 void increase_polyphony_rate(float change) {
837 polyphony_rate *= change;
840 void decrease_polyphony_rate(float change) {
841 polyphony_rate /= change;
846 void set_timbre(float timbre) {
847 note_timbre = timbre;
852 void set_tempo(uint8_t tempo) {
856 void decrease_tempo(uint8_t tempo_change) {
857 note_tempo += tempo_change;
860 void increase_tempo(uint8_t tempo_change) {
861 if (note_tempo - tempo_change < 10) {
864 note_tempo -= tempo_change;