18 #include <util/atomic.h> 19 #include "MozziGuts.h" 20 #include "mozzi_config.h" 21 #include "mozzi_analog.h" 22 #include "CircularBuffer.h" 25 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1 26 #include "IntervalTimer.h" 28 #include "TimerZero.h" 30 #include "FrequencyTimer2.h" 34 #if !(F_CPU == 16000000 || F_CPU == 48000000) 35 #warning "Mozzi has been tested with a cpu clock speed of 16MHz on Arduino and 48MHz on Teensy 3! Results may vary with other speeds." 40 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1 71 #if (STEREO_HACK == true) 76 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1 81 static uint8_t pre_mozzi_TCCR0A, pre_mozzi_TCCR0B, pre_mozzi_OCR0A, pre_mozzi_TIMSK0;
82 static uint8_t pre_mozzi_TCCR1A, pre_mozzi_TCCR1B, pre_mozzi_OCR1A, pre_mozzi_TIMSK1;
84 #if (AUDIO_MODE == HIFI) 86 static uint8_t pre_mozzi_TCCR2A, pre_mozzi_TCCR2B, pre_mozzi_OCR2A, pre_mozzi_TIMSK2;
88 static uint8_t pre_mozzi_TCCR2, pre_mozzi_OCR2, pre_mozzi_TIMSK;
90 static uint8_t pre_mozzi_TCCR4A, pre_mozzi_TCCR4B, pre_mozzi_TCCR4C, pre_mozzi_TCCR4D, pre_mozzi_TCCR4E, pre_mozzi_OCR4C, pre_mozzi_TIMSK4;
95 static void backupPreMozziTimer1()
98 pre_mozzi_TCCR1A = TCCR1A;
99 pre_mozzi_TCCR1B = TCCR1B;
100 pre_mozzi_OCR1A = OCR1A;
101 pre_mozzi_TIMSK1 = TIMSK1;
109 static uint8_t mozzi_TCCR0A, mozzi_TCCR0B, mozzi_OCR0A, mozzi_TIMSK0;
110 static uint8_t mozzi_TCCR1A, mozzi_TCCR1B, mozzi_OCR1A, mozzi_TIMSK1;
112 #if (AUDIO_MODE == HIFI) 114 static uint8_t mozzi_TCCR2A, mozzi_TCCR2B, mozzi_OCR2A, mozzi_TIMSK2;
116 static uint8_t mozzi_TCCR2, mozzi_OCR2, mozzi_TIMSK;
117 #elif defined(TCCR4A) 118 static uint8_t mozzi_TCCR4A, mozzi_TCCR4B, mozzi_TCCR4C, mozzi_TCCR4D, mozzi_TCCR4E, mozzi_OCR4C, mozzi_TIMSK4;
123 static void backupMozziTimer1()
126 mozzi_TCCR1A = TCCR1A;
127 mozzi_TCCR1B = TCCR1B;
129 mozzi_TIMSK1 = TIMSK1;
132 #endif // end of timer backups for non-Teensy 3 boards 135 #if (USE_AUDIO_INPUT==true) 140 static boolean audio_input_is_available;
141 static int audio_input;
142 uint8_t adc_count = 0;
151 static void startFirstAudioADC()
153 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1 167 static void startSecondAudioADC()
169 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1 172 ADCSRA |= (1 << ADSC);
178 static void receiveSecondAudioADC()
180 if (!input_buffer.isFull())
181 #
if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO)
182 input_buffer.write(adc->readSingle());
184 input_buffer.write(ADC);
189 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1 192 ISR(ADC_vect, ISR_BLOCK)
198 receiveSecondAudioADC();
199 adcReadSelectedChannels();
205 startSecondControlADC();
210 receiveSecondControlADC();
211 startFirstAudioADC();
223 #endif // end main audio input section 225 #if (STEREO_HACK == true) 226 extern int audio_out_1, audio_out_2;
232 #if (USE_AUDIO_INPUT==true) 233 if (!input_buffer.isEmpty())
234 audio_input = input_buffer.read();
237 if (!output_buffer.isFull()) {
238 #if (STEREO_HACK == true) 240 output_buffer.write((
unsigned int) (audio_out_1 + AUDIO_BIAS));
241 output_buffer2.write((
unsigned int) (audio_out_2 + AUDIO_BIAS));
243 output_buffer.write((
unsigned int) (
updateAudio() + AUDIO_BIAS));
253 #if (AUDIO_MODE == STANDARD) || (AUDIO_MODE == STANDARD_PLUS) 255 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1 258 IntervalTimer timer1;
261 static void teensyAudioOutput()
264 #if (USE_AUDIO_INPUT==true) 266 startSecondAudioADC();
269 analogWrite(AUDIO_CHANNEL_1_PIN, (
int)output_buffer.read());
273 static void startAudioStandard()
277 analogWriteResolution(12);
278 adc->setAveraging(0);
279 adc->setConversionSpeed(ADC_MED_SPEED);
280 timer1.begin(teensyAudioOutput, 1000000UL/
AUDIO_RATE);
288 static void startAudioStandard()
290 backupPreMozziTimer1();
292 pinMode(AUDIO_CHANNEL_1_PIN, OUTPUT);
294 #if (AUDIO_MODE == STANDARD) 295 Timer1.initializeCPUCycles(16000000UL/
AUDIO_RATE, PHASE_FREQ_CORRECT);
296 #else // (AUDIO_MODE == STANDARD_PLUS) 297 Timer1.initializeCPUCycles(16000000UL/PWM_RATE, FAST);
299 Timer1.pwm(AUDIO_CHANNEL_1_PIN, AUDIO_BIAS);
323 ISR(TIMER1_OVF_vect, ISR_BLOCK)
326 #if (AUDIO_MODE == STANDARD_PLUS) && (AUDIO_RATE == 16384) // only update every second ISR, if lower audio rate 327 static boolean alternate;
328 alternate = !alternate;
333 #if (USE_AUDIO_INPUT==true) 335 startSecondAudioADC();
345 AUDIO_CHANNEL_1_OUTPUT_REGISTER = output_buffer.read();
346 #if (STEREO_HACK == true) 347 AUDIO_CHANNEL_2_OUTPUT_REGISTER = output_buffer2.read();
360 #if (AUDIO_MODE == STANDARD_PLUS) && (AUDIO_RATE==16384) // all this conditional compilation is so clutsy! 370 #elif (AUDIO_MODE == HIFI) 372 static void startAudioHiFi()
374 backupPreMozziTimer1();
376 pinMode(AUDIO_CHANNEL_1_highByte_PIN, OUTPUT);
377 pinMode(AUDIO_CHANNEL_1_lowByte_PIN, OUTPUT);
378 Timer1.initializeCPUCycles(16000000UL/125000, FAST);
379 Timer1.pwm(AUDIO_CHANNEL_1_highByte_PIN, 0);
380 Timer1.pwm(AUDIO_CHANNEL_1_lowByte_PIN, 0);
390 static void backupPreMozziTimer2()
394 pre_mozzi_TCCR2A = TCCR2A;
395 pre_mozzi_TCCR2B = TCCR2B;
396 pre_mozzi_OCR2A = OCR2A;
397 pre_mozzi_TIMSK2 = TIMSK2;
399 pre_mozzi_TCCR2 = TCCR2;
400 pre_mozzi_OCR2 = OCR2;
401 pre_mozzi_TIMSK = TIMSK;
402 #elif defined(TCCR4A) 403 pre_mozzi_TCCR4B = TCCR4A;
404 pre_mozzi_TCCR4B = TCCR4B;
405 pre_mozzi_TCCR4B = TCCR4C;
406 pre_mozzi_TCCR4B = TCCR4D;
407 pre_mozzi_TCCR4B = TCCR4E;
408 pre_mozzi_OCR4C = OCR4C;
409 pre_mozzi_TIMSK4 = TIMSK4;
415 static void backupMozziTimer2()
418 mozzi_TCCR2A = TCCR2A;
419 mozzi_TCCR2B = TCCR2B;
421 mozzi_TIMSK2 = TIMSK2;
426 #elif defined(TCCR4A) 427 mozzi_TCCR4B = TCCR4A;
428 mozzi_TCCR4B = TCCR4B;
429 mozzi_TCCR4B = TCCR4C;
430 mozzi_TCCR4B = TCCR4D;
431 mozzi_TCCR4B = TCCR4E;
433 mozzi_TIMSK4 = TIMSK4;
439 static void setupTimer2()
441 backupPreMozziTimer2();
443 period *= FrequencyTimer2::clockCyclesPerMicrosecond();
444 FrequencyTimer2::setPeriod(period);
445 FrequencyTimer2::setOnOverflow(dummy);
446 FrequencyTimer2::enable();
454 #if defined(TIMER2_COMPA_vect) 455 ISR(TIMER2_COMPA_vect)
456 #elif defined(TIMER2_COMP_vect) 457 ISR(TIMER2_COMP_vect)
458 #elif defined(TIMER4_COMPA_vect) 459 ISR(TIMER4_COMPA_vect)
461 #error "This board does not have a hardware timer which is compatible with FrequencyTimer2" 462 void dummy_function(
void)
465 #if (USE_AUDIO_INPUT==true) 467 startSecondAudioADC();
473 unsigned int out = output_buffer.read();
477 unsigned int out_high = out<<1;
478 AUDIO_CHANNEL_1_highByte_REGISTER = out_high >> 8;
480 AUDIO_CHANNEL_1_lowByte_REGISTER = out & 127;
491 static void updateControlWithAutoADC()
509 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1 510 IntervalTimer timer0;
514 static void startControl(
unsigned int control_rate_hz)
516 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1 517 timer0.begin(updateControlWithAutoADC, 1000000/control_rate_hz);
520 pre_mozzi_TCCR0A = TCCR0A;
521 pre_mozzi_TCCR0B = TCCR0B;
522 pre_mozzi_OCR0A = OCR0A;
523 pre_mozzi_TIMSK0 = TIMSK0;
525 TimerZero::init(1000000/control_rate_hz,updateControlWithAutoADC);
529 mozzi_TCCR0A = TCCR0A;
530 mozzi_TCCR0B = TCCR0B;
532 mozzi_TIMSK0 = TIMSK0;
541 startControl(control_rate_hz);
542 #if (AUDIO_MODE == STANDARD) || (AUDIO_MODE == STANDARD_PLUS) 543 startAudioStandard();
544 #elif (AUDIO_MODE == HIFI) 551 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1 555 TCCR0A = pre_mozzi_TCCR0A;
556 TCCR0B = pre_mozzi_TCCR0B;
557 OCR0A = pre_mozzi_OCR0A;
558 TIMSK0 = pre_mozzi_TIMSK0;
560 TCCR1A = pre_mozzi_TCCR1A;
561 TCCR1B = pre_mozzi_TCCR1B;
562 OCR1A = pre_mozzi_OCR1A;
563 TIMSK1 = pre_mozzi_TIMSK1;
565 #if (AUDIO_MODE == HIFI) 567 TCCR2A = pre_mozzi_TCCR2A;
568 TCCR2B = pre_mozzi_TCCR2B;
569 OCR2A = pre_mozzi_OCR2A;
570 TIMSK2 = pre_mozzi_TIMSK2;
572 TCCR2 = pre_mozzi_TCCR2;
573 OCR2 = pre_mozzi_OCR2;
574 TIMSK = pre_mozzi_TIMSK;
575 #elif defined(TCCR4A) 576 TCCR4B = pre_mozzi_TCCR4A;
577 TCCR4B = pre_mozzi_TCCR4B;
578 TCCR4B = pre_mozzi_TCCR4C;
579 TCCR4B = pre_mozzi_TCCR4D;
580 TCCR4B = pre_mozzi_TCCR4E;
581 OCR4C = pre_mozzi_OCR4C;
582 TIMSK4 = pre_mozzi_TIMSK4;
591 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1 592 timer1.begin(teensyAudioOutput, 1000000UL/
AUDIO_RATE);
595 TCCR0A = mozzi_TCCR0A;
596 TCCR0B = mozzi_TCCR0B;
598 TIMSK0 = mozzi_TIMSK0;
600 TCCR1A = mozzi_TCCR1A;
601 TCCR1B = mozzi_TCCR1B;
603 TIMSK1 = mozzi_TIMSK1;
605 #if (AUDIO_MODE == HIFI) 607 TCCR2A = mozzi_TCCR2A;
608 TCCR2B = mozzi_TCCR2B;
610 TIMSK2 = mozzi_TIMSK2;
615 #elif defined(TCCR4A) 616 TCCR4B = mozzi_TCCR4A;
617 TCCR4B = mozzi_TCCR4B;
618 TCCR4B = mozzi_TCCR4C;
619 TCCR4B = mozzi_TCCR4D;
620 TCCR4B = mozzi_TCCR4E;
622 TIMSK4 = mozzi_TIMSK4;
631 return output_buffer.count();
unsigned long mozziMicros()
A replacement for Arduino micros() which is disabled by Mozzi which takes over Timer 0 for control in...
void updateAudio()
This is where you put your audio code.
void updateControl()
This is where you put your control code.
#define AUDIO_RATE
Holds the audio rate setting.
#define AUDIO_INPUT_PIN
This sets which analog input channel to use for audio input, if you have #define USE_AUDIO_INPUT true...
void audioHook()
This is required in Arduino's loop().
void unPauseMozzi()
Restores Mozzi audio and control interrupts, if they have been temporarily disabled with pauseMozzi()...
unsigned long audioTicks()
An alternative for Arduino time funcitions like micros() which are disabled by Mozzi when it takes ov...
void pauseMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
int getAudioInput()
This returns audio input from the input buffer, if #define USE_AUDIO_INPUT true is in the Mozzi/mozzi...
void startMozzi(int control_rate_hz)
Sets up the timers for audio and control rate processes, storing the timer registers so they can be r...