Mozzi  version 2016-12-11-17:03
sound synthesis library for Arduino
MozziGuts.cpp
1 /*
2  * MozziGuts.cpp
3  *
4  * Copyright 2012 Tim Barrass.
5  *
6  * This file is part of Mozzi.
7  *
8  * Mozzi by Tim Barrass is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
9  *
10  */
11 
12  #if ARDUINO >= 100
13  #include "Arduino.h"
14 #else
15  #include "WProgram.h"
16 #endif
17 
18 #include <util/atomic.h>
19 #include "MozziGuts.h"
20 #include "mozzi_config.h" // at the top of all MozziGuts and analog files
21 #include "mozzi_analog.h"
22 #include "CircularBuffer.h"
23 //#include "mozzi_utils.h"
24 
25 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
26 #include "IntervalTimer.h"
27 #else
28 #include "TimerZero.h"
29 #include "TimerOne.h"
30 #include "FrequencyTimer2.h"
31 #endif
32 
33 
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."
36 #endif
37 
38 
39 // this seems to get included before mozzi_analog.cpp
40 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
41  ADC *adc; // adc object
42  uint8_t teensy_pin;
43 #endif
44 
45 /*
46 ATmega328 technical manual, Section 12.7.4:
47 The dual-slope operation [of phase correct pwm] has lower maximum operation
48 frequency than single slope operation. However, due to the symmetric feature
49 of the dual-slope PWM modes, these modes are preferred for motor control
50 applications.
51 Due to the single-slope operation, the operating frequency of the
52 fast PWM mode can be twice as high as the phase correct PWM mode that use
53 dual-slope operation. This high frequency makes the fast PWM mode well suited
54 for power regulation, rectification, and DAC applications. High frequency allows
55 physically small sized external components (coils, capacitors)..
56 
57 DAC, that's us! Fast PWM.
58 
59 PWM frequency tests
60 62500Hz, single 8 or dual 16 bits, bad aliasing
61 125000Hz dual 14 bits, sweet
62 250000Hz dual 12 bits, gritty, if you're gonna have 2 pins, have 14 bits
63 500000Hz dual 10 bits, grittier
64 16384Hz single nearly 9 bits (original mode) not bad for a single pin, but carrier freq noise can be an issue
65 */
66 
67 
68 //-----------------------------------------------------------------------------------------------------------------
69 // ring buffer for audio output
70 CircularBuffer <unsigned int> output_buffer; // fixed size 256
71 #if (STEREO_HACK == true)
72 CircularBuffer <unsigned int> output_buffer2; // fixed size 256
73 #endif
74 //-----------------------------------------------------------------------------------------------------------------
75 
76 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
77 // not storing backups, just turning timer on and off for pause
78 #else
79 
80 // to store backups of timer registers so Mozzi can be stopped and pre_mozzi timer values can be restored
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;
83 
84 #if (AUDIO_MODE == HIFI)
85 #if defined(TCCR2A)
86 static uint8_t pre_mozzi_TCCR2A, pre_mozzi_TCCR2B, pre_mozzi_OCR2A, pre_mozzi_TIMSK2;
87 #elif defined(TCCR2)
88 static uint8_t pre_mozzi_TCCR2, pre_mozzi_OCR2, pre_mozzi_TIMSK;
89 #elif defined(TCCR4A)
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;
91 #endif
92 #endif
93 
94 
95 static void backupPreMozziTimer1()
96 {
97  // backup pre-mozzi register values for pausing later
98  pre_mozzi_TCCR1A = TCCR1A;
99  pre_mozzi_TCCR1B = TCCR1B;
100  pre_mozzi_OCR1A = OCR1A;
101  pre_mozzi_TIMSK1 = TIMSK1;
102 }
103 
104 
105 //-----------------------------------------------------------------------------------------------------------------
106 
107 
108 // to store backups of mozzi's changes to timer registers so Mozzi can be paused and unPaused
109 static uint8_t mozzi_TCCR0A, mozzi_TCCR0B, mozzi_OCR0A, mozzi_TIMSK0;
110 static uint8_t mozzi_TCCR1A, mozzi_TCCR1B, mozzi_OCR1A, mozzi_TIMSK1;
111 
112 #if (AUDIO_MODE == HIFI)
113 #if defined(TCCR2A)
114 static uint8_t mozzi_TCCR2A, mozzi_TCCR2B, mozzi_OCR2A, mozzi_TIMSK2;
115 #elif defined(TCCR2)
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;
119 #endif
120 #endif
121 
122 
123 static void backupMozziTimer1()
124 {
125  // backup mozzi register values for unpausing later
126  mozzi_TCCR1A = TCCR1A;
127  mozzi_TCCR1B = TCCR1B;
128  mozzi_OCR1A = OCR1A;
129  mozzi_TIMSK1 = TIMSK1;
130 }
131 
132 #endif // end of timer backups for non-Teensy 3 boards
133 //-----------------------------------------------------------------------------------------------------------------
134 
135 #if (USE_AUDIO_INPUT==true)
136 
137 // ring buffer for audio input
138 CircularBuffer <unsigned int>input_buffer; // fixed size 256
139 
140 static boolean audio_input_is_available;
141 static int audio_input; // holds the latest audio from input_buffer
142 uint8_t adc_count = 0;
143 
144 
146 {
147  return audio_input;
148 }
149 
150 
151 static void startFirstAudioADC()
152 {
153 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
154  adc->startSingleRead(AUDIO_INPUT_PIN); // ADC lib converts pin/channel in startSingleRead
155 #else
156  adcStartConversion(adcPinToChannelNum(AUDIO_INPUT_PIN));
157 #endif
158 }
159 
160 /*
161 static void receiveFirstAudioADC()
162 {
163  // nothing
164 }
165 */
166 
167 static void startSecondAudioADC()
168 {
169 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
170  adc->startSingleRead(AUDIO_INPUT_PIN);
171 #else
172  ADCSRA |= (1 << ADSC); // start a second conversion on the current channel
173 #endif
174 }
175 
176 
177 
178 static void receiveSecondAudioADC()
179 {
180  if (!input_buffer.isFull())
181 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
182  input_buffer.write(adc->readSingle());
183 #else
184  input_buffer.write(ADC);
185 #endif
186 }
187 
188 
189 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
190 void adc0_isr(void)
191 #else
192 ISR(ADC_vect, ISR_BLOCK)
193 #endif
194 {
195  switch (adc_count){
196  case 0:
197  // 6us
198  receiveSecondAudioADC();
199  adcReadSelectedChannels();
200  break;
201 
202  case 1:
203  // <2us, <1us w/o receive
204  //receiveFirstControlADC();
205  startSecondControlADC();
206  break;
207 
208  case 2:
209  // 3us
210  receiveSecondControlADC();
211  startFirstAudioADC();
212  break;
213 
214 
215  // case 3:
216  // invisible
217  // receiveFirstAudioADC();
218  // break;
219 
220  }
221  adc_count++;
222 }
223 #endif // end main audio input section
224 
225 #if (STEREO_HACK == true)
226 extern int audio_out_1, audio_out_2;
227 #endif
228 
229 void audioHook() // 2us excluding updateAudio()
230 {
231 //setPin13High();
232 #if (USE_AUDIO_INPUT==true)
233  if (!input_buffer.isEmpty())
234  audio_input = input_buffer.read();
235 #endif
236 
237  if (!output_buffer.isFull()) {
238  #if (STEREO_HACK == true)
239  updateAudio(); // in hacked version, this returns void
240  output_buffer.write((unsigned int) (audio_out_1 + AUDIO_BIAS));
241  output_buffer2.write((unsigned int) (audio_out_2 + AUDIO_BIAS));
242  #else
243  output_buffer.write((unsigned int) (updateAudio() + AUDIO_BIAS));
244  #endif
245 
246  }
247 //setPin13Low();
248 }
249 
250 
251 
252 //-----------------------------------------------------------------------------------------------------------------
253 #if (AUDIO_MODE == STANDARD) || (AUDIO_MODE == STANDARD_PLUS)
254 
255 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
256 //teensy 3 architecture
257 
258  IntervalTimer timer1;
259 
260 
261 static void teensyAudioOutput()
262 {
263 
264 #if (USE_AUDIO_INPUT==true)
265  adc_count = 0;
266  startSecondAudioADC();
267 #endif
268 
269  analogWrite(AUDIO_CHANNEL_1_PIN, (int)output_buffer.read());
270 }
271 
272 
273 static void startAudioStandard()
274 {
275  //backupPreMozziTimer1(); // not for Teensy 3.1
276 
277  analogWriteResolution(12);
278  adc->setAveraging(0);
279  adc->setConversionSpeed(ADC_MED_SPEED); // could be ADC_HIGH_SPEED, noisier
280  timer1.begin(teensyAudioOutput, 1000000UL/AUDIO_RATE);
281 
282  //backupMozziTimer1(); // // not for Teensy 3.1
283 }
284 
285 #else
286 
287 // avr architecture
288 static void startAudioStandard()
289 {
290  backupPreMozziTimer1();
291 
292  pinMode(AUDIO_CHANNEL_1_PIN, OUTPUT); // set pin to output for audio
293  // pinMode(AUDIO_CHANNEL_2_PIN, OUTPUT); // set pin to output for audio
294 #if (AUDIO_MODE == STANDARD)
295  Timer1.initializeCPUCycles(16000000UL/AUDIO_RATE, PHASE_FREQ_CORRECT); // set period, phase and frequency correct
296 #else // (AUDIO_MODE == STANDARD_PLUS)
297  Timer1.initializeCPUCycles(16000000UL/PWM_RATE, FAST); // fast mode enables higher PWM rate
298 #endif
299  Timer1.pwm(AUDIO_CHANNEL_1_PIN, AUDIO_BIAS); // pwm pin, 50% of Mozzi's duty cycle, ie. 0 signal
300  //Timer1.pwm(AUDIO_CHANNEL_2_PIN, AUDIO_BIAS);
301  TIMSK1 = _BV(TOIE1); // Overflow Interrupt Enable (when not using Timer1.attachInterrupt())
302  //TIMSK1 |= _BV(TOIE1) | _BV(OCIE1A); // Overflow Interrupt Enable and Output Compare A Match Interrupt Enable
303  backupMozziTimer1();
304 }
305 
306 /*
307 // trying to get ac output for piezo
308 unsigned int output;
309 
310 //extern unsigned long interruptcounter;
311 ISR(TIMER1_COMPA_vect){
312  //Serial.print(9);
313  //interruptcounter++;
314  // change polarity of pwm output pins 9 and 10 - one becomes ground, the other becomes max-output
315  AUDIO_CHANNEL_1_OUTPUT_REGISTER = 0;//STANDARD_PWM_RESOLUTION;
316  //AUDIO_CHANNEL_2_OUTPUT_REGISTER = STANDARD_PWM_RESOLUTION-output;
317 }
318 */
319 
320 /* Interrupt service routine moves sound data from the output buffer to the
321 Arduino output register, running at AUDIO_RATE. */
322 
323 ISR(TIMER1_OVF_vect, ISR_BLOCK)
324 {
325 
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;
329  if(alternate)
330  {
331 #endif
332 
333 #if (USE_AUDIO_INPUT==true)
334  adc_count = 0;
335  startSecondAudioADC();
336 #endif
337 
338 //if (!output_buffer.isEmpty()) {
339 /*
340 output = output_buffer.read();
341 AUDIO_CHANNEL_1_OUTPUT_REGISTER = output;
342 AUDIO_CHANNEL_2_OUTPUT_REGISTER = 0;
343 */
344 
345  AUDIO_CHANNEL_1_OUTPUT_REGISTER = output_buffer.read();
346 #if (STEREO_HACK == true)
347  AUDIO_CHANNEL_2_OUTPUT_REGISTER = output_buffer2.read();
348 #endif
349 
350 //}
351 
352  // flip signal polarity - instead of signal going to 0 (both pins 0), it goes to pseudo-negative of its current value.
353  // this would set non-inverted when setting sample value, and then inverted when top is reached (in an interrupt)
354  // non-invert
355  //TCCR1A |= _BV(COM1A1);
356  // invert
357  //TCCR1A |= ~_BV(COM1A1)
358 
359 
360 #if (AUDIO_MODE == STANDARD_PLUS) && (AUDIO_RATE==16384) // all this conditional compilation is so clutsy!
361  }
362 #endif
363 
364 }
365 // end avr
366 #endif
367 // end STANDARD
368 
369 //-----------------------------------------------------------------------------------------------------------------
370 #elif (AUDIO_MODE == HIFI)
371 
372 static void startAudioHiFi()
373 {
374  backupPreMozziTimer1();
375  // pwm on timer 1
376  pinMode(AUDIO_CHANNEL_1_highByte_PIN, OUTPUT); // set pin to output for audio, use 3.9k resistor
377  pinMode(AUDIO_CHANNEL_1_lowByte_PIN, OUTPUT); // set pin to output for audio, use 499k resistor
378  Timer1.initializeCPUCycles(16000000UL/125000, FAST); // set period for 125000 Hz fast pwm carrier frequency = 14 bits
379  Timer1.pwm(AUDIO_CHANNEL_1_highByte_PIN, 0); // pwm pin, 0% duty cycle, ie. 0 signal
380  Timer1.pwm(AUDIO_CHANNEL_1_lowByte_PIN, 0); // pwm pin, 0% duty cycle, ie. 0 signal
381  backupMozziTimer1();
382  // audio output interrupt on timer 2, sets the pwm levels of timer 1
383  setupTimer2();
384 }
385 
386 /* set up Timer 2 using modified FrequencyTimer2 library */
387 void dummy(){}
388 
389 
390 static void backupPreMozziTimer2()
391 {
392  //backup Timer2 register values
393 #if defined(TCCR2A)
394  pre_mozzi_TCCR2A = TCCR2A;
395  pre_mozzi_TCCR2B = TCCR2B;
396  pre_mozzi_OCR2A = OCR2A;
397  pre_mozzi_TIMSK2 = TIMSK2;
398 #elif defined(TCCR2)
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;
410 #endif
411 }
412 
413 
414 
415 static void backupMozziTimer2()
416 {
417 #if defined(TCCR2A)
418  mozzi_TCCR2A = TCCR2A;
419  mozzi_TCCR2B = TCCR2B;
420  mozzi_OCR2A = OCR2A;
421  mozzi_TIMSK2 = TIMSK2;
422 #elif defined(TCCR2)
423  mozzi_TCCR2 = TCCR2;
424  mozzi_OCR2 = OCR2;
425  mozzi_TIMSK = TIMSK;
426 #elif defined(TCCR4A)
427  mozzi_TCCR4B = TCCR4A;
428  mozzi_TCCR4B = TCCR4B;
429  mozzi_TCCR4B = TCCR4C;
430  mozzi_TCCR4B = TCCR4D;
431  mozzi_TCCR4B = TCCR4E;
432  mozzi_OCR4C = OCR4C;
433  mozzi_TIMSK4 = TIMSK4;
434 #endif
435 }
436 
437 
438 // audio output interrupt on timer 2 (or 4 on ATMEGA32U4 cpu), sets the pwm levels of timer 1
439 static void setupTimer2()
440 {
441  backupPreMozziTimer2(); // to reset while pausing
442  unsigned long period = 16000000UL/AUDIO_RATE;
443  period *= FrequencyTimer2::clockCyclesPerMicrosecond();
444  FrequencyTimer2::setPeriod(period);
445  FrequencyTimer2::setOnOverflow(dummy);
446  FrequencyTimer2::enable();
447 
448  // backup mozzi register values for unpausing later
449  backupMozziTimer2();
450 }
451 
452 
453 
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)
460 #else
461 #error "This board does not have a hardware timer which is compatible with FrequencyTimer2"
462 void dummy_function(void)
463 #endif
464 {
465 #if (USE_AUDIO_INPUT==true)
466  adc_count = 0;
467  startSecondAudioADC();
468 #endif
469 
470  // read about dual pwm at http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/
471  // sketches at http://wiki.openmusiclabs.com/wiki/PWMDAC, http://wiki.openmusiclabs.com/wiki/MiniArDSP
472  //if (!output_buffer.isEmpty()){
473  unsigned int out = output_buffer.read();
474  // 14 bit, 7 bits on each pin
475  //AUDIO_CHANNEL_1_highByte_REGISTER = out >> 7; // B00111111 10000000 becomes B1111111
476  // try to avoid looping over 7 shifts - need to check timing or disassemble to see what really happens
477  unsigned int out_high = out<<1; // B00111111 10000000 becomes B01111111 00000000
478  AUDIO_CHANNEL_1_highByte_REGISTER = out_high >> 8; // B01111111 00000000 produces B01111111
479  //
480  AUDIO_CHANNEL_1_lowByte_REGISTER = out & 127;
481  //}
482 }
483 
484 // end of HIFI
485 
486 #endif
487 
488 
489 //-----------------------------------------------------------------------------------------------------------------
490 
491 static void updateControlWithAutoADC()
492 {
493  updateControl();
494  /*
495  #if (USE_AUDIO_INPUT==true)
496  adc_count = 0;
497  startSecondAudioADC();
498 #endif
499 */
500  adcStartReadCycle();
501 }
502 
503 
504 /* Sets up Timer 0 for control interrupts. This is the same for all output
505 options Using Timer0 for control disables Arduino's time functions but also
506 saves on the interrupts and blocking action of those functions. May add a config
507 option for Using Timer2 instead if needed. (MozziTimer2 can be re-introduced for
508 that). */
509 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
510 IntervalTimer timer0;
511 #endif
512 
513 
514 static void startControl(unsigned int control_rate_hz)
515 {
516 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
517  timer0.begin(updateControlWithAutoADC, 1000000/control_rate_hz);
518 #else
519  // backup pre-mozzi register values
520  pre_mozzi_TCCR0A = TCCR0A;
521  pre_mozzi_TCCR0B = TCCR0B;
522  pre_mozzi_OCR0A = OCR0A;
523  pre_mozzi_TIMSK0 = TIMSK0;
524 
525  TimerZero::init(1000000/control_rate_hz,updateControlWithAutoADC); // set period, attach updateControlWithAutoADC()
526  TimerZero::start();
527 
528  // backup mozzi register values for unpausing later
529  mozzi_TCCR0A = TCCR0A;
530  mozzi_TCCR0B = TCCR0B;
531  mozzi_OCR0A = OCR0A;
532  mozzi_TIMSK0 = TIMSK0;
533 #endif
534 }
535 
536 
537 void startMozzi(int control_rate_hz)
538 {
539  setupMozziADC(); // you can use setupFastAnalogRead() with FASTER or FASTEST in setup() if desired (not for Teensy 3.1)
540  // delay(200); // so AutoRange doesn't read 0 to start with
541  startControl(control_rate_hz);
542 #if (AUDIO_MODE == STANDARD) || (AUDIO_MODE == STANDARD_PLUS)
543  startAudioStandard();
544 #elif (AUDIO_MODE == HIFI)
545  startAudioHiFi();
546 #endif
547 }
548 
549 
550 void pauseMozzi(){
551 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
552  timer1.end();
553 #else
554  // restore backed up register values
555  TCCR0A = pre_mozzi_TCCR0A;
556  TCCR0B = pre_mozzi_TCCR0B;
557  OCR0A = pre_mozzi_OCR0A;
558  TIMSK0 = pre_mozzi_TIMSK0;
559 
560  TCCR1A = pre_mozzi_TCCR1A;
561  TCCR1B = pre_mozzi_TCCR1B;
562  OCR1A = pre_mozzi_OCR1A;
563  TIMSK1 = pre_mozzi_TIMSK1;
564 
565 #if (AUDIO_MODE == HIFI)
566 #if defined(TCCR2A)
567  TCCR2A = pre_mozzi_TCCR2A;
568  TCCR2B = pre_mozzi_TCCR2B;
569  OCR2A = pre_mozzi_OCR2A;
570  TIMSK2 = pre_mozzi_TIMSK2;
571 #elif defined(TCCR2)
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;
583 #endif
584 #endif
585 #endif
586 }
587 
588 
590 {
591 #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(TEENSYDUINO) // teensy 3, 3.1
592  timer1.begin(teensyAudioOutput, 1000000UL/AUDIO_RATE);
593 #else
594  // restore backed up register values
595  TCCR0A = mozzi_TCCR0A;
596  TCCR0B = mozzi_TCCR0B;
597  OCR0A = mozzi_OCR0A;
598  TIMSK0 = mozzi_TIMSK0;
599 
600  TCCR1A = mozzi_TCCR1A;
601  TCCR1B = mozzi_TCCR1B;
602  OCR1A = mozzi_OCR1A;
603  TIMSK1 = mozzi_TIMSK1;
604 
605 #if (AUDIO_MODE == HIFI)
606 #if defined(TCCR2A)
607  TCCR2A = mozzi_TCCR2A;
608  TCCR2B = mozzi_TCCR2B;
609  OCR2A = mozzi_OCR2A;
610  TIMSK2 = mozzi_TIMSK2;
611 #elif defined(TCCR2)
612  TCCR2 = mozzi_TCCR2;
613  OCR2 = mozzi_OCR2;
614  TIMSK = mozzi_TIMSK;
615 #elif defined(TCCR4A)
616  TCCR4B = mozzi_TCCR4A;
617  TCCR4B = mozzi_TCCR4B;
618  TCCR4B = mozzi_TCCR4C;
619  TCCR4B = mozzi_TCCR4D;
620  TCCR4B = mozzi_TCCR4E;
621  OCR4C = mozzi_OCR4C;
622  TIMSK4 = mozzi_TIMSK4;
623 #endif
624 #endif
625 #endif
626 }
627 
628 
629 unsigned long audioTicks()
630 {
631  return output_buffer.count();
632 }
633 
634 
635 unsigned long mozziMicros()
636 {
637  return audioTicks() * MICROS_PER_AUDIO_TICK;
638 }
639 
640 
641 
642 // Unmodified TimerOne.cpp has TIMER3_OVF_vect.
643 // Watch out if you update the library file.
644 // The symptom will be no sound.
645 // ISR(TIMER1_OVF_vect)
646 // {
647 // Timer1.isrCallback();
648 // }
unsigned long mozziMicros()
A replacement for Arduino micros() which is disabled by Mozzi which takes over Timer 0 for control in...
Definition: MozziGuts.cpp:635
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.
Definition: mozzi_config.h:61
#define AUDIO_INPUT_PIN
This sets which analog input channel to use for audio input, if you have #define USE_AUDIO_INPUT true...
Definition: mozzi_config.h:83
Circular buffer object.
void audioHook()
This is required in Arduino&#39;s loop().
Definition: MozziGuts.cpp:229
void unPauseMozzi()
Restores Mozzi audio and control interrupts, if they have been temporarily disabled with pauseMozzi()...
Definition: MozziGuts.cpp:589
unsigned long audioTicks()
An alternative for Arduino time funcitions like micros() which are disabled by Mozzi when it takes ov...
Definition: MozziGuts.cpp:629
void pauseMozzi()
Stops audio and control interrupts and restores the timers to the values they had before Mozzi was st...
Definition: MozziGuts.cpp:550
int getAudioInput()
This returns audio input from the input buffer, if #define USE_AUDIO_INPUT true is in the Mozzi/mozzi...
Definition: MozziGuts.cpp:145
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...
Definition: MozziGuts.cpp:537