@ -35,44 +35,81 @@
/ / Timer Abstractions
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/ / TIMSK3 - Timer / Counter # 3 Interrupt Mask Register
/ / Turn on / off 3 A interputs , stopping / enabling the ISR calls
# ifdef C6_AUDIO
/ / Currently we support timers 1 and 3 used at the sime time , channels A - C ,
/ / pins PB5 , PB6 , PB7 , PC4 , PC5 , and PC6
# if defined(C6_AUDIO)
# define CPIN_AUDIO
# define CPIN_SET_DIRECTION DDRC |= _BV(PORTC6);
# define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
# define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A)
# define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A)
# endif
# ifdef B5_AUDIO
# define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A)
# define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A)
# endif
/ / TCCR3A : Timer / Counter # 3 Control Register
/ / Compare Output Mode ( COM3An ) = 0 b00 = Normal port operation , OC3A disconnected from PC6
# ifdef C6_AUDIO
# define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1);
# define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0));
# define TIMER_3_PERIOD ICR3
# define TIMER_3_DUTY_CYCLE OCR3A
# define TIMER3_AUDIO_vect TIMER3_COMPA_vect
# endif
# ifdef B5_AUDIO
# define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1);
# define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0));
# if defined(C5_AUDIO)
# define CPIN_AUDIO
# define CPIN_SET_DIRECTION DDRC |= _BV(PORTC5);
# define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3B1) | (0 << COM3B0) | (1 << WGM31) | (0 << WGM30);
# define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3B)
# define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3B)
# define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3B1);
# define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3B1) | _BV(COM3B0));
# define TIMER_3_PERIOD ICR3
# define TIMER_3_DUTY_CYCLE OCR3B
# define TIMER3_AUDIO_vect TIMER3_COMPB_vect
# endif
/ / Fast PWM Mode Controls
# ifdef C6_AUDIO
# if defined(C4_AUDIO)
# define CPIN_AUDIO
# define CPIN_SET_DIRECTION DDRC |= _BV(PORTC4);
# define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3C1) | (0 << COM3C0) | (1 << WGM31) | (0 << WGM30);
# define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3C)
# define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3C)
# define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3C1);
# define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3C1) | _BV(COM3C0));
# define TIMER_3_PERIOD ICR3
# define TIMER_3_DUTY_CYCLE OCR3A
# define TIMER_3_DUTY_CYCLE OCR3C
# define TIMER3_AUDIO_vect TIMER3_COMPC_vect
# endif
# ifdef B5_AUDIO
# if defined(B5_AUDIO)
# define BPIN_AUDIO
# define BPIN_SET_DIRECTION DDRC |= _BV(PORTB5);
# define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
# define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A)
# define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A)
# define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1);
# define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0));
# define TIMER_1_PERIOD ICR1
# define TIMER_1_DUTY_CYCLE OCR1A
# define TIMER1_AUDIO_vect TIMER1_COMPA_vect
# endif
# if defined(B6_AUDIO)
# define BPIN_AUDIO
# define BPIN_SET_DIRECTION DDRC |= _BV(PORTB6);
# define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1B1) | (0 << COM1B0) | (1 << WGM11) | (0 << WGM10);
# define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1B)
# define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1B)
# define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1B1);
# define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1B1) | _BV(COM1B0));
# define TIMER_1_PERIOD ICR1
# define TIMER_1_DUTY_CYCLE OCR1B
# define TIMER1_AUDIO_vect TIMER1_COMPB_vect
# endif
# if defined(B7_AUDIO)
# define BPIN_AUDIO
# define BPIN_SET_DIRECTION DDRC |= _BV(PORTB7);
# define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1C1) | (0 << COM1C0) | (1 << WGM11) | (0 << WGM10);
# define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1C)
# define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1C)
# define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1C1);
# define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1C1) | _BV(COM1C0));
# define TIMER_1_PERIOD ICR1
# define TIMER_1_DUTY_CYCLE OCR1C
# define TIMER1_AUDIO_vect TIMER1_COMPC_vect
# endif
/ / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -147,47 +184,51 @@ void audio_init()
if ( ! audio_initialized ) {
/ / Set port PC6 ( OC3A and / OC4A ) as output
# ifdef C6_AUDIO
DDRC | = _BV ( PORTC6 ) ;
/ / # else
/ / DDRC | = _BV ( PORTC6 ) ; / / Why is PC6 being set as output low , if C6_audio isn ' t defined ?
/ / PORTC & = ~ _BV ( PORTC6 ) ;
/ / Set audio ports as output
# ifdef CPIN_AUDIO
CPIN_SET_DIRECTION
# endif
# ifdef B5_AUDIO
DDRB | = _BV ( PORTB5 ) ;
/ / # else
/ / DDRB | = _BV ( PORTB5 ) ; / / Same as with PC6
/ / PORTB & = ~ _BV ( PORTB5 ) ;
# ifdef BPIN_AUDIO
BPIN_SET_DIRECTION
# endif
# ifdef C6 _AUDIO
# ifdef CPIN_AUDIO
DISABLE_AUDIO_COUNTER_3_ISR ;
# endif
# ifdef B5_AUDIO
# ifdef BPIN_AUDIO
DISABLE_AUDIO_COUNTER_1_ISR ;
# endif
/ / TCCR3A / TCCR3B : Timer / Counter # 3 Control Registers
/ / Compare Output Mode ( COM3An ) = 0 b00 = Normal port operation , OC3A disconnected from PC6
/ / Waveform Generation Mode ( WGM3n ) = 0 b1110 = Fast PWM Mode 14 ( Period = ICR3 , Duty Cycle = OCR3A )
/ / Clock Select ( CS3n ) = 0 b010 = Clock / 8
/ / TCCR3A / TCCR3B : Timer / Counter # 3 Control Registers TCCR3A / TCCR3B , TCCR1A / TCCR1B
/ / Compare Output Mode ( COM3An and COM1An ) = 0 b00 = Normal port operation
/ / OC3A - - PC6
/ / OC3B - - PC5
/ / OC3C - - PC4
/ / OC1A - - PB5
/ / OC1B - - PB6
/ / OC1C - - PB7
/ / Waveform Generation Mode ( WGM3n ) = 0 b1110 = Fast PWM Mode 14. Period = ICR3 , Duty Cycle OCR3A )
/ / OCR3A - PC6
/ / OCR3B - PC5
/ / OCR3C - PC4
/ / OCR1A - PB5
/ / OCR1B - PB6
/ / OCR1C - PB7
# ifdef C6_AUDIO
TCCR3A = ( 0 < < COM3A1 ) | ( 0 < < COM3A0 ) | ( 1 < < WGM31 ) | ( 0 < < WGM30 ) ;
/ / Clock Select ( CS3n ) = 0 b010 = Clock / 8
# ifdef CPIN_AUDIO
INIT_AUDIO_COUNTER_3
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 ) ;
# endif
# ifdef B5_AUDIO
TCCR1A = ( 0 < < COM1A1 ) | ( 0 < < COM1A0 ) | ( 1 < < WGM11 ) | ( 0 < < WGM10 ) ;
# ifdef BPIN_AUDIO
INIT_AUDIO_COUNTER_1
TCCR1B = ( 1 < < WGM13 ) | ( 1 < < WGM12 ) | ( 0 < < CS12 ) | ( 1 < < CS11 ) | ( 0 < < CS10 ) ;
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 ) ;
# endif
# endif
audio_initialized = true ;
}
@ -207,13 +248,12 @@ void stop_all_notes()
}
voices = 0 ;
# ifdef C6_AUDIO
# ifdef CPIN_AUDIO
DISABLE_AUDIO_COUNTER_3_ISR ;
DISABLE_AUDIO_COUNTER_3_OUTPUT ;
# endif
# ifdef B5 _AUDIO
# ifdef BPIN _AUDIO
DISABLE_AUDIO_COUNTER_1_ISR ;
DISABLE_AUDIO_COUNTER_1_OUTPUT ;
# endif
@ -259,11 +299,11 @@ void stop_note(float freq)
voice_place = 0 ;
}
if ( voices = = 0 ) {
# ifdef C6 _AUDIO
# ifdef CPIN _AUDIO
DISABLE_AUDIO_COUNTER_3_ISR ;
DISABLE_AUDIO_COUNTER_3_OUTPUT ;
# endif
# ifdef B5 _AUDIO
# ifdef BPIN _AUDIO
DISABLE_AUDIO_COUNTER_1_ISR ;
DISABLE_AUDIO_COUNTER_1_OUTPUT ;
# endif
@ -295,15 +335,15 @@ float vibrato(float average_freq) {
# endif
# ifdef C6 _AUDIO
ISR ( TIMER3_COMP A_vect )
# ifdef CPIN _AUDIO
ISR ( TIMER3_AUDIO _vect )
{
float freq ;
if ( playing_note ) {
if ( voices > 0 ) {
# ifdef B5 _AUDIO
# ifdef BPIN _AUDIO
float freq_alt = 0 ;
if ( voices > 1 ) {
if ( polyphony_rate = = 0 ) {
@ -477,10 +517,10 @@ ISR(TIMER3_COMPA_vect)
}
# endif
# ifdef B5 _AUDIO
ISR ( TIMER1_COMP A_vect )
# ifdef BPIN _AUDIO
ISR ( TIMER1_AUDIO _vect )
{
# if defined(B5_AUDIO) && !defined(C6 _AUDIO)
# if defined(BPIN_AUDIO) && !defined(CPIN _AUDIO)
float freq = 0 ;
if ( playing_note ) {
@ -627,10 +667,10 @@ void play_note(float freq, int vol) {
}
if ( audio_config . enable & & voices < 8 ) {
# ifdef C6 _AUDIO
# ifdef CPIN _AUDIO
DISABLE_AUDIO_COUNTER_3_ISR ;
# endif
# ifdef B5 _AUDIO
# ifdef BPIN _AUDIO
DISABLE_AUDIO_COUNTER_1_ISR ;
# endif
@ -648,12 +688,12 @@ void play_note(float freq, int vol) {
voices + + ;
}
# ifdef C6 _AUDIO
# ifdef CPIN _AUDIO
ENABLE_AUDIO_COUNTER_3_ISR ;
ENABLE_AUDIO_COUNTER_3_OUTPUT ;
# endif
# ifdef B5 _AUDIO
# ifdef C6 _AUDIO
# ifdef BPIN _AUDIO
# ifdef CPIN _AUDIO
if ( voices > 1 ) {
ENABLE_AUDIO_COUNTER_1_ISR ;
ENABLE_AUDIO_COUNTER_1_OUTPUT ;
@ -676,10 +716,10 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
if ( audio_config . enable ) {
# ifdef C6 _AUDIO
# ifdef CPIN _AUDIO
DISABLE_AUDIO_COUNTER_3_ISR ;
# endif
# ifdef B5 _AUDIO
# ifdef BPIN _AUDIO
DISABLE_AUDIO_COUNTER_1_ISR ;
# endif
@ -701,12 +741,12 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
note_position = 0 ;
# ifdef C6 _AUDIO
# ifdef CPIN _AUDIO
ENABLE_AUDIO_COUNTER_3_ISR ;
ENABLE_AUDIO_COUNTER_3_OUTPUT ;
# endif
# ifdef B5 _AUDIO
# ifndef C6 _AUDIO
# ifdef BPIN _AUDIO
# ifndef CPIN _AUDIO
ENABLE_AUDIO_COUNTER_1_ISR ;
ENABLE_AUDIO_COUNTER_1_OUTPUT ;
# endif