|
|
@ -47,6 +47,16 @@
|
|
|
|
#define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A)
|
|
|
|
#define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B6_AUDIO
|
|
|
|
|
|
|
|
#define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1B)
|
|
|
|
|
|
|
|
#define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1B)
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B7_AUDIO
|
|
|
|
|
|
|
|
#define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1C)
|
|
|
|
|
|
|
|
#define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1C)
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// TCCR3A: Timer/Counter #3 Control Register
|
|
|
|
// TCCR3A: Timer/Counter #3 Control Register
|
|
|
|
// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
|
|
|
|
// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
|
|
|
|
|
|
|
|
|
|
|
@ -60,6 +70,16 @@
|
|
|
|
#define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0));
|
|
|
|
#define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0));
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B6_AUDIO
|
|
|
|
|
|
|
|
#define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1B1);
|
|
|
|
|
|
|
|
#define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1B1) | _BV(COM1B0));
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B7_AUDIO
|
|
|
|
|
|
|
|
#define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1C1);
|
|
|
|
|
|
|
|
#define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1C1) | _BV(COM1C0));
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// Fast PWM Mode Controls
|
|
|
|
// Fast PWM Mode Controls
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
#ifdef C6_AUDIO
|
|
|
@ -72,6 +92,16 @@
|
|
|
|
#define TIMER_1_DUTY_CYCLE OCR1A
|
|
|
|
#define TIMER_1_DUTY_CYCLE OCR1A
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B6_AUDIO
|
|
|
|
|
|
|
|
#define TIMER_1_PERIOD ICR1
|
|
|
|
|
|
|
|
#define TIMER_1_DUTY_CYCLE OCR1B
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B7_AUDIO
|
|
|
|
|
|
|
|
#define TIMER_1_PERIOD ICR1
|
|
|
|
|
|
|
|
#define TIMER_1_DUTY_CYCLE OCR1C
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
@ -97,7 +127,7 @@ bool playing_note = false;
|
|
|
|
float note_frequency = 0;
|
|
|
|
float note_frequency = 0;
|
|
|
|
float note_length = 0;
|
|
|
|
float note_length = 0;
|
|
|
|
uint8_t note_tempo = TEMPO_DEFAULT;
|
|
|
|
uint8_t note_tempo = TEMPO_DEFAULT;
|
|
|
|
float note_timbre = TIMBRE_DEFAULT;
|
|
|
|
float note_timbre[NUMBER_OF_TIMERS] = {TIMBRE_DEFAULT};
|
|
|
|
uint16_t note_position = 0;
|
|
|
|
uint16_t note_position = 0;
|
|
|
|
float (* notes_pointer)[][2];
|
|
|
|
float (* notes_pointer)[][2];
|
|
|
|
uint16_t notes_count;
|
|
|
|
uint16_t notes_count;
|
|
|
@ -119,8 +149,8 @@ static bool audio_initialized = false;
|
|
|
|
|
|
|
|
|
|
|
|
audio_config_t audio_config;
|
|
|
|
audio_config_t audio_config;
|
|
|
|
|
|
|
|
|
|
|
|
uint16_t envelope_index = 0;
|
|
|
|
uint16_t envelope_index[NUMBER_OF_TIMERS] = {0};
|
|
|
|
bool glissando = true;
|
|
|
|
bool glissando[NUMBER_OF_TIMERS] = {true};
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef STARTUP_SONG
|
|
|
|
#ifndef STARTUP_SONG
|
|
|
|
#define STARTUP_SONG SONG(STARTUP_SOUND)
|
|
|
|
#define STARTUP_SONG SONG(STARTUP_SOUND)
|
|
|
@ -163,11 +193,25 @@ void audio_init()
|
|
|
|
// PORTB &= ~_BV(PORTB5);
|
|
|
|
// PORTB &= ~_BV(PORTB5);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B6_AUDIO
|
|
|
|
|
|
|
|
DDRB |= _BV(PORTB6);
|
|
|
|
|
|
|
|
// #else
|
|
|
|
|
|
|
|
// DDRB |= _BV(PORTB6);
|
|
|
|
|
|
|
|
// PORTB &= ~_BV(PORTB6);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B7_AUDIO
|
|
|
|
|
|
|
|
DDRB |= _BV(PORTB7);
|
|
|
|
|
|
|
|
// #else
|
|
|
|
|
|
|
|
// DDRB |= _BV(PORTB7);
|
|
|
|
|
|
|
|
// PORTB &= ~_BV(PORTB7);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
DISABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B5_AUDIO
|
|
|
|
#ifdef B_AUDIO
|
|
|
|
DISABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
@ -179,14 +223,17 @@ void audio_init()
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
|
|
|
|
TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
|
|
|
|
TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
|
|
|
|
TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));
|
|
|
|
|
|
|
|
TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre[TIMER_3_INDEX]);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B5_AUDIO
|
|
|
|
#ifdef B_AUDIO
|
|
|
|
TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
|
|
|
|
TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
|
|
|
|
TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
|
|
|
|
TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
|
|
|
|
|
|
|
|
|
|
|
|
TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));
|
|
|
|
TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));
|
|
|
|
TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre);
|
|
|
|
TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre[TIMER_1_INDEX]);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
audio_initialized = true;
|
|
|
|
audio_initialized = true;
|
|
|
@ -200,7 +247,7 @@ void audio_init()
|
|
|
|
|
|
|
|
|
|
|
|
void stop_all_notes()
|
|
|
|
void stop_all_notes()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
dprintf("audio stop all notes");
|
|
|
|
dprintf("audio stop all notes\n");
|
|
|
|
|
|
|
|
|
|
|
|
if (!audio_initialized) {
|
|
|
|
if (!audio_initialized) {
|
|
|
|
audio_init();
|
|
|
|
audio_init();
|
|
|
@ -213,7 +260,7 @@ void stop_all_notes()
|
|
|
|
DISABLE_AUDIO_COUNTER_3_OUTPUT;
|
|
|
|
DISABLE_AUDIO_COUNTER_3_OUTPUT;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B5_AUDIO
|
|
|
|
#ifdef B_AUDIO
|
|
|
|
DISABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_1_OUTPUT;
|
|
|
|
DISABLE_AUDIO_COUNTER_1_OUTPUT;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
@ -233,7 +280,7 @@ void stop_all_notes()
|
|
|
|
|
|
|
|
|
|
|
|
void stop_note(float freq)
|
|
|
|
void stop_note(float freq)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
dprintf("audio stop note freq=%d", (int)freq);
|
|
|
|
dprintf("audio stop note freq=%d\n", (int)freq);
|
|
|
|
|
|
|
|
|
|
|
|
if (playing_note) {
|
|
|
|
if (playing_note) {
|
|
|
|
if (!audio_initialized) {
|
|
|
|
if (!audio_initialized) {
|
|
|
@ -258,12 +305,18 @@ void stop_note(float freq)
|
|
|
|
if (voice_place >= voices) {
|
|
|
|
if (voice_place >= voices) {
|
|
|
|
voice_place = 0;
|
|
|
|
voice_place = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (voices == 1) {
|
|
|
|
|
|
|
|
#if defined(C6_AUDIO) && defined(B_AUDIO)
|
|
|
|
|
|
|
|
DISABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
|
|
|
|
DISABLE_AUDIO_COUNTER_1_OUTPUT;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
if (voices == 0) {
|
|
|
|
if (voices == 0) {
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
DISABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_3_OUTPUT;
|
|
|
|
DISABLE_AUDIO_COUNTER_3_OUTPUT;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#ifdef B5_AUDIO
|
|
|
|
#ifdef B_AUDIO
|
|
|
|
DISABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_1_OUTPUT;
|
|
|
|
DISABLE_AUDIO_COUNTER_1_OUTPUT;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
@ -303,11 +356,11 @@ ISR(TIMER3_COMPA_vect)
|
|
|
|
if (playing_note) {
|
|
|
|
if (playing_note) {
|
|
|
|
if (voices > 0) {
|
|
|
|
if (voices > 0) {
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B5_AUDIO
|
|
|
|
#ifdef B_AUDIO
|
|
|
|
float freq_alt = 0;
|
|
|
|
float freq_alt = 0;
|
|
|
|
if (voices > 1) {
|
|
|
|
if (voices > 1) {
|
|
|
|
if (polyphony_rate == 0) {
|
|
|
|
if (polyphony_rate == 0) {
|
|
|
|
if (glissando) {
|
|
|
|
if (glissando[TIMER_1_INDEX] && NUMBER_OF_TIMERS == 1) {
|
|
|
|
if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440/frequencies[voices - 2]/12/2)) {
|
|
|
|
if (frequency_alt != 0 && frequency_alt < frequencies[voices - 2] && frequency_alt < frequencies[voices - 2] * pow(2, -440/frequencies[voices - 2]/12/2)) {
|
|
|
|
frequency_alt = frequency_alt * pow(2, 440/frequency_alt/12/2);
|
|
|
|
frequency_alt = frequency_alt * pow(2, 440/frequency_alt/12/2);
|
|
|
|
} else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440/frequencies[voices - 2]/12/2)) {
|
|
|
|
} else if (frequency_alt != 0 && frequency_alt > frequencies[voices - 2] && frequency_alt > frequencies[voices - 2] * pow(2, 440/frequencies[voices - 2]/12/2)) {
|
|
|
@ -330,18 +383,18 @@ ISR(TIMER3_COMPA_vect)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (envelope_index < 65535) {
|
|
|
|
if (envelope_index[TIMER_1_INDEX] < 65535) {
|
|
|
|
envelope_index++;
|
|
|
|
envelope_index[TIMER_1_INDEX]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
freq_alt = voice_envelope(freq_alt);
|
|
|
|
freq_alt = voice_envelope(freq_alt,TIMER_1_INDEX);
|
|
|
|
|
|
|
|
|
|
|
|
if (freq_alt < 30.517578125) {
|
|
|
|
if (freq_alt < 30.517578125) {
|
|
|
|
freq_alt = 30.52;
|
|
|
|
freq_alt = 30.52;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER));
|
|
|
|
TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq_alt * CPU_PRESCALER));
|
|
|
|
TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre);
|
|
|
|
TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq_alt * CPU_PRESCALER)) * note_timbre[TIMER_1_INDEX]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
@ -364,7 +417,7 @@ ISR(TIMER3_COMPA_vect)
|
|
|
|
freq = frequencies[voice_place];
|
|
|
|
freq = frequencies[voice_place];
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (glissando) {
|
|
|
|
if (glissando[TIMER_3_INDEX] && NUMBER_OF_TIMERS == 1) {
|
|
|
|
if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
|
|
|
|
if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
|
|
|
|
frequency = frequency * pow(2, 440/frequency/12/2);
|
|
|
|
frequency = frequency * pow(2, 440/frequency/12/2);
|
|
|
|
} else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
|
|
|
|
} else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
|
|
|
@ -387,18 +440,18 @@ ISR(TIMER3_COMPA_vect)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (envelope_index < 65535) {
|
|
|
|
if (envelope_index[TIMER_3_INDEX] < 65535) {
|
|
|
|
envelope_index++;
|
|
|
|
envelope_index[TIMER_3_INDEX]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
freq = voice_envelope(freq);
|
|
|
|
freq = voice_envelope(freq, TIMER_3_INDEX);
|
|
|
|
|
|
|
|
|
|
|
|
if (freq < 30.517578125) {
|
|
|
|
if (freq < 30.517578125) {
|
|
|
|
freq = 30.52;
|
|
|
|
freq = 30.52;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
|
|
|
|
TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
|
|
|
|
TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
|
|
|
|
TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre[TIMER_3_INDEX]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -414,13 +467,13 @@ ISR(TIMER3_COMPA_vect)
|
|
|
|
freq = note_frequency;
|
|
|
|
freq = note_frequency;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (envelope_index < 65535) {
|
|
|
|
if (envelope_index[TIMER_3_INDEX] < 65535) {
|
|
|
|
envelope_index++;
|
|
|
|
envelope_index[TIMER_3_INDEX]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
freq = voice_envelope(freq);
|
|
|
|
freq = voice_envelope(freq, TIMER_3_INDEX);
|
|
|
|
|
|
|
|
|
|
|
|
TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
|
|
|
|
TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
|
|
|
|
TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
|
|
|
|
TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre[TIMER_3_INDEX]);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
TIMER_3_PERIOD = 0;
|
|
|
|
TIMER_3_PERIOD = 0;
|
|
|
|
TIMER_3_DUTY_CYCLE = 0;
|
|
|
|
TIMER_3_DUTY_CYCLE = 0;
|
|
|
@ -461,7 +514,7 @@ ISR(TIMER3_COMPA_vect)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
note_resting = false;
|
|
|
|
note_resting = false;
|
|
|
|
envelope_index = 0;
|
|
|
|
envelope_index[TIMER_3_INDEX] = 0;
|
|
|
|
note_frequency = (*notes_pointer)[current_note][0];
|
|
|
|
note_frequency = (*notes_pointer)[current_note][0];
|
|
|
|
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
|
|
|
|
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -477,10 +530,16 @@ ISR(TIMER3_COMPA_vect)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B_AUDIO
|
|
|
|
#ifdef B5_AUDIO
|
|
|
|
#ifdef B5_AUDIO
|
|
|
|
ISR(TIMER1_COMPA_vect)
|
|
|
|
ISR(TIMER1_COMPA_vect)
|
|
|
|
|
|
|
|
#elif defined(B6_AUDIO)
|
|
|
|
|
|
|
|
ISR(TIMER1_COMPB_vect)
|
|
|
|
|
|
|
|
#elif defined(B7_AUDIO)
|
|
|
|
|
|
|
|
ISR(TIMER1_COMPC_vect)
|
|
|
|
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
{
|
|
|
|
#if defined(B5_AUDIO) && !defined(C6_AUDIO)
|
|
|
|
#if defined(B_AUDIO) && !defined(C6_AUDIO)
|
|
|
|
float freq = 0;
|
|
|
|
float freq = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (playing_note) {
|
|
|
|
if (playing_note) {
|
|
|
@ -504,7 +563,7 @@ ISR(TIMER1_COMPA_vect)
|
|
|
|
freq = frequencies[voice_place];
|
|
|
|
freq = frequencies[voice_place];
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (glissando) {
|
|
|
|
if (glissando[TIMER_1_INDEX] && NUMBER_OF_TIMERS == 1) {
|
|
|
|
if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
|
|
|
|
if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
|
|
|
|
frequency = frequency * pow(2, 440/frequency/12/2);
|
|
|
|
frequency = frequency * pow(2, 440/frequency/12/2);
|
|
|
|
} else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
|
|
|
|
} else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
|
|
|
@ -527,18 +586,18 @@ ISR(TIMER1_COMPA_vect)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (envelope_index < 65535) {
|
|
|
|
if (envelope_index[TIMER_1_INDEX] < 65535) {
|
|
|
|
envelope_index++;
|
|
|
|
envelope_index[TIMER_1_INDEX]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
freq = voice_envelope(freq);
|
|
|
|
freq = voice_envelope(freq, TIMER_1_INDEX);
|
|
|
|
|
|
|
|
|
|
|
|
if (freq < 30.517578125) {
|
|
|
|
if (freq < 30.517578125) {
|
|
|
|
freq = 30.52;
|
|
|
|
freq = 30.52;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
|
|
|
|
TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
|
|
|
|
TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
|
|
|
|
TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre[TIMER_1_INDEX]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -554,13 +613,13 @@ ISR(TIMER1_COMPA_vect)
|
|
|
|
freq = note_frequency;
|
|
|
|
freq = note_frequency;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (envelope_index < 65535) {
|
|
|
|
if (envelope_index[TIMER_1_INDEX] < 65535) {
|
|
|
|
envelope_index++;
|
|
|
|
envelope_index[TIMER_1_INDEX]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
freq = voice_envelope(freq);
|
|
|
|
freq = voice_envelope(freq, TIMER_1_INDEX);
|
|
|
|
|
|
|
|
|
|
|
|
TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
|
|
|
|
TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
|
|
|
|
TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
|
|
|
|
TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre[TIMER_1_INDEX]);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
TIMER_1_PERIOD = 0;
|
|
|
|
TIMER_1_PERIOD = 0;
|
|
|
|
TIMER_1_DUTY_CYCLE = 0;
|
|
|
|
TIMER_1_DUTY_CYCLE = 0;
|
|
|
@ -601,7 +660,7 @@ ISR(TIMER1_COMPA_vect)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
note_resting = false;
|
|
|
|
note_resting = false;
|
|
|
|
envelope_index = 0;
|
|
|
|
envelope_index[TIMER_1_INDEX] = 0;
|
|
|
|
note_frequency = (*notes_pointer)[current_note][0];
|
|
|
|
note_frequency = (*notes_pointer)[current_note][0];
|
|
|
|
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
|
|
|
|
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -620,7 +679,7 @@ ISR(TIMER1_COMPA_vect)
|
|
|
|
|
|
|
|
|
|
|
|
void play_note(float freq, int vol) {
|
|
|
|
void play_note(float freq, int vol) {
|
|
|
|
|
|
|
|
|
|
|
|
dprintf("audio play note freq=%d vol=%d", (int)freq, vol);
|
|
|
|
dprintf("audio play note freq=%d vol=%d\n", (int)freq, vol);
|
|
|
|
|
|
|
|
|
|
|
|
if (!audio_initialized) {
|
|
|
|
if (!audio_initialized) {
|
|
|
|
audio_init();
|
|
|
|
audio_init();
|
|
|
@ -630,7 +689,7 @@ void play_note(float freq, int vol) {
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
DISABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#ifdef B5_AUDIO
|
|
|
|
#ifdef B_AUDIO
|
|
|
|
DISABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
@ -640,7 +699,6 @@ void play_note(float freq, int vol) {
|
|
|
|
|
|
|
|
|
|
|
|
playing_note = true;
|
|
|
|
playing_note = true;
|
|
|
|
|
|
|
|
|
|
|
|
envelope_index = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (freq > 0) {
|
|
|
|
if (freq > 0) {
|
|
|
|
frequencies[voices] = freq;
|
|
|
|
frequencies[voices] = freq;
|
|
|
@ -652,16 +710,23 @@ void play_note(float freq, int vol) {
|
|
|
|
ENABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
ENABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
ENABLE_AUDIO_COUNTER_3_OUTPUT;
|
|
|
|
ENABLE_AUDIO_COUNTER_3_OUTPUT;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#ifdef B5_AUDIO
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef B_AUDIO
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
if (voices > 1) {
|
|
|
|
if (voices > 1) {
|
|
|
|
|
|
|
|
envelope_index[TIMER_3_INDEX] = 0;
|
|
|
|
ENABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
ENABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
ENABLE_AUDIO_COUNTER_1_OUTPUT;
|
|
|
|
ENABLE_AUDIO_COUNTER_1_OUTPUT;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
envelope_index[TIMER_3_INDEX] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
|
|
|
|
envelope_index[TIMER_1_INDEX] = 0;
|
|
|
|
ENABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
ENABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
ENABLE_AUDIO_COUNTER_1_OUTPUT;
|
|
|
|
ENABLE_AUDIO_COUNTER_1_OUTPUT;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
envelope_index[TIMER_3_INDEX] = 0;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -679,7 +744,7 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
#ifdef C6_AUDIO
|
|
|
|
DISABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#ifdef B5_AUDIO
|
|
|
|
#ifdef B_AUDIO
|
|
|
|
DISABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
DISABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
@ -705,7 +770,7 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
|
|
|
|
ENABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
ENABLE_AUDIO_COUNTER_3_ISR;
|
|
|
|
ENABLE_AUDIO_COUNTER_3_OUTPUT;
|
|
|
|
ENABLE_AUDIO_COUNTER_3_OUTPUT;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#ifdef B5_AUDIO
|
|
|
|
#ifdef B_AUDIO
|
|
|
|
#ifndef C6_AUDIO
|
|
|
|
#ifndef C6_AUDIO
|
|
|
|
ENABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
ENABLE_AUDIO_COUNTER_1_ISR;
|
|
|
|
ENABLE_AUDIO_COUNTER_1_OUTPUT;
|
|
|
|
ENABLE_AUDIO_COUNTER_1_OUTPUT;
|
|
|
@ -803,8 +868,8 @@ void decrease_polyphony_rate(float change) {
|
|
|
|
|
|
|
|
|
|
|
|
// Timbre function
|
|
|
|
// Timbre function
|
|
|
|
|
|
|
|
|
|
|
|
void set_timbre(float timbre) {
|
|
|
|
void set_timbre(float timbre, uint8_t timer_index) {
|
|
|
|
note_timbre = timbre;
|
|
|
|
note_timbre[timer_index] = timbre;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Tempo functions
|
|
|
|
// Tempo functions
|
|
|
|