Mozzi  version v1.1.0
sound synthesis library for Arduino
Core


Core definitions and functions. More...

Macros

#define AUDIO_MODE   STANDARD_PLUS
 AUDIO_MODE holds the audio mode setting. More...
 
#define AUDIO_RATE   AUDIO_RATE_PLATFORM_DEFAULT
 Holds the audio rate setting. More...
 
#define AUDIO_INPUT_PIN   0
 This sets which analog input channel to use for audio input, if you have uncommented #define USE_AUDIO_INPUT true in mozz_config.h. More...
 
#define AUDIO_CHANNELS   MONO
 This sets allows to change from a single/mono audio output channel to stereo output. More...
 
#define EXTERNAL_AUDIO_OUTPUT   false
 Defining this option as true in mozzi_config.h allows to completely customize the audio output, e.g. More...
 
#define STANDARD   0
 Used to set AUDIO_MODE to STANDARD, STANDARD_PLUS, or HIFI. More...
 
#define AUDIO_BIAS   ((uint16_t) 1 << (AUDIO_BITS - 1))
 
#define STANDARD_PWM_RESOLUTION   488
 This is the dynamic range of Mozzi's audio output in STANDARD mode. More...
 
#define STANDARD_PWM_RESOLUTION   488
 This is the dynamic range of Mozzi's audio output in STANDARD mode. More...
 
#define AUDIO_BIAS   ((uint16_t) 2048)
 
#define AUDIO_BIAS   ((uint16_t) 512)
 

Functions

void startMozzi (int control_rate_hz=CONTROL_RATE)
 Sets up the timers for audio and control rate processes, storing the timer registers so they can be restored when Mozzi stops. More...
 
void stopMozzi ()
 Stops audio and control interrupts and restores the timers to the values they had before Mozzi was started. More...
 
void pauseMozzi ()
 Obsolete function, use stopMozzi() instead.
 
void unPauseMozzi ()
 Obsolete function, use startMozzi() instead. More...
 
AudioOutput_t updateAudio ()
 This is where you put your audio code. More...
 
void updateControl ()
 This is where you put your control code. More...
 
void audioHook ()
 This is required in Arduino's loop(). More...
 
unsigned long audioTicks ()
 An alternative for Arduino time functions like micros() and millis(). More...
 
unsigned long mozziMicros ()
 An alternative for Arduino time functions like micros() and millis(). More...
 

Detailed Description


Core definitions and functions.

The bones of every Mozzi sketch.

Macro Definition Documentation

◆ AUDIO_CHANNELS

#define AUDIO_CHANNELS   MONO

This sets allows to change from a single/mono audio output channel to stereo output.

To actually generate two channels, your updateAudio()-function should return a StereoOutput(). Sketches returning a MonoOutput() in a stereo config, or vice versa will continue to work, but will generate a warning a compile time.

Note
This option superseeds the earlier STEREO_HACK, which is still available at the time of this writing, but should not be used in new sketches.
At the time of this writing, only MONO and STEREO are supported. The value of MONO is 1 and the value of STEREO is 2, so future extensions are also expected to set this to the number of available channels.

Definition at line 92 of file mozzi_config.h.

◆ AUDIO_INPUT_PIN

#define AUDIO_INPUT_PIN   0

This sets which analog input channel to use for audio input, if you have uncommented #define USE_AUDIO_INPUT true in mozz_config.h.

Note
You may have to call setupFastAnalogReads(FASTEST_ADC) after setupMozzi(), when using this.

Definition at line 76 of file mozzi_config.h.

◆ AUDIO_MODE

#define AUDIO_MODE   STANDARD_PLUS

AUDIO_MODE holds the audio mode setting.

Select STANDARD (deprecated), STANDARD_PLUS or HIFI audio output mode in the Mozzi/mozzi_config.h file with #define AUDIO_MODE STANDARD_PLUS or #define AUDIO_MODE HIFI. In Mozzi/config.h, comment one of these options in and the others out to set the audio mode.

In STANDARD_PLUS mode the sample resolution is 488, which provides some headroom above the 8 bit table resolution currently used by the oscillators. You can look at utility/TimerOne library for more info about how interrupt rate and pwm resolution relate.

HIFI audio mode enables much higher quality output by combining signals from pins 9 and 10. For HIFI mode, edit Mozzi/mozzi_config.h to contain #define AUDIO_MODE HIFI, and comment out #define AUDIO_MODE STANDARD and #define AUDIO_MODE STANDARD_PLUS.

Note
Teensy 3.* plays 12 bit audio in STANDARD or STANDARD_PLUS modes, and has no HIFI mode.

Definition at line 28 of file mozzi_config.h.

◆ AUDIO_RATE

#define AUDIO_RATE   AUDIO_RATE_PLATFORM_DEFAULT

Holds the audio rate setting.

AUDIO_RATE can be #defined as 16384 or 32768 Hertz in Mozzi/mozzi_config.h.

Mozzi's original audio mode, now called STANDARD, uses 16384 Hz, chosen as a compromise between the sample rate (interrupt rate) and sample bitdepth (pwm width), which are interdependent due to the way pulse wave modulation is used to generate the sound output. An AUDIO_RATE of 32768 Hz works in STANDARD_PLUS and HIFI modes. Of course, doubling the sample rate halves the amount of time available to calculate the each sample, so it may only be useful for relatively simple sketches. The increased frequency response can also make unwanted artefacts of low resolution synthesis calculations more apparent, so it's not always a bonus.

Another factor which is important for Mozzi's operation is that with AUDIO_RATE being a power of two, some internal calculations can be highly optimised for speed.

In STANDARD and STANDARD_PLUS modes, the sample resolution is 488, which provides some headroom above the 8 bit table resolution currently used by the oscillators. You can look at the TimerOne library for more info about how interrupt rate and pwm resolution relate.

HIFI audio mode enables much higher quality output by combining signals from pins 9 and 10. For HIFI mode, edit Mozzi/mozzi_config.h to contain #define AUDIO_MODE HIFI, and comment out #define AUDIO_MODE STANDARD and #define AUDIO_MODE STANDARD_PLUS.

Definition at line 62 of file mozzi_config.h.

◆ EXTERNAL_AUDIO_OUTPUT

#define EXTERNAL_AUDIO_OUTPUT   false

Defining this option as true in mozzi_config.h allows to completely customize the audio output, e.g.

for connecting to external DACs. For more detail,

See also
AudioOuput .

Definition at line 99 of file mozzi_config.h.

◆ STANDARD

#define STANDARD   0

Used to set AUDIO_MODE to STANDARD, STANDARD_PLUS, or HIFI.

STANDARD / STANDARD_PLUS

Use #define AUDIO_MODE STANDARD_PLUS in Mozzi/config.h to select this output configuration, which is nearly 9 bit sound (-244 to 243) at 16384 Hz sample rate (AUDIO_RATE) and 32768 Hz PWM rate. It uses Timer 1 for PWM and the sample updating routine (as an interrupt).

STANDARD is obsolete now, replaced by STANDARD_PLUS which is the default audio mode. STANDARD mode uses 16384 Hz PWM rate with an output interrupt at the same frequency. Some people can hear the PWM carrier frequency as an annoying whine.

STANDARD_PLUS mode uses 32768 Hz PWM rate, so the PWM carrier is out of hearing range. In this mode every alternate interrupt is used for the sample update (unless you /#define AUDIO_RATE 32768 in mozzi_config.h), which makes it slightly less efficient than STANDARD, but almost always better.

Advantages: Only uses one timer for audio, and one output pin. Disadvantages: low dynamic range.

Below is a list of the Digital Pins used by Mozzi for STANDARD and STANDARD_PLUS audio out on different boards. Those which have been tested and reported to work have an x. Feedback about others is welcome.

Model Pin Tested
Arduino Uno 9 yes
Arduino Duemilanove 9 yes
Arduino Nano 9 yes
Arduino Pro Mini 9 yes
Arduino Leonardo 9 yes
Arduino Mega 11 yes
Freetronics EtherMega 11 yes
Ardweeny 9 yes
Boarduino 9 yes
Teensy 14 -
Teensy2 B5 yes
Teensy2++ B5(25) yes
Teensy 3.0 3.1 LC 3.2 DAC/D yes
Teensy 3.4, 3.5 DAC/D -
Teensy 4.0 4.1 A8 yes
Gemma M0 A0 yes
Adafruit Playground Express Built in Speaker yes
Sanguino 13 -
STM32duino (see "Hardware specific notes", below) PB8 yes
ESP8266 see details in README GPIO2 yes
RP2040 0 yes

On Teensy 3.* STANDARD and STANDARD_PLUS are the same, providing 16384Hz sample rate and 12 bit resolution on pin A14/ADC. The Teensy 3.* DAC output does not rely on PWM.

Used to set AUDIO_MODE to HIFI.

HIFI for AVR and STM32 (not for Teensy 3.*)

Use #define AUDIO_MODE HIFI in Mozzi/config.h to set the audio mode to HIFI for output 14 bit sound at 16384 Hz sample rate and 125kHz PWM rate. The high PWM rate of HIFI mode places the carrier frequency beyond audible range.

Also, 14 bits of dynamic range in HIFI mode provides more definition than the nearly 9 bits in STANDARD_PLUS mode. HIFI mode takes about the same amount of processing time as STANDARD_PLUS mode, and should sound clearer and brighter. However, it requires an extra timer to be used on the Arduino, which could increase the chances of conflicts with other libraries or processes if they rely on Timer 2.

Timer 1 is used to provide the PWM output at 125kHz. Timer 2 generates an interrupt at AUDIO_RATE 16384 Hz, which sets the Timer1 PWM levels. HIFI mode uses 2 output pins, and sums their outputs with resistors, so is slightly less convenient for rapid prototyping where you could listen to STANDARD_PLUS mode by connecting the single output pin directly to a speaker or audio input (though a resistor of about 100 ohms is recommended).

The resistors needed for HIFI output are 3.9k and 499k, with 0.5% or better tolerance. If you can only get 1% resistors, use a multimeter to find the most accurate. Use two 1M resistors in parallel if you can't find 499k.

On 328 based Arduino boards, output is on Timer1, with the high byte on Pin 9 and low byte on Pin 10. Add the signals through a 3.9k resistor on high byte pin (9) and 499k resistor on low byte pin (10). Also, a 4.7nF capacitor is recommended between the summing junction of the resistors and ground.

This dual PWM technique is discussed on http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/ Also, there are higher quality output circuits are on the site.

Advantages: should be higher quality sound than STANDARD_PLUS mode. Doesn't need a notch filter on the audio signal (like STANDARD which is now obsolete) because the carrier frequency is out of hearing range.

Disadvantages: requires 2 pins, 2 resistors and a capacitor, so it's not so quick to set up compared to a rough, direct single-pin output in STANDARD_PLUS mode.

Pins and where to put the resistors on various boards for HIFI mode. Boards tested in HIFI mode have an x, though most of these have been tested in STANDARD_PLUS mode and there's no reason for them not to work in HIFI (unless the pin number is wrong or something). Any reports are welcome.
resistor.....3.9k......499k
x................9..........10...............Arduino Uno
x................9..........10...............Arduino Duemilanove
x................9..........10...............Arduino Nano
x................9..........10...............Arduino Leonardo
x................9..........10...............Ardweeny
x................9..........10...............Boarduino
x...............11.........12...............Freetronics EtherMega
.................11.........12...............Arduino Mega
.................14.........15...............Teensy
.............B5(14)...B6(15)...........Teensy2
x...........B5(25)...B6(26)...........Teensy2++
.................13.........12...............Sanguino
HIFI is not available/not required on Teensy 3.* or ARM.

Definition at line 164 of file MozziGuts.h.

◆ STANDARD_PWM_RESOLUTION [1/2]

#define STANDARD_PWM_RESOLUTION   488

This is the dynamic range of Mozzi's audio output in STANDARD mode.

It is equal to Timer1.pwmPeriod calculated for interrupt rate 16384. It's included in the documentation because it's a slightly unusual number and useful to know about when you're writing sketches.

Definition at line 11 of file AudioConfigStandard9bitPwm.h.

◆ STANDARD_PWM_RESOLUTION [2/2]

#define STANDARD_PWM_RESOLUTION   488

This is the dynamic range of Mozzi's audio output in STANDARD mode.

It is equal to Timer1.pwmPeriod calculated for interrupt rate 16384. It's included in the documentation because it's a slightly unusual number and useful to know about when you're writing sketches.

Definition at line 11 of file AudioConfigStandardPlus.h.

Function Documentation

◆ audioHook()

void audioHook ( )

This is required in Arduino's loop().

If there is room in Mozzi's output buffer, audioHook() calls updateAudio() once and puts the result into the output buffer. Also, if #define USE_AUDIO_INPUT true is in Mozzi/mozzi_config.h, audioHook() takes care of moving audio input from the input buffer so it can be accessed with getAudioInput() in your updateAudio() routine. If other functions are called in loop() along with audioHook(), see if they can be called less often by moving them into updateControl(), to save processing power. Otherwise it may be most efficient to calculate a block of samples at a time by putting audioHook() in a loop of its own, rather than calculating only 1 sample for each time your other functions are called.

Definition at line 190 of file MozziGuts.cpp.

◆ audioTicks()

unsigned long audioTicks ( )

An alternative for Arduino time functions like micros() and millis().

This is slightly faster than micros(), and also it is synchronized with the currently processed audio sample (which, due to the audio output buffer, could diverge up to 256/AUDIO_RATE seconds from the current time). audioTicks() is updated each time an audio sample is output, so the resolution is 1/AUDIO_RATE microseconds (61 microseconds when AUDIO_RATE is 16384 Hz).

Returns
the number of audio ticks since the program began.

Definition at line 219 of file MozziGuts.cpp.

◆ mozziMicros()

unsigned long mozziMicros ( )

An alternative for Arduino time functions like micros() and millis().

This is slightly faster than micros(), and also it is synchronized with the currently processed audio sample (which, due to the audio output buffer, could diverge up to 256/AUDIO_RATE seconds from the current time). audioTicks() is updated each time an audio sample is output, so the resolution is 1/AUDIO_RATE microseconds (61 microseconds when AUDIO_RATE is 16384 Hz).

Returns
the approximate number of microseconds since the program began.

Definition at line 229 of file MozziGuts.cpp.

◆ startMozzi()

void startMozzi ( int  control_rate_hz = CONTROL_RATE)

Sets up the timers for audio and control rate processes, storing the timer registers so they can be restored when Mozzi stops.

startMozzi() goes in your sketch's setup() routine.

Contrary to earlier versions of Mozzi, this version does not take over Timer 0, and thus Arduino functions delay(), millis(), micros() and delayMicroseconds() remain usable in theory. That said, you should avoid these functions, as they are slow (or even blocking). For measuring time, refer to mozziMircos(). For delaying events, you can use Mozzi's EventDelay() unit instead (not to be confused with AudioDelay()).

In STANDARD mode, startMozzi() starts Timer 1 for PWM output and audio output interrupts, and in STANDARD_PLUS and HIFI modes, Mozzi uses Timer 1 for PWM and Timer2 for audio interrupts.

The audio rate defaults to 16384 Hz, but you can experiment with 32768 Hz by changing AUDIO_RATE in mozzi_config.h.

Parameters
control_rate_hzSets how often updateControl() is called. It must be a power of 2. If no parameter is provided, control_rate_hz is set to CONTROL_RATE, which has a default value of 64 (you can re-#define it in your sketch). The practical upper limit for control rate depends on how busy the processor is, and you might need to do some tests to find the best setting.
Note
startMozzi calls setupMozziADC(), which calls setupFastAnalogRead() and adcDisconnectAllDigitalIns(), which disables digital inputs on all analog input pins. All in mozzi_analog.h and easy to change if you need to (hack). They are all called automatically and hidden away because it keeps things simple for a STANDARD_PLUS set up, but if it turns out to be confusing, they might need to become visible again.

Definition at line 234 of file MozziGuts.cpp.

◆ stopMozzi()

void stopMozzi ( )

Stops audio and control interrupts and restores the timers to the values they had before Mozzi was started.

This could be useful when using sensor libraries which depend on the same timers as Mozzi.

A potentially better option for resolving timer conflicts involves using non-blocking methods, such as demonstrated by the twowire_nonblock code in the forked version of Mozzi on github, so sound production can continue while reading sensors.

As it is, stopMozzi restores all the Timers used by Mozzi to their previous settings. Another scenario which could be easily hacked in MozziGuts.cpp could involve individually saving and restoring particular Timer registers depending on which one(s) are required for other tasks.

Definition at line 337 of file MozziGuts_impl_AVR.hpp.

◆ unPauseMozzi()

void unPauseMozzi ( )

Obsolete function, use startMozzi() instead.

Restores Mozzi audio and control interrupts, if they have been temporarily disabled with pauseMozzi().

◆ updateAudio()

AudioOutput_t updateAudio ( )

This is where you put your audio code.

updateAudio() has to keep up with the AUDIO_RATE of 16384 Hz, so to keep things running smoothly, avoid doing any calculations here which could be done in setup() or updateControl().

Returns
an audio sample. In STANDARD modes this is between -244 and 243 inclusive. In HIFI mode, it's a 14 bit number between -16384 and 16383 inclusive.

◆ updateControl()

void updateControl ( )

This is where you put your control code.

You need updateControl() somewhere in your sketch, even if it's empty. updateControl() is called at the control rate you set in startMozzi(). To save processor load, avoid any calculations here which could be done in setup().