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