Mozzi  version v2.0
sound synthesis library for Arduino
MozziGuts.h
1 /*
2  * MozziGuts.h
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2012-2024 Tim Barrass and the Mozzi Team
7  *
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
9  *
10  */
11 
12 #ifndef MOZZIGUTS_H_
13 #define MOZZIGUTS_H_
14 
15 #include "Arduino.h"
16 
17 #include "MozziConfigValues.h"
18 
19 #if !(defined(MOZZI_H_) || defined(MOZZI_HEADERS_ONLY_H_))
20 #warning Direct inclusion of MozziGuts.h is deprecated. Use Mozzi.h, instead, and read about porting to Mozzi 2.0
21 #define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_1_1
22 #endif
23 
24 #include "hardware_defines.h"
25 
26 #if IS_TEENSY3() || IS_TEENSY4()
27 // required from http://github.com/pedvide/ADC for Teensy 3.*
28 #include <ADC.h>
29 #endif
30 
31 #include "internal/config_checks_generic.h"
32 
33 #include "mozzi_analog.h"
34 #include "AudioOutput.h"
35 
36 // TODO Mozzi 2.0: These typedef probably obsolete?
37 // common numeric types
38 typedef unsigned char uchar;
39 typedef unsigned int uint;
40 typedef unsigned long ulong;
41 
42 #if defined(__AVR__)
43 typedef unsigned char byte; // for arduino ide
44 typedef unsigned char uint8_t;
45 typedef signed char int8_t;
46 typedef unsigned int uint16_t;
47 typedef signed int int16_t;
48 typedef unsigned long uint32_t;
49 typedef signed long int32_t;
50 #else
51 // Other supported arches add typedefs, here, unless already defined for that platform needed
52 #endif
53 
54 /*! @defgroup core Mozzi Core Functions
55 
56 The bones of every Mozzi sketch.
57 
58 @ingroup core
59 Sets up the timers for audio and control rate processes, storing the timer
60 registers so they can be restored when Mozzi stops. startMozzi() goes in your sketch's
61 setup() routine.
62 
63 This function intializes the timer(s) needed to move audio samples to the output according to the
64 configured @ref MOZZI_AUDIO_MODE .
65 
66 @param control_rate_hz Sets how often updateControl() is called. It must be a power of 2.
67 If no parameter is provided, control_rate_hz is set to MOZZI_CONTROL_RATE,
68 which has a default value of 64 (you can re-\#define it in your sketch).
69 The practical upper limit for control rate depends on how busy the processor is,
70 and you might need to do some tests to find the best setting.
71 
72 @note startMozzi calls setupMozziADC(), which calls setupFastAnalogRead() and adcDisconnectAllDigitalIns(),
73 which disables digital inputs on all analog input pins. All in mozzi_analog.h and easy to change if you need to (hack).
74 They are all called automatically and hidden away because it keeps things simple for a STANDARD_PLUS set up,
75 but if it turns out to be confusing, they might need to become visible again.
76 */
77 void startMozzi(int control_rate_hz = MOZZI_CONTROL_RATE);
78 
79 
80 
81 /** @ingroup core
82 Stops audio and control interrupts and restores the timers to the values they
83 had before Mozzi was started. This could be useful when using sensor libraries
84 which depend on the same timers as Mozzi.
85 
86 A potentially better option for resolving timer conflicts involves using
87 non-blocking methods, such as demonstrated by the twowire_nonblock code in the
88 forked version of Mozzi on github, so sound production can continue while
89 reading sensors.
90 
91 As it is, stopMozzi restores all the Timers used by Mozzi to their previous
92 settings. Another scenario which could be easily hacked in MozziGuts.hpp could
93 involve individually saving and restoring particular Timer registers depending
94 on which one(s) are required for other tasks.
95 
96 @note This function is not actually implemented on all platforms.
97 */
98 void stopMozzi();
99 
100 
102 AudioOutput_t updateAudio();
103 #else
104 /** @ingroup core
105 This is where you put your audio code. updateAudio() has to keep up with the
106 MOZZI_AUDIO_RATE of 16384 or 32768 Hz, so to keep things running smoothly, avoid doing any
107 calculations here which could be done in setup() or updateControl().
108 @return an audio sample.
109 
110 While is possible (in mono sketches) to return a plain unscaled int, it is generally best to return
111 auto-scaled samples using MonoOutput::from8Bit(), MonoOutput::from16Bit(), MonoOutput::fromNbit(), or
112 their StereoOutput equivalents.
113 */
114 AudioOutput updateAudio();
115 #endif
116 
117 /** @ingroup core
118 This is where you put your control code. You need updateControl() somewhere in
119 your sketch, even if it's empty. updateControl() is called at the control rate
120 you set in startMozzi(). To save processor load, avoid any calculations here
121 which could be done in setup().
122 */
123 void updateControl();
124 
125 
126 /** @ingroup core
127 This is required in Arduino's loop(). If there is room in Mozzi's output buffer,
128 audioHook() calls updateAudio() once and puts the result into the output
129 buffer. Also, if \@ref MOZZI_AUDIO_INPUT is enabled in the config,
130 audioHook() takes care of moving audio input from the input buffer so it can be
131 accessed with getAudioInput() in your updateAudio() routine.
132 If other functions are called in loop() along with audioHook(), see if
133 they can be called less often by moving them into updateControl(),
134 to save processing power. Otherwise it may be most efficient to
135 calculate a block of samples at a time by putting audioHook() in a loop of its
136 own, rather than calculating only 1 sample for each time your other functions
137 are called.
138 */
139 void audioHook();
140 
141 /** @ingroup analog
142 
143 See getAudioInput(). The template parameter specifies the desired value range in bits. */
144 template<byte RES> uint16_t getAudioInput();
145 
146 /** @ingroup analog
147 
148 See getAudioInput(). Equivalent to getAudioInput<16>(). */
149 template<byte RES> inline uint16_t getAudioInput16() { return getAudioInput<16>(); }
150 
151 /** @ingroup analog
152 This returns audio input from the input buffer, if
153 \@ref MOZZI_AUDIO_INPUT is enabled in the config (see also the related option MOZZI_AUDIO_INPUT_PIN).
154 
155 The audio signal needs to be in the range 0 to VCC volts (i.e. 5 volts on Arduino Uno R3).
156 Circuits and discussions about biasing a signal
157 in the middle of this range can be found at
158 http://electronics.stackexchange.com/questions/14404/dc-biasing-audio-signal
159 and
160 http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/ .
161 A circuit and instructions for amplifying and biasing a microphone signal can be found at
162 http://www.instructables.com/id/Arduino-Audio-Input/?ALLSTEPS
163 
164 @note The value range returned by this function follows the same rules as detailed in the documentation
165  for mozziAnalogRead(): For portable code, define MOZZI_ANALGO_READ_RESOLUTION at the top of your
166  sketch, or use the templated version of this function.
167 
168 @return audio data from the input buffer
169 */
170 #if defined(FOR_DOXYGEN_ONLY) || (!MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE))
171 #if defined(FOR_DOXYGEN_ONLY) || defined(MOZZI_ANALOG_READ_RESOLUTION)
172 inline uint16_t getAudioInput() { return getAudioInput<MOZZI_ANALOG_READ_RESOLUTION>(); };
173 #else
174 MOZZI_DEPRECATED("2.0", "This use of getAudioInput() is not portable. Refer to the API documentation for suggested alternatives") inline uint16_t getAudioInput() { return getAudioInput<MOZZI__INTERNAL_ANALOG_READ_RESOLUTION>(); };
175 #endif
176 #endif
177 
178 
179 /** @ingroup core
180 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
181 and also it is synchronized with the currently processed audio sample (which, due to the audio
182 output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time).
183 audioTicks() is updated each time an audio sample
184 is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is
185 16384 Hz).
186 @return the number of audio ticks since the program began.
187 */
188 unsigned long audioTicks();
189 
190 
191 
192 /** @ingroup core
193 An alternative for Arduino time functions like micros() and millis(). This is slightly faster than micros(),
194 and also it is synchronized with the currently processed audio sample (which, due to the audio
195 output buffer, could diverge up to 256/MOZZI_AUDIO_RATE seconds from the current time).
196 audioTicks() is updated each time an audio sample
197 is output, so the resolution is 1/MOZZI_AUDIO_RATE microseconds (61 microseconds when MOZZI_AUDIO_RATE is
198 16384 Hz).
199 @return the approximate number of microseconds since the program began.
200 @todo incorporate mozziMicros() in a more accurate EventDelay()?
201 */
202 unsigned long mozziMicros();
203 
204 #ifndef _MOZZI_HEADER_ONLY
205 #include "internal/MozziGuts.hpp"
206 #endif
207 
208 #endif /* MOZZIGUTS_H_ */