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/>.
20 #include <avr/pgmspace.h>
21 #include <avr/interrupt.h>
30 #define CPU_PRESCALER 8
32 // -----------------------------------------------------------------------------
34 // -----------------------------------------------------------------------------
36 // TIMSK3 - Timer/Counter #3 Interrupt Mask Register
37 // Turn on/off 3A interputs, stopping/enabling the ISR calls
39 #define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A)
40 #define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A)
44 #define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A)
45 #define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A)
48 // TCCR3A: Timer/Counter #3 Control Register
49 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
52 #define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1);
53 #define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0));
57 #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1);
58 #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0));
61 // Fast PWM Mode Controls
64 #define TIMER_3_PERIOD ICR3
65 #define TIMER_3_DUTY_CYCLE OCR3A
69 #define TIMER_1_PERIOD ICR1
70 #define TIMER_1_DUTY_CYCLE OCR1A
74 // -----------------------------------------------------------------------------
80 float frequency_alt = 0;
84 float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
85 int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
91 uint16_t sample_length = 0;
93 bool playing_notes = false;
94 bool playing_note = false;
95 float note_frequency = 0;
96 float note_length = 0;
97 uint8_t note_tempo = TEMPO_DEFAULT;
98 float note_timbre = TIMBRE_DEFAULT;
99 uint16_t note_position = 0;
100 float (* notes_pointer)[][2];
101 uint16_t notes_count;
103 bool note_resting = false;
105 uint8_t current_note = 0;
106 uint8_t rest_counter = 0;
108 #ifdef VIBRATO_ENABLE
109 float vibrato_counter = 0;
110 float vibrato_strength = .5;
111 float vibrato_rate = 0.125;
114 float polyphony_rate = 0;
116 static bool audio_initialized = false;
118 audio_config_t audio_config;
120 uint16_t envelope_index = 0;
121 bool glissando = true;
124 #define STARTUP_SONG SONG(STARTUP_SOUND)
126 #ifndef AUDIO_ON_SONG
127 #define AUDIO_ON_SONG SONG(AUDIO_ON_SOUND)
129 #ifndef AUDIO_OFF_SONG
130 #define AUDIO_OFF_SONG SONG(AUDIO_OFF_SOUND)
132 float startup_song[][2] = STARTUP_SONG;
133 float audio_on_song[][2] = AUDIO_ON_SONG;
134 float audio_off_song[][2] = AUDIO_OFF_SONG;
140 if (!eeconfig_is_enabled())
144 audio_config.raw = eeconfig_read_audio();
146 if (!audio_initialized) {
148 // Set port PC6 (OC3A and /OC4A) as output
154 PORTC &= ~_BV(PORTC6);
161 PORTB &= ~_BV(PORTB5);
165 DISABLE_AUDIO_COUNTER_3_ISR;
169 DISABLE_AUDIO_COUNTER_1_ISR;
172 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
173 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
174 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
175 // Clock Select (CS3n) = 0b010 = Clock / 8
178 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
179 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
183 TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
184 TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
187 audio_initialized = true;
190 if (audio_config.enable) {
191 PLAY_SONG(startup_song);
196 void stop_all_notes()
198 dprintf("audio stop all notes");
200 if (!audio_initialized) {
207 DISABLE_AUDIO_COUNTER_3_ISR;
208 DISABLE_AUDIO_COUNTER_3_OUTPUT;
212 DISABLE_AUDIO_COUNTER_1_ISR;
213 DISABLE_AUDIO_COUNTER_1_OUTPUT;
216 playing_notes = false;
217 playing_note = false;
222 for (uint8_t i = 0; i < 8; i++)
229 void stop_note(float freq)
231 dprintf("audio stop note freq=%d", (int)freq);
234 if (!audio_initialized) {
237 for (int i = 7; i >= 0; i--) {
238 if (frequencies[i] == freq) {
241 for (int j = i; (j < 7); j++) {
242 frequencies[j] = frequencies[j+1];
243 frequencies[j+1] = 0;
244 volumes[j] = volumes[j+1];
253 if (voice_place >= voices) {
258 DISABLE_AUDIO_COUNTER_3_ISR;
259 DISABLE_AUDIO_COUNTER_3_OUTPUT;
262 DISABLE_AUDIO_COUNTER_1_ISR;
263 DISABLE_AUDIO_COUNTER_1_OUTPUT;
268 playing_note = false;
273 #ifdef VIBRATO_ENABLE
275 float mod(float a, int b)
277 float r = fmod(a, b);
278 return r < 0 ? r + b : r;
281 float vibrato(float average_freq) {
282 #ifdef VIBRATO_STRENGTH_ENABLE
283 float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength);
285 float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter];
287 vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH);
288 return vibrated_freq;
294 ISR(TIMER3_COMPA_vect)
304 if (polyphony_rate == 0) {
306 if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440/frequencies[voices - 2]/12/2)) {
307 frequency_alt = frequency_alt * pow(2, 440/frequency_alt/12/2);
308 } else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440/frequencies[voices - 2]/12/2)) {
309 frequency_alt = frequency_alt * pow(2, -440/frequency_alt/12/2);
311 frequency_alt = frequencies[voices - 2];
314 frequency_alt = frequencies[voices - 2];
317 #ifdef VIBRATO_ENABLE
318 if (vibrato_strength > 0) {
319 freq_alt = vibrato(frequency_alt);
321 freq_alt = frequency_alt;
324 freq_alt = frequency_alt;
328 if (envelope_index < 65535) {
332 freq_alt = voice_envelope(freq_alt);
334 if (freq_alt < 30.517578125) {
338 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER));
339 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre);
343 if (polyphony_rate > 0) {
345 voice_place %= voices;
346 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
347 voice_place = (voice_place + 1) % voices;
352 #ifdef VIBRATO_ENABLE
353 if (vibrato_strength > 0) {
354 freq = vibrato(frequencies[voice_place]);
356 freq = frequencies[voice_place];
359 freq = frequencies[voice_place];
363 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
364 frequency = frequency * pow(2, 440/frequency/12/2);
365 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
366 frequency = frequency * pow(2, -440/frequency/12/2);
368 frequency = frequencies[voices - 1];
371 frequency = frequencies[voices - 1];
374 #ifdef VIBRATO_ENABLE
375 if (vibrato_strength > 0) {
376 freq = vibrato(frequency);
385 if (envelope_index < 65535) {
389 freq = voice_envelope(freq);
391 if (freq < 30.517578125) {
395 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
396 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
401 if (note_frequency > 0) {
402 #ifdef VIBRATO_ENABLE
403 if (vibrato_strength > 0) {
404 freq = vibrato(note_frequency);
406 freq = note_frequency;
409 freq = note_frequency;
412 if (envelope_index < 65535) {
415 freq = voice_envelope(freq);
417 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
418 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
421 TIMER_3_DUTY_CYCLE = 0;
425 bool end_of_note = false;
426 if (TIMER_3_PERIOD > 0) {
428 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1));
430 end_of_note = (note_position >= (note_length));
432 end_of_note = (note_position >= (note_length));
437 if (current_note >= notes_count) {
441 DISABLE_AUDIO_COUNTER_3_ISR;
442 DISABLE_AUDIO_COUNTER_3_OUTPUT;
443 playing_notes = false;
450 if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
454 note_frequency = (*notes_pointer)[current_note][0];
458 note_resting = false;
460 note_frequency = (*notes_pointer)[current_note][0];
461 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
468 if (!audio_config.enable) {
469 playing_notes = false;
470 playing_note = false;
476 ISR(TIMER1_COMPA_vect)
478 #if defined(B5_AUDIO) && !defined(C6_AUDIO)
483 if (polyphony_rate > 0) {
485 voice_place %= voices;
486 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
487 voice_place = (voice_place + 1) % voices;
492 #ifdef VIBRATO_ENABLE
493 if (vibrato_strength > 0) {
494 freq = vibrato(frequencies[voice_place]);
496 freq = frequencies[voice_place];
499 freq = frequencies[voice_place];
503 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
504 frequency = frequency * pow(2, 440/frequency/12/2);
505 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
506 frequency = frequency * pow(2, -440/frequency/12/2);
508 frequency = frequencies[voices - 1];
511 frequency = frequencies[voices - 1];
514 #ifdef VIBRATO_ENABLE
515 if (vibrato_strength > 0) {
516 freq = vibrato(frequency);
525 if (envelope_index < 65535) {
529 freq = voice_envelope(freq);
531 if (freq < 30.517578125) {
535 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
536 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
541 if (note_frequency > 0) {
542 #ifdef VIBRATO_ENABLE
543 if (vibrato_strength > 0) {
544 freq = vibrato(note_frequency);
546 freq = note_frequency;
549 freq = note_frequency;
552 if (envelope_index < 65535) {
555 freq = voice_envelope(freq);
557 TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
558 TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
561 TIMER_1_DUTY_CYCLE = 0;
565 bool end_of_note = false;
566 if (TIMER_1_PERIOD > 0) {
568 end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1));
570 end_of_note = (note_position >= (note_length));
572 end_of_note = (note_position >= (note_length));
577 if (current_note >= notes_count) {
581 DISABLE_AUDIO_COUNTER_1_ISR;
582 DISABLE_AUDIO_COUNTER_1_OUTPUT;
583 playing_notes = false;
590 if ((*notes_pointer)[current_note][0] == (*notes_pointer)[current_note + 1][0]) {
594 note_frequency = (*notes_pointer)[current_note][0];
598 note_resting = false;
600 note_frequency = (*notes_pointer)[current_note][0];
601 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
608 if (!audio_config.enable) {
609 playing_notes = false;
610 playing_note = false;
616 void play_note(float freq, int vol) {
618 dprintf("audio play note freq=%d vol=%d", (int)freq, vol);
620 if (!audio_initialized) {
624 if (audio_config.enable && voices < 8) {
626 DISABLE_AUDIO_COUNTER_3_ISR;
629 DISABLE_AUDIO_COUNTER_1_ISR;
632 // Cancel notes if notes are playing
641 frequencies[voices] = freq;
642 volumes[voices] = vol;
647 ENABLE_AUDIO_COUNTER_3_ISR;
648 ENABLE_AUDIO_COUNTER_3_OUTPUT;
653 ENABLE_AUDIO_COUNTER_1_ISR;
654 ENABLE_AUDIO_COUNTER_1_OUTPUT;
657 ENABLE_AUDIO_COUNTER_1_ISR;
658 ENABLE_AUDIO_COUNTER_1_OUTPUT;
665 void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
668 if (!audio_initialized) {
672 if (audio_config.enable) {
675 DISABLE_AUDIO_COUNTER_3_ISR;
678 DISABLE_AUDIO_COUNTER_1_ISR;
681 // Cancel note if a note is playing
685 playing_notes = true;
688 notes_count = n_count;
689 notes_repeat = n_repeat;
694 note_frequency = (*notes_pointer)[current_note][0];
695 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
700 ENABLE_AUDIO_COUNTER_3_ISR;
701 ENABLE_AUDIO_COUNTER_3_OUTPUT;
705 ENABLE_AUDIO_COUNTER_1_ISR;
706 ENABLE_AUDIO_COUNTER_1_OUTPUT;
713 bool is_playing_notes(void) {
714 return playing_notes;
717 bool is_audio_on(void) {
718 return (audio_config.enable != 0);
721 void audio_toggle(void) {
722 audio_config.enable ^= 1;
723 eeconfig_update_audio(audio_config.raw);
724 if (audio_config.enable)
728 void audio_on(void) {
729 audio_config.enable = 1;
730 eeconfig_update_audio(audio_config.raw);
732 PLAY_SONG(audio_on_song);
735 void audio_off(void) {
736 PLAY_SONG(audio_off_song);
739 audio_config.enable = 0;
740 eeconfig_update_audio(audio_config.raw);
743 #ifdef VIBRATO_ENABLE
745 // Vibrato rate functions
747 void set_vibrato_rate(float rate) {
751 void increase_vibrato_rate(float change) {
752 vibrato_rate *= change;
755 void decrease_vibrato_rate(float change) {
756 vibrato_rate /= change;
759 #ifdef VIBRATO_STRENGTH_ENABLE
761 void set_vibrato_strength(float strength) {
762 vibrato_strength = strength;
765 void increase_vibrato_strength(float change) {
766 vibrato_strength *= change;
769 void decrease_vibrato_strength(float change) {
770 vibrato_strength /= change;
773 #endif /* VIBRATO_STRENGTH_ENABLE */
775 #endif /* VIBRATO_ENABLE */
777 // Polyphony functions
779 void set_polyphony_rate(float rate) {
780 polyphony_rate = rate;
783 void enable_polyphony() {
787 void disable_polyphony() {
791 void increase_polyphony_rate(float change) {
792 polyphony_rate *= change;
795 void decrease_polyphony_rate(float change) {
796 polyphony_rate /= change;
801 void set_timbre(float timbre) {
802 note_timbre = timbre;
807 void set_tempo(uint8_t tempo) {
811 void decrease_tempo(uint8_t tempo_change) {
812 note_tempo += tempo_change;
815 void increase_tempo(uint8_t tempo_change) {
816 if (note_tempo - tempo_change < 10) {
819 note_tempo -= tempo_change;