These are the example sketches that come with Mozzi, and the sounds they make.
They’re intended to be instructive, rather than musically interesting…
01.Basics : how to make a sound and simple modifications like gain.
02.Control : changing sound parameters, scheduling, pausing.
03.Sensors : using various sensors to change sounds.
04.Audio Input : sample incoming sound at audio rate.
05.Control Filters : smoothing and other processing for sensor inputs.
06.Synthesis : for more versatile and detailed sounds.
07.Envelopes : give sounds changing dynamics.
08.Samples : play recorded sounds in various ways.
09.Delays : for effects like flanging or reverb.
10.Audio Filters : modify audio frequencies.
11.Communication : non-blocking communication with external devices.
12.Misc : other useful things.
01.Basics
Control_Gain
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example changing the gain of a sinewave,
using Mozzi sonification library.
Demonstrates the use of a control variable to influence an
audio signal.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
// control variable, use the smallest data size you can for anything used in audio
byte gain = 255 ;
void setup (){
startMozzi (); // start with default control rate of 64
aSin . setFreq ( 3320 ); // set the frequency
}
void updateControl (){
// as byte, this will automatically roll around to 255 when it passes 0
gain = gain - 3 ;
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit ( aSin . next () * gain ); // 8 bits waveform * 8 bits gain makes 16 bits
}
void loop (){
audioHook (); // required here
}
Sinewave
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example playing a sinewave at a set frequency,
using Mozzi sonification library.
Demonstrates the use of Oscil to play a wavetable.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable; 64 Hz is actually the default, but shown here, for clarity
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
void setup (){
startMozzi (); // :)
aSin . setFreq ( 440 ); // set the frequency
}
void updateControl (){
// put changing controls in here
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aSin . next ()); // return an int signal centred around 0
}
void loop (){
audioHook (); // required here
}
Sinewave_HIFI
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example playing a sinewave at a set frequency,
using Mozzi sonification library.
Demonstrates the use of Oscil to play a wavetable.
Important:
This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which
is not available on all boards (among others, it works on the
classic Arduino boards, but not Teensy 3.x and friends).
Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar),
Check the Mozzi core module documentation for others and more detail
3.9k
pin 9 ---WWWW-----|-----output
499k |
pin 10 ---WWWW---- |
|
4.7n ==
|
ground
Resistors are ±0.5% Measure and choose the most precise
from a batch of whatever you can get. Use two 1M resistors
in parallel if you can't find 499k.
Alternatively using 39 ohm, 4.99k and 470nF components will
work directly with headphones.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
void setup (){
startMozzi (); // uses the default control rate of 64
aSin . setFreq ( 440 ); // set the frequency
}
void updateControl (){}
AudioOutput updateAudio (){
// this would make more sense with a higher resolution signal
// MonoOutput::from8Bit() (and it friends from16Bit() and fromNBit()) take care of scaling the output signal
// as appropiate for the platform (to 14 bits on AVR with AUDIO_MODE HIFI).
return MonoOutput :: from8Bit ( aSin . next ());
}
void loop (){
audioHook (); // required here
}
Skeleton
…(no recording of this one)
show sketch
hide sketch
#include <MozziConfigValues.h> // only needed, if you want to change some defaults
#define MOZZI_CONTROL_RATE 64 // any options then go above the Mozzi.h include
#include <Mozzi.h> // needed once in each sketch
void setup () {
startMozzi ();
}
void updateControl () {
// your control code
}
AudioOutput updateAudio () {
// For mono output, the return value of this function is really just a signed integer.
// However, for best portability of your sketch to different boards and configurations,
// pick one of the variants below, depending on the "natural" range of the audio values
// you generate:
return MonoOutput :: from8Bit ( 0 ); // if your signal is in 8 bit range
/* OR */
return MonoOutput :: fromAlmostNBit ( 9 , 0 ); // if your signal is between -244 and 243 (_almost_ 9 bits is a special case on AVR boards)
/* OR */
return MonoOutput :: fromAlmostNBit ( 9 , 0 ). clip (); // To clip (instead of overflow), should a few stray values exceed the allowable range
/* OR */
return MonoOutput :: from16Bit ( 0 ); // if your signal is in 16 bit range, e.g. the product of two 8 bit numbers
/* OR */
return MonoOutput :: fromNBit ( 21 , 0 ); // if your signal happens to be in 21 bit range
// In case you are wondering:
// In older sketches, you will find "int updateAudio()", returning a plain int value.
// That will still work, but is not recommended.
}
void loop () {
audioHook (); // fills the audio buffer
}
Skeleton_Multi
…(no recording of this one)
show sketch
hide sketch
/* This example shows how to set up a sketch where Mozzi-related functions are called
from more than one .cpp source file (which will be compiled, separately).
Unless you have good reason to do this, it is recommended to base your sketch on the
single-file "Skeleton" example, instead.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h> // at the top of your sketch
void setup () {
startMozzi ();
}
void updateControl () {
// your control code
}
void loop () {
audioHook (); // fills the audio buffer
}
Table_Resolution
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example playing sine tables of different sizes
with Mozzi sonification library.
Demonstrates the audible quality of different length tables
played with Oscil and scheduling with EventDelay.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 64
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/sin256_int8.h>
#include <tables/sin512_int8.h>
#include <tables/sin1024_int8.h>
#include <tables/sin2048_int8.h>
#include <tables/sin4096_int8.h>
#include <tables/sin8192_int8.h>
#include <EventDelay.h> // for scheduling events
#include <Line.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN256_NUM_CELLS , MOZZI_AUDIO_RATE > aSin0 ( SIN256_DATA ); // can hear significant aliasing noise
Oscil < SIN512_NUM_CELLS , MOZZI_AUDIO_RATE > aSin1 ( SIN512_DATA ); // noise still there but less noticeable
Oscil < SIN1024_NUM_CELLS , MOZZI_AUDIO_RATE > aSin2 ( SIN1024_DATA ); // borderline, hardly there if at all
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin3 ( SIN2048_DATA ); // no audible improvement from here on
Oscil < SIN4096_NUM_CELLS , MOZZI_AUDIO_RATE > aSin4 ( SIN4096_DATA ); // for 45 year old loud sound damaged ears
Oscil < SIN8192_NUM_CELLS , MOZZI_AUDIO_RATE > aSin5 ( SIN8192_DATA );
EventDelay kWhoseTurnDelay ;
const byte NUM_OSCILS = 6 ;
byte whose_turn = 0 ; // which oscil to listen to
// Line to sweep frequency at control rate
Line < float > kSweep ;
const unsigned int MILLIS_PER_SWEEP = 2000 ;
const unsigned int MILLIS_PER_CONTROL = 1000u / MOZZI_CONTROL_RATE ;
const unsigned long CONTROL_STEPS_PER_SWEEP = ( unsigned long ) MILLIS_PER_SWEEP / MILLIS_PER_CONTROL ;
void setup (){
startMozzi ();
kWhoseTurnDelay . set ( MILLIS_PER_SWEEP );
kSweep . set ( 0. f , 8192. f , CONTROL_STEPS_PER_SWEEP );
}
void updateControl (){
if ( kWhoseTurnDelay . ready ()){
if ( ++ whose_turn >= NUM_OSCILS ) whose_turn = 0 ;
kWhoseTurnDelay . start ();
kSweep . set ( 0UL );
}
float f = kSweep . next ();
switch ( whose_turn ) {
case 0 :
aSin0 . setFreq ( f );
break ;
case 1 :
aSin1 . setFreq ( f );
break ;
case 2 :
aSin2 . setFreq ( f );
break ;
case 3 :
aSin3 . setFreq ( f );
break ;
case 4 :
aSin4 . setFreq ( f );
break ;
case 5 :
aSin5 . setFreq ( f );
break ;
}
}
AudioOutput updateAudio (){
int asig ;
switch ( whose_turn ) {
case 0 :
asig = aSin0 . next ();
break ;
case 1 :
asig = aSin1 . next ();
break ;
case 2 :
asig = aSin2 . next ();
break ;
case 3 :
asig = aSin3 . next ();
break ;
case 4 :
asig = aSin4 . next ();
break ;
case 5 :
asig = aSin5 . next ();
break ;
}
return MonoOutput :: from8Bit ( asig );
}
void loop (){
audioHook (); // required here
}
Vibrato
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example playing a sinewave with vibrato,
using Mozzi sonification library.
Demonstrates simple FM using phase modulation.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <mozzi_midi.h> // for mtof
//#include <mozzi_fixmath.h>
#include <FixMath.h> // Fixed point arithmetics
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCos ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aVibrato ( COS2048_DATA );
//const byte intensity = 255;
const UFix < 0 , 8 > intensity = 0.5 ; // amplitude of the phase modulation
// 0.5 leads to a modulation of half the
// wavetable
void setup (){
startMozzi ();
aCos . setFreq ( mtof ( 84. f ));
aVibrato . setFreq ( 15. f );
}
void updateControl (){
}
AudioOutput updateAudio (){
//Q15n16 vibrato = (Q15n16) intensity * aVibrato.next();
auto vibrato = intensity * toSFraction ( aVibrato . next ()); // Oscils in Mozzi are 8bits: 7bits of signal plus one bit of sign, so what they fit into a SFixMath<0,7> which is a signed fixMath type with 7 bits of value.
return MonoOutput :: from8Bit ( aCos . phMod ( vibrato )); // phase modulation to modulate frequency
}
void loop (){
audioHook ();
}
Vibrato_Midi_Note
…(no recording of this one)
show sketch
hide sketch
/* Example playing a sinewave with vibrato,
using Mozzi sonification library.
Demonstrates how to use fixed point arithmetics and midi notes to make an easy-to-adjust vibrato effect.
This is probably less efficient than the Vibrato example, but is also easier to understand the amount
of modulation
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <mozzi_midi.h> // for mtof
#include <FixMath.h> // Fixed point arithmetics
#define CONTROL_RATE 256 // Hz, powers of 2 are most reliable \
// we chose here an higher number than in the Vibrato example \
// because the modulation is performed at CONTROL_RATE
Oscil < COS2048_NUM_CELLS , AUDIO_RATE > aCos ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , CONTROL_RATE > kVibrato ( COS2048_DATA );
UFix < 7 , 0 > midi_note = 65 ;
UFix < 2 , 1 > mod_amplitude = 2.5 ; // the amplitude of the vibrato, in semi-tones.
// 2.5 can be represented with only 2 integer bits
// and 1 fractionnal bit
// hence UFix<2,1> is good enough to represent
// that number. You can put numbers with decimals
// or higher ones, but beware to adjust the number
// of bits NI and NF of the UFix<NI,NF> accordingly.
// It is always good to keep these as small as possible
// for performances.
void setup () {
startMozzi ( CONTROL_RATE );
aCos . setFreq ( mtof ( midi_note ));
kVibrato . setFreq ( UFix < 16 , 16 > ( 10 )); // frequency of the modulation
}
void updateControl () {
auto modulation = toSFraction ( kVibrato . next ()) * mod_amplitude ; // Oscil in Mozzi are fundamentally 8 bits: 7bits of data and 1bit of sign.
// Here, we make it oscillate between nearly -1 and 1 (no integer bit).
// The FixMath class will take care of making modulation the correct type
// to preserve range and precision.
aCos . setFreq ( mtof ( midi_note + modulation )); // changing the frequency of the main oscillator, adding the modulation as a midi note.
}
AudioOutput_t updateAudio () {
return MonoOutput :: from8Bit ( aCos . next ());
}
void loop () {
audioHook ();
}
02.Control
Control_Echo_Theremin
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of a simple light-sensing theremin-like
instrument with long echoes,
using Mozzi sonification library.
Demonstrates ControlDelay() for echoing control values,
and smoothing an analog input from a sensor
signal with RollingAverage().
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 64
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <RollingAverage.h>
#include <ControlDelay.h>
#define INPUT_PIN 0 // analog control input
unsigned int echo_cells_1 = 32 ;
unsigned int echo_cells_2 = 60 ;
unsigned int echo_cells_3 = 127 ;
ControlDelay < 128 , int > kDelay ; // 2seconds
// oscils to compare bumpy to averaged control input
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin0 ( SIN2048_DATA );
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin1 ( SIN2048_DATA );
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin2 ( SIN2048_DATA );
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin3 ( SIN2048_DATA );
// use: RollingAverage <number_type, how_many_to_average> myThing
RollingAverage < int , 32 > kAverage ; // how_many_to_average has to be power of 2
int averaged ;
void setup (){
kDelay . set ( echo_cells_1 );
startMozzi ();
}
void updateControl (){
int bumpy_input = mozziAnalogRead < 10 > ( INPUT_PIN ); // request reading at 10-bit resolution, i.e. 0-1023
averaged = kAverage . next ( bumpy_input );
aSin0 . setFreq ( averaged );
aSin1 . setFreq ( kDelay . next ( averaged ));
aSin2 . setFreq ( kDelay . read ( echo_cells_2 ));
aSin3 . setFreq ( kDelay . read ( echo_cells_3 ));
}
AudioOutput updateAudio (){
return MonoOutput :: fromAlmostNBit ( 12 ,
3 * (( int ) aSin0 . next () + aSin1 . next () + ( aSin2 . next () >> 1 )
+ ( aSin3 . next () >> 2 ))
);
}
void loop (){
audioHook ();
}
Control_Oscil_Wash
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Plays a fluctuating ambient wash,
using Mozzi sonification library.
Demonstrates audio and control rate updates.
There are 8 oscillators updated at control rate to set
the volume of 8 audio oscillators. Updating the volume
at control rate saves processor time, incrementing the
Oscils only 128 times per second rather than at the
audio rate of 16384 Hz.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 128
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <mozzi_midi.h>
// harmonics
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos2 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos3 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos4 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos5 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos6 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos7 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos8 ( COS8192_DATA );
// volume controls
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol1 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol2 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol3 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol4 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol5 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol6 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol7 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol8 ( COS8192_DATA );
// audio volumes updated each control interrupt and reused in audio till next control
char v1 , v2 , v3 , v4 , v5 , v6 , v7 , v8 ;
void setup (){
// set harmonic frequencies
aCos1 . setFreq ( mtof ( 60 ));
aCos2 . setFreq ( mtof ( 74 ));
aCos3 . setFreq ( mtof ( 64 ));
aCos4 . setFreq ( mtof ( 77 ));
aCos5 . setFreq ( mtof ( 67 ));
aCos6 . setFreq ( mtof ( 81 ));
aCos7 . setFreq ( mtof ( 60 ));
aCos8 . setFreq ( mtof ( 84 ));
// set volume change frequencies
kVol1 . setFreq ( 4.43 f ); // more of a pulse
kVol2 . setFreq ( 0.0245 f );
kVol3 . setFreq ( 0.019 f );
kVol4 . setFreq ( 0.07 f );
kVol5 . setFreq ( 0.047 f );
kVol6 . setFreq ( 0.031 f );
kVol7 . setFreq ( 0.0717 f );
kVol8 . setFreq ( 0.041 f );
v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = 127 ;
startMozzi ();
}
void loop (){
audioHook ();
}
void updateControl (){
v1 = kVol1 . next () >> 1 ; // going at a higher freq, this creates zipper noise, so reduce the gain
v2 = kVol2 . next ();
v3 = kVol3 . next ();
v4 = kVol4 . next ();
v5 = kVol5 . next ();
v6 = kVol6 . next ();
v7 = kVol7 . next ();
v8 = kVol8 . next ();
}
AudioOutput updateAudio (){
long asig = ( long )
aCos1 . next () * v1 +
aCos2 . next () * v2 +
aCos3 . next () * v3 +
aCos4 . next () * v4 +
aCos5 . next () * v5 +
aCos6 . next () * v6 +
aCos7 . next () * v7 +
aCos8 . next () * v8 ;
return MonoOutput :: fromAlmostNBit ( 18 , asig );
}
Control_Tremelo
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of amplitude modulation (as tremelo),
using Mozzi sonification library.
Demonstrates audio and control rate updates.
The tremelo oscillator is updated at control rate,
and a Line is used to interpolate the control updates
at audio rate, to remove zipper noise.
A bit contrived and probably less efficient than just
using an audio-rate tremelo oscillator, but hey it's a demo!
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/triangle_valve_2048_int8.h>
#include <tables/sin2048_int8.h>
#include <Line.h>
#include <mozzi_midi.h>
// audio oscillator
Oscil < TRIANGLE_VALVE_2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSig ( TRIANGLE_VALVE_2048_DATA );
// control oscillator for tremelo
Oscil < SIN2048_NUM_CELLS , MOZZI_CONTROL_RATE > kTremelo ( SIN2048_DATA );
// a line to interpolate control tremolo at audio rate
Line < unsigned int > aGain ;
void setup (){
aSig . setFreq ( mtof ( 65. f ));
kTremelo . setFreq ( 5.5 f );
startMozzi ();
}
void updateControl (){
// gain shifted up to give enough range for line's internal steps
unsigned int gain = ( 128u + kTremelo . next ()) << 8 ;
aGain . set ( gain , MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE ); // divide of literals should get optimised away
}
AudioOutput updateAudio (){
// cast to long before multiply to give room for intermediate result,
// and also before shift,
// to give consistent results for both 8 and 32 bit processors.
return MonoOutput :: fromNBit ( 24 , ( int32_t ) aSig . next () * aGain . next ()); // shifted back to audio range after multiply
}
void loop (){
audioHook ();
}
EventDelay
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of a sound being toggled on an off,
using Mozzi sonification library.
Demonstrates scheduling with EventDelay.
EventDelay is a way to make non-blocking
time delays for events. Use this instead of
the Arduino delay() function, which doesn't
work with Mozzi.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 64
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin8192_int8.h> // sine table for oscillator
#include <EventDelay.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN8192_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN8192_DATA );
// for scheduling audio gain changes
EventDelay kGainChangeDelay ;
char gain = 1 ;
void setup (){
startMozzi ();
aSin . setFreq ( 330 ); // set the frequency
kGainChangeDelay . set ( 1000 ); // 1 second countdown, within resolution of MOZZI_CONTROL_RATE
}
void updateControl (){
if ( kGainChangeDelay . ready ()){
gain = 1 - gain ; // flip 0/1
kGainChangeDelay . start ();
}
}
AudioOutput updateAudio (){
return AudioOutput :: from8Bit ( aSin . next () * gain );
}
void loop (){
audioHook ();
}
Line_Gliss
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of sliding smoothly
between oscillator frequencies,
using Mozzi sonification library.
Demonstrates using a Line to efficiently change the
frequency of an oscillator at audio rate. Calculating
a new frequency for every step of a slide is a lot to
do for every single sample, so instead this sketch works out the
start and end frequencies for each control period and
the phase increments (size of the steps through the sound table)
required for the audio oscillator to generate those frequencies.
Then, a computationally cheap Line() is used to slide between the
different phase increments smoothly at audio rate.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Line.h> // for smooth transitions
#include <Oscil.h> // oscillator template
#include <tables/saw8192_int8.h> // saw table for oscillator
#include <mozzi_midi.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SAW8192_NUM_CELLS , MOZZI_AUDIO_RATE > aSaw ( SAW8192_DATA );
// use: Line <type> lineName
Line < long > aGliss ;
byte lo_note = 24 ; // midi note numbers
byte hi_note = 36 ;
long audio_steps_per_gliss = MOZZI_AUDIO_RATE / 4 ; // ie. 4 glisses per second
long control_steps_per_gliss = MOZZI_CONTROL_RATE / 4 ;
// stuff for changing starting positions, probably just confusing really
int counter = 0 ;
byte gliss_offset = 0 ;
byte gliss_offset_step = 2 ;
byte gliss_offset_max = 36 ;
void setup (){
startMozzi ();
}
void loop (){
audioHook ();
}
void updateControl (){
if ( -- counter <= 0 ){
// start at a new note
gliss_offset += gliss_offset_step ;
if ( gliss_offset >= gliss_offset_max ) gliss_offset = 0 ;
// only need to calculate frequencies once each control update
int start_freq = mtof ( lo_note + gliss_offset );
int end_freq = mtof ( hi_note + gliss_offset );
// find the phase increments (step sizes) through the audio table for those freqs
// they are big ugly numbers which the oscillator understands but you don't really want to know
long gliss_start = aSaw . phaseIncFromFreq ( start_freq );
long gliss_end = aSaw . phaseIncFromFreq ( end_freq );
// set the audio rate line to transition between the different step sizes
aGliss . set ( gliss_start , gliss_end , audio_steps_per_gliss );
counter = control_steps_per_gliss ;
}
}
AudioOutput updateAudio (){
aSaw . setPhaseInc ( aGliss . next ());
return MonoOutput :: from8Bit ( aSaw . next ());
}
Line_Gliss_Double_32k_HIFI
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of a pair of detuned oscillators
sliding smoothly between frequencies,
using Mozzi sonification library.
Demonstrates using Lines to efficiently change the
frequency of each oscillator at audio rate. Calculating
a new frequency for every step of a slide is a lot to
do for every single sample, so instead this sketch works out the
start and end frequencies for each control period and
the phase increments (size of the steps through the sound table)
required for the audio oscillators to generate those frequencies.
Then, computationally cheap Lines are used to slide between the
different phase increments smoothly at audio rate.
Also shows how to use random offsets between the oscillators'
frequencies to produce a chorusing/doubling effect.
Important:
This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which
is not available on all boards (among others, it works on the
classic Arduino boards, but not Teensy 3.x and friends).
The MOZZI_AUDIO_RATE (sample rate) is additionally configured at 32768 Hz,
which is the default on most platforms, but twice the standard rate on
AVR-CPUs.
Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar),
Check the Mozzi core module documentation for others and more detail
3.9k
pin 9 ---WWWW-----|-----output
499k |
pin 10 ---WWWW---- |
|
4.7n ==
|
ground
Resistors are ±0.5% Measure and choose the most precise
from a batch of whatever you can get. Use two 1M resistors
in parallel if you can't find 499k.
Alternatively using 39 ohm, 4.99k and 470nF components will
work directly with headphones.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
#define MOZZI_AUDIO_RATE 32768
#include <Mozzi.h>
#include <Line.h> // for smooth transitions
#include <Oscil.h> // oscillator template
#include <tables/saw8192_int8.h> // saw table for oscillator
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <mozzi_fixmath.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SAW8192_NUM_CELLS , MOZZI_AUDIO_RATE > aSaw1 ( SAW8192_DATA );
Oscil < SAW8192_NUM_CELLS , MOZZI_AUDIO_RATE > aSaw2 ( SAW8192_DATA );
// use: Line <type> lineName
Line < long > aGliss1 ;
Line < long > aGliss2 ;
byte lo_note = 24 ; // midi note numbers
byte hi_note = 46 ;
long audio_steps_per_gliss = MOZZI_AUDIO_RATE / 4 ; // ie. 4 glisses per second
long control_steps_per_gliss = MOZZI_CONTROL_RATE / 4 ;
// stuff for changing starting positions, probably just confusing really
int counter = 0 ;
byte gliss_offset = 0 ;
byte gliss_offset_step = 2 ;
byte gliss_offset_max = 36 ;
void setup () {
//randSeed();
//pinMode(0,OUTPUT); // without this, updateControl() gets interrupted ........??
startMozzi (); // uses default 50 control rate
}
// variation between oscillator's phase increments
// looks like a big number, but they are high precision
// and this is just a fractional part
long variation (){
return rand ( 16383 );
}
void updateControl (){ // 900 us floats vs 160 fixed
if ( -- counter <= 0 ){
// start at a new note
gliss_offset += gliss_offset_step ;
if ( gliss_offset >= gliss_offset_max ) {
gliss_offset = 0 ;
// this is just confusing, you should ignore it!
// alternate between 2 and 3 steps per start note each time a new "run" starts
if ( gliss_offset_step != 2 ){
gliss_offset_step = 2 ;
}
else {
gliss_offset_step = 3 ;
}
}
// only need to calculate frequencies once each control update
int start_freq = mtof ( lo_note + gliss_offset );
int end_freq = mtof ( hi_note + gliss_offset );
// find the phase increments (step sizes) through the audio table for those freqs
// they are big ugly numbers which the oscillator understands but you don't really want to know
long gliss_start = aSaw1 . phaseIncFromFreq ( start_freq );
long gliss_end = aSaw1 . phaseIncFromFreq ( end_freq );
aGliss1 . set ( gliss_start , gliss_end , audio_steps_per_gliss );
// aGliss2 is an octave up and detuned
aGliss2 . set (( gliss_start + ( variation () * gliss_offset )) * 2 , ( gliss_end + ( variation () * gliss_offset )) * 2 , audio_steps_per_gliss );
counter = control_steps_per_gliss ;
}
}
AudioOutput updateAudio (){
aSaw1 . setPhaseInc ( aGliss1 . next ());
aSaw2 . setPhaseInc ( aGliss2 . next ());
return MonoOutput :: fromNBit ( 9 , ( int ) aSaw1 . next () + aSaw2 . next ());
}
void loop (){
audioHook ();
}
Metronome_SampleHuffman
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example using Metronome to playing samples encoded with Huffman compression.
Demonstrates Metronome start, stop and ready, and the the SampleHuffman class.
Circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Metronome.h>
#include <SampleHuffman.h>
#include <mozzi_rand.h>
#include <samples/thumbpiano_huffman/thumbpiano0.h>
#include <samples/thumbpiano_huffman/thumbpiano1.h>
#include <samples/thumbpiano_huffman/thumbpiano2.h>
#include <samples/thumbpiano_huffman/thumbpiano3.h>
#include <samples/thumbpiano_huffman/thumbpiano4.h>
SampleHuffman thumb0 ( THUMB0_SOUNDDATA , THUMB0_HUFFMAN , THUMB0_SOUNDDATA_BITS );
SampleHuffman thumb1 ( THUMB1_SOUNDDATA , THUMB1_HUFFMAN , THUMB1_SOUNDDATA_BITS );
SampleHuffman thumb2 ( THUMB2_SOUNDDATA , THUMB2_HUFFMAN , THUMB2_SOUNDDATA_BITS );
SampleHuffman thumb3 ( THUMB3_SOUNDDATA , THUMB3_HUFFMAN , THUMB3_SOUNDDATA_BITS );
SampleHuffman thumb4 ( THUMB4_SOUNDDATA , THUMB4_HUFFMAN , THUMB4_SOUNDDATA_BITS );
const char NUM_SAMPLES = 5 ;
Metronome kMetro ( 800 ); // enough delay so samples don't overlap, because the load would be too much
void setup () {
startMozzi ();
}
void updateControl (){
static unsigned int counter ;
counter ++ ;
if ( counter == 177 ) kMetro . stop ();
if ( counter == 203 ){ kMetro . start (); counter = 0 ;}
if ( kMetro . ready ()){
switch ( rand ( NUM_SAMPLES )){
case 0 :
thumb0 . start ();
break ;
case 1 :
thumb1 . start ();
break ;
case 2 :
thumb2 . start ();
break ;
case 3 :
thumb3 . start ();
break ;
case 4 :
thumb4 . start ();
break ;
}
}
}
AudioOutput updateAudio (){
int asig = ( int )
thumb0 . next () +
thumb1 . next () +
thumb2 . next () +
thumb3 . next () +
thumb4 . next ();
// Note: Samples don't overlap, here, therefore this the sum is still only 8 bits range
return MonoOutput :: from8Bit ( asig );
}
void loop () {
audioHook ();
}
Pause
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example pausing Mozzi, restoring timers to previous states,
during which Arduino delay() works, then resuming Mozzi again.
This may be useful when using sensors or other libraries which need to use
the same timers as Mozzi. (Atmel Timer 0, Timer 1, and in HIFI mode, Timer 2).
Circuit:
Pushbutton on digital pin D4
button from the digital pin to +5V (3.3V on Teensy 3.1)
10K resistor from the digital pin to ground
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or https://sensorium.github.io/Mozzi/
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2013, CC by-nc-sa.
*/
//#include <ADC.h> // Teensy 3.1 uncomment this line and install https://github.com/pedvide/ADC
#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/brownnoise8192_int8.h> // recorded audio wavetable
#include <mozzi_rand.h>
Oscil < BROWNNOISE8192_NUM_CELLS , AUDIO_RATE > aNoise ( BROWNNOISE8192_DATA );
#define STOP_PIN 4
void setup (){
pinMode ( STOP_PIN , INPUT );
aNoise . setFreq ( 2. f );
startMozzi ();
}
void updateControl (){
static int previous ;
int current = digitalRead ( STOP_PIN );
if ( previous == LOW && current == HIGH ){
pauseMozzi ();
} else if ( previous == HIGH && current == LOW ){
unPauseMozzi ();
}
previous = current ;
// jump to a new spot in the noise table to stop it sounding like it repeats
aNoise . setPhase ( rand ( BROWNNOISE8192_NUM_CELLS ));
}
int updateAudio (){
return aNoise . next ();
}
void loop (){
audioHook ();
}
Stop_Start
…(no recording of this one)
show sketch
hide sketch
/* Example stopping Mozzi, which restores timers to previous states,
so Arduino delay() and milleseconds() work, then resuming Mozzi again.
This may be useful when using sensors or other libraries which need to use
the same timers as Mozzi. (Atmel Timer 0, Timer 1, and in HIFI mode, Timer 2).
Circuit:
Pushbutton on digital pin D4
button from the digital pin to +5V (3.3V on Teensy 3.1)
10K resistor from the digital pin to ground
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/sin2048_int8.h> // sine table for oscillator
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
#define STOP_PIN 4
boolean pause_triggered , paused = false ;;
unsigned int count = 0 ;
void setup () {
pinMode ( STOP_PIN , INPUT );
aSin . setFreq ( 220 ); // set the frequency
startMozzi ();
Serial . begin ( 115200 );
}
void updateControl () {
if ( digitalRead ( STOP_PIN ) == HIGH ) {
pause_triggered = true ;
count = 0 ;
}
}
AudioOutput updateAudio () {
return MonoOutput :: from8Bit ( aSin . next ());
}
void loop () {
if ( pause_triggered ) {
paused = true ;
pause_triggered = false ;
stopMozzi ();
}
if ( paused ) {
Serial . println ( count ++ );
delay ( 100 );
if ( count > 10 ) {
paused = false ;
startMozzi ();
}
}
if ( ! paused ) audioHook ();
}
03.Sensors
Knob_LDR_x2_WavePacket
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example of Wavepacket synthesis, using analog
inputs to change the fundamental frequency,
bandwidth and centre frequency,
using Mozzi sonification library.
Demonstrates WavePacket, mozziAnalogRead(), and smoothing
control signals with RollingAverage.
Also demonstrates AutoMap, which maps unpredictable inputs to a set range.
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 2:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_ANALOG_READ_RESOLUTION 10 // code below assumes readings to be in the classic 10-bit (0-1023) range
#include <Mozzi.h>
#include <WavePacket.h>
#include <RollingAverage.h>
#include <AutoMap.h>
#include <IntMap.h>
const int KNOB_PIN = 0 ; // set the input for the knob to analog pin 0
const int LDR1_PIN = 1 ; // set the analog input for fm_intensity to pin 1
const int LDR2_PIN = 2 ; // set the analog input for mod rate to pin 2
// min and max values of synth parameters to map AutoRanged analog inputs to
const int MIN_F = 20 ;
const int MAX_F = 150 ;
const int MIN_BW = 20 ;
const int MAX_BW = 600 ;
const int MIN_CF = 60 ;
const int MAX_CF = 600 ;
// for smoothing the control signals
// use: RollingAverage <number_type, how_many_to_average> myThing
RollingAverage < int , 16 > kAverageF ;
RollingAverage < int , 16 > kAverageBw ;
RollingAverage < int , 16 > kAverageCf ;
// Intmap is a pre-calculated faster version of Arduino's map, OK for pots
IntMap kMapF ( 0 , 1023 , MIN_F , MAX_F );
// AutoMap adapts to range of input as it arrives, useful for LDR's
AutoMap kMapBw ( 0 , 1023 , MIN_BW , MAX_BW );
AutoMap kMapCf ( 0 , 1023 , MIN_CF , MAX_CF );
WavePacket < DOUBLE > wavey ; // DOUBLE selects 2 overlapping streams
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 );
// wait before starting Mozzi to receive analog reads, so AutoRange will not get 0
delay ( 200 );
startMozzi ();
}
void updateControl (){
int fundamental = mozziAnalogRead ( KNOB_PIN ) + 1 ;
fundamental = kMapF ( fundamental );
Serial . print ( "f=" );
Serial . print ( fundamental );
int bandwidth = mozziAnalogRead ( LDR1_PIN );
bandwidth = kMapBw ( bandwidth );
Serial . print ( " \t bw=" );
Serial . print ( bandwidth );
int centre_freq = mozziAnalogRead ( LDR2_PIN );
centre_freq = kMapCf ( centre_freq );
Serial . print ( " \t cf=" );
Serial . print ( centre_freq );
Serial . println ();
wavey . set ( fundamental , bandwidth , centre_freq );
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit ( wavey . next ());
}
void loop (){
audioHook (); // required here
}
Knob_LightLevel_FMsynth
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example using a light dependent resistor (LDR) to change
an FM synthesis parameter, and a knob for fundamental frequency,
using Mozzi sonification library.
Demonstrates analog input, audio oscillators, and phase modulation.
Also demonstrates AutoMap, which maps unpredictable inputs to a set range.
There might be clicks in the audio from rapid control changes, which
could be smoothed with Line or Smooth objects.
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h> // oscillator
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <AutoMap.h> // maps unpredictable inputs to a range
// desired carrier frequency max and min, for AutoMap
const int MIN_CARRIER_FREQ = 22 ;
const int MAX_CARRIER_FREQ = 440 ;
// desired intensity max and min, for AutoMap, note they're inverted for reverse dynamics
const int MIN_INTENSITY = 700 ;
const int MAX_INTENSITY = 10 ;
AutoMap kMapCarrierFreq ( 0 , 1023 , MIN_CARRIER_FREQ , MAX_CARRIER_FREQ );
AutoMap kMapIntensity ( 0 , 1023 , MIN_INTENSITY , MAX_INTENSITY );
const int KNOB_PIN = 0 ; // set the input for the knob to analog pin 0
const int LDR_PIN = 1 ; // set the input for the LDR to analog pin 1
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCarrier ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aModulator ( COS2048_DATA );
int mod_ratio = 3 ; // harmonics
long fm_intensity ; // carries control info from updateControl() to updateAudio()
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 ); // set up the Serial output so we can look at the piezo values // set up the Serial output for debugging
startMozzi (); // :))
}
void updateControl (){
// read the knob
int knob_value = mozziAnalogRead < 10 > ( KNOB_PIN ); // value is 0-1023
// map the knob to carrier frequency
int carrier_freq = kMapCarrierFreq ( knob_value );
//calculate the modulation frequency to stay in ratio
int mod_freq = carrier_freq * mod_ratio ;
// set the FM oscillator frequencies to the calculated values
aCarrier . setFreq ( carrier_freq );
aModulator . setFreq ( mod_freq );
// read the light dependent resistor on the Analog input pin
int light_level = mozziAnalogRead < 10 > ( LDR_PIN ); // value is 0-1023
// print the value to the Serial monitor for debugging
Serial . print ( "light_level = " );
Serial . print ( light_level );
Serial . print ( " \t " ); // prints a tab
fm_intensity = kMapIntensity ( light_level );
Serial . print ( "fm_intensity = " );
Serial . print ( fm_intensity );
Serial . println (); // print a carraige return for the next line of debugging info
}
AudioOutput updateAudio (){
long modulation = fm_intensity * aModulator . next ();
return MonoOutput :: from8Bit ( aCarrier . phMod ( modulation )); // phMod does the FM
}
void loop (){
audioHook ();
}
Knob_LightLevel_x2_FMsynth
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example using 2 light dependent resistors (LDRs) to change
FM synthesis parameters, and a knob for fundamental frequency,
using Mozzi sonification library.
Demonstrates analog input, audio and control oscillators, phase modulation
and smoothing a control signal at audio rate to avoid clicks.
Also demonstrates AutoMap, which maps unpredictable inputs to a set range.
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 2:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_ANALOG_READ_RESOLUTION 10 // code below assumes readings to be in the classic 10-bit (0-1023) range
#include <Mozzi.h>
#include <Oscil.h> // oscillator
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <Smooth.h>
#include <AutoMap.h> // maps unpredictable inputs to a range
// desired carrier frequency max and min, for AutoMap
const int MIN_CARRIER_FREQ = 22 ;
const int MAX_CARRIER_FREQ = 440 ;
// desired intensity max and min, for AutoMap, note they're inverted for reverse dynamics
const int MIN_INTENSITY = 700 ;
const int MAX_INTENSITY = 10 ;
// desired mod speed max and min, for AutoMap, note they're inverted for reverse dynamics
const int MIN_MOD_SPEED = 10000 ;
const int MAX_MOD_SPEED = 1 ;
AutoMap kMapCarrierFreq ( 0 , 1023 , MIN_CARRIER_FREQ , MAX_CARRIER_FREQ );
AutoMap kMapIntensity ( 0 , 1023 , MIN_INTENSITY , MAX_INTENSITY );
AutoMap kMapModSpeed ( 0 , 1023 , MIN_MOD_SPEED , MAX_MOD_SPEED );
const int KNOB_PIN = 0 ; // set the input for the knob to analog pin 0
const int LDR1_PIN = 1 ; // set the analog input for fm_intensity to pin 1
const int LDR2_PIN = 2 ; // set the analog input for mod rate to pin 2
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCarrier ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aModulator ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kIntensityMod ( COS2048_DATA );
int mod_ratio = 5 ; // brightness (harmonics)
long fm_intensity ; // carries control info from updateControl to updateAudio
// smoothing for intensity to remove clicks on transitions
float smoothness = 0.95 f ;
Smooth < long > aSmoothIntensity ( smoothness );
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 ); // set up the Serial output so we can look at the piezo values // set up the Serial output so we can look at the light level
startMozzi (); // :))
}
void updateControl (){
// read the knob
int knob_value = mozziAnalogRead ( KNOB_PIN ); // value is 0-1023
// map the knob to carrier frequency
int carrier_freq = kMapCarrierFreq ( knob_value );
//calculate the modulation frequency to stay in ratio
int mod_freq = carrier_freq * mod_ratio ;
// set the FM oscillator frequencies
aCarrier . setFreq ( carrier_freq );
aModulator . setFreq ( mod_freq );
// read the light dependent resistor on the width Analog input pin
int LDR1_value = mozziAnalogRead ( LDR1_PIN ); // value is 0-1023
// print the value to the Serial monitor for debugging
Serial . print ( "LDR1 = " );
Serial . print ( LDR1_value );
Serial . print ( " \t " ); // prints a tab
int LDR1_calibrated = kMapIntensity ( LDR1_value );
Serial . print ( "LDR1_calibrated = " );
Serial . print ( LDR1_calibrated );
Serial . print ( " \t " ); // prints a tab
// calculate the fm_intensity
fm_intensity = (( long ) LDR1_calibrated * ( kIntensityMod . next () + 128 )) >> 8 ; // shift back to range after 8 bit multiply
Serial . print ( "fm_intensity = " );
Serial . print ( fm_intensity );
Serial . print ( " \t " ); // prints a tab
// read the light dependent resistor on the speed Analog input pin
int LDR2_value = mozziAnalogRead ( LDR2_PIN ); // value is 0-1023
Serial . print ( "LDR2 = " );
Serial . print ( LDR2_value );
Serial . print ( " \t " ); // prints a tab
// use a float here for low frequencies
float mod_speed = ( float ) kMapModSpeed ( LDR2_value ) / 1000 ;
Serial . print ( " mod_speed = " );
Serial . print ( mod_speed );
kIntensityMod . setFreq ( mod_speed );
Serial . println (); // finally, print a carraige return for the next line of debugging info
}
AudioOutput updateAudio (){
long modulation = aSmoothIntensity . next ( fm_intensity ) * aModulator . next ();
return MonoOutput :: from8Bit ( aCarrier . phMod ( modulation ));
}
void loop (){
audioHook ();
}
Light_Temperature_Detuned
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Plays a fluctuating ambient wash in response to light and temperature sensors.
Pairs of audio oscillators are detuned in response to light on an LDR and
the base frequencies are offset depending on the temperature.
It's a pretty dumb sonification, but at this stage
it's just to demonstrate the possibility of reading sensors while
lots of audio oscillators are running.
Circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Temperature dependent resistor (Thermistor) and 5.1k resistor on analog pin 1:
Thermistor from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 2:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#define THERMISTOR_PIN 1
#define LDR_PIN 2
// harmonics
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos2 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos3 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos4 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos5 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos6 ( COS8192_DATA );
// duplicates but slightly off frequency for adding to originals
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1b ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos2b ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos3b ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos4b ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos5b ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos6b ( COS8192_DATA );
// base pitch frequencies
float f0 , f1 , f2 , f3 , f4 , f5 , f6 ;
// to map light input to frequency divergence of the b oscillators
const float DIVERGENCE_SCALE = 0.01 ; // 0.01*1023 = 10.23 Hz max divergence
// to map temperature to base freq drift
const float OFFSET_SCALE = 0.1 ; // 0.1*1023 = 102.3 Hz max drift
void setup (){
startMozzi ();
// select base frequencies using mtof
// C F♯ B♭ E A D the "Promethean chord"
f1 = mtof ( 48. f );
f2 = mtof ( 54. f );
f3 = mtof ( 58. f );
f4 = mtof ( 64. f );
f5 = mtof ( 69. f );
f6 = mtof ( 74. f );
// set Oscils with chosen frequencies
aCos1 . setFreq ( f1 );
aCos2 . setFreq ( f2 );
aCos3 . setFreq ( f3 );
aCos4 . setFreq ( f4 );
aCos5 . setFreq ( f5 );
aCos6 . setFreq ( f6 );
// set frequencies of duplicate oscillators
aCos1b . setFreq ( f1 );
aCos2b . setFreq ( f2 );
aCos3b . setFreq ( f3 );
aCos4b . setFreq ( f4 );
aCos5b . setFreq ( f5 );
aCos6b . setFreq ( f6 );
}
void loop (){
audioHook ();
}
void updateControl (){
// read analog inputs
int temperature = mozziAnalogRead < 10 > ( THERMISTOR_PIN ); // not calibrated to degrees! Simply a 10-bit voltage reading (0-1023)
int light_input = mozziAnalogRead < 10 > ( LDR_PIN );
float base_freq_offset = OFFSET_SCALE * temperature ;
float divergence = DIVERGENCE_SCALE * light_input ;
float freq ;
// change frequencies of the oscillators, randomly choosing one pair each time to change
switch ( rand ( 6 ) + 1 ){
case 1 :
freq = f1 + base_freq_offset ;
aCos1 . setFreq ( freq );
aCos1b . setFreq ( freq + divergence );
break ;
case 2 :
freq = f2 + base_freq_offset ;
aCos2 . setFreq ( freq );
aCos2b . setFreq ( freq + divergence );
break ;
case 3 :
freq = f3 + base_freq_offset ;
aCos3 . setFreq ( freq );
aCos3b . setFreq ( freq + divergence );
break ;
case 4 :
freq = f4 + base_freq_offset ;
aCos4 . setFreq ( freq );
aCos4b . setFreq ( freq + divergence );
break ;
case 5 :
freq = f5 + base_freq_offset ;
aCos5 . setFreq ( freq );
aCos5b . setFreq ( freq + divergence );
break ;
case 6 :
freq = f6 + base_freq_offset ;
aCos6 . setFreq ( freq );
aCos6b . setFreq ( freq + divergence );
break ;
}
}
AudioOutput updateAudio (){
int asig =
aCos1 . next () + aCos1b . next () +
aCos2 . next () + aCos2b . next () +
aCos3 . next () + aCos3b . next () +
aCos4 . next () + aCos4b . next () +
aCos5 . next () + aCos5b . next () +
aCos6 . next () + aCos6b . next ();
return MonoOutput :: fromAlmostNBit ( 12 , asig );
}
Light_Temperature_Multi_Oscil
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Plays a fluctuating ambient wash in response to light and temperature sensors,
using Mozzi sonification library.
8 control rate oscillators are used to set the volume of 8 audio oscillators.
Temperature readings from a thermistor are used to set the notes
being played, and light readings from a light dependent resistor are
mapped to the pulse rates of the volume control oscillators.
Circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Temperature dependent resistor (Thermistor) and 5.1k resistor on analog pin 1:
Thermistor from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Light dependent resistor (LDR) and 5.1k resistor on analog pin 2:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 256
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <mozzi_midi.h>
#define THERMISTOR_PIN 1
#define LDR_PIN 2
#define NUM_VOICES 8
#define THRESHOLD 10
// harmonics
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos2 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos3 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos4 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos5 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos6 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos7 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos0 ( COS8192_DATA );
// volume controls
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol1 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol2 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol3 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol4 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol5 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol6 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol7 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kVol0 ( COS8192_DATA );
// audio volumes updated each control interrupt and reused in audio till next control
char v1 , v2 , v3 , v4 , v5 , v6 , v7 , v0 ;
// notes to play depending on whether temperature reading increases or decreases
float upnotes [ NUM_VOICES ] = {
mtof ( 62. f ), mtof ( 64. f ), mtof ( 70. f ), mtof ( 72. f ), mtof ( 79. f ), mtof ( 81. f ), mtof ( 86. f ), mtof ( 88. f )};
float downnotes [ NUM_VOICES ] = {
mtof ( 64. f ), mtof ( 65. f ), mtof ( 88. f ), mtof ( 72. f ), mtof ( 79. f ), mtof ( 84. f ), mtof ( 86. f ), mtof ( 89. f )};
void setup (){
startMozzi ();
}
// returns freq
int temperatureToFreq ( char oscil_num , int temperature ){
static int previous_temperature ;
int freq ;
if ( temperature > previous_temperature ){
freq = upnotes [ oscil_num ];
} else {
freq = downnotes [ oscil_num ];
}
previous_temperature = temperature ;
return freq ;
}
void updateControl (){
static float previous_pulse_freq ;
// read analog inputs
int temperature = mozziAnalogRead < 10 > ( THERMISTOR_PIN ); // not calibrated to degrees!
int light = mozziAnalogRead < 10 > ( LDR_PIN );
// map light reading to volume pulse frequency
float pulse_freq = ( float ) light / 256 ;
previous_pulse_freq = pulse_freq ;
v0 = kVol0 . next ();
v1 = kVol1 . next ();
v2 = kVol2 . next ();
v3 = kVol3 . next ();
v4 = kVol4 . next ();
v5 = kVol5 . next ();
v6 = kVol6 . next ();
v7 = kVol7 . next ();
// set one note oscillator frequency each time (if it's volume is close to 0)
static char whoseTurn ;
switch ( whoseTurn ){
case 0 :
kVol0 . setFreq ( pulse_freq );
if ( abs ( v0 ) < THRESHOLD ) aCos0 . setFreq ( temperatureToFreq ( 0 , temperature ));
break ;
case 1 :
kVol1 . setFreq ( pulse_freq );
if ( abs ( v1 ) < THRESHOLD ) aCos1 . setFreq ( temperatureToFreq ( 1 , temperature ));
break ;
case 2 :
kVol2 . setFreq ( pulse_freq );
if ( abs ( v2 ) < THRESHOLD ) aCos2 . setFreq ( temperatureToFreq ( 2 , temperature ));
break ;
case 3 :
kVol3 . setFreq ( pulse_freq );
if ( abs ( v3 ) < THRESHOLD ) aCos3 . setFreq ( temperatureToFreq ( 3 , temperature ));
break ;
case 4 :
kVol4 . setFreq ( pulse_freq );
if ( abs ( v4 ) < THRESHOLD ) aCos4 . setFreq ( temperatureToFreq ( 4 , temperature ));
break ;
case 5 :
kVol5 . setFreq ( pulse_freq );
if ( abs ( v5 ) < THRESHOLD ) aCos5 . setFreq ( temperatureToFreq ( 5 , temperature ));
break ;
case 6 :
kVol6 . setFreq ( pulse_freq );
if ( abs ( v6 ) < THRESHOLD ) aCos6 . setFreq ( temperatureToFreq ( 6 , temperature ));
break ;
case 7 :
kVol7 . setFreq ( pulse_freq );
if ( abs ( v7 ) < THRESHOLD ) aCos7 . setFreq ( temperatureToFreq ( 7 , temperature ));
break ;
}
if ( ++ whoseTurn >= NUM_VOICES ) whoseTurn = 0 ;
}
AudioOutput updateAudio (){
long asig = ( long )
aCos0 . next () * v0 +
aCos1 . next () * v1 +
aCos2 . next () * v2 +
aCos3 . next () * v3 +
aCos4 . next () * v4 +
aCos5 . next () * v5 +
aCos6 . next () * v6 +
aCos7 . next () * v7 ;
return MonoOutput :: fromAlmostNBit ( 18 , asig );
}
void loop (){
audioHook ();
}
Piezo_Frequency
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example using a piezo to change the frequency of a sinewave
with Mozzi sonification library.
Demonstrates the use of Oscil to play a wavetable, and analog input for control.
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Piezo on analog pin 3:
+ connection of the piezo attached to the analog pin
- connection of the piezo attached to ground
1-megohm resistor between the analog pin and ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
// increase the rate of updateControl from the default of 64, to catch the piezo's rapid transients
#define MOZZI_CONTROL_RATE 128
#include <Mozzi.h>
#include <Oscil.h> // oscillator
#include <tables/sin2048_int8.h> // table for Oscils to play
#include <Smooth.h>
const int PIEZO_PIN = 3 ; // set the analog input pin for the piezo
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 ); // set up the Serial output so we can look at the piezo values
startMozzi (); // :)) uses the control rate defined above
}
void updateControl (){
// read the piezo. We request 12-bits resolution, here, for values of 0-4095. Some boards
// will actually provide that much accuracy, for others the readings are simply shifted to a
// larger range.
int piezo_value = mozziAnalogRead ( PIEZO_PIN ); // value is 0-1023
// print the value to the Serial monitor for debugging
Serial . print ( "piezo_value = " );
Serial . print ( piezo_value );
Serial . print ( " \t \t " ); // prints 2 tabs
// print the frequency to the Serial monitor for debugging
Serial . print ( "frequency = " );
Serial . print ( frequency );
// set the frequency
aSin . setFreq ( frequency );
Serial . println (); // next line
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aSin . next ());
}
void loop (){
audioHook ();
}
Piezo_SampleScrubber
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example of simple "scrubbing" through a sampled sound with a knob
using Mozzi sonification library.
Demonstrates getting audio samples from a table using a Line to
slide between different indexes.
Also demonstrates mozziAnalogRead(pin), a non-blocking replacement for mozziAnalogRead
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Piezo on analog pin A3:
+ connection of the piezo attached to the analog pin
- connection of the piezo attached to ground
1-megOhm resistor attached from the analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Sample.h> // Sample template
#include "blahblah4b_int8.h"
#include <Line.h>
#include <Smooth.h>
#define INPUT_PIN 3
// use this smooth out the wandering/jumping rate of scrubbing, gives more convincing reverses
Smooth < int > kSmoothOffset ( 0.85 f );
// use: Sample <table_size, update_rate, interpolation > SampleName (wavetable)
Sample < BLAHBLAH4B_NUM_CELLS , MOZZI_AUDIO_RATE , INTERP_LINEAR > aSample ( BLAHBLAH4B_DATA );
//Line to scrub through sample at audio rate, Line target is set at control rate
Line < Q16n16 > scrub ; // Q16n16 fixed point for high precision
// the number of audio steps the line has to take to reach the next offset
const unsigned int AUDIO_STEPS_PER_CONTROL = MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE ;
void setup (){
aSample . setLoopingOn ();
startMozzi ();
}
void updateControl (){
// read the pot
int sensor_value = mozziAnalogRead < 10 > ( INPUT_PIN ); // value is 0-1023
// map it to an 8 bit range for efficient calculations in updateAudio
int target = (( long ) sensor_value * BLAHBLAH4B_NUM_CELLS ) >> 10 ; // >> 10 is / 1024
int smooth_offset = kSmoothOffset . next ( target );
// set new target for interpolating line to scrub to
scrub . set ( Q16n0_to_Q16n16 ( smooth_offset ), AUDIO_STEPS_PER_CONTROL );
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aSample . atIndex ( Q16n16_to_Q16n0 ( scrub . next ())));
}
void loop (){
audioHook ();
}
Piezo_SampleTrigger
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example using a piezo to trigger an audio sample to play,
and a knob to set the playback pitch,
with Mozzi sonification library.
Demonstrates one-shot samples and analog input for control.
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Piezo on analog pin 3:
+ connection of the piezo attached to the analog pin
- connection of the piezo attached to ground
1-megohm resistor between the analog pin and ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Sample.h> // Sample template
#include <samples/burroughs1_18649_int8.h> // a converted audio sample included in the Mozzi download
const char KNOB_PIN = 0 ; // set the analog input pin for the knob
const char PIEZO_PIN = 3 ; // set the analog input pin for the piezo
const int threshold = 80 ; // threshold value to decide when the detected signal is a knock or not
// use: Sample <table_size, update_rate> SampleName (wavetable)
Sample < BURROUGHS1_18649_NUM_CELLS , MOZZI_AUDIO_RATE > aSample ( BURROUGHS1_18649_DATA );
float recorded_pitch = ( float ) BURROUGHS1_18649_SAMPLERATE / ( float ) BURROUGHS1_18649_NUM_CELLS ;
boolean triggered = false ;
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 ); // set up the Serial output so we can look at the piezo values // set up the Serial output so we can look at the piezo values
startMozzi (); // :))
}
void updateControl (){
// read the knob
int knob_value = mozziAnalogRead < 10 > ( KNOB_PIN ); // value is 0-1023
// map it to values between 0.1 and about double the recorded pitch
float pitch = ( recorded_pitch * ( float ) knob_value / 512. f ) + 0.1 f ;
// set the sample playback frequency
aSample . setFreq ( pitch );
// read the piezo
int piezo_value = mozziAnalogRead < 10 > ( PIEZO_PIN ); // value is 0-1023
// print the value to the Serial monitor for debugging
Serial . print ( "piezo value = " );
Serial . print ( piezo_value );
// only trigger once each time the piezo goes over the threshold
if ( piezo_value > threshold ) {
if ( ! triggered ){
aSample . start ();
triggered = true ;
}
} else {
triggered = false ;
}
Serial . println (); // next line
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aSample . next ());
}
void loop (){
audioHook ();
}
Piezo_Switch_Pitch
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example using a piezo to trigger an audio sample
and a switch to change the playback pitch.
using Mozzi sonification library.
Demonstrates one-shot samples, analog input for triggering,
and digital input for switching.
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Piezo on analog pin A3:
+ connection of the piezo attached to the analog pin
- connection of the piezo attached to ground
1-megOhm resistor attached from the analog pin to ground
Pushbutton on digital pin D4
button between the digital pin and +5V
10K resistor from the digital pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Sample.h> // Sample template
#include <samples/burroughs1_18649_int8.h> // a converted audio sample included in the Mozzi download
const int PIEZO_PIN = 3 ; // set the analog input pin for the piezo
const int threshold = 80 ; // threshold value to decide when the detected signal is a knock or not
const int BUTTON_PIN = 4 ; // set the digital input pin for the button
// use: Sample <table_size, update_rate> SampleName (wavetable)
Sample < BURROUGHS1_18649_NUM_CELLS , MOZZI_AUDIO_RATE > aSample ( BURROUGHS1_18649_DATA );
float recorded_pitch = ( float ) BURROUGHS1_18649_SAMPLERATE / ( float ) BURROUGHS1_18649_NUM_CELLS ;
char button_state , previous_button_state ; // variable for reading the pushbutton status
char latest_button_change ;
boolean triggered = false ;
float pitch , pitch_change ;
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 ); // set up the Serial output so we can look at the piezo values // set up the Serial output so we can look at the piezo values
startMozzi (); // :))
}
void buttonChangePitch (){
// read the state of the pushbutton value:
button_state = digitalRead ( BUTTON_PIN );
// has the button state changed?
if ( button_state != previous_button_state ){
// if the latest change was a press, pitch up, else pitch down
if ( button_state == HIGH ) {
pitch = 2. f * recorded_pitch ;
}
else {
pitch = 0.5 f * recorded_pitch ;
}
}
previous_button_state = button_state ;
}
void updateControl (){
// read the piezo
int piezo_value = mozziAnalogRead < 10 > ( PIEZO_PIN ); // value is 0-1023
// print the value to the Serial monitor for debugging
Serial . print ( "piezo value = " );
Serial . print ( piezo_value );
// only trigger once each time the piezo goes over the threshold
if ( piezo_value > threshold ) {
if ( ! triggered ){
pitch = recorded_pitch ;
aSample . start ();
triggered = true ;
}
}
else {
triggered = false ;
}
buttonChangePitch ();
aSample . setFreq ( pitch );
Serial . println (); // next line
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aSample . next ());
}
void loop (){
audioHook ();
}
RCpoll
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Sets the frequency of an oscillator with a resistive sensor on a digital pin,
* using Mozzi sonification library.
*
* Demonstrates RCpoll to read a resistive sensor on a digital pin,
* without blocking audio output.
*
* Control circuit: http://arduino.cc/en/Tutorial/RCtime
* Values for components which work with this sketch are:
* Sensing Capacitor .1uf (104)
* Variable resistor 1 MegaOhm
* Input resistor 470 Ohms
*
+5V
|
|
___
___ Sensing Cap
| .1 uf
|
sPin ---\/\/\/-----.
220 - 1K |
|
\
/ Variable Resistive Sensor
\ Photocell, phototransistor, FSR etc.
/
|
|
_____
___
_
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <RCpoll.h>
#define SENSOR_PIN 4 // digital pin for sensor input
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
RCpoll < SENSOR_PIN > sensor ;
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 );
startMozzi ();
}
void updateControl (){
int freq = 60 + 8 * sensor . next (); // sensor ranges about 0 to 13
Serial . println ( freq );
aSin . setFreq ( freq );
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aSin . next ());
}
void loop (){
audioHook ();
}
Sinewave_Pinchange_Interrupt
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example of changing a sound in response to pin changes detected
in the background with an interrupt, using PinChangeInt library
with Mozzi sonification library.
Demonstrates using Mozzi with PinChangeInterrupt library from:
https://github.com/NicoHood/PinChangeInterrupt
(AVR only)
Circuit:
Audio output on digital pin 9 on a Uno or similar, or
check the README or http://sensorium.github.io/Mozzi/
Pushbutton on digital pin D4
button from the digital pin to +5V
10K resistor from the digital pin to ground
6.8nf capacitor from the digital pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <PinChangeInterrupt.h>
#define PIN 4 // the pin we are interested in
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
void setup (){
aSin . setFreq ( 440 );
pinMode ( PIN , INPUT ); //set the pin to input
digitalWrite ( PIN , HIGH ); //use the internal pullup resistor
attachPCINT ( digitalPinToPCINT ( PIN ), changeFreq , RISING ); // attach a PinChange Interrupt to our pin on the rising edge
// (RISING, FALLING and CHANGE all work with this library)
// and execute the function changeFreq when that pin changes
startMozzi ();
}
void updateControl (){
// everything is done by the pinchange interrupt
}
void changeFreq ()
{
static int freq = 220 ;
if ( freq == 220 ){
freq = 330 ;
}
else {
freq = 220 ;
}
aSin . setFreq ( freq ); // set the frequency
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aSin . next ()); // return an int signal centred around 0
}
void loop (){
audioHook (); // required here
}
Volume_Knob
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example using a potentiometer to control the amplitude of a sinewave
with Mozzi sonification library.
Demonstrates the use of Oscil to play a wavetable, and analog input for control.
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0:
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
+5V ---|
/
A0 ----\ potentiometer
/
GND ---|
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
const char INPUT_PIN = 0 ; // set the input for the knob to analog pin 0
// to convey the volume level from updateControl() to updateAudio()
byte volume ;
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 ); // set up the Serial output so we can look at the piezo values // set up the Serial output so we can look at the input values
aSin . setFreq ( 440 );
startMozzi (); // :))
}
void updateControl (){
// read the variable resistor for volume. We specifically request only 8 bits of resolution, here, which
// is less than the default on most platforms, but a convenient range to work with, where accuracy is not too important.
volume = mozziAnalogRead < 8 > ( INPUT_PIN );
// print the value to the Serial monitor for debugging
Serial . print ( "volume = " );
Serial . println (( int ) volume );
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit (( int ) aSin . next () * volume ); // 8 bit * 8 bit gives 16 bits value
}
void loop (){
audioHook (); // required here
}
Volume_Knob_LightLevel_Frequency
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example using a potentiometer to change the amplitude of a sinewave
and a light dependent resister (LDR) to change the frequency.
with Mozzi sonification library.
Demonstrates the use of Oscil to play a wavetable, and analog input for control.
This example goes with a tutorial on the Mozzi site:
http://sensorium.github.io/Mozzi/learn/introductory-tutorial/
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0:
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
+5V ---|
/
A0 ----\ potentiometer
/
GND ---|
Light dependent resistor (LDR) and 5.1k resistor on analog pin 1:
LDR from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
const char KNOB_PIN = 0 ; // set the input for the knob to analog pin 0
const char LDR_PIN = 1 ; // set the input for the LDR to analog pin 1
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
byte volume ;
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 ); // set up the Serial output so we can look at the piezo values // set up the Serial output so we can look at the analog levels
startMozzi (); // :))
}
void updateControl (){
// read the potentiometer as only 8 bit volume range for efficient calculations in updateAudio
volume = mozziAnalogRead < 8 > ( KNOB_PIN ); // value is 0-255
// print the value to the Serial monitor for debugging
Serial . print ( "volume = " );
Serial . print (( int ) volume );
Serial . print ( " \t " ); // prints a tab
// read the light dependent resistor
int light_level = mozziAnalogRead < 10 > ( LDR_PIN ); // We request 10 bits, here, however. Value is 0-1023
// print the value to the Serial monitor for debugging
Serial . print ( "light level = " );
Serial . print ( light_level );
Serial . print ( " \t " ); // prints a tab
// set the frequency
aSin . setFreq ( light_level );
Serial . println (); // next line
}
AudioOutput updateAudio (){
// cast char output from aSin.next() to int to make room for multiplication
return MonoOutput :: from16Bit (( int ) aSin . next () * volume ); // 8 bit * 8 bit gives 16 bits value
}
void loop (){
audioHook (); // required here
}
Audio_Input
…(no recording of this one)
show sketch
hide sketch
Audio_Input_with_Knob_Filter
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
Audio_and_Control_Input
…(no recording of this one)
show sketch
hide sketch
05.Control_Filters
DCfilter
…(no recording of this one)
show sketch
hide sketch
/* Example of filtering an analog input to remove DC bias,
using Mozzi sonification library.
Demonstrates DCfilter(), DC-blocking filter useful for
highlighting changes in control signals.
The output of the filter settles to 0 if the incoming signal stays constant.
If the input changes, the filter output swings to track the change and
eventually settles back to 0.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <DCfilter.h>
int sensorPin = A0 ;
DCfilter dcFiltered ( 0.9 ); // parameter sets how long the filter takes to settle
void setup () {
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 );
startMozzi ();
}
void updateControl (){
// read the value from the sensor in 10 bit resolution:
int sensorValue = mozziAnalogRead < 10 > ( sensorPin );
Serial . print ( sensorValue );
Serial . print ( " Filtered = " );
Serial . println ( dcFiltered . next ( sensorValue ));
}
AudioOutput updateAudio (){
return 0 ;
}
void loop (){
audioHook ();
}
Line_vs_Smooth
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of 2 different ways to smooth analog inputs,
using Mozzi sonification library. The inputs are used
to control the frequencies of two oscillators.
Demonstrates how to read analog inputs asynchronously, so values are
updated in the background while audio generation continues,
and the most recent readings can be read anytime from an array.
Also demonstrates linear interpolation with Line(),
filtering with Smooth(), and fixed point numbers from FixMath
Circuit: Audio output on digital pin 9
(for standard output on a Uno or similar), or
check the README or http://sensorium.github.io/Mozzi/
Your choice of analog sesnsors, or
2 10k Potentiometers with wipers (middle terminals)
connected to analog pins 0, 1 and 2, and
outside leads to ground and +5V.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <FixMath.h>
#include <Line.h>
#include <Smooth.h>
#include <mozzi_analog.h>
// 2 oscillators to compare linear interpolated vs smoothed control
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin0 ( SIN2048_DATA );
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin1 ( SIN2048_DATA );
// Line to interpolate frequency for aSin0.
// UFix<16,16>(yourNumber) is basically encoded in 16bits
// with 16 extra bits for additionnal precision.
// Line needs the small analog input integer values of 0-1023
// to be scaled up if the time (the number of steps) is big
// enough that distance/time gives a step-size of 0.
// Then you need floats (which are sometimes too slow and create glitches).
Line < UFix < 16 , 16 >> aInterpolate ;
// the number of audio steps the line has to take to reach the next control value
const unsigned int AUDIO_STEPS_PER_CONTROL = MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE ;
// Smoothing unit for aSin1
// This might be better with Q24n8 numbers for more precision,
// but we'll keep it simpler for the demo.
float smoothness = 0.995 f ;
Smooth < unsigned int > aSmooth ( smoothness ); // to smooth frequency for aSin1
void setup (){
aSin0 . setFreq ( 660 );
aSin1 . setFreq ( 220 );
startMozzi ();
}
unsigned int freq1 ; // global so it can be used in updateAudio
void updateControl (){
UFix < 16 , 16 > freq0 = mozziAnalogRead ( 0 ); // 0 to 1023, with an additionnal 16bits of precision (which will be used in the interpolation.)
freq1 = ( unsigned int ) mozziAnalogRead ( 1 ); // 0 to 1023
aInterpolate . set ( freq0 , AUDIO_STEPS_PER_CONTROL );
}
AudioOutput updateAudio (){
auto interpolatedFreq = aInterpolate . next (); // get the next linear interpolated freq
aSin0 . setFreq ( interpolatedFreq );
int smoothedFreq = aSmooth . next ( freq1 ); // get the next filtered frequency
aSin1 . setFreq ( smoothedFreq );
// Here we add to SFix numbers, created from the Oscil, for the output. Mozzi knows what is the final range of this allowing for auto-scaling.
return MonoOutput :: fromSFix ( toSFraction ( aSin0 . next ()) + toSFraction ( aSin1 . next ())); // auto-scaling of the output.
}
void loop (){
audioHook ();
}
MIDI_portamento
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of a sound being triggered by MIDI input, with portamento.
Demonstrates playing notes with Mozzi in response to MIDI input.
Also demonstrates Portamento(), a traditional portamento with a
duration which can be set.
Uses Arduino MIDI library v4.2
(https://github.com/FortySevenEffects/arduino_midi_library/releases/tag/4.2)
Circuit:
MIDI input circuit as per http://arduino.cc/en/Tutorial/Midi
(midi has to be disconnected from rx for sketch to upload)
Audio output on digital pin 9 on a Uno or similar.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <MIDI.h>
// use #define for MOZZI_CONTROL_RATE, not a constant
#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <Line.h> // for envelope
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <mozzi_midi.h>
#include <ADSR.h>
#include <mozzi_fixmath.h>
#include <Portamento.h>
MIDI_CREATE_DEFAULT_INSTANCE ();
// audio sinewave oscillator
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
// envelope generator
ADSR < MOZZI_CONTROL_RATE , MOZZI_AUDIO_RATE > envelope ;
Portamento < MOZZI_CONTROL_RATE > aPortamento ;
#define LED 13
void HandleNoteOn ( byte channel , byte note , byte velocity ) {
aPortamento . start ( note );
envelope . noteOn ();
digitalWrite ( LED , HIGH );
}
void HandleNoteOff ( byte channel , byte note , byte velocity ) {
envelope . noteOff ();
digitalWrite ( LED , LOW );
}
void setup () {
pinMode ( LED , OUTPUT );
// Initiate MIDI communications, listen to all channels
MIDI . begin ( MIDI_CHANNEL_OMNI );
// Connect the HandleNoteOn function to the library, so it is called upon reception of a NoteOn.
MIDI . setHandleNoteOn ( HandleNoteOn ); // Put only the name of the function
MIDI . setHandleNoteOff ( HandleNoteOff ); // Put only the name of the function
envelope . setADLevels ( 255 , 64 );
envelope . setTimes ( 50 , 200 , 10000 , 300 ); // 10000 is so the note will sustain 10 seconds unless a noteOff comes
aPortamento . setTime ( 300u );
startMozzi ();
}
void updateControl (){
MIDI . read ();
envelope . update ();
aSin . setFreq_Q16n16 ( aPortamento . next ());
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit (( int ) ( envelope . next () * aSin . next ()));
}
void loop () {
audioHook (); // required here
}
RollingAverage
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example changing the frequency of 2 sinewaves with 1 analog input,
using RollingAverage() to filter one of the control signals
and the other one unfiltered,
using Mozzi sonification library.
Demonstrates the difference between a raw control
signal and one smoothed with RollingAverage().
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <RollingAverage.h>
#define INPUT_PIN 0 // analog control input
// oscils to compare bumpy to averaged control input
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin0 ( SIN2048_DATA );
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin1 ( SIN2048_DATA );
// use: RollingAverage <number_type, how_many_to_average> myThing
RollingAverage < int , 32 > kAverage ; // how_many_to_average has to be power of 2
int averaged ;
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 );
startMozzi ();
}
void updateControl (){
int bumpy_input = mozziAnalogRead < 10 > ( INPUT_PIN );
averaged = kAverage . next ( bumpy_input );
Serial . print ( "bumpy \t " );
Serial . print ( bumpy_input );
Serial . print ( " \t averaged \t " );
Serial . println ( averaged );
aSin0 . setFreq ( bumpy_input );
aSin1 . setFreq ( averaged );
}
AudioOutput updateAudio (){
return MonoOutput :: fromAlmostNBit ( 10 , 3 * ( aSin0 . next () + aSin1 . next ()));
}
void loop (){
audioHook ();
}
Smooth
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of a sound changing volume with and without
smoothing of the control signal to remove obvious clicks,
using Mozzi sonification library.
Demonstrates using Smooth to filter a control signal at audio rate,
EventDelay to schedule changes and rand() to choose random volumes.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
your board check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 128
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <EventDelay.h>
#include <Smooth.h>
#include <mozzi_rand.h>
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
// for scheduling audio gain changes
EventDelay kGainChangeDelay ;
const unsigned int gainChangeMsec = 200 ;
// for scheduling turning smoothing on and off
EventDelay kSmoothOnOff ;
const unsigned int smoothOnOffMsec = 2000 ;
float smoothness = 0.9975 f ;
Smooth < long > aSmoothGain ( smoothness );
boolean smoothIsOn = true ;
long target_gain = 0 ;
void setup (){
aSin . setFreq ( 330 ); // set the frequency
kGainChangeDelay . set ( gainChangeMsec );
kSmoothOnOff . set ( smoothOnOffMsec );
startMozzi ();
}
void updateControl (){
// switch smoothing on and off to show the difference
if ( kSmoothOnOff . ready ()){
if ( smoothIsOn ) {
aSmoothGain . setSmoothness ( 0. f );
smoothIsOn = false ;
}
else {
aSmoothGain . setSmoothness ( smoothness );
smoothIsOn = true ;
}
kSmoothOnOff . start ();
}
// random volume changes
if ( kGainChangeDelay . ready ()){
target_gain = rand (( byte ) 255 );
kGainChangeDelay . start ();
}
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit ( aSmoothGain . next ( target_gain ) * aSin . next ());
}
void loop (){
audioHook ();
}
Smooth_Frequency
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example sliding between frequencies,
using Mozzi sonification library.
Demonstrates using Smooth to filter a control signal.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
// this is a high value to avoid zipper noise
#define MOZZI_CONTROL_RATE 1280
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <EventDelay.h>
#include <Smooth.h>
#include <mozzi_midi.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
// for scheduling freq changes
EventDelay kFreqChangeDelay ;
Smooth < int > kSmoothFreq ( 0.975 f );
int target_freq , target_freq1 , target_freq2 ;
void setup (){
target_freq1 = 441 ;
target_freq2 = 330 ;
kFreqChangeDelay . set ( 1000 ); // 1000ms countdown, within resolution of MOZZI_CONTROL_RATE
startMozzi ();
}
void updateControl (){
if ( kFreqChangeDelay . ready ()){
if ( target_freq == target_freq1 ) {
target_freq = target_freq2 ;
}
else {
target_freq = target_freq1 ;
}
kFreqChangeDelay . start ();
}
int smoothed_freq = kSmoothFreq . next ( target_freq );
aSin . setFreq ( smoothed_freq );
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aSin . next ());
}
void loop (){
audioHook ();
}
Thermistor_OverSample
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example of oversampling analog input from a thermistor
for increased resolution. It's a basic attempt at a biofeedback
device used as an ineffective treatment for migraines. The idea
is that if you can focus on making your hands warm, increased blood
flow to the extremities is associated with a reduced stress response.
Anyway, the bleeps sweep up if the temperature increases, down for decrease,
and level for no change. The tremelo rate increases with the temperature.
Using Mozzi sonification library.
Demonstrates OverSample object.
The circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Temperature dependent resistor (Thermistor) and 5.1k resistor on analog pin 1:
Thermistor from analog pin to +5V (3.3V on Teensy 3.1)
5.1k resistor from analog pin to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <Line.h>
#include <tables/sin2048_int8.h> // SINe table for oscillator
#include <OverSample.h>
#include <ControlDelay.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable)
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aTremelo ( SIN2048_DATA );
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aEnvelope ( SIN2048_DATA );
Line < float > freqLine ;
OverSample < unsigned int , 3 > overSampler ; // will give 10+3=13 bits resolution, 0->8191, using 128 bytes
const byte INPUT_PIN = 1 ;
float ENVELOPE_DURATION = 1. f ;
const byte LINE_LENGTH = ( byte )(( float ) MOZZI_CONTROL_RATE * ENVELOPE_DURATION * 0.5 ); // 0.5 seconds per line
// adjustments to get tremelo in useful range from oversampled temperature input
const int TREMOLO_OFFSET = 4000 ;
const float TREMOLO_SCALE = 0.002 ;
void setup (){
pinMode ( INPUT_PIN , INPUT );
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 );
aEnvelope . setFreq ( ENVELOPE_DURATION );
startMozzi ();
}
void updateControl (){
float start_freq , end_freq ;
static int counter , old_oversampled ;
// read the variable resistor
int sensor_value = mozziAnalogRead < 10 > ( INPUT_PIN ); // value is 0-1023
// get the next oversampled sensor value
int oversampled = overSampler . next ( sensor_value );
// modulate the amplitude of the sound in proportion to the magnitude of the oversampled sensor
float tremeloRate = TREMOLO_SCALE * ( oversampled - TREMOLO_OFFSET );
tremeloRate = tremeloRate * tremeloRate * tremeloRate * tremeloRate * tremeloRate ;
aTremelo . setFreq ( tremeloRate );
// every half second
if ( -- counter < 0 ){
if ( oversampled > old_oversampled ){ // high tweet up if temp rose
start_freq = 550. f ;
end_freq = 660. f ;
} else if ( oversampled < old_oversampled ){ // low tweet down if temp fell
start_freq = 330. f ;
end_freq = 220. f ;
} else { // flat beep if no change
start_freq = 440. f ;
end_freq = 440. f ;
}
old_oversampled = oversampled ;
counter = LINE_LENGTH - 1 ; // reset counter
// set the line to change the main frequency
freqLine . set ( start_freq , end_freq , LINE_LENGTH );
// print out for debugging
Serial . print ( oversampled ); Serial . print ( " \t " ); Serial . print ( start_freq ); Serial . print ( " \t " ); Serial . println ( end_freq );
}
// update the main frequency of the sound
aSin . setFreq ( freqLine . next ());
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit (((( int ) aSin . next () * ( 128 + aTremelo . next ())) >> 8 ) * aEnvelope . next ());
}
void loop (){
audioHook (); // required here
}
06.Synthesis
AMsynth
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of Amplitude Modulation synthesis
using Mozzi sonification library.
Demonstrates modulating the gain of one oscillator
by the instantaneous amplitude of another,
shows the use of fixed-point numbers to express fractional
values, random numbers with rand(), and EventDelay()
for scheduling.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <EventDelay.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <Smooth.h>
// audio oscils
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCarrier ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aModulator ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aModDepth ( COS2048_DATA );
// for scheduling note changes in updateControl()
EventDelay kNoteChangeDelay ;
UFix < 8 , 8 > ratio ; // unsigned int with 8 integer bits and 8 fractional bits
UFix < 24 , 8 > carrier_freq ; // unsigned long with 24 integer bits and 8 fractional bits
// for random notes
const UFix < 7 , 0 > octave_start_note = 42 ;
void setup () {
ratio = 3 ;
kNoteChangeDelay . set ( 200 ); // note duration ms, within resolution of MOZZI_CONTROL_RATE
aModDepth . setFreq ( 13. f ); // vary mod depth to highlight am effects
randSeed (); // reseed the random generator for different results each time the sketch runs
startMozzi ();
}
void updateControl () {
static auto last_note = octave_start_note ;
if ( kNoteChangeDelay . ready ()) {
// change octave now and then
if ( rand (( byte ) 5 ) == 0 ) {
last_note = UFix < 7 , 0 > ( 36 + ( rand (( byte ) 6 ) * 12 ));
}
// change step up or down a semitone occasionally
if ( rand (( byte ) 13 ) == 0 ) {
last_note = last_note + SFix < 7 , 0 > ( 1 - rand (( byte ) 3 ));
}
// change modulation ratio now and then
if ( rand (( byte ) 5 ) == 0 ) {
ratio = 1 + rand (( byte ) 5 );
}
// sometimes add a fractionto the ratio
if ( rand (( byte ) 5 ) == 0 ) {
ratio = ratio + toUFraction ( rand (( byte ) 255 ));
}
// step up or down 3 semitones (or 0)
last_note = last_note + SFix < 7 , 0 > ( 3 * ( 1 - rand (( byte ) 3 )));
// convert midi to frequency
carrier_freq = mtof ( last_note );
// calculate modulation frequency to stay in ratio with carrier
auto mod_freq = carrier_freq * ratio ;
// set frequencies of the oscillators
aCarrier . setFreq ( carrier_freq );
aModulator . setFreq ( mod_freq );
// reset the note scheduler
kNoteChangeDelay . start ();
}
}
AudioOutput updateAudio () {
auto mod = UFix < 8 , 0 > ( 128 + aModulator . next ()) * UFix < 8 , 0 > ( 128 + aModDepth . next ());
return MonoOutput :: fromSFix ( mod * toSFraction ( aCarrier . next ()));
}
void loop () {
audioHook ();
}
AMsynth_HIFI
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of Amplitude Modulation synthesis
using Mozzi sonification library.
Demonstrates modulating the gain of one oscillator
by the instantaneous amplitude of another,
shows the use of fixed-point numbers to express fractional
values, random numbers with rand(), and EventDelay()
for scheduling.
Important:
This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which
is not available on all boards (among others, it works on the
classic Arduino boards, but not Teensy 3.x and friends).
Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar),
Check the Mozzi core module documentation for others and more detail
3.9k
pin 9 ---WWWW-----|-----output
499k |
pin 10 ---WWWW---- |
|
4.7n ==
|
ground
Resistors are ±0.5% Measure and choose the most precise
from a batch of whatever you can get. Use two 1M resistors
in parallel if you can't find 499k.
Alternatively using 39 ohm, 4.99k and 470nF components will
work directly with headphones.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <EventDelay.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <Smooth.h>
// audio oscils
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCarrier ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aModulator ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aModDepth ( COS2048_DATA );
// for scheduling note changes in updateControl()
EventDelay kNoteChangeDelay ;
UFix < 8 , 8 > ratio ; // unsigned int with 8 integer bits and 8 fractional bits
UFix < 24 , 8 > carrier_freq ; // unsigned long with 24 integer bits and 8 fractional bits
// for random notes
const UFix < 7 , 0 > octave_start_note = 42 ;
void setup () {
ratio = 3 ;
kNoteChangeDelay . set ( 200 ); // note duration ms, within resolution of MOZZI_CONTROL_RATE
aModDepth . setFreq ( 13. f ); // vary mod depth to highlight am effects
randSeed (); // reseed the random generator for different results each time the sketch runs
startMozzi ();
}
void updateControl () {
static auto last_note = octave_start_note ;
if ( kNoteChangeDelay . ready ()) {
// change octave now and then
if ( rand (( byte ) 5 ) == 0 ) {
last_note = UFix < 7 , 0 > ( 36 + ( rand (( byte ) 6 ) * 12 ));
}
// change step up or down a semitone occasionally
if ( rand (( byte ) 13 ) == 0 ) {
last_note = last_note + SFix < 7 , 0 > ( 1 - rand (( byte ) 3 ));
}
// change modulation ratio now and then
if ( rand (( byte ) 5 ) == 0 ) {
ratio = 1 + rand (( byte ) 5 );
}
// sometimes add a fractionto the ratio
if ( rand (( byte ) 5 ) == 0 ) {
ratio = ratio + toUFraction ( rand (( byte ) 255 ));
}
// step up or down 3 semitones (or 0)
last_note = last_note + SFix < 7 , 0 > ( 3 * ( 1 - rand (( byte ) 3 )));
// convert midi to frequency
carrier_freq = mtof ( last_note );
// calculate modulation frequency to stay in ratio with carrier
auto mod_freq = carrier_freq * ratio ;
// set frequencies of the oscillators
aCarrier . setFreq ( carrier_freq );
aModulator . setFreq ( mod_freq );
// reset the note scheduler
kNoteChangeDelay . start ();
}
}
AudioOutput updateAudio () {
auto mod = UFix < 8 , 0 > ( 128 + aModulator . next ()) * UFix < 8 , 0 > ( 128 + aModDepth . next ());
return MonoOutput :: fromSFix ( mod * toSFraction ( aCarrier . next ()));
}
void loop () {
audioHook ();
}
Brown_Noise_Realtime
…(no recording of this one)
show sketch
hide sketch
/* Example generating brownian noise in real time,
using Mozzi sonification library.
Demonstrates rand(), a fast random generator,
a filter used as a "leaky integrator"
(based on an implementation by Barry Dorr:
https://www.edn.com/design/systems-design/4320010/A-simple-software-lowpass-filter-suits-embedded-system-applications)
and the use of Oscil to modulate amplitude.
Circuit: Audio output on digital pin 9 on a Uno or similar.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <mozzi_rand.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#define FILTER_SHIFT 6 // 5 or 6 work well - the spectrum of 6 looks a bit more linear, like the generated brown noise in Audacity
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
void setup ()
{
startMozzi (); // :)
aSin . setFreq ( 0.05 f ); // set the frequency
}
void updateControl ()
{
// put changing controls in here
}
AudioOutput updateAudio ()
{
static int filtered ;
char whitenoise = rand (( byte ) 255 ) - 128 ;
filtered = filtered - ( filtered >> FILTER_SHIFT ) + whitenoise ;
int asig = filtered >> 3 ; // shift to 8 bit range (trial and error)
return MonoOutput :: from16Bit (( int ) asig * aSin . next ());
}
void loop (){
audioHook (); // required here
}
Detuned_Beats_Wash
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Plays a fluctuating ambient wash using pairs
of slightly detuned oscillators, following an example
from Miller Puckette's Pure Data manual.
The detune frequencies are modified by chance in
updateControl(), and the outputs of 12 audio
oscillators are summed in updateAudio().
Demonstrates the use of FixMath fixed point
format numbers, mtof() for converting midi note
values to frequency, and xorshift96() for random numbers.
This sketch is pushing the limits of computing power on the
8-bit AVR boards. At the time of this writing, you will have
to manually alter your platform.txt file to use optimization
for speed rather than size on Arduino Uno and similar.
(Alternatively, remove one of the oscillators)
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <FixMath.h>
// harmonics
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos2 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos3 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos4 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos5 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos6 ( COS8192_DATA );
//Oscil<COS8192_NUM_CELLS, MOZZI_AUDIO_RATE> aCos7(COS8192_DATA); // used to work smoothly in Arduino 1.05
// duplicates but slightly off frequency for adding to originals
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1b ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos2b ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos3b ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos4b ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos5b ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos6b ( COS8192_DATA );
//Oscil<COS8192_NUM_CELLS, MOZZI_AUDIO_RATE> aCos7b(COS8192_DATA);
// base pitch frequencies in Q16n16 fixed int format (for speed later)
UFix < 12 , 15 > f1 , f2 , f3 , f4 , f5 , f6 ; //,f7;
/*Q16n16 variation() {
// 32 random bits & with 524287 (b111 1111 1111 1111 1111)
// gives between 0-8 in Q16n16 format
return (Q16n16) (xorshift96() & 524287UL);
}*/
UFix < 3 , 16 > variation () // changing the return type here enables to easily
// increase or decrease the variation
{
return UFix < 3 , 16 >:: fromRaw ( xorshift96 () & 524287UL );
}
void setup (){
startMozzi ();
// select base frequencies using mtof (midi to freq) and fixed-point numbers
f1 = mtof ( UFix < 7 , 0 > ( 48 ));
f2 = mtof ( UFix < 7 , 0 > ( 74 ));
f3 = mtof ( UFix < 7 , 0 > ( 64 ));
f4 = mtof ( UFix < 7 , 0 > ( 77 ));
f5 = mtof ( UFix < 7 , 0 > ( 67 ));
f6 = mtof ( UFix < 7 , 0 > ( 57 ));
// f7 = mtof(UFix<7,0>(60));
// set Oscils with chosen frequencies
aCos1 . setFreq ( f1 );
aCos2 . setFreq ( f2 );
aCos3 . setFreq ( f3 );
aCos4 . setFreq ( f4 );
aCos5 . setFreq ( f5 );
aCos6 . setFreq ( f6 );
// aCos7.setFreq(f7);
// set frequencies of duplicate oscillators
aCos1b . setFreq ( f1 + variation ());
aCos2b . setFreq ( f2 + variation ());
aCos3b . setFreq ( f3 + variation ());
aCos4b . setFreq ( f4 + variation ());
aCos5b . setFreq ( f5 + variation ());
aCos6b . setFreq ( f6 + variation ());
//aCos7b.setFreq(f7+variation());
}
void loop (){
audioHook ();
}
void updateControl (){
// todo: choose a nice scale or progression and make a table for it
// or add a very slow gliss for f1-f7, like shephard tones
// change frequencies of the b oscillators
switch ( lowByte ( xorshift96 ()) & 7 ){ // 7 is 0111
case 0 :
aCos1b . setFreq ( f1 + variation ());
break ;
case 1 :
aCos2b . setFreq ( f2 + variation ());
break ;
case 2 :
aCos3b . setFreq ( f3 + variation ());
break ;
case 3 :
aCos4b . setFreq ( f4 + variation ());
break ;
case 4 :
aCos5b . setFreq ( f5 + variation ());
break ;
case 5 :
aCos6b . setFreq ( f6 + variation ());
break ;
/*
case 6:
aCos7b.setFreq(f7+variation());
break;
*/
}
}
AudioOutput updateAudio (){
/*
The following block is the "classical" way of outputting the sound, from a standard C/C++ type.
You need to know how many bits you are dealing with and can use a reduced number to bring in some
distorsion with .clip() if you want.
*/
/* int asig =
aCos1.next() + aCos1b.next() +
aCos2.next() + aCos2b.next() +
aCos3.next() + aCos3b.next() +
aCos4.next() + aCos4b.next() +
aCos5.next() + aCos5b.next() +
aCos6.next() + aCos6b.next();// +
// aCos7.next() + aCos7b.next();
return MonoOutput::fromAlmostNBit(12, asig);
*/
/*
This is letting Mozzi compute the number of bits for you.
The syntax is a bit more cumbersome but FixMath will be
clever enough to figure out the exact number of bits needed
to create asig without any overflow, but no more.
This number of bits will be used by Mozzi for right/left shifting
the number to match the capability of the system.
*/
auto asig =
toSFraction ( aCos1 . next ()) + toSFraction ( aCos1b . next ()) +
toSFraction ( aCos2 . next ()) + toSFraction ( aCos2b . next ()) +
toSFraction ( aCos3 . next ()) + toSFraction ( aCos3b . next ()) +
toSFraction ( aCos4 . next ()) + toSFraction ( aCos4b . next ()) +
toSFraction ( aCos5 . next ()) + toSFraction ( aCos5b . next ()) +
toSFraction ( aCos6 . next ()) + toSFraction ( aCos6b . next ()); /* +
toSFraction(aCos7.next()) + toSFraction(aCos7b.next()) +*/
return MonoOutput :: fromSFix ( asig );
}
Difference_Tone
…(no recording of this one)
show sketch
hide sketch
/* Example using clipping to modify the spectrum of an audio signal
and emphasise a tone generated by the difference in frequency of 2 waves,
using Mozzi sonification library.
Demonstrates the use of EventDelay(), rand() and fixed-point numbers.
Note that an example using the newer FixMath paradigm is also available: Difference_Tone_FixMath.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <EventDelay.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <tables/sin2048_int8.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin1 ( SIN2048_DATA ); // sine wave sound source
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin2 ( SIN2048_DATA ); // sine wave sound source
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aGain ( SIN2048_DATA ); // to fade audio signal in and out before waveshaping
// for scheduling note changes
EventDelay kChangeNoteDelay ;
// audio frequency as Q16n16 fractional number
Q16n16 freq1 = Q8n0_to_Q16n16 ( 440 );
void setup (){
startMozzi (); // :)
aSin1 . setFreq_Q16n16 ( freq1 ); // set the frequency with a Q16n16 fractional number
aGain . setFreq ( 0.2 f ); // use a float for low frequencies, in setup it doesn't need to be fast
kChangeNoteDelay . set ( 2000 ); // note duration ms, within resolution of MOZZI_CONTROL_RATE
}
void updateControl (){
if ( kChangeNoteDelay . ready ()){
// change proportional frequency of second tone
byte harmonic = rand (( byte ) 12 );
byte shimmer = rand (( byte ) 255 );
Q16n16 harmonic_step = freq1 / 12 ;
Q16n16 freq2difference = harmonic * harmonic_step ;
freq2difference += ( harmonic_step * shimmer ) >> 11 ;
Q16n16 freq2 = freq1 - freq2difference ;
aSin2 . setFreq_Q16n16 ( freq2 ); // set the frequency with a Q16n16 fractional number
kChangeNoteDelay . start ();
}
}
AudioOutput updateAudio (){
int asig = ( int )(((( uint32_t ) aSin1 . next () + aSin2 . next ()) * ( 200u + aGain . next ())) >> 3 );
return MonoOutput :: fromAlmostNBit ( 9 , asig ). clip ();
}
void loop (){
audioHook (); // required here
}
Difference_Tone_FixMath
…(no recording of this one)
show sketch
hide sketch
/* Example using clipping to modify the spectrum of an audio signal
and emphasise a tone generated by the difference in frequency of 2 waves,
using Mozzi sonification library.
Adaptation of the Difference_Tone example using FixMath.
Demonstrates the use of EventDelay(), rand() and fixed-point numbers.
Demonstrates Oscil::phMod() for phase modulation,
Smooth() for smoothing control signals,
and FixMath fixed point number types for fractional frequencies.
This is the same technique than the FMsynth example but
using FixMath instead of mozzi_fixmath.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barras, Thomas Combriat and the Mozzi team 2023, CC by-nc-sa.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <EventDelay.h>
#include <FixMath.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <tables/sin2048_int8.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , AUDIO_RATE > aSin1 ( SIN2048_DATA ); // sine wave sound source
Oscil < SIN2048_NUM_CELLS , AUDIO_RATE > aSin2 ( SIN2048_DATA ); // sine wave sound source
Oscil < SIN2048_NUM_CELLS , AUDIO_RATE > aGain ( SIN2048_DATA ); // to fade audio signal in and out before waveshaping
// for scheduling note changes
EventDelay kChangeNoteDelay ;
const UFix < 8 , 0 > freq1 = 184 ;
const auto harmonic_step = freq1 * UFix < 8 , 0 > ( 12 ). invAccurate (); // harmonic_step = freq1/12;
void setup () {
Serial . begin ( 115200 );
aSin1 . setFreq ( freq1 );
aGain . setFreq ( 0.2 f ); // use a float for low frequencies, in setup it doesn't need to be fast
kChangeNoteDelay . set ( 2000 ); // note duration ms, within resolution of CONTROL_RATE
startMozzi (); // :)
}
void updateControl () {
if ( kChangeNoteDelay . ready ()) {
UFix < 4 , 0 > harmonic = rand (( byte ) 12 );
auto shimmer = toUFraction ( rand (( byte ) 255 )); // Creates a UFix<0,8>
auto freq2difference = ( harmonic * harmonic_step ) + ( harmonic_step * shimmer ). sR < 3 > (); // the shimmering is divided by 8 here
auto freq2 = ( freq1 - freq2difference ). asUFix ();
aSin2 . setFreq (( freq2 ));
kChangeNoteDelay . start ();
}
}
AudioOutput_t updateAudio () {
auto asig = ( toSInt ( aSin1 . next ()) + toSInt ( aSin2 . next ())) * ( toSFraction ( aGain . next ()) + UFix < 1 , 7 > ( 1.2 )); // this is a SFix<9,9> in the end
return MonoOutput :: fromAlmostNBit ( 11 , asig . asRaw ()). clip (); // TODO, implement smart MonoOutput
}
void loop () {
audioHook (); // required here
}
FMsynth
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of simple FM with the phase modulation technique,
using Mozzi sonification library.
Demonstrates Oscil::phMod() for phase modulation,
Smooth() for smoothing control signals,
and Mozzi's fixed point number types for fractional frequencies.
Also shows the limitations of Mozzi's 16384Hz Sample rate,
as aliasing audibly intrudes as the sound gets brighter around
midi note 48.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <mozzi_midi.h>
#include <mozzi_fixmath.h>
#include <EventDelay.h>
#include <Smooth.h>
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCarrier ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aModulator ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kModIndex ( COS2048_DATA );
// The ratio of deviation to modulation frequency is called the "index of modulation". ( I = d / Fm )
// It will vary according to the frequency that is modulating the carrier and the amount of deviation.
// so deviation d = I Fm
// haven't quite worked this out properly yet...
Q8n8 mod_index ; // = float_to_Q8n8(2.0f); // constant version
Q16n16 deviation ;
Q16n16 carrier_freq , mod_freq ;
// FM ratio between oscillator frequencies, stays the same through note range
Q8n8 mod_to_carrier_ratio = float_to_Q8n8 ( 3. f );
EventDelay kNoteChangeDelay ;
// for note changes
Q7n8 target_note , note0 , note1 , note_upper_limit , note_lower_limit , note_change_step , smoothed_note ;
// using Smooth on midi notes rather than frequency,
// because fractional frequencies need larger types than Smooth can handle
// Inefficient, but...until there is a better Smooth....
Smooth < int > kSmoothNote ( 0.95 f );
void setup (){
kNoteChangeDelay . set ( 768 ); // ms countdown, taylored to resolution of MOZZI_CONTROL_RATE
kModIndex . setFreq ( .768 f ); // sync with kNoteChangeDelay
target_note = note0 ;
note_change_step = Q7n0_to_Q7n8 ( 3 );
note_upper_limit = Q7n0_to_Q7n8 ( 50 );
note_lower_limit = Q7n0_to_Q7n8 ( 32 );
note0 = note_lower_limit ;
note1 = note_lower_limit + Q7n0_to_Q7n8 ( 5 );
startMozzi ();
}
void setFreqs ( Q8n8 midi_note ){
carrier_freq = Q16n16_mtof ( Q8n8_to_Q16n16 ( midi_note )); // convert midi note to fractional frequency
mod_freq = (( carrier_freq >> 8 ) * mod_to_carrier_ratio ) ; // (Q16n16>>8) Q8n8 = Q16n16, beware of overflow
deviation = (( mod_freq >> 16 ) * mod_index ); // (Q16n16>>16) Q8n8 = Q24n8, beware of overflow
aCarrier . setFreq_Q16n16 ( carrier_freq );
aModulator . setFreq_Q16n16 ( mod_freq );
}
void updateControl (){
// change note
if ( kNoteChangeDelay . ready ()){
if ( target_note == note0 ){
note1 += note_change_step ;
target_note = note1 ;
}
else {
note0 += note_change_step ;
target_note = note0 ;
}
// change direction
if ( note0 > note_upper_limit ) note_change_step = Q7n0_to_Q7n8 ( - 3 );
if ( note0 < note_lower_limit ) note_change_step = Q7n0_to_Q7n8 ( 3 );
// reset eventdelay
kNoteChangeDelay . start ();
}
// vary the modulation index
mod_index = ( Q8n8 ) 350 + kModIndex . next ();
// here's where the smoothing happens
smoothed_note = kSmoothNote . next ( target_note );
setFreqs ( smoothed_note );
}
AudioOutput updateAudio (){
Q15n16 modulation = deviation * aModulator . next () >> 8 ;
return MonoOutput :: from8Bit ( aCarrier . phMod ( modulation ));
}
void loop (){
audioHook ();
}
FMsynth_32k_HIFI
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of simple FM with the phase modulation technique,
using Mozzi sonification library.
Demonstrates Oscil::phMod() for phase modulation,
Smooth() for smoothing control signals,
and FixMath fixed point number types for fractional frequencies.
This sketch using HIFI mode is not for Teensy 3.1.
This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which
is not available on all boards (among others, it works on the
classic Arduino boards, but not Teensy 3.x and friends).
The MOZZI_AUDIO_RATE (sample rate) is additionally configured at 32768 Hz,
which is the default on most platforms, but twice the standard rate on
AVR-CPUs. Try chaging it back to hear the difference.
Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar),
Check the Mozzi core module documentation for others and more detail
3.9k
pin 9 ---WWWW-----|-----output
499k |
pin 10 ---WWWW---- |
|
4.7n ==
|
ground
Resistors are ±0.5% Measure and choose the most precise
from a batch of whatever you can get. Use two 1M resistors
in parallel if you can't find 499k.
Alternatively using 39 ohm, 4.99k and 470nF components will
work directly with headphones.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
#define MOZZI_AUDIO_RATE 32768
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <mozzi_midi.h>
#include <FixMath.h>
#include <EventDelay.h>
#include <Smooth.h>
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCarrier ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aModulator ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kModIndex ( COS2048_DATA );
UFix < 0 , 16 > mod_index ;
UFix < 8 , 16 > deviation ; // 8 so that we do not exceed 32bits in updateAudio
UFix < 16 , 16 > carrier_freq , mod_freq ;
const UFix < 0 , 16 > modulation_amp = 0.001 ; // how much the modulation index will vary around its mean
const UFix < 2 , 0 > mean_modulation_unscaled = 2 ; // the real mean modulation will be mean_modulation_unscaled * modulation_max
// this one is adding a bias to the oscillator, hence it should be bigger than one.
const UFix < 2 , 0 > mod_to_carrier_ratio = 3 ; // 3 fits in UFix<2,0> which has a maximum range of (2^2)-1=3
EventDelay kNoteChangeDelay ;
const UFix < 7 , 0 > note_upper_limit = 50 , note_lower_limit = 32 ;
UFix < 7 , 0 > note0 = note_lower_limit , note1 = note_lower_limit + UFix < 7 , 0 > ( 5 ), target_note = 0 ;
SFix < 2 , 0 > note_change_step = 3 ; // will only take +3 or -3, 2bits are enough for that
UFix < 7 , 8 > smoothed_note ;
Smooth < UFix < 7 , 8 >> kSmoothNote ( 0.95 f );
void setup () {
kNoteChangeDelay . set ( 768 );
kModIndex . setFreq ( .768 f ); // sync with kNoteChangeDelay
startMozzi ();
}
void setFreqs ( UFix < 7 , 8 > midi_note ) {
carrier_freq = mtof ( midi_note );
mod_freq = UFix < 14 , 16 > ( carrier_freq ) * mod_to_carrier_ratio ;
deviation = (( UFix < 16 , 0 > ( mod_freq )) * mod_index ). sR < 8 > (); // the sR here cheaply divides the deviation by 256.
aCarrier . setFreq ( carrier_freq );
aModulator . setFreq ( mod_freq );
}
void updateControl () {
if ( kNoteChangeDelay . ready ()) {
if ( target_note == note0 )
{
note1 = note1 + note_change_step ;
target_note = note1 ;
}
else
{
note0 = note0 + note_change_step ;
target_note = note0 ;
}
if ( note0 > note_upper_limit ) note_change_step = - 3 ;
if ( note0 < note_lower_limit ) note_change_step = 3 ;
kNoteChangeDelay . start ();
}
mod_index = ( toSFraction ( kModIndex . next ()) + mean_modulation_unscaled ). sR < 2 > (); // the sR is to scale back in pure fractional range
smoothed_note = kSmoothNote . next ( target_note );
setFreqs ( smoothed_note );
}
AudioOutput updateAudio (){
auto modulation = ( deviation * toSFraction ( aModulator . next ()));
return MonoOutput :: from8Bit ( aCarrier . phMod ( modulation ));
}
void loop () {
audioHook ();
}
FMsynth_FixMath
…(no recording of this one)
show sketch
hide sketch
/* Example of simple FM with the phase modulation technique,
using Mozzi sonification library.
Demonstrates Oscil::phMod() for phase modulation,
Smooth() for smoothing control signals,
and FixMath fixed point number types for fractional frequencies.
This is the same technique than the FMsynth example but
using FixMath instead of mozzi_fixmath.
Note that it is slightly less optimized (but runs fine on an
Uno) in order to make the underlying algorithm clearer.
An optimized version, using FixMath can be found in the
example FMsynth_32k_HIFI.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, Thomas Combriat and the Mozzi team 2023, CC by-nc-sa.
*/
#include <MozziConfigValues.h>
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <mozzi_midi.h>
#include <FixMath.h>
#include <EventDelay.h>
#include <Smooth.h>
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCarrier ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aModulator ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kModIndex ( COS2048_DATA );
UFix < 0 , 16 > mod_index ;
UFix < 16 , 16 > deviation ;
UFix < 16 , 16 > carrier_freq , mod_freq ;
const UFix < 0 , 16 > modulation_amp = 0.001 ; // how much the modulation index will vary around its mean
const UFix < 2 , 0 > mean_modulation_unscaled = 2 ; // the real mean modulation will be mean_modulation_unscaled * modulation_max
// this one is adding a bias to the oscillator, hence it should be bigger than one.
const UFix < 2 , 0 > mod_to_carrier_ratio = 3 ; // 3 fits in UFix<2,0> which has a maximum range of (2^2)-1=3
EventDelay kNoteChangeDelay ;
const UFix < 7 , 0 > note_upper_limit = 50 , note_lower_limit = 32 ;
UFix < 7 , 0 > note0 = note_lower_limit , note1 = note_lower_limit + UFix < 7 , 0 > ( 5 ), target_note = 0 ;
SFix < 2 , 0 > note_change_step = 3 ; // will only take +3 or -3, 2bits are enough for that
UFix < 7 , 8 > smoothed_note ;
Smooth < UFix < 7 , 8 >> kSmoothNote ( 0.95 f );
void setup () {
kNoteChangeDelay . set ( 768 );
kModIndex . setFreq ( .768 f ); // sync with kNoteChangeDelay
startMozzi ();
}
void setFreqs ( UFix < 7 , 8 > midi_note ) {
carrier_freq = mtof ( midi_note );
mod_freq = carrier_freq * mod_to_carrier_ratio ;
deviation = mod_freq * mod_index ;
aCarrier . setFreq ( carrier_freq );
aModulator . setFreq ( mod_freq );
}
void updateControl () {
if ( kNoteChangeDelay . ready ()) {
if ( target_note == note0 )
{
note1 = note1 + note_change_step ;
target_note = note1 ;
}
else
{
note0 = note0 + note_change_step ;
target_note = note0 ;
}
if ( note0 > note_upper_limit ) note_change_step = - 3 ;
if ( note0 < note_lower_limit ) note_change_step = 3 ;
kNoteChangeDelay . start ();
}
mod_index = ( toSFraction ( kModIndex . next ()) + mean_modulation_unscaled ) * modulation_amp ; // toSFraction(kModIndex.next() is in [-1,1[,
// we bias it to [1, 3[ and then scale it with modulation_amp to [0.001, 0.003[
smoothed_note = kSmoothNote . next ( target_note );
setFreqs ( smoothed_note );
}
AudioOutput updateAudio (){
auto modulation = ( deviation * toSFraction ( aModulator . next ()));
return MonoOutput :: from8Bit ( aCarrier . phMod ( modulation ));
}
void loop () {
audioHook ();
}
NonAlias_MetaOscil
…(no recording of this one)
show sketch
hide sketch
PDresonant
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Phase distortion used to simulate resonant filter, based on
https://en.wikipedia.org/wiki/Phase_distortion_synthesis
Demonstrates PDResonant, a class which can be used as a
simple midi instrument. The class shows how the Mozzi Phasor class
can be used to generate an index into a wavetable, and an ADSR
is used to modulate the effect by modifying the Phasor frequency and sync.
More complex phase distortion effects could be developed by using
precalculated tables, or calcuating tables on the fly using a double buffer,
or a line-breakpoint model, a sort of hybridPhasor-Line object.
This version can only play a single voice at a time, it might
be possible to optimise it enough for more simultaneous voices.
Circuit:
MIDI input circuit as per http://arduino.cc/en/Tutorial/Midi
(midi has to be disconnected from rx for sketch to upload)
Audio output on digital pin 9 on a Uno or similar.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
//#include <MIDI.h> may be needed on some systems/versions
#include <Mozzi.h>
// for fake midi
#include <EventDelay.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <mozzi_analog.h>
#include <IntMap.h>
#include "PDResonant.h"
// wavetable for oscillator:
#include <tables/sin2048_int8.h>
// MIDI_CREATE_DEFAULT_INSTANCE(); // if really using midi
// analog joystick for controlling speed of modulation: assigned to attack, decay times and sustain level
#define X A0
#define Y A1
unsigned int x_axis = 512 ; // give a static value for test without midi
unsigned int y_axis = 512 ;
const IntMap kmapX ( 0 , 1023 , 0 , 1000 ); // A
const IntMap kmapY ( 0 , 1023 , 0 , 3000 ); //D
PDResonant voice ;
// for fake midi
EventDelay startNote ;
EventDelay endNote ;
void setup (){
randSeed (); // fresh random for fake midi
pinMode ( 13 , OUTPUT ); // for midi feedback
// initialize midi channel:
//MIDI.begin(MIDI_CHANNEL_OMNI);
//MIDI.setHandleNoteOn(HandleNoteOn);
//MIDI.setHandleNoteOff(HandleNoteOff);
// open MOZZI (:
startMozzi ();
}
void HandleNoteOn ( byte channel , byte pitch , byte velocity ){
if ( velocity > 0 )
{
voice . noteOn ( channel , pitch , velocity );
unsigned int attack = kmapX ( x_axis );
unsigned int decay = kmapY ( y_axis );
voice . setPDEnv ( attack , decay );
digitalWrite ( 13 , HIGH );
}
else {
stopNote ( channel , pitch , velocity );
}
}
void HandleNoteOff ( byte channel , byte pitch , byte velocity ){
stopNote ( channel , pitch , velocity );
}
void stopNote ( byte channel , byte pitch , byte velocity ){
voice . noteOff ( channel , pitch , velocity );
digitalWrite ( 13 , LOW );
}
void fakeMidiRead (){
static char curr_note ;
if ( startNote . ready ()){
curr_note = 20 + rand ( 40 );
HandleNoteOn ( 1 , curr_note , 127 );
startNote . set ( 2000 );
startNote . start ();
endNote . set ( 1000 );
endNote . start ();
}
if ( endNote . ready ()){
HandleNoteOff ( 1 , curr_note , 0 );
}
}
void updateControl (){
// check MIDI :
//MIDI.read();
// analog joystick for controlling speed of modulation: assigned to attack, decay times and sustain level
//x_axis = mozziAnalogRead<10>(X);
//y_axis = mozziAnalogRead<10>(Y);
// for testing/demo without external input
fakeMidiRead ();
x_axis = 512 ; //mozziAnalogRead<10>(X);
y_axis = 512 ; // mozziAnalogRead<10>(Y);
voice . update ();
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( voice . next ());
}
void loop (){
audioHook (); // required here
}
PWM_Phasing
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of pulse width modulation,
using Mozzi sonification library.
Based Miller Puckette's j03.pulse.width.mod example
in the Pure Data documentation, subtracting 2 sawtooth
waves with slightly different tunings to produce a
varying phase difference.
Demonstrates Phasor().
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Phasor.h>
Phasor < MOZZI_AUDIO_RATE > aPhasor1 ;
Phasor < MOZZI_AUDIO_RATE > aPhasor2 ;
float freq = 55. f ;
void setup (){
aPhasor1 . setFreq ( freq );
aPhasor2 . setFreq ( freq + 0.2 f );
startMozzi (); // :)
}
void updateControl (){
}
AudioOutput updateAudio (){
char asig1 = ( char )( aPhasor1 . next () >> 24 );
char asig2 = ( char )( aPhasor2 . next () >> 24 );
return MonoOutput :: fromNBit ( 9 , (( int ) asig1 - asig2 ));
}
void loop (){
audioHook (); // required here
}
SelfModulator
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of Self Modulation synthesis,
using Mozzi sonification library.
Demonstrates the use of Oscil::phMod to modulate an Oscillator by itself.
Self Modulation is a part of frequency modulation synthesis (FM).
Compared to "standard" FM where one oscillator modulates another
in Self Modulation the output of one oscillator is used to modulate
itself, directly, of after further modulation, or to modulate one of its
modulator (looking at the DX7 diagram is probably clearer).
Here we demonstrate the simple case of Self Modulation, one oscillator modulating himself.
The equivalent diagram is:
_____
\/ |
|----| |
| 1 | |
|----| |
|_____|
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <EventDelay.h>
#include <Smooth.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
EventDelay kModulationChangeDelay ; // to change the modulation amount
EventDelay kChangeNoteDelay ; // to change the base note
Smooth < uint8_t > kSmoothModulation ( 0.99 f );
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
uint8_t self_mod_amount , smoothed_self_mod_amount ;
UFix < 8 , 0 > notes [ 4 ] = { 40 - 12 , 52 - 12 , 28 - 12 , 30 - 12 }; // note played. Because of the Modulation the oscillator is called *two times*
// hence produces a note is which an octave to high, so we compensate for that here (12 midi notes makes an octave).
void setup () {
kModulationChangeDelay . set ( 2000 );
kChangeNoteDelay . set ( 300 );
startMozzi (); // :)
aSin . setFreq ( mtof ( notes [ 0 ])); // set the frequency
}
void updateControl () {
if ( kModulationChangeDelay . ready ()) {
self_mod_amount = rand ( 255 ); // next target value of modulation
kModulationChangeDelay . start ();
}
smoothed_self_mod_amount = kSmoothModulation ( self_mod_amount ); // smoothing of the modulation
if ( kChangeNoteDelay . ready ()) {
aSin . setFreq ( mtof ( notes [ rand ( 4 )]));
kChangeNoteDelay . start ();
}
}
AudioOutput updateAudio () {
return MonoOutput :: from8Bit ( aSin . phMod (( int32_t ( aSin . next ()) * smoothed_self_mod_amount ) << 4 ));
}
void loop () {
audioHook (); // required here
}
WaveFolder
…(no recording of this one)
show sketch
hide sketch
/* Example demonstrating the WaveFolder class,
using Mozzi sonification library.
The WaveFolder class is used to fold a sine table several times
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2022-2024 Tom Combriat and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <tables/saw512_int8.h> // saw table for oscillator
#include <WaveFolder.h>
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA ); // audio oscillator
Oscil < SIN2048_NUM_CELLS , MOZZI_CONTROL_RATE > kBias ( SIN2048_DATA ); // LFO changing the bias
Oscil < SAW512_NUM_CELLS , MOZZI_CONTROL_RATE > kGain ( SAW512_DATA ); // Gain oscillator
// Create a WaveFolder on the native audio type (int).
// The template argument can be used to increase (or reduce)
// the data type this class is working on (affects performances)
WaveFolder <> wf ;
int8_t gain = 0 ;
int8_t bias ;
void setup () {
aSin . setFreq ( 440 ); // set the frequency of the audio oscillator
kBias . setFreq ( 0.3 f ); // set the frequency
kGain . setFreq ( 0.2 f );
wf . setLimits ( - 2047 , 2047 ); // sets the values the wavefolder will start folding (in this case, containing in 12 bits)
// can also be done at MOZZI_CONTROL_RATE (even maybe at MOZZI_AUDIO_RATE)
startMozzi ();
}
void updateControl () {
bias = kBias . next ();
gain = ( kGain . next () >> 1 ) + 64 ;
}
AudioOutput updateAudio () {
int sample = ( gain * aSin . next () >> 1 ) + ( bias << 4 ); // this is 8 + 7 - 1 + 1 = 15bits maximum.
// the wavefolder, set on an output of 12 bits will fold the exceeding values.
return MonoOutput :: fromNBit ( 12 , wf . next ( sample )); // return an int signal centred around 0
}
void loop () {
audioHook (); // required here
}
WavePacket_Double
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of Wavepacket synthesis, using Mozzi sonification library.
This sketch draws on Miller Puckette's
Pure Data example, F14.wave.packet.pd, with
two overlapping streams of wave packets.
Circuit:
Audio output on DAC/A14 on Teensy 3.0, 3.1,
or digital pin 9 on a Uno or similar, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Potentiometer connected to analog pin 1.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Potentiometer connected to analog pin 2.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <mozzi_analog.h>
#include <WavePacket.h>
#include <RollingAverage.h>
#define FUNDAMENTAL_PIN 0
#define BANDWIDTH_PIN 1
#define CENTREFREQ_PIN 2
// for smoothing the control signals
// use: RollingAverage <number_type, how_many_to_average> myThing
RollingAverage < int , 32 > kAverageF ;
RollingAverage < int , 32 > kAverageBw ;
RollingAverage < int , 32 > kAverageCf ;
WavePacket < DOUBLE > wavey ; // DOUBLE selects 2 overlapping streams
void setup (){
startMozzi ();
}
void updateControl (){
wavey . set ( kAverageF . next ( mozziAnalogRead < 10 > ( FUNDAMENTAL_PIN )) + 1 , // 1-1024
kAverageBw . next ( mozziAnalogRead < 10 > ( BANDWIDTH_PIN )), // 0-1023
kAverageCf . next ( mozziAnalogRead < 11 > ( CENTREFREQ_PIN ))); // 0-2047
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit ( wavey . next ());
}
void loop (){
audioHook (); // required here
}
WavePacket_Sample
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of Wavepacket synthesis, using Mozzi sonification library.
This sketch draws on Miller Puckette's
Pure Data example, F14.wave.packet.pd, with
two overlapping streams of wave packets.
Demonstrates the WavePacketSample object, which enables a
custom sound table to be used as the audio source for wavepackets.
Circuit:
Audio output on DAC/A14 on Teensy 3.0, 3.1,
or digital pin 9 on a Uno or similar, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Potentiometer connected to analog pin 1.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Potentiometer connected to analog pin 2.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <mozzi_analog.h>
#include <WavePacketSample.h>
#include <RollingAverage.h>
#include <samples/raven_arh_int8.h>
#define FUNDAMENTAL_PIN 0
#define BANDWIDTH_PIN 1
#define CENTREFREQ_PIN 2
// for smoothing the control signals
// use: RollingAverage <number_type, how_many_to_average> myThing
RollingAverage < int , 32 > kAverageF ;
RollingAverage < int , 32 > kAverageBw ;
RollingAverage < int , 32 > kAverageCf ;
WavePacketSample < DOUBLE > wavey ; // DOUBLE selects 2 overlapping streams
void setup (){
wavey . setTable ( RAVEN_ARH_DATA );
pinMode ( 11 , OUTPUT );
digitalWrite ( 11 , LOW );
startMozzi ();
}
void updateControl (){
int f = kAverageF . next ( mozziAnalogRead < 10 > ( FUNDAMENTAL_PIN )) + 1 ;
int b = kAverageBw . next ( mozziAnalogRead < 10 > ( BANDWIDTH_PIN ));
int cf = kAverageCf . next ( mozziAnalogRead < 11 > ( CENTREFREQ_PIN ));
wavey . set ( f , b , cf );
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit ( wavey . next ());
}
void loop (){
audioHook (); // required here
}
WavePacket_Single
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of Wavepacket synthesis, using Mozzi sonification library.
This sketch draws on Miller Puckette's
Pure Data example, F14.wave.packet.pd, with
one non-overlapping stream of wave packets.
Circuit:
Audio output on DAC/A14 on Teensy 3.0, 3.1,
or digital pin 9 on a Uno or similar, or
check the README or http://sensorium.github.io/Mozzi/
Potentiometer connected to analog pin 0.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Potentiometer connected to analog pin 1.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Potentiometer connected to analog pin 2.
Center pin of the potentiometer goes to the analog pin.
Side pins of the potentiometer go to +5V and ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <mozzi_analog.h>
#include <WavePacket.h>
#include <RollingAverage.h>
#define FUNDAMENTAL_PIN 0
#define BANDWIDTH_PIN 1
#define CENTREFREQ_PIN 2
// for smoothing the control signals
// use: RollingAverage <number_type, how_many_to_average> myThing
RollingAverage < int , 32 > kAverageF ;
RollingAverage < int , 32 > kAverageBw ;
RollingAverage < int , 32 > kAverageCf ;
WavePacket < SINGLE > wavey ; // SINGLE selects 1 non-overlapping stream
void setup (){
startMozzi ();
}
void updateControl (){
wavey . set ( kAverageF . next ( mozziAnalogRead < 10 > ( FUNDAMENTAL_PIN )) + 1 ,
kAverageBw . next ( mozziAnalogRead < 10 > ( BANDWIDTH_PIN )),
kAverageCf . next ( mozziAnalogRead < 11 > ( CENTREFREQ_PIN )));
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit ( wavey . next ());
}
void loop (){
audioHook (); // required here
}
Waveshaper
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example using waveshaping to modify the spectrum of an audio signal
using Mozzi sonification library.
Demonstrates the use of WaveShaper(), EventDelay(), Smooth(),
rand(), and FixMath.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <WaveShaper.h>
#include <EventDelay.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
#include <Smooth.h>
#include <FixMath.h>
#include <tables/sin2048_int8.h>
#include <tables/waveshape_chebyshev_3rd_256_int8.h>
#include <tables/waveshape_chebyshev_6th_256_int8.h>
#include <tables/waveshape_compress_512_to_488_int16.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA ); // sine wave sound source
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aGain1 ( SIN2048_DATA ); // to fade sine wave in and out before waveshaping
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aGain2 ( SIN2048_DATA ); // to fade sine wave in and out before waveshaping
// Chebyshev polynomial curves, The nth curve produces the n+2th harmonic component.
WaveShaper < char > aCheby3rd ( CHEBYSHEV_3RD_256_DATA ); // 5th harmonic
WaveShaper < char > aCheby6th ( CHEBYSHEV_6TH_256_DATA ); // 8th harmonic
WaveShaper < int > aCompress ( WAVESHAPE_COMPRESS_512_TO_488_DATA ); // to compress instead of dividing by 2 after adding signals
// for scheduling note changes
EventDelay kChangeNoteDelay ;
// for random notes
UFix < 7 , 0 > octave_start_note = 42 ;
// smooth transitions between notes
Smooth < UFix < 14 , 12 >> kSmoothFreq ( 0.85 f );
UFix < 14 , 2 > target_freq , smoothed_freq ; //Optimization to have the frequencies on 16bits only.
void setup (){
startMozzi (); // :)
randSeed (); // reseed the random generator for different results each time the sketch runs
aSin . setFreq ( 110 ); // set the frequency
aGain1 . setFreq ( 2. f ); // use a float for low frequencies, in setup it doesn't need to be fast
aGain2 . setFreq ( .4 f );
kChangeNoteDelay . set ( 4000 ); // note duration ms, within resolution of MOZZI_CONTROL_RATE
}
byte rndPentatonic (){
byte note = rand (( byte ) 5 );
switch ( note ){
case 0 :
note = 0 ;
break ;
case 1 :
note = 3 ;
break ;
case 2 :
note = 5 ;
break ;
case 3 :
note = 7 ;
break ;
case 4 :
note = 10 ;
break ;
}
return note ;
}
void updateControl (){
if ( kChangeNoteDelay . ready ()){
if ( rand (( byte ) 5 ) == 0 ){ // about 1 in 5 or so
// change octave to midi 24 or any of 3 octaves above
octave_start_note = ( rand (( byte ) 4 ) * 12 ) + 36 ;
}
auto midi_note = octave_start_note + toUInt ( rndPentatonic ());
target_freq = mtof ( midi_note ); // mtof return a UFix<16,16>, which is casted to UFix<14,2> (could overflow if the frequency is greater than 16kHz)
kChangeNoteDelay . start ();
}
smoothed_freq = kSmoothFreq . next ( target_freq ); // temporarily scale up target_freq to get better int smoothing at low values
aSin . setFreq ( smoothed_freq );
}
AudioOutput updateAudio (){
char asig0 = aSin . next (); // sine wave source
// make 2 signals fading in and out to show effect of amplitude when waveshaping with Chebyshev polynomial curves
// offset the signals by 128 to fit in the 0-255 range for the waveshaping table lookups
byte asig1 = ( byte ) 128 + (( asig0 * (( byte ) 128 + aGain1 . next ())) >> 8 );
byte asig2 = ( byte ) 128 + (( asig0 * (( byte ) 128 + aGain2 . next ())) >> 8 );
// get the waveshaped signals
char awaveshaped1 = aCheby3rd . next ( asig1 );
char awaveshaped2 = aCheby6th . next ( asig2 );
// use a waveshaping table to squeeze 2 summed 8 bit signals into the range -244 to 243
int awaveshaped3 = aCompress . next ( 256u + awaveshaped1 + awaveshaped2 );
return MonoOutput :: fromAlmostNBit ( 9 , awaveshaped3 );
}
void loop (){
audioHook (); // required here
}
07.Envelopes
ADSR_Audio_Rate_Envelope
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example applying an ADSR envelope to an audio signal
with Mozzi sonification library. This shows
how to use an ADSR which updates at MOZZI_AUDIO_RATE, in updateAudio(),
and output using next() at MOZZI_AUDIO_RATE in updateAudio().
Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE,
which is more efficient, but MOZZI_AUDIO_RATE updates shown in this example
enable faster envelope transitions.
Demonstrates a simple ADSR object being controlled with
noteOn() and noteOff() instructions.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <EventDelay.h>
#include <ADSR.h>
#include <tables/sin8192_int8.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
Oscil < 8192 , MOZZI_AUDIO_RATE > aOscil ( SIN8192_DATA );;
// for triggering the envelope
EventDelay noteDelay ;
ADSR < MOZZI_AUDIO_RATE , MOZZI_AUDIO_RATE > envelope ;
boolean note_is_on = true ;
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 );
randSeed (); // fresh random
noteDelay . set ( 2000 ); // 2 second countdown
startMozzi ();
}
unsigned int duration , attack , decay , sustain , release_ms ;
void updateControl (){
if ( noteDelay . ready ()){
// choose envelope levels
byte attack_level = rand ( 128 ) + 127 ;
byte decay_level = rand ( 255 );
envelope . setADLevels ( attack_level , decay_level );
// generate a random new adsr time parameter value in milliseconds
unsigned int new_value = rand ( 300 ) + 100 ;
Serial . println ( new_value );
// randomly choose one of the adsr parameters and set the new value
switch ( rand ( 4 )){
case 0 :
attack = new_value ;
break ;
case 1 :
decay = new_value ;
break ;
case 2 :
sustain = new_value ;
break ;
case 3 :
release_ms = new_value ;
break ;
}
envelope . setTimes ( attack , decay , sustain , release_ms );
envelope . noteOn ();
byte midi_note = rand ( 107 ) + 20 ;
aOscil . setFreq (( int ) mtof ( midi_note ));
/*
// print to screen
Serial.print("midi_note\t"); Serial.println(midi_note);
Serial.print("attack_level\t"); Serial.println(attack_level);
Serial.print("decay_level\t"); Serial.println(decay_level);
Serial.print("attack\t\t"); Serial.println(attack);
Serial.print("decay\t\t"); Serial.println(decay);
Serial.print("sustain\t\t"); Serial.println(sustain);
Serial.print("release\t\t"); Serial.println(release_ms);
Serial.println();
*/
noteDelay . start ( attack + decay + sustain + release_ms );
}
}
AudioOutput updateAudio (){
envelope . update ();
return MonoOutput :: from16Bit (( int ) ( envelope . next () * aOscil . next ()));
}
void loop (){
audioHook (); // required here
}
ADSR_Audio_Rate_Envelope_Long
…(no recording of this one)
show sketch
hide sketch
/* Example applying an ADSR envelope to an audio signal
with Mozzi sonification library. This is nearly an exact copy of
ADSR_Audio_Rate_Envelope which shows
how to use an ADSR which updates at MOZZI_AUDIO_RATE, in updateAudio(),
output using next() at MOZZI_AUDIO_RATE in updateAudio(). This one uses
unsigned long as the third ADSR parameter to allow long envelopes
to be updated at MOZZI_AUDIO_RATE.
Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE,
which is more efficient, but MOZZI_AUDIO_RATE updates shown in this example
enable faster envelope transitions.
Demonstrates a simple ADSR object being controlled with
noteOn() and noteOff() instructions.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <EventDelay.h>
#include <ADSR.h>
#include <tables/sin8192_int8.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
Oscil < 8192 , MOZZI_AUDIO_RATE > aOscil ( SIN8192_DATA );;
// for triggering the envelope
EventDelay noteDelay ;
ADSR < MOZZI_AUDIO_RATE , MOZZI_AUDIO_RATE , unsigned long > envelope ;
boolean note_is_on = true ;
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 );
randSeed (); // fresh random
noteDelay . set ( 20000 ); // 2 second countdown
startMozzi ();
}
unsigned int duration , attack , decay , sustain , release_ms ;
void updateControl (){
if ( noteDelay . ready ()){
// choose envelope levels
byte attack_level = rand ( 1024 ) + 127 ;
byte decay_level = rand ( 2048 );
envelope . setADLevels ( attack_level , decay_level );
// generate a random new adsr time parameter value in milliseconds
unsigned int new_value = rand ( 3000 ) + 100 ;
Serial . println ( new_value );
// randomly choose one of the adsr parameters and set the new value
switch ( rand ( 4 )){
case 0 :
attack = new_value ;
break ;
case 1 :
decay = new_value ;
break ;
case 2 :
sustain = new_value ;
break ;
case 3 :
release_ms = new_value ;
break ;
}
envelope . setTimes ( attack , decay , sustain , release_ms );
envelope . noteOn ();
byte midi_note = rand ( 107 ) + 20 ;
aOscil . setFreq (( int ) mtof ( midi_note ));
/*
// print to screen
Serial.print("midi_note\t"); Serial.println(midi_note);
Serial.print("attack_level\t"); Serial.println(attack_level);
Serial.print("decay_level\t"); Serial.println(decay_level);
Serial.print("attack\t\t"); Serial.println(attack);
Serial.print("decay\t\t"); Serial.println(decay);
Serial.print("sustain\t\t"); Serial.println(sustain);
Serial.print("release\t\t"); Serial.println(release_ms);
Serial.println();
*/
noteDelay . start ( attack + decay + sustain + release_ms );
}
}
AudioOutput updateAudio (){
envelope . update ();
return MonoOutput :: from16Bit (( int ) ( envelope . next () * aOscil . next ()));
}
void loop (){
audioHook (); // required here
}
ADSR_Audio_Rate_Envelope_x2
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example applying ADSR envelopes to 2 audio oscillators
with Mozzi sonification library.
This shows how to use an ADSR which updates at MOZZI_AUDIO_RATE,
in updateAudio(), and output using next() at MOZZI_AUDIO_RATE in updateAudio().
Another example in this folder shows an ADSR updating at MOZZI_CONTROL_RATE,
which is more efficient, but MOZZI_AUDIO_RATE updates shown in this example
enable faster envelope transitions.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <EventDelay.h>
#include <ADSR.h>
#include <tables/sin8192_int8.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
Oscil < 8192 , MOZZI_AUDIO_RATE > aOscil0 ( SIN8192_DATA );
Oscil < 8192 , MOZZI_AUDIO_RATE > aOscil1 ( SIN8192_DATA );
// for triggering the envelope
EventDelay noteDelay ;
// ADSR update_rate, interpolation_rte
ADSR < MOZZI_CONTROL_RATE , MOZZI_AUDIO_RATE > envelope0 ;
ADSR < MOZZI_CONTROL_RATE , MOZZI_AUDIO_RATE > envelope1 ;
boolean note_is_on = true ;
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
//Serial.begin(115200);
randSeed (); // fresh random
envelope0 . setTimes ( rand ( 300 ), rand ( 300 ), rand ( 300 ), rand ( 300 ));
envelope1 . setTimes ( rand ( 300 ), rand ( 300 ), rand ( 300 ), rand ( 300 ));
noteDelay . set ( 2000 ); // 2 second countdown
startMozzi ();
}
unsigned int attack0 , decay0 , sustain0 , release_ms0 ;
unsigned int attack1 , decay1 , sustain1 , release_ms1 ;
void updateControl (){
if ( noteDelay . ready ()){
// change adsr 0
// choose envelope levels
byte attack0_level = rand ( 128 ) + 127 ;
byte decay0_level = rand ( 255 );
envelope0 . setADLevels ( attack0_level , decay0_level );
// generate a random new adsr time parameter value in milliseconds
unsigned int new_value = rand ( 300 ) + 100 ;
// randomly choose one of the adsr parameters and set the new value
switch ( rand ( 4 )){
case 0 :
attack0 = new_value ;
break ;
case 1 :
decay0 = new_value ;
break ;
case 2 :
sustain0 = new_value ;
break ;
case 3 :
release_ms0 = new_value ;
break ;
}
envelope0 . setTimes ( attack0 , decay0 , sustain0 , release_ms0 );
envelope0 . noteOn ();
// change adsr 1
// choose envelope levels
byte attack1_level = rand ( 128 ) + 127 ;
byte decay1_level = rand ( 255 );
envelope1 . setADLevels ( attack1_level , decay1_level );
// generate a random new adsr time parameter value in milliseconds
new_value = rand ( 300 ) + 100 ;
// randomly choose one of the adsr parameters and set the new value
switch ( rand ( 4 )){
case 0 :
attack1 = new_value ;
break ;
case 1 :
decay1 = new_value ;
break ;
case 2 :
sustain1 = new_value ;
break ;
case 3 :
release_ms1 = new_value ;
break ;
}
envelope1 . setTimes ( attack1 , decay1 , sustain1 , release_ms1 );
envelope1 . noteOn ();
// change the pitch
byte midi_note = rand ( 107 ) + 20 ;
int freq = ( int ) mtof ( midi_note );
aOscil0 . setFreq ( freq );
aOscil1 . setFreq ( freq * 2 );
/*
// print to screen
Serial.print("midi_note\t");
Serial.println(midi_note);
Serial.print("attack0_level\t");
Serial.print(attack0_level);
Serial.print("\t attack1_level\t");
Serial.println(attack1_level);
Serial.print("decay0_level\t");
Serial.print(decay0_level);
Serial.print("\t decay1_level\t");
Serial.println(decay1_level);
Serial.print("attack0\t\t");
Serial.print(attack0);
Serial.print("\t attack1\t");
Serial.println(attack1);
Serial.print("decay0\t\t");
Serial.print(decay0);
Serial.print("\t decay1\t\t");
Serial.println(decay1);
Serial.print("sustain0\t");
Serial.print(sustain0);
Serial.print("\t sustain1\t");
Serial.println(sustain1);
Serial.print("release0\t");
Serial.print(release_ms0);
Serial.print("\t release1\t");
Serial.println(release_ms1);
Serial.println();
*/
// set duration to longest adsr of the 2
int dur0 = attack0 + decay0 + sustain0 + release_ms0 ;
int dur1 = attack1 + decay1 + sustain1 + release_ms1 ;
if ( dur0 > dur1 ){
noteDelay . start ( dur0 );
}
else {
noteDelay . start ( dur1 );
}
}
envelope0 . update ();
envelope1 . update ();
}
AudioOutput updateAudio (){
return MonoOutput :: fromNBit ( 17 ,
(( long ) envelope0 . next () * aOscil0 . next ()) +
(( int ) envelope1 . next () * aOscil1 . next ())
);
}
void loop (){
audioHook (); // required here
}
ADSR_Control_Rate_Envelope
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example applying an ADSR envelope to an audio signal
with Mozzi sonification library. This shows
internal updates as well as interpolation at MOZZI_CONTROL_RATE, using both
update() and next() in updateControl().
This is less computationally intensive than doing interpolation with
next() in updateAudio(), but can be less smooth, especially with fast envelopes.
Demonstrates a simple ADSR object being controlled with
noteOn() and noteOff() instructions.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 128 // faster than usual to help smooth MOZZI_CONTROL_RATE adsr interpolation (next())
#include <Mozzi.h>
#include <Oscil.h>
#include <EventDelay.h>
#include <ADSR.h>
#include <tables/sin8192_int8.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
Oscil < 8192 , MOZZI_AUDIO_RATE > aOscil ( SIN8192_DATA );;
// for triggering the envelope
EventDelay noteDelay ;
ADSR < MOZZI_CONTROL_RATE , MOZZI_CONTROL_RATE > envelope ;
boolean note_is_on = true ;
byte gain ;
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 );
randSeed (); // fresh random
noteDelay . set ( 2000 ); // 2 second countdown
startMozzi ();
}
unsigned int duration , attack , decay , sustain , release_ms ;
void updateControl (){
if ( noteDelay . ready ()){
// choose envelope levels
byte attack_level = rand ( 128 ) + 127 ;
byte decay_level = rand ( 255 );
envelope . setADLevels ( attack_level , decay_level );
// generate a random new adsr parameter value in milliseconds
int r = rand ( 1000 ) - rand ( 1000 );
unsigned int new_value = abs ( r );
// randomly choose one of the adsr parameters and set the new value
switch ( rand ( 4 )){
case 0 :
attack = new_value ;
break ;
case 1 :
decay = new_value ;
break ;
case 2 :
sustain = new_value ;
break ;
case 3 :
release_ms = new_value ;
break ;
}
envelope . setTimes ( attack , decay , sustain , release_ms );
envelope . noteOn ();
byte midi_note = rand ( 107 ) + 20 ;
aOscil . setFreq (( int ) mtof ( midi_note ));
// print to screen
Serial . print ( "midi_note \t " ); Serial . println ( midi_note );
Serial . print ( "attack_level \t " ); Serial . println ( attack_level );
Serial . print ( "decay_level \t " ); Serial . println ( decay_level );
Serial . print ( "attack \t\t " ); Serial . println ( attack );
Serial . print ( "decay \t\t " ); Serial . println ( decay );
Serial . print ( "sustain \t\t " ); Serial . println ( sustain );
Serial . print ( "release \t\t " ); Serial . println ( release_ms );
Serial . println ();
noteDelay . start ( attack + decay + sustain + release_ms );
}
envelope . update ();
gain = envelope . next (); // this is where it's different to an audio rate envelope
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit (( int ) ( gain * aOscil . next ()));
}
void loop (){
audioHook (); // required here
}
Ead_Envelope
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example playing an enveloped noise source
using Mozzi sonification library.
Demonstrates Ead (exponential attack decay).
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/brownnoise8192_int8.h> // recorded audio wavetable
#include <Ead.h> // exponential attack decay
#include <EventDelay.h>
#include <mozzi_rand.h>
Oscil < BROWNNOISE8192_NUM_CELLS , MOZZI_AUDIO_RATE > aNoise ( BROWNNOISE8192_DATA );
EventDelay kDelay ; // for triggering envelope start
Ead kEnvelope ( MOZZI_CONTROL_RATE ); // resolution will be MOZZI_CONTROL_RATE
int gain ;
void setup (){
// use float to set freq because it will be small and fractional
aNoise . setFreq (( float ) MOZZI_AUDIO_RATE / BROWNNOISE8192_SAMPLERATE );
randSeed (); // fresh random, MUST be called before startMozzi - wierd bug
startMozzi ();
kDelay . start ( 1000 );
}
void updateControl (){
// jump around in audio noise table to disrupt obvious looping
aNoise . setPhase ( rand (( unsigned int ) BROWNNOISE8192_NUM_CELLS ));
if ( kDelay . ready ()){
// set random parameters
unsigned int duration = rand ( 500u ) + 200 ;
unsigned int attack = rand ( 75 ) + 5 ; // +5 so the internal step size is more likely to be >0
unsigned int decay = duration - attack ;
kEnvelope . start ( attack , decay );
kDelay . start ( duration + 500 );
}
gain = ( int ) kEnvelope . next ();
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit ( gain * aNoise . next ());
}
void loop (){
audioHook (); // required here
}
Filter_Envelope
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example applying an ADSR envelope to an audio filter
with Mozzi sonification library. This shows
how to use an ADSR which updates at MOZZI_AUDIO_RATE, in updateAudio(),
and output using next() at MOZZI_AUDIO_RATE in updateAudio().
Demonstrates a simple ADSR object being controlled with
noteOn() and controlling the cutoff frequency of a LowPassFilter.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <EventDelay.h>
#include <ADSR.h>
#include <ResonantFilter.h>
#include <tables/saw2048_int8.h>
#include <mozzi_rand.h>
#include <mozzi_midi.h>
Oscil < SAW2048_NUM_CELLS , MOZZI_AUDIO_RATE > aOscil ( SAW2048_DATA );
// for triggering the envelope
EventDelay noteDelay ;
ADSR < MOZZI_AUDIO_RATE , MOZZI_AUDIO_RATE > envelope ;
// LowPass filter controlled by the envelope
LowPassFilter lpf ;
void setup () {
randSeed (); // fresh random
envelope . setADLevels ( 128 , 64 );
envelope . setTimes ( 2000 , 1500 , 250 , 1250 ); // always the same envelope times
noteDelay . set ( 5000 ); // 5 second countdown
lpf . setResonance ( 230 );
startMozzi ();
}
void updateControl () {
if ( noteDelay . ready ()) {
envelope . noteOn ( true );
byte midi_note = rand ( 50 ) + 20 ;
aOscil . setFreq (( int ) mtof ( midi_note ));
noteDelay . start ( 5000 );
}
}
AudioOutput updateAudio () {
envelope . update ();
// change the cutoff frequency with the envelope.
lpf . setCutoffFreq ( envelope . next ());
// the signal returned by aOscil is 8 bits, but with this much resonance the filtered signal goes higher,
// so we let 1 bit of headroom, and clip in case it goes beyond...
return MonoOutput :: fromNBit ( 9 , ( int )( lpf . next ( aOscil . next ()))). clip ();
}
void loop () {
audioHook (); // required here
}
Phasemod_Envelope
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of a modulating timbre with a rhythmic
volume envelope, using Mozzi sonification library.
Demonstrates phase modulation and modifying
the volume of a sound with an envelope setd in a table.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <tables/envelop2048_uint8.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCarrier ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aModulator ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aModWidth ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kModFreq1 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kModFreq2 ( COS8192_DATA );
Oscil < ENVELOP2048_NUM_CELLS , MOZZI_AUDIO_RATE > aEnvelop ( ENVELOP2048_DATA );
void setup () {
startMozzi ();
aCarrier . setFreq ( 220 );
kModFreq1 . setFreq ( 1.78 f );
kModFreq2 . setFreq ( 0.1757 f );
aModWidth . setFreq ( 0.1434 f );
aEnvelop . setFreq ( 9.0 f );
}
void updateControl () {
aModulator . setFreq ( 277.0 f + 0.4313 f * kModFreq1 . next () + kModFreq2 . next ());
}
AudioOutput updateAudio (){
int asig = aCarrier . phMod (( int ) aModulator . next () * ( 260u + aModWidth . next ()));
return MonoOutput :: from16Bit ( asig * ( byte ) aEnvelop . next ());
}
void loop () {
audioHook ();
}
08.Samples
Sample
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of playing a sampled sound,
using Mozzi sonification library.
Demonstrates one-shot samples scheduled
with EventDelay.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Sample.h> // Sample template
#include <samples/burroughs1_18649_int8.h>
#include <EventDelay.h>
// use: Sample <table_size, update_rate> SampleName (wavetable)
Sample < BURROUGHS1_18649_NUM_CELLS , MOZZI_AUDIO_RATE > aSample ( BURROUGHS1_18649_DATA );
// for scheduling sample start
EventDelay kTriggerDelay ;
void setup (){
startMozzi ();
aSample . setFreq (( float ) BURROUGHS1_18649_SAMPLERATE / ( float ) BURROUGHS1_18649_NUM_CELLS ); // play at the speed it was recorded
kTriggerDelay . set ( 1500 ); // 1500 msec countdown, within resolution of MOZZI_CONTROL_RATE
}
void updateControl (){
if ( kTriggerDelay . ready ()){
aSample . start ();
kTriggerDelay . start ();
}
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit (( int ) aSample . next ());
}
void loop (){
audioHook ();
}
SampleHuffman_Umpah
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/*
Example playing samples encoded with Huffman compression.
Demonstrates the SampleHuffman class.
SampleHuffman, most of this explanation, and the audio2huff.py script are adapted from "audioout",
an Arduino sketch by Thomas Grill, 2011 http//grrrr.org.
Huffman decoding is used on sample differentials,
saving 50-70% of space for 8 bit data, depending on the sample rate.
This implementation just plays back one sample each time next() is called, with no
speed or other adjustments. It's slow, so it's likely you will only be able to play one sound at a time.
Audio data, Huffman decoder table, sample rate and bit depth are defined
in a sounddata.h header file. This file can be generated for a sound file with the
accompanying Python script audio2huff.py, in Mozzi/extras/python/
Invoke with:
python audio2huff.py --sndfile=arduinosnd.wav --hdrfile=sounddata.h --bits=8 --name=soundtablename
You can resample and dither your audio file with SOX,
e.g. to 8 bits depth @ Mozzi's 16384 Hz sample rate:
sox fullglory.wav -b 8 -r 16384 arduinosnd.wav
Alternatively you can export a sound from Audacity, which seems to have less noticeable or no dithering,
using Project Rate 16384 Hz and these output options:
Other uncompressed files, Header: WAV(Microsoft), Encoding: Unsigned 8 bit PCM
The header file contains two lengthy arrays:
One is "SOUNDDATA" which must fit into Flash RAM (available in total: 32k for ATMega328)
The other is "HUFFMAN" which must also fit into Flash RAM
Circuit:
Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <SampleHuffman.h>
#include "umpah_huff.h"
SampleHuffman umpah ( UMPAH_SOUNDDATA , UMPAH_HUFFMAN , UMPAH_SOUNDDATA_BITS );
void setup () {
umpah . setLoopingOn ();
startMozzi ();
}
void updateControl (){
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( umpah . next ());
}
void loop () {
audioHook ();
}
Sample_Loop_Points
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example playing a looped sampled sound while
changing the start end end loop points,
and sliding the frequency around,
using Mozzi sonification library.
Demonstrates Sample(), looping with random
changes to loop and frequency parameters
scheduled with EventDelay.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 128
#include <Mozzi.h>
#include <Sample.h> // Sample template
#include <samples/abomb16384_int8.h> // table for Sample
#include <EventDelay.h>
#include <mozzi_rand.h>
// use: Sample <table_size, update_rate> SampleName (wavetable)
Sample < ABOMB_NUM_CELLS , MOZZI_AUDIO_RATE > aSample ( ABOMB_DATA );
// for scheduling changes
EventDelay kTriggerDelay ;
const float playspeed = 1.3 ;
float playspeedmod = 0 ;
float speedchange = 0 ;
const unsigned int full = ( int ) ( 1000. f / playspeed ) - 23 ; // adjustment approx for MOZZI_CONTROL_RATE difference
void setup (){
randSeed (); // reseed the random generator for different results each time the sketch runs
aSample . setFreq ( playspeed * (( float ) ABOMB_SAMPLERATE / ( float ) ABOMB_NUM_CELLS ));
kTriggerDelay . set ( full );
aSample . setLoopingOn ();
startMozzi ();
}
unsigned int chooseStart (){
return rand (( unsigned int ) ABOMB_NUM_CELLS );
}
unsigned int chooseEnd ( unsigned int startpos ){
return rand ( startpos , ( unsigned int ) ABOMB_NUM_CELLS );
}
void chooseSpeedMod (){
if ( rand (( byte ) 3 ) == 0 ){
speedchange = ( float ) rand (( char ) - 100 ,( char ) 100 ) / 8000 ;
float startspeed = ( float ) rand (( char ) - 100 ,( char ) 100 ) / 100 ;
playspeedmod = playspeed + startspeed ;
}
else {
speedchange = 0 ;
playspeedmod = playspeed ;
}
}
void chooseStartEnd (){
unsigned int s , e ;
if ( rand (( byte ) 2 ) == 0 ){
s = chooseStart ();
e = chooseEnd ( s );
}
else {
s = 0 ;
e = ABOMB_NUM_CELLS ;
}
aSample . setStart ( s );
aSample . setEnd ( e );
}
void updateControl (){
if ( kTriggerDelay . ready ()){
chooseStartEnd ();
chooseSpeedMod ();
kTriggerDelay . start ();
}
playspeedmod += speedchange ;
aSample . setFreq ( playspeedmod );
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aSample . next ());
}
void loop (){
audioHook ();
}
Sample_Scrub
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of simple "scrubbing" through a sampled sound
using Mozzi sonification library.
Demonstrates getting audio samples from a table using a Line to
slide between different offsets.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Sample.h> // Sample template
#include <samples/burroughs1_18649_int8.h>
#include <mozzi_rand.h>
#include <Line.h>
#include <Smooth.h>
// use: Sample <table_size, update_rate, interpolation > SampleName (wavetable)
Sample < BURROUGHS1_18649_NUM_CELLS , MOZZI_AUDIO_RATE , INTERP_LINEAR > aSample ( BURROUGHS1_18649_DATA );
//Line to scrub through sample at audio rate, Line target is set at control rate
Line < Q16n16 > scrub ; // Q16n16 fixed point for high precision
// the number of audio steps the line has to take to reach the next offset
const unsigned int AUDIO_STEPS_PER_CONTROL = MOZZI_AUDIO_RATE / MOZZI_CONTROL_RATE ;
int offset = 0 ;
int offset_advance = 400 ; // just a guess
// use this smooth out the wandering/jumping rate of scrubbing, gives more convincing reverses
float smoothness = 0.9 f ;
Smooth < int > kSmoothOffsetAdvance ( smoothness );
void setup (){
randSeed (); // fresh randomness
aSample . setLoopingOn ();
startMozzi ();
}
void updateControl (){
// wandering advance rate
offset_advance += ( int ) rand ( 20 ) - rand ( 20 );
if ( ! rand ( MOZZI_CONTROL_RATE )) offset_advance = - offset_advance ; // reverse sometimes
if ( ! rand ( MOZZI_CONTROL_RATE )) offset_advance = 500 - rand ( 1000 ); // jump speed sometimes
int smooth_offset_advance = kSmoothOffsetAdvance . next ( offset_advance );
offset += smooth_offset_advance ;
// keep offset in range
if ( offset >= BURROUGHS1_18649_NUM_CELLS ) offset -= BURROUGHS1_18649_NUM_CELLS ;
if ( offset < 0 ) offset += BURROUGHS1_18649_NUM_CELLS ;
// set new target for interpolating line to scrub to
scrub . set ( Q16n0_to_Q16n16 ( offset ), AUDIO_STEPS_PER_CONTROL );
}
AudioOutput updateAudio (){
unsigned int index = Q16n16_to_Q16n0 ( scrub . next ());
return MonoOutput :: from8Bit ( aSample . atIndex ( index ));
}
void loop (){
audioHook ();
}
Samples
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of playing sampled sounds,
using Mozzi sonification library.
Demonstrates one-shot samples scheduled
with EventDelay(), and fast random numbers with
xorshift96() and rand(), a more friendly wrapper for xorshift96().
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Sample.h> // Sample template
#include <samples/bamboo/bamboo_00_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_01_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_02_2048_int8.h> // wavetable data
#include <EventDelay.h>
#include <mozzi_rand.h>
// use: Sample <table_size, update_rate> SampleName (wavetable)
Sample < BAMBOO_00_2048_NUM_CELLS , MOZZI_AUDIO_RATE > aBamboo0 ( BAMBOO_00_2048_DATA );
Sample < BAMBOO_01_2048_NUM_CELLS , MOZZI_AUDIO_RATE > aBamboo1 ( BAMBOO_01_2048_DATA );
Sample < BAMBOO_02_2048_NUM_CELLS , MOZZI_AUDIO_RATE > aBamboo2 ( BAMBOO_02_2048_DATA );
// for scheduling audio gain changes
EventDelay kTriggerDelay ;
void setup (){
startMozzi ();
aBamboo0 . setFreq (( float ) BAMBOO_00_2048_SAMPLERATE / ( float ) BAMBOO_00_2048_NUM_CELLS ); // play at the speed it was recorded at
aBamboo1 . setFreq (( float ) BAMBOO_01_2048_SAMPLERATE / ( float ) BAMBOO_01_2048_NUM_CELLS );
aBamboo2 . setFreq (( float ) BAMBOO_02_2048_SAMPLERATE / ( float ) BAMBOO_02_2048_NUM_CELLS );
kTriggerDelay . set ( 111 ); // countdown ms, within resolution of MOZZI_CONTROL_RATE
}
byte randomGain (){
//return lowByte(xorshift96())<<1;
return rand ( 200 ) + 55 ;
}
// referencing members from a struct is meant to be a bit faster than seperately
// ....haven't actually tested it here...
struct gainstruct {
byte gain0 ;
byte gain1 ;
byte gain2 ;
}
gains ;
void updateControl (){
if ( kTriggerDelay . ready ()){
switch ( rand ( 0 , 3 )) {
case 0 :
gains . gain0 = randomGain ();
aBamboo0 . start ();
break ;
case 1 :
gains . gain1 = randomGain ();
aBamboo1 . start ();
break ;
case 2 :
gains . gain2 = randomGain ();
aBamboo2 . start ();
break ;
}
kTriggerDelay . start ();
}
}
AudioOutput updateAudio (){
int asig = ( int )
(( long ) aBamboo0 . next () * gains . gain0 +
aBamboo1 . next () * gains . gain1 +
aBamboo2 . next () * gains . gain2 ) >> 4 ;
// clip to keep sample loud but still in range
return MonoOutput :: fromAlmostNBit ( 9 , asig ). clip ();
}
void loop (){
audioHook ();
}
Samples_Tables_Arrays
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of a polyphonic sketch in which
11 sound tables are shared between 3 voices,
using Mozzi sonification library.
Demonstrates use of Sample() objects as players,
using setTable() to share many sound tables between
a few players, to minimise processing in updateAudio().
Shows how to use Samples and sound tables in arrays,
EventDelay() for scheduling, and rand() to select
sound tables and vary the gain of each player.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Sample.h>
#include <EventDelay.h>
#include <mozzi_rand.h> // for rand()
#include <samples/bamboo/bamboo_00_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_01_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_02_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_03_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_04_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_05_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_06_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_07_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_08_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_09_2048_int8.h> // wavetable data
#include <samples/bamboo/bamboo_10_2048_int8.h> // wavetable data
// for scheduling samples to play
EventDelay kTriggerDelay ;
EventDelay kTriggerSlowDelay ;
byte ms_per_note = 111 ; // subject to MOZZI_CONTROL_RATE
const byte NUM_PLAYERS = 3 ; // 3 seems to be enough
const byte NUM_TABLES = 11 ;
Sample < BAMBOO_00_2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSample [ NUM_PLAYERS ] = {
Sample < BAMBOO_00_2048_NUM_CELLS , MOZZI_AUDIO_RATE > ( BAMBOO_00_2048_DATA ),
Sample < BAMBOO_01_2048_NUM_CELLS , MOZZI_AUDIO_RATE > ( BAMBOO_01_2048_DATA ),
Sample < BAMBOO_02_2048_NUM_CELLS , MOZZI_AUDIO_RATE > ( BAMBOO_02_2048_DATA ),
};
// watch out - tables are const (but you can choose which ones you reference)
const int8_t * tables [ NUM_TABLES ] = {
BAMBOO_00_2048_DATA ,
BAMBOO_01_2048_DATA ,
BAMBOO_02_2048_DATA ,
BAMBOO_03_2048_DATA ,
BAMBOO_04_2048_DATA ,
BAMBOO_05_2048_DATA ,
BAMBOO_06_2048_DATA ,
BAMBOO_07_2048_DATA ,
BAMBOO_08_2048_DATA ,
BAMBOO_09_2048_DATA ,
BAMBOO_10_2048_DATA
};
// gains for each sample player
byte gain [ NUM_PLAYERS ];
void setup (){
for ( int i = 0 ; i < NUM_PLAYERS ; i ++ ){ // play at the speed they're sampled at
( aSample [ i ]). setFreq (( float ) BAMBOO_00_2048_SAMPLERATE / ( float ) BAMBOO_00_2048_NUM_CELLS );
}
kTriggerDelay . set ( ms_per_note ); // countdown ms, within resolution of MOZZI_CONTROL_RATE
kTriggerSlowDelay . set ( ms_per_note * 6 ); // resolution-dependent inaccuracy leads to polyrhythm :)
startMozzi ();
}
byte randomGain (){
return rand (( byte ) 80 ,( byte ) 255 );
}
void updateControl (){
static byte player = 0 ;
if ( kTriggerDelay . ready ()){
gain [ player ] = randomGain ();
( aSample [ player ]). setTable ( tables [ rand ( NUM_TABLES )]);
( aSample [ player ]). start ();
player ++ ;
if ( player == NUM_PLAYERS ) player = 0 ;
kTriggerDelay . start ();
}
if ( kTriggerSlowDelay . ready ()){
gain [ player ] = randomGain ();
( aSample [ player ]). setTable ( tables [ rand ( NUM_TABLES )]);
( aSample [ player ]). start ();
player ++ ;
if ( player == NUM_PLAYERS ) player = 0 ;
kTriggerSlowDelay . start ();
}
}
AudioOutput updateAudio (){
long asig = 0 ;
for ( byte i = 0 ; i < NUM_PLAYERS ; i ++ ){
asig += ( int ) ( aSample [ i ]). next () * gain [ i ];
}
//clip any stray peaks to max output range
return MonoOutput :: fromAlmostNBit ( 15 , asig ). clip ();
}
void loop (){
audioHook ();
}
Wavetable_Swap
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example swapping between sounds played by a single Oscil
with Mozzi sonification library.
Demonstrates declaring an Oscil without a table,
and Oscil::setTable() method.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <EventDelay.h>
// tables need to be the same size
#include <tables/sin512_int8.h>
#include <tables/saw_analogue512_int8.h>
// declare with or without a wavetable, and use setTable() later
Oscil < 512 , MOZZI_AUDIO_RATE > aOscil ;
// for scheduling table swaps
EventDelay kSwapTablesDelay ;
boolean using_sin = true ;
void setup (){
startMozzi ();
kSwapTablesDelay . set ( 1000 ); // 1 second countdown, within resolution of MOZZI_CONTROL_RATE
aOscil . setFreq ( 440. f );
}
void updateControl (){
if ( kSwapTablesDelay . ready ()){
if ( using_sin ){
aOscil . setTable ( SAW_ANALOGUE512_DATA );
using_sin = false ;
} else {
aOscil . setTable ( SIN512_DATA );
using_sin = true ;
}
kSwapTablesDelay . start ();
}
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aOscil . next ());
}
void loop (){
audioHook (); // required here
}
09.Delays
AudioDelay
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of modulating a signal by using a variable delay,
using Mozzi sonification library.
Demonstrates AudioDelay.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/triangle_analogue512_int8.h> // wavetable
#include <tables/cos2048_int8.h> // wavetable
#include <AudioDelay.h>
#include <mozzi_midi.h> // for mtof
Oscil < TRIANGLE_ANALOGUE512_NUM_CELLS , MOZZI_AUDIO_RATE > aTriangle ( TRIANGLE_ANALOGUE512_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kFreq ( COS2048_DATA );
AudioDelay < 256 > aDel ;
int del_samps ;
void setup (){
aTriangle . setFreq ( mtof ( 60. f ));
kFreq . setFreq ( .63 f );
startMozzi ();
}
void loop (){
audioHook ();
}
void updateControl (){
del_samps = 128 + kFreq . next ();
}
AudioOutput updateAudio (){
char asig = aDel . next ( aTriangle . next (), del_samps );
return MonoOutput :: from8Bit ( asig );
}
AudioDelayFeedback
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of flanging,
using Mozzi sonification library.
Demonstrates AudioDelayFeedback.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/triangle_analogue512_int8.h> // wavetable
#include <tables/triangle512_int8.h> // wavetable
#include <AudioDelayFeedback.h>
#include <mozzi_midi.h> // for mtof
Oscil < TRIANGLE_ANALOGUE512_NUM_CELLS , MOZZI_AUDIO_RATE > aTriangle ( TRIANGLE_ANALOGUE512_DATA ); // audio oscillator
Oscil < TRIANGLE512_NUM_CELLS , MOZZI_CONTROL_RATE > kDelSamps ( TRIANGLE512_DATA ); // for modulating delay time, measured in audio samples
AudioDelayFeedback < 128 > aDel ;
// the delay time, measured in samples, updated in updateControl, and used in updateAudio
byte del_samps ;
void setup (){
startMozzi ();
aTriangle . setFreq ( mtof ( 48. f ));
kDelSamps . setFreq ( .163 f ); // set the delay time modulation frequency (ie. the sweep frequency)
aDel . setFeedbackLevel ( - 111 ); // can be -128 to 127
}
Q16n16 deltime ;
void updateControl (){
// delay time range from 0 to 127 samples, @ 16384 samps per sec = 0 to 7 milliseconds
//del_samps = 64+kDelSamps.next();
// delay time range from 1 to 33 samples, @ 16384 samps per sec = 0 to 2 milliseconds
//del_samps = 17+kDelSamps.next()/8;
deltime = Q8n0_to_Q16n16 ( 17 ) + (( long ) kDelSamps . next () << 12 );
}
AudioOutput updateAudio (){
char asig = aTriangle . next (); // get this so it can be used twice without calling next() again
//return asig/8 + aDel.next(asig, (uint16_t) del_samps); // mix some straight signal with the delayed signal
//return aDel.next(aTriangle.next(), (uint16_t) del_samps); // instead of the previous 2 lines for only the delayed signal
return MonoOutput :: fromAlmostNBit ( 9 , ( asig >> 3 ) + aDel . next ( asig , deltime )); // mix some straight signal with the delayed signal
}
void loop (){
audioHook ();
}
AudioDelayFeedbackAllpass
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of allpass interpolation for fractional delays,
using Mozzi sonification library.
Demonstrates AudioDelayFeedback with allpass interpolation,
random delaytimes and feedback levels on a
(random) percussive adsr whitenoise sound.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <AudioDelayFeedback.h>
#include <Ead.h> // exponential attack decay
#include <EventDelay.h>
#include <mozzi_rand.h>
#include <tables/whitenoise8192_int8.h>
Oscil < WHITENOISE8192_NUM_CELLS , MOZZI_AUDIO_RATE > aNoise ( WHITENOISE8192_DATA ); // audio noise
EventDelay kDelay ; // for triggering envelope start
Ead kEnvelope ( MOZZI_CONTROL_RATE ); // resolution will be MOZZI_CONTROL_RATE
AudioDelayFeedback < 256 , ALLPASS > aDel ;
int gain ;
void setup (){
//Serial.begin(9600);
startMozzi ();
randSeed (); // reseed the random generator for different results each time the sketch runs
// use float to set freq because it will be small and fractional
aNoise . setFreq (( float ) MOZZI_AUDIO_RATE / WHITENOISE8192_SAMPLERATE );
kDelay . start ( 1000 );
}
void updateControl (){
// jump around in audio noise table to disrupt obvious looping
aNoise . setPhase ( rand (( unsigned int ) WHITENOISE8192_NUM_CELLS ));
if ( kDelay . ready ()){
// set random adsr parameters
unsigned int duration = rand ( 500u ) + 200 ;
unsigned int attack = rand ( 75 );
unsigned int decay = duration - attack ;
kEnvelope . start ( attack , decay );
// set random delay parameters
float del_cells = ( float ) rand ( 65535u ) / 256 ;
aDel . setDelayTimeCells ( del_cells ); // Allpass interpolation for fractional delay time
char fb = rand ( - 50 , 50 );
aDel . setFeedbackLevel ( fb );
kDelay . start ( duration + 500 );
}
gain = ( int ) kEnvelope . next ();
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aDel . next (( gain * aNoise . next ()) >> 8 ));
}
void loop (){
audioHook ();
}
AudioDelayFeedbackX2
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of flanging,
using Mozzi sonification library.
Demonstrates 2 oscillators going through 2 AudioDelayFeedback units,
with straight signal mixed in.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/triangle_analogue512_int8.h> // wavetable for audio
#include <tables/triangle512_int8.h> // wavetable for delay sweep
#include <AudioDelayFeedback.h>
#include <mozzi_midi.h> // for mtof
Oscil < TRIANGLE_ANALOGUE512_NUM_CELLS , MOZZI_AUDIO_RATE > aTriangle1 ( TRIANGLE_ANALOGUE512_DATA ); // audio oscillator
Oscil < TRIANGLE_ANALOGUE512_NUM_CELLS , MOZZI_AUDIO_RATE > aTriangle2 ( TRIANGLE_ANALOGUE512_DATA ); // audio oscillator
Oscil < TRIANGLE512_NUM_CELLS , MOZZI_CONTROL_RATE > kDelSamps1 ( TRIANGLE512_DATA ); // for modulating delay time, measured in audio samples
Oscil < TRIANGLE512_NUM_CELLS , MOZZI_CONTROL_RATE > kDelSamps2 ( TRIANGLE512_DATA ); // for modulating delay time, measured in audio samples
AudioDelayFeedback < 128 > aDel1 ;
AudioDelayFeedback < 128 > aDel2 ;
// the delay time, measured in samples, updated in updateControl, and used in updateAudio
uint16_t del_samps1 ;
uint16_t del_samps2 ;
void setup (){
aTriangle1 . setFreq ( mtof ( 48. f ));
kDelSamps1 . setFreq ( .163 f ); // set the delay time modulation frequency (ie. the sweep frequency)
aDel1 . setFeedbackLevel ( - 111 ); // can be -128 to 127
aTriangle2 . setFreq ( mtof ( 52. f ));
kDelSamps2 . setFreq ( 1.43 f ); // set the delay time modulation frequency (ie. the sweep frequency)
aDel2 . setFeedbackLevel ( 109 ); // can be -128 to 127
startMozzi ();
}
void updateControl (){
// delay time range from 0 to 127 samples, @ 16384 samps per sec = 0 to 7 milliseconds
del_samps1 = 64 + kDelSamps1 . next ();
// delay time range from 1 to 33 samples, @ 16384 samps per sec = 0 to 2 milliseconds
del_samps2 = 17 + kDelSamps2 . next () / 8 ;
}
AudioOutput updateAudio (){
char asig1 = aTriangle1 . next (); // get this so it can be used twice without calling next() again
int aflange1 = ( asig1 >> 3 ) + aDel1 . next ( asig1 , del_samps1 ); // mix some straignt signal with the delayed signal
char asig2 = aTriangle2 . next (); // get this so it can be used twice without calling next() again
int aflange2 = ( asig2 >> 3 ) + aDel2 . next ( asig2 , del_samps2 ); // mix some straignt signal with the delayed signal
return MonoOutput :: fromAlmostNBit ( 10 , aflange1 + aflange2 );
}
void loop (){
audioHook ();
}
AudioDelayFeedback_HIFI
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of flanging,
using Mozzi sonification library.
Demonstrates AudioDelayFeedback.
This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which
is not available on all boards (among others, it works on the
classic Arduino boards, but not Teensy 3.x and friends).
Important:
The MOZZI_AUDIO_RATE (sample rate) is additionally configured at 32768 Hz,
which is the default on most platforms, but twice the standard rate on
AVR-CPUs. Try chaging it back to hear the difference.
Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar),
Check the Mozzi core module documentation for others and more detail
3.9k
pin 9 ---WWWW-----|-----output
499k |
pin 10 ---WWWW---- |
|
4.7n ==
|
ground
Resistors are ±0.5% Measure and choose the most precise
from a batch of whatever you can get. Use two 1M resistors
in parallel if you can't find 499k.
Alternatively using 39 ohm, 4.99k and 470nF components will
work directly with headphones.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
#define MOZZI_AUDIO_RATE 32768
#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/triangle_analogue512_int8.h> // wavetable
#include <tables/triangle512_int8.h> // wavetable
#include <AudioDelayFeedback.h>
#include <mozzi_midi.h> // for mtof
Oscil < TRIANGLE_ANALOGUE512_NUM_CELLS , MOZZI_AUDIO_RATE > aTriangle ( TRIANGLE_ANALOGUE512_DATA ); // audio oscillator
Oscil < TRIANGLE512_NUM_CELLS , MOZZI_CONTROL_RATE > kDelSamps ( TRIANGLE512_DATA ); // for modulating delay time, measured in audio samples
AudioDelayFeedback < 128 > aDel ;
// the delay time, measured in samples, updated in updateControl, and used in updateAudio
byte del_samps ;
Q16n16 del_samps_fractional ;
void setup (){
startMozzi ();
aTriangle . setFreq ( mtof ( 48. f ));
kDelSamps . setFreq ( .163 f ); // set the delay time modulation frequency (ie. the sweep frequency)
aDel . setFeedbackLevel ( - 111 ); // can be -128 to 127
}
void updateControl (){
// delay time range from 0 to 127 samples, @ 16384 samps per sec = 0 to 7 milliseconds
//del_samps = 64+kDelSamps.next();
// delay time range from 1 to 33 samples, @ 16384 samps per sec = 0 to 2 milliseconds
//del_samps = 17+kDelSamps.next()/8;
del_samps_fractional = Q8n0_to_Q16n16 ( 17 ) + (( long ) kDelSamps . next () << 12 );
}
AudioOutput updateAudio (){
char asig = aTriangle . next (); // get this so it can be used twice without calling next() again
//return asig/8 + aDel.next(asig, del_samps); // mix some straight signal with the delayed signal
//return aDel.next(aTriangle.next(), del_samps); // instead of the previous 2 lines for only the delayed signal
return MonoOutput :: fromAlmostNBit ( 13 , asig + ( aDel . next ( asig , del_samps_fractional ) << 4 )); // mix some straight signal with the delayed signal
}
void loop (){
audioHook ();
}
ReverbTank_HIFI
…(no recording of this one)
show sketch
hide sketch
/* Example of reverb on a synthesised sound
using Mozzi sonification library.
Demonstrates ReverbTank, a reverb small enough to fit on
the Arduino Nano, which for some reason wasn't able to fit a larger version
which did fit on other 328 based boards.
It's a pretty horrible reverb which sounds like the inside of a tin can.
For simplicity, ReverbTank has hardcoded maximum delay sizes
but also has default delay times which can be changed in the constructor
or by setting during run time to allow live tweaking.
The synthesised sound comes from the phasemod synth example.
Circuit: Audio output on digital pin 9 for STANDARD output on a Uno or similar, or
see the readme.md file for others.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth
#include <Mozzi.h>
#include <ReverbTank.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <tables/envelop2048_uint8.h>
ReverbTank reverb ;
// Synth from PhaseMod_Envelope example
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCarrier ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aModulator ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aModWidth ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kModFreq1 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kModFreq2 ( COS8192_DATA );
Oscil < ENVELOP2048_NUM_CELLS , MOZZI_AUDIO_RATE > aEnvelop ( ENVELOP2048_DATA );
void setup (){
// synth params
aCarrier . setFreq ( 55 );
kModFreq1 . setFreq ( 3.98 f );
kModFreq2 . setFreq ( 3.31757 f );
aModWidth . setFreq ( 2.52434 f );
aEnvelop . setFreq ( 9.0 f );
startMozzi ();
}
void updateControl (){
// synth control
aModulator . setFreq ( 277.0 f + 0.4313 f * kModFreq1 . next () + kModFreq2 . next ());
}
AudioOutput updateAudio (){
int synth = aCarrier . phMod (( int ) aModulator . next () * ( 150u + aModWidth . next ()));
synth *= ( byte ) aEnvelop . next ();
// here's the reverb
int arev = reverb . next ( synth >> 8 ); // >>8 avoids clipping
// experiment to adjust levels of the dry and wet signals
return MonoOutput :: fromNBit ( 12 , ( synth + ( arev << 4 )));
}
void loop (){
audioHook ();
}
ReverbTank_STANDARD
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of reverb on a synthesised sound
using Mozzi sonification library.
Demonstrates ReverbTank, a reverb small enough to fit on
the Arduino Nano, which for some reason wasn't able to fit a larger version
which did fit on other 328 based boards.
It's a pretty horrible reverb which sounds like the inside of a tin can.
For simplicity, ReverbTank has hardcoded maximum delay sizes
but also has default delay times which can be changed in the constructor
or by setting during run time to allow live tweaking.
The synthesised sound comes from the phasemod synth example.
Circuit: Audio output on digital pin 9 for STANDARD output on a Uno or similar, or
see the readme.md file for others.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 640 // quite fast, keeps modulation smooth
#include <Mozzi.h>
#include <ReverbTank.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <tables/envelop2048_uint8.h>
ReverbTank reverb ;
// Synth from PhaseMod_Envelope example
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCarrier ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aModulator ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_AUDIO_RATE > aModWidth ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kModFreq1 ( COS8192_DATA );
Oscil < COS8192_NUM_CELLS , MOZZI_CONTROL_RATE > kModFreq2 ( COS8192_DATA );
Oscil < ENVELOP2048_NUM_CELLS , MOZZI_AUDIO_RATE > aEnvelop ( ENVELOP2048_DATA );
void setup (){
// synth params
aCarrier . setFreq ( 55 );
kModFreq1 . setFreq ( 3.98 f );
kModFreq2 . setFreq ( 3.31757 f );
aModWidth . setFreq ( 2.52434 f );
aEnvelop . setFreq ( 9.0 f );
startMozzi ();
}
void updateControl (){
// synth control
aModulator . setFreq ( 277.0 f + 0.4313 f * kModFreq1 . next () + kModFreq2 . next ());
}
AudioOutput updateAudio (){
int synth = aCarrier . phMod (( int ) aModulator . next () * ( 150u + aModWidth . next ()));
synth *= ( byte ) aEnvelop . next ();
synth >>= 8 ;
// here's the reverb
int arev = reverb . next ( synth );
// add the dry and wet signals
return MonoOutput :: fromAlmostNBit ( 9 , synth + ( arev >> 3 ));
}
void loop (){
audioHook ();
}
10.Audio_Filters
LowPassFilter
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of filtering a wave,
using Mozzi sonification library.
Demonstrates LowPassFilter().
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2012, CC by-nc-sa.
*/
#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos2048_int8.h> // for filter modulation
#include <LowPassFilter.h>
#include <mozzi_rand.h>
Oscil < CHUM9_NUM_CELLS , AUDIO_RATE > aCrunchySound ( CHUM9_DATA );
Oscil < COS2048_NUM_CELLS , CONTROL_RATE > kFilterMod ( COS2048_DATA );
LowPassFilter lpf ;
uint8_t resonance = 200 ; // range 0-255, 255 is most resonant
void setup (){
startMozzi ();
aCrunchySound . setFreq ( 2. f );
kFilterMod . setFreq ( 1.3 f );
}
void loop (){
audioHook ();
}
void updateControl (){
if ( rand ( CONTROL_RATE / 2 ) == 0 ){ // about once every half second
kFilterMod . setFreq (( float ) rand ( 255 ) / 64 ); // choose a new modulation frequency
}
// map the modulation into the filter range (0-255), corresponds with 0-8191Hz
byte cutoff_freq = 100 + kFilterMod . next () / 2 ;
lpf . setCutoffFreqAndResonance ( cutoff_freq , resonance );
}
int updateAudio (){
char asig = lpf . next ( aCrunchySound . next ());
return ( int ) asig ;
}
LowPassFilterX2
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of filtering 2 waves with different filter settings,
using Mozzi sonification library.
Demonstrates 2 Oscillators, each with a LowPassFilter().
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos512_int8.h> // for filter modulation
#include <ResonantFilter.h>
#include <mozzi_rand.h> // for rand()
Oscil < CHUM9_NUM_CELLS , MOZZI_AUDIO_RATE > aCrunchySound1 ( CHUM9_DATA ); //audio oscillator
Oscil < CHUM9_NUM_CELLS , MOZZI_AUDIO_RATE > aCrunchySound2 ( CHUM9_DATA ); //audio oscillator
Oscil < COS512_NUM_CELLS , MOZZI_CONTROL_RATE > kFilterMod1 ( COS512_DATA ); // to modulate filter frequency
Oscil < COS512_NUM_CELLS , MOZZI_CONTROL_RATE > kFilterMod2 ( COS512_DATA ); // to modulate filter frequency
LowPassFilter lpf1 ; // can be changed to HighPassFilter, BandPassFilter or NotchFilter
LowPassFilter lpf2 ;
uint8_t resonance1 = 180 ; // range 0-255, 255 is most resonant
uint8_t resonance2 = 200 ;
void setup (){
startMozzi ();
aCrunchySound1 . setFreq ( 2. f );
aCrunchySound2 . setFreq ( 6. f );
kFilterMod1 . setFreq ( 1.3 f );
kFilterMod2 . setFreq ( 0.1 f );
}
void updateControl (){
// map the modulation depth into the filter range, 0-255 to represent 0-8192 Hz
byte cutoff_freq1 = 100 + kFilterMod1 . next () / 2 ; // 100 ± 63
lpf1 . setCutoffFreqAndResonance ( cutoff_freq1 , resonance1 );
// also update lpf2 cutoff
byte cutoff_freq2 = 70 + kFilterMod2 . next () / 4 ; // 70 ± 31
lpf2 . setCutoffFreqAndResonance ( cutoff_freq2 , resonance2 );
}
AudioOutput updateAudio (){
return MonoOutput :: fromAlmostNBit ( 9 , ((( char ) lpf1 . next ( aCrunchySound1 . next ())) >> 1 ) + ( char ) lpf2 . next ( aCrunchySound2 . next ()));
}
void loop (){
audioHook ();
}
MultiResonantFilter
…(no recording of this one)
show sketch
hide sketch
/* Example of filtering a wave with different types of filters
using Mozzi sonification library.
Demonstrates MultiResonantFilter<uint8_t>.
MultiResonantFilter is a derivative of ResonantFilter which allows all filter types to be accessed with only one filter.
It behaves similarly to ResonantFilter except:
- next(in) does not return anything and is just used to pass the current sample to the filter. Except for special cases should probably be called only once in updateAudio()
- different filter outputs are accessible via low(), high(), band() and notch() functions.
- note that the different filter types can be called in the same updateAudio(), for eg. to get different part of the signal.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2023-2024 Tom Combriat and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos2048_int8.h> // for filter modulation
#include <ResonantFilter.h>
#include <mozzi_rand.h>
Oscil < CHUM9_NUM_CELLS , MOZZI_AUDIO_RATE > aCrunchySound ( CHUM9_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kFilterMod ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kFilterMod2 ( COS2048_DATA );
MultiResonantFilter < uint8_t > mf ; // Multifilter applied to a 8 bits signal.
// MultiResonantFilter<uint16_t> can also be used for signals with higher number of bits
// in this last case, both the cutoff frequency and the resonance are uint16_t,
// ranging from 0, to 65535.
enum types { lowpass , bandpass , highpass , notch };
byte filter_type = 0 ;
uint8_t resonance = 200 ; // range 0-255, 255 is most resonant.
void setup () {
startMozzi ();
aCrunchySound . setFreq ( 2. f );
kFilterMod . setFreq ( 1.3 f );
kFilterMod2 . setFreq ( 0.1 f );
}
void loop () {
audioHook ();
}
void updateControl () {
if ( rand ( MOZZI_CONTROL_RATE / 2 ) == 0 ) { // about once every half second
kFilterMod . setFreq (( float ) rand ( 255 ) / 64 ); // choose a new modulation frequency
filter_type = rand ( 4 ); // change the filter type, randomly
}
// map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz
uint8_t cutoff_freq = ( 100 + kFilterMod . next () / 2 ) ;
mf . setCutoffFreqAndResonance ( cutoff_freq , resonance );
}
AudioOutput updateAudio () {
AudioOutput asig ;
mf . next ( aCrunchySound . next ()); // this send the current sample to the filter, does not return anything
switch ( filter_type ) // recover the output from the current selected filter type.
{
case lowpass :
asig = mf . low (); // lowpassed sample
break ;
case highpass :
asig = mf . high (); // highpassed sample
break ;
case bandpass :
asig = mf . band (); // bandpassed sample
break ;
case notch :
asig = mf . notch (); // notched sample
break ;
}
return MonoOutput :: fromNBit ( 9 , asig ); // signal is theoretically 8 bits, but resonance push it further so we let one bit of margin
}
ResonantFilter
…(no recording of this one)
show sketch
hide sketch
/* Example of filtering a wave,
using Mozzi sonification library.
Demonstrates ResonantFilter<uint8_t, FILTER_TYPE>>.
Note that, on 8bits platforms (Arduino) this filter cannot work
on samples of more than 8bits. Use LowPassFilter16() if you need
more than that.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos2048_int8.h> // for filter modulation
#include <ResonantFilter.h>
#include <mozzi_rand.h>
Oscil < CHUM9_NUM_CELLS , MOZZI_AUDIO_RATE > aCrunchySound ( CHUM9_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kFilterMod ( COS2048_DATA );
//Different types of filters available
LowPassFilter rf ; // Equivalent to ResonantFilter<LOWPASS>
//ResonantFilter<HIGHPASS> rf; // HighPass filter
//ResonantFilter<BANDPASS> rf; // BandPass filter
//ResonantFilter<NOTCH> rf; // Notch filter
uint8_t resonance = 200 ; // range 0-255, 255 is most resonant
void setup (){
startMozzi ();
aCrunchySound . setFreq ( 2. f );
kFilterMod . setFreq ( 1.3 f );
}
void loop (){
audioHook ();
}
void updateControl (){
if ( rand ( MOZZI_CONTROL_RATE / 2 ) == 0 ){ // about once every half second
kFilterMod . setFreq (( float ) rand ( 255 ) / 64 ); // choose a new modulation frequency
}
// map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz
byte cutoff_freq = 100 + kFilterMod . next () / 2 ;
rf . setCutoffFreqAndResonance ( cutoff_freq , resonance );
}
AudioOutput updateAudio (){
char asig = rf . next ( aCrunchySound . next ());
return MonoOutput :: from8Bit ( asig );
}
ResonantFilter16
…(no recording of this one)
show sketch
hide sketch
/* Example of filtering a wave,
using Mozzi sonification library.
Demonstrates ResonantFilter<uint16_t, FILTER_TYPE>.
ResonantFilter<uint16_t, FILTER_TYPE> is a different version of ResonantFilter<uint8_t, FILTER_TYPE> which uses bigger containing types for internal calculations.
The main differences with LowPassFilter are:
- parameters (resonance and cutoff_freq) are coded on 16bits, allowing for smoother transitions and finer tuning if needed,
- for 8bits platforms (like the Arduino) it will accept input samples of more than 8bits without overflowing,
- the drawback is higher CPU usage, especially for 8bits platform. If speed is crucial, you should probably use ResonantFilter<uint8_t, FILTER_TYPE> instead.
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/chum9_int8.h> // recorded audio wavetable
#include <tables/cos2048_int8.h> // for filter modulation
#include <ResonantFilter.h>
#include <mozzi_rand.h>
Oscil < CHUM9_NUM_CELLS , MOZZI_AUDIO_RATE > aCrunchySound ( CHUM9_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kFilterMod ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kFilterMod2 ( COS2048_DATA );
//Different types of filters available
LowPassFilter16 rf ; // Equivalent to ResonantFilter<LOWPASS, uint16_t>
//ResonantFilter<HIGHPASS, uint16_t> rf; // HighPass filter
//ResonantFilter<BANDPASS, uint16_t> rf; // BandPass filter
//ResonantFilter<NOTCH, uint16_t> rf; // Notch filter
uint16_t resonance = 50000 ; // range 0-65535, 65535 is most resonant.
// note the difference of type with the LowPassFilter()
void setup (){
startMozzi ();
aCrunchySound . setFreq ( 2. f );
kFilterMod . setFreq ( 1.3 f );
kFilterMod2 . setFreq ( 0.1 f );
}
void loop (){
audioHook ();
}
void updateControl (){
if ( rand ( MOZZI_CONTROL_RATE / 2 ) == 0 ){ // about once every half second
kFilterMod . setFreq (( float ) rand ( 255 ) / 64 ); // choose a new modulation frequency
}
// map the modulation into the filter range (0-255), corresponds with 0-MOZZI_AUDIO_RATE/(sqrt(2)*pi) Hz
uint16_t cutoff_freq = ( 100 + kFilterMod . next () / 2 ) * ( 170 + kFilterMod2 . next ());
rf . setCutoffFreqAndResonance ( cutoff_freq , resonance );
}
AudioOutput updateAudio (){
AudioOutput asig = rf . next ( aCrunchySound . next ());
return MonoOutput :: from8Bit ( asig );
}
StateVariableFilter
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of filtering a wave,
using Mozzi sonification library.
Demonstrates StateVariable().
Circuit: Audio output on digital pin 9 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/whitenoise8192_int8.h>
#include <tables/cos2048_int8.h> // for filter modulation
#include <StateVariable.h>
#include <mozzi_rand.h> // for rand()
Oscil < WHITENOISE8192_NUM_CELLS , MOZZI_AUDIO_RATE > aNoise ( WHITENOISE8192_DATA ); // audio noise
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kFilterMod ( COS2048_DATA );
StateVariable < NOTCH > svf ; // can be LOWPASS, BANDPASS, HIGHPASS or NOTCH
void setup (){
startMozzi ();
// cast to float because the resulting freq will be small and fractional
aNoise . setFreq (( float ) MOZZI_AUDIO_RATE / WHITENOISE8192_SAMPLERATE );
kFilterMod . setFreq ( 1.3 f );
svf . setResonance ( 25 );
svf . setCentreFreq ( 1200 );
}
void updateControl (){
if ( rand ( MOZZI_CONTROL_RATE / 2 ) == 0 ){ // about once every half second
kFilterMod . setFreq (( float ) rand ( 255 ) / 64 ); // choose a new modulation frequency
}
int cutoff_freq = 2200 + kFilterMod . next () * 12 ;
svf . setCentreFreq ( cutoff_freq );
}
AudioOutput updateAudio (){
// watch output levels, they can distort if too high
// also, at very resonant settings, the input signal may need attenuating
return MonoOutput :: fromAlmostNBit ( 12 , svf . next ( aNoise . next ()));
}
void loop (){
audioHook ();
}
StateVariableFilter_HIFI
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example of filtering audio noise with a resonant filter,
using Mozzi sonification library.
Demonstrates StateVariable() with acute resonance,
which in this case requires the input signal level to be reduced
to avoid distortion which can occur with sharp resonance settings.
Important:
This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which
is not available on all boards (among others, it works on the
classic Arduino boards, but not Teensy 3.x and friends).
Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar),
Check the Mozzi core module documentation for others and more detail
3.9k
pin 9 ---WWWW-----|-----output
499k |
pin 10 ---WWWW---- |
|
4.7n ==
|
ground
Resistors are ±0.5% Measure and choose the most precise
from a batch of whatever you can get. Use two 1M resistors
in parallel if you can't find 499k.
Alternatively using 39 ohm, 4.99k and 470nF components will
work directly with headphones.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/whitenoise8192_int8.h>
#include <StateVariable.h>
Oscil < WHITENOISE8192_NUM_CELLS , MOZZI_AUDIO_RATE > aNoise ( WHITENOISE8192_DATA ); // audio noise
StateVariable < BANDPASS > svf ; // can be LOWPASS, BANDPASS, HIGHPASS or NOTCH
void setup (){
startMozzi ();
aNoise . setFreq ( 1.27 f * ( float ) MOZZI_AUDIO_RATE / WHITENOISE8192_SAMPLERATE ); // * by an oddish number (1.27) to avoid exact repeating of noise oscil
svf . setResonance ( 1 ); // 0 to 255, 0 is the "sharp" end
svf . setCentreFreq ( 3500 );
}
void updateControl (){
}
AudioOutput updateAudio (){
int input = aNoise . next () >> 1 ; // shift down (ie. fast /) to avoid distortion with extreme resonant filter setting
int output = svf . next ( input );
return MonoOutput :: fromNBit ( 10 , output );
}
void loop (){
audioHook ();
}
11.Communication
Mozzi_MIDI_Input
…(no recording of this one)
show sketch
hide sketch
Mozzi_Processing_Serial
…(no recording of this one)
show sketch
hide sketch
/*
Modified from Arduino > Examples > Communication > Dimmer
Demonstrates the sending data from the computer to the Arduino board,
in this case to control the frequency of an oscillator. The data is sent
in individual bytes, each of which ranges from 0 to 255. Arduino
reads these bytes and uses them to set the frequency of the oscillator.
Circuit: Audio output on digital pin 9. (on Arduino Uno/Nano, in default config)
Serial connection to Processing, Max/MSP, or another serial application
Dimmer example created 2006
by David A. Mellis
modified 30 Aug 2011
by Tom Igoe and Scott Fitzgerald
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/Dimmer
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 );
startMozzi (); // uses default control rate of 64
}
void updateControl (){
// check if data has been sent from the computer:
if ( Serial . available ()) {
// read the most recent byte (which will be from 0 to 255):
int val = Serial . read ();
aSin . setFreq ( val + 100 );
}
}
AudioOutput updateAudio (){
return MonoOutput :: from8Bit ( aSin . next ());
}
void loop (){
audioHook (); // required here
}
/* Processing code for this example
// Dimmer - sends bytes over a serial port
// by David A. Mellis
// This code is in the Public Domain.
import processing.serial.*;
Serial port;
void setup() {
size(256, 150);
println("Available serial ports:");
println(Serial.list());
// Uses the first port in this list (number 0). Change this to
// select the port corresponding to your Arduino board. The last
// parameter (e.g. 9600) is the speed of the communication. It
// has to correspond to the value passed to Serial.begin() in your
// Arduino sketch.
port = new Serial(this, Serial.list()[0], 9600);
// If you know the name of the port used by the Arduino board, you
// can specify it directly like this.
//port = new Serial(this, "COM1", 9600);
}
void draw() {
// draw a gradient from black to white
for (int i = 0; i < 256; i++) {
stroke(i);
line(i, 0, i, 150);
}
// write the current X-position of the mouse to the serial port as
// a single byte
port.write(mouseX);
}
*/
/* Max/MSP v5 patch for this example
----------begin_max5_patcher----------
1008.3ocuXszaiaCD9r8uhA5rqAeHIa0aAMaAVf1S6hdoYQAsDiL6JQZHQ2M
YWr+2KeX4vjnjXKKkKhhiGQ9MeyCNz+X9rnMp63sQvuB+MLa1OlOalSjUvrC
ymEUytKuh05TKJWUWyk5nE9eSyuS6jesvHu4F4MxOuUzB6X57sPKWVzBLXiP
xZtGj6q2vafaaT0.BzJfjj.p8ZPukazsQvpfcpFs8mXR3plh8BoBxURIOWyK
rxspZ0YI.eTCEh5Vqp+wGtFXZMKe6CZc3yWZwTdCmYW.BBkdiby8v0r+ST.W
sD9SdUkn8FYspPbqvnBNFtZWiUyLmleJWo0vuKzeuj2vpJLaWA7YiE7wREui
FpDFDp1KcbAFcP5sJoVxp4NB5Jq40ougIDxJt1wo3GDZHiNocKhiIExx+owv
AdOEAksDs.RRrOoww1Arc.9RvN2J9tamwjkcqknvAE0l+8WnjHqreNet8whK
z6mukIK4d+Xknv3jstvJs8EirMMhxsZIusET25jXbX8xczIl5xPVxhPcTGFu
xNDu9rXtUCg37g9Q8Yc+EuofIYmg8QdkPCrOnXsaHwYs3rWx9PGsO+pqueG2
uNQBqWFh1X7qQG+3.VHcHrfO1nyR2TlqpTM9MDsLKNCQVz6KO.+Sfc5j1Ykj
jzkn2jwNDRP7LVb3d9LtoWBAOnvB92Le6yRmZ4UF7YpQhiFi7A5Ka8zXhKdA
4r9TRGG7V4COiSbAJKdXrWNhhF0hNUh7uBa4Mba0l7JUK+omjDMwkSn95Izr
TOwkdp7W.oPRmNRQsiKeu4j3CkfVgt.NYPEYqMGvvJ48vIlPiyzrIuZskWIS
xGJPcmPiWOfLodybH3wjPbMYwlbFIMNHPHFOtLBNaLSa9sGk1TxMzCX5KTa6
WIH2ocxSdngM0QPqFRxyPHFsprrhGc9Gy9xoBjz0NWdR2yW9DUa2F85jG2v9
FgTO4Q8qiC7fzzQNpmNpsY3BrYPVJBMJQ1uVmoItRhw9NrVGO3NMNzYZ+zS7
3WTvTOnUydG5kHMKLqAOjTe7fN2bGSxOZDkMrBrGQ9J1gONBEy0k4gVo8qHc
cxmfxVihWz6a3yqY9NazzUYkua9UnynadOtogW.JfsVGRVNEbWF8I+eHtcwJ
+wLXqZeSdWLo+FQF6731Tva0BISKTx.cLwmgJsUTTvkg1YsnXmxDge.CDR7x
D6YmX6fMznaF7kdczmJXwm.XSOOrdoHhNA7GMiZYLZZR.+4lconMaJP6JOZ8
ftCs1YWHZI3o.sIXezX5ihMSuXzZtk3ai1mXRSczoCS32hAydeyXNEu5SHyS
xqZqbd3ZLdera1iPqYxOm++v7SUSz
-----------end_max5_patcher-----------
*/
Sinewave_PWM_leds_HIFI
…(no recording of this one)
show sketch
hide sketch
/* Example playing a sinewave
and changing the brightness of 3 leds
using Mozzi sonification library.
Demonstrates the use of Oscil for audio and control,
and a way to do PWM on digital pins without disrupting audio.
Control oscillators are used here to modulate the brightness of the leds
between 0-255.
The technique is explained here:
http://playground.arduino.cc/Main/PWMallPins
With MOZZI_AUDIO_RATE at 16384 Hz (default on AVR), this gives a 64 Hz pwm duty cycle for the LEDs.
If there is visible flicker, the resolution of the pwm could be made lower,
or the MOZZI_AUDIO_RATE could be increased to 32768 Hz, if the
cpu isn't too busy.
Important:
This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which
is not available on all boards (among others, it works on the
classic Arduino boards, but not Teensy 3.x and friends).
Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar),
Check the Mozzi core module documentation for others and more detail
3.9k
pin 9 ---WWWW-----|-----output
499k |
pin 10 ---WWWW---- |
|
4.7n ==
|
ground
Resistors are ±0.5% Measure and choose the most precise
from a batch of whatever you can get. Use two 1M resistors
in parallel if you can't find 499k.
Alternatively using 39 ohm, 4.99k and 470nF components will
work directly with headphones.
LEDs:
Red led from pin 3 through a 1.5k resistor to ground
Green led from pin 4 through a 1.5k resistor to ground
Blue led from pin 5 through a 1.5k resistor to ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2013-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
//#define MOZZI_AUDIO_RATE 32768
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
// LED pins, use 0-7 for PORTD, otherwise change to PORTB in updateRGB
const byte RED_PIN = 3 ;
const byte GREEN_PIN = 4 ;
const byte BLUE_PIN = 5 ;
byte red_brightness , green_brightness , blue_brightness ;
// control oscillators using sinewaves to modulate LED brightness
Oscil < SIN2048_NUM_CELLS , MOZZI_CONTROL_RATE > kRed ( SIN2048_DATA );
Oscil < SIN2048_NUM_CELLS , MOZZI_CONTROL_RATE > kGreen ( SIN2048_DATA );
Oscil < SIN2048_NUM_CELLS , MOZZI_CONTROL_RATE > kBlue ( SIN2048_DATA );
// audio oscillator
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
void updateRGB ( byte r , byte g , byte b ){
// stagger pwm counter starts to try to reduce combined flicker
static byte red_count = 0 ;
static byte green_count = 85 ;
static byte blue_count = 170 ;
// PORTD maps to Arduino digital pins 0 to 7
// http://playground.arduino.cc/Learning/PortManipulation
( red_count ++ >= r ) ? PORTD &= ~ ( 1 << RED_PIN ) : PORTD |= ( 1 << RED_PIN );
( green_count ++ >= g ) ? PORTD &= ~ ( 1 << GREEN_PIN ) : PORTD |= ( 1 << GREEN_PIN );
( blue_count ++ >= b ) ? PORTD &= ~ ( 1 << BLUE_PIN ) : PORTD |= ( 1 << BLUE_PIN );
}
void setup (){
pinMode ( RED_PIN , OUTPUT );
pinMode ( GREEN_PIN , OUTPUT );
pinMode ( BLUE_PIN , OUTPUT );
// set led brightness modulation frequencies
kRed . setFreq ( 0.21 f );
kGreen . setFreq ( 0.3 f );
kBlue . setFreq ( 0.27 f );
// set audio oscil frequency
aSin . setFreq ( 440 );
startMozzi (); // uses the default control rate of 64
}
void updateControl (){
red_brightness = 128 + kRed . next ();
green_brightness = 128 + kGreen . next ();
blue_brightness = 128 + kBlue . next ();
}
AudioOutput updateAudio (){
updateRGB ( red_brightness , green_brightness , blue_brightness );
// this would make more sense with a higher resolution signal
// but still benefits from using HIFI to avoid the 16kHz pwm noise
return MonoOutput :: from8Bit ( aSin . next ());
}
void loop (){
audioHook (); // required here
}
Teensy_USB_MIDI_Input
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
TwoWire_Read_ADXL345
…(no recording of this one)
show sketch
hide sketch
/* Example reading an ADXL345 accelerometer
using I2C communication without blocking audio synthesis,
using Mozzi sonification library.
Demonstrates use of twi_nonblock functions
to replace processor-blocking Wire methods.
Note: The twi_nonblock code is not compatible with Teesy 3.1.
Circuit: Audio output on digital pin 9.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Marije Baalman and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#define MOZZI_CONTROL_RATE 128 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <Ead.h> // exponential attack decay
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <twi_nonblock.h>
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
Ead kEnvelope ( MOZZI_CONTROL_RATE ); // resolution will be MOZZI_CONTROL_RATE
int gain ;
#define ADXL345_DEVICE (0x53) // ADXL345 device address
#define ADXL345_POWER_CTL 0x2d
#define ADXL345_DATA_FORMAT 0x31
#define ADXL345_DATAX0 0x32
#define ADXL345_THRESH_INACT 0x25
#define ADXL345_TIME_INACT 0x26
#define ADXL345_ACT_INACT_CTL 0x27
static volatile byte acc_status = 0 ;
#define ACC_IDLE 0
#define ACC_READING 1
#define ACC_WRITING 2
byte accbytedata [ 6 ];
void setup_accelero (){
initialize_twi_nonblock ();
acc_writeTo ( ADXL345_POWER_CTL , 0 ); // all registers off
acc_writeTo ( ADXL345_POWER_CTL , 16 ); // auto sleep on
// ADXL345_DATA_FORMAT : (self test)(spi)(int_invert)(0)(fullres)(justify)(range..)
// 11 //= B00001011
acc_writeTo ( ADXL345_DATA_FORMAT , 11 );
// set the threshold for inactivity
// acc_writeTo( ADXL345_THRESH_INACT, inactivityThreshold );
// acc_writeTo( ADXL345_TIME_INACT, inactivityTime );
// 0B10001111
// acc_writeTo( ADXL345_ACT_INACT_CTL, B10001111 );
// acc_writeTo(ADXL345_POWER_CTL, B00111000);
acc_writeTo ( ADXL345_POWER_CTL , 8 ); // auto sleep off, measure on
acc_status = ACC_IDLE ;
}
/// ---------- non-blocking version ----------
void initiate_read_accelero (){
// Reads num bytes starting from address register on device in to _buff array
// indicate that we are transmitting
// transmitting = 1;
// set address of targeted slave
txAddress = ADXL345_DEVICE ;
// reset tx buffer iterator vars
txBufferIndex = 0 ;
txBufferLength = 0 ;
// put byte in tx buffer
txBuffer [ txBufferIndex ] = ADXL345_DATAX0 ;
++ txBufferIndex ;
// update amount in buffer
txBufferLength = txBufferIndex ;
twi_initiateWriteTo ( txAddress , txBuffer , txBufferLength );
acc_status = ACC_WRITING ;
}
void initiate_request_accelero (){
// reset tx buffer iterator vars
txBufferIndex = 0 ;
txBufferLength = 0 ;
// indicate that we are done transmitting
// transmitting = 0;
byte read = twi_initiateReadFrom ( ADXL345_DEVICE , 6 );
acc_status = ACC_READING ;
}
void finalise_request_accelero (){
byte read = twi_readMasterBuffer ( rxBuffer , 6 );
// set rx buffer iterator vars
rxBufferIndex = 0 ;
rxBufferLength = read ;
byte i = 0 ;
while ( rxBufferLength - rxBufferIndex > 0 ) // device may send less than requested (abnormal)
{
accbytedata [ i ] = rxBuffer [ rxBufferIndex ];
++ rxBufferIndex ;
i ++ ;
}
acc_status = ACC_IDLE ;
}
/// ----end------ non-blocking version ----------
// Writes val to address register on device
void acc_writeTo ( byte address , byte val ) {
// Wire.beginTransmission(ADXL345_DEVICE); // start transmission to device
twowire_beginTransmission ( ADXL345_DEVICE ); // start transmission to device
// Wire.send(address); // send register address
twowire_send ( address );
// Wire.send(val); // send value to write
twowire_send ( val );
// Wire.endTransmission(); // end transmission
twowire_endTransmission ();
}
void setup (){
setup_accelero ();
startMozzi ();
aSin . setFreq ( 800 );
int attack = 30 ;
int decay = 500 ;
kEnvelope . set ( attack , decay );
}
int accx ;
int accy ;
int accz ;
int envgain ;
void updateControl (){
envgain = ( int ) kEnvelope . next ();
if ( envgain < 5 ){
if ( accx > 512 ){
aSin . setFreq ( 400 );
kEnvelope . start ();
}
else if ( accy > 512 ) {
aSin . setFreq ( 800 );
kEnvelope . start ();
}
else if ( accz > 512 ) {
aSin . setFreq ( 1200 );
kEnvelope . start ();
}
}
switch ( acc_status ){
case ACC_IDLE :
accx = ( int ) ( accbytedata [ 1 ] * 256 + accbytedata [ 0 ]); // accelerometer x reading
accy = ( int ) ( accbytedata [ 3 ] * 256 + accbytedata [ 2 ]); // accelerometer y reading
accz = ( int ) ( accbytedata [ 5 ] * 256 + accbytedata [ 4 ]); // accelerometer z reading
initiate_read_accelero ();
break ;
case ACC_WRITING :
if ( TWI_MTX != twi_state ){
initiate_request_accelero ();
}
break ;
case ACC_READING :
if ( TWI_MRX != twi_state ){
finalise_request_accelero ();
}
break ;
}
gain = envgain ;
}
AudioOutput updateAudio (){
return MonoOutput :: from16Bit ( aSin . next () * gain );
}
void loop (){
audioHook (); // required here
}
12.Misc
IntMap_test
…(no recording of this one)
show sketch
hide sketch
/* Maps a range of input numbers to an output range, comparing
the results of Mozzi's IntMap object with Arduino map().
Demonstrates IntMap, a fast integer replacement for map().
Circuit: not required
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2014-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <IntMap.h>
const IntMap testIntMap ( 0 , 100 , 10 , 1000 );
void setup (){
//Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches
Serial . begin ( 115200 );
int n ;
int i = - 2000 ;
while ( i < 5000 ){
n = testIntMap ( i );
Serial . print ( "testIntMap: \t " );
Serial . print ( n , DEC );
n = map ( i , 0 , 100 , 10 , 1000 );
Serial . print ( " \t map: \t " );
Serial . println ( n , DEC );
i += 7 ;
}
}
void loop (){
}
MozziByte_HIFI
…(no recording of this one)
show sketch
hide sketch
/*
A cartoon mosquito sound, to demonstrate the Mozzibyte board.
The Arduino-compatible "Pro Micro" board sent with Mozzibytes
needs "Arduino Leonardo" to be set under Arduino>Tools>Board.
Important:
This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which
is not available on all boards (among others, it works on the
classic Arduino boards, but not Teensy 3.x and friends).
Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar),
Check the Mozzi core module documentation for others and more detail
3.9k
pin 9 ---WWWW-----|-----output
499k|
pin 10 ---WWWW---- |
|
4.7n ==
|
ground
Resistors are ±0.5%
Circuit: Audio output on digital pins 9 and 10 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2018-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
#define MOZZI_CONTROL_RATE 128
#include <Mozzi.h>
#include <WavePacketSample.h>
#include <EventDelay.h>
#include <mozzi_rand.h>
#include <Smooth.h>
#include <Oscil.h> // oscillator template
#include <tables/sin1024_int8.h> // sine table for oscillator
#define F_MAX ((int) 750)
#define F_MIN ((int) 150)
#define F_CHANGE ((byte) 60)
#define B_MAX ((int) 500)
#define B_MIN ((int) 10)
#define B_CHANGE ((byte) 200)
#define CF_MAX ((int) 500)
#define CF_MIN ((int) 5)
#define CF_CHANGE ((byte) 40)
#define LEVEL_MAX ((int) 255)
#define LEVEL_MIN ((int) 20)
#define LEVEL_CHANGE ((byte) 50)
#define OFFSET_TIME_MAX_MS ((int) 500)
#define SYNTH_PARAM_MAX_MS ((byte) 200)
Oscil < SIN1024_NUM_CELLS , MOZZI_CONTROL_RATE > kFOffsetTrem ( SIN1024_DATA );
Oscil < SIN1024_NUM_CELLS , MOZZI_CONTROL_RATE > kBOffsetTrem ( SIN1024_DATA );
Oscil < SIN1024_NUM_CELLS , MOZZI_CONTROL_RATE > kCFOffsetTrem ( SIN1024_DATA );
Oscil < SIN1024_NUM_CELLS , MOZZI_CONTROL_RATE > kLevelOffsetTrem ( SIN1024_DATA );
WavePacketSample < SINGLE > wavey ;
EventDelay kFTime ;
EventDelay kBTime ;
EventDelay kCFTime ;
EventDelay kLevelTime ;
EventDelay kFOffsetTime ;
EventDelay kBOffsetTime ;
EventDelay kCFOffsetTime ;
EventDelay kLevelOffsetTime ;
int k_ftarget , k_btarget , k_cftarget , k_leveltarget ;
int k_foffset_amp , k_boffset_amp , k_cfoffset_amp , k_leveloffset_amp ;;
Smooth < int > kSmoothF ( 0.85 f );
Smooth < int > kSmoothBw ( 0.85 );
Smooth < int > kSmoothCf ( 0.85 );
Smooth < long > aSmoothLevel ( 0.997 f );
Smooth < int > kSmoothFOffset ( 0.99 f );
Smooth < int > kSmoothBOffset ( 0.99 f );
Smooth < int > kSmoothCFOffset ( 0.99 f );
Smooth < int > kSmoothLevelOffset ( 0.99 f );
void setup () {
randSeed ();
//Serial.begin(115200);
wavey . setTable ( SIN1024_DATA );
kFTime . start ( rand ( 1 , 500 ));
kBTime . start ( rand ( 1 , 500 ));
kCFTime . start ( rand ( 1 , 500 ));
kLevelTime . start ( rand ( 1 , 500 ));
k_ftarget = rand ( F_MIN , F_MAX );
k_btarget = rand ( B_MIN , B_MAX );
k_cftarget = rand ( CF_MIN , CF_MAX );
k_leveltarget = rand ( LEVEL_MIN , LEVEL_MAX );
kFOffsetTrem . setFreq ( 7 );
kBOffsetTrem . setFreq ( 7 );
kCFOffsetTrem . setFreq ( 7 );
kLevelOffsetTrem . setFreq ( 7 );
k_foffset_amp = 0 ; // 0-255 is full range of Oscil, +-char
k_boffset_amp = 0 ;
k_cfoffset_amp = 0 ;
k_leveloffset_amp = 0 ;
kFOffsetTime . start ( rand ( 200 ));
kBOffsetTime . start ( rand ( 200 ));
kCFOffsetTime . start ( rand ( 200 ));
kLevelOffsetTime . start ( rand ( 200 ));
startMozzi ();
}
void updateControl () {
if ( kFOffsetTime . ready ())
{
if ( k_foffset_amp == 0 )
{
k_foffset_amp = 1 + rand ( 50 );
kFOffsetTrem . setFreq ( 3 + rand (( byte ) 6 ));
} else {
k_foffset_amp = 0 ;
}
kFOffsetTime . start ( rand ( OFFSET_TIME_MAX_MS ));
}
if ( kBOffsetTime . ready ())
{
if ( k_boffset_amp == 0 )
{
k_boffset_amp = 1 + rand ( 50 );
kBOffsetTrem . setFreq ( 1 + rand (( byte ) 8 ));
} else {
k_boffset_amp = 0 ;
}
kBOffsetTime . start ( rand ( OFFSET_TIME_MAX_MS ));
}
if ( kCFOffsetTime . ready ())
{
if ( k_cfoffset_amp == 0 )
{
k_cfoffset_amp = 1 + rand ( 50 );
kCFOffsetTrem . setFreq ( 1 + rand (( byte ) 8 ));
} else {
k_cfoffset_amp = 0 ;
}
kCFOffsetTime . start ( rand ( OFFSET_TIME_MAX_MS ));
}
if ( kLevelOffsetTime . ready ())
{
if ( k_leveloffset_amp == 0 )
{
k_leveloffset_amp = rand ( 200 );
kLevelOffsetTrem . setFreq ( 3 + rand (( byte ) 6 ));
} else {
k_leveloffset_amp = 0 ;
}
kLevelOffsetTime . start ( rand ( OFFSET_TIME_MAX_MS ));
}
if ( kFTime . ready ()) {
k_ftarget += rand ( - F_CHANGE , F_CHANGE );
if ( k_ftarget < F_MIN ) k_ftarget += F_CHANGE ;
if ( k_ftarget > F_MAX ) k_ftarget -= F_CHANGE ;
kFTime . start ( rand ( SYNTH_PARAM_MAX_MS ));
}
if ( kBTime . ready ()) {
k_btarget += rand ( - B_CHANGE , B_CHANGE );
if ( k_btarget < B_MIN ) k_btarget += B_CHANGE ;
if ( k_btarget > B_MAX ) k_btarget -= B_CHANGE ;
kBTime . start ( rand ( SYNTH_PARAM_MAX_MS ));
}
if ( kCFTime . ready ()) {
k_cftarget += rand ( - CF_CHANGE , CF_CHANGE );
if ( k_cftarget < CF_MIN ) k_cftarget += CF_CHANGE ;
if ( k_cftarget > CF_MAX ) k_cftarget -= CF_CHANGE ;
kCFTime . start ( rand ( SYNTH_PARAM_MAX_MS ));
}
if ( kLevelTime . ready ()) {
k_leveltarget += rand ( - LEVEL_CHANGE , LEVEL_CHANGE );
if ( k_leveltarget < LEVEL_MIN ) k_leveltarget += LEVEL_CHANGE ;
if ( k_leveltarget > LEVEL_MAX ) k_leveltarget -= LEVEL_CHANGE ;
kLevelTime . start ( rand ( SYNTH_PARAM_MAX_MS ));
}
char k_ftrem = kFOffsetTrem . next ();
char k_btrem = kBOffsetTrem . next ();
char k_cftrem = kCFOffsetTrem . next ();
char k_leveltrem = kCFOffsetTrem . next ();
int k_foffset = (( long ) k_ftrem * kSmoothFOffset . next ( k_foffset_amp )) >> 8 ;
int k_boffset = (( long ) k_btrem * kSmoothBOffset . next ( k_boffset_amp )) >> 8 ;
int k_cfoffset = (( long ) k_cftrem * kSmoothCFOffset . next ( k_cfoffset_amp )) >> 8 ;
int k_leveloffset = (( long ) k_leveltrem * kSmoothLevelOffset . next ( k_leveloffset_amp )) >> 8 ;
int f = min ( F_MAX , kSmoothF . next ( k_ftarget ) + k_foffset );
int b = min ( B_MAX , kSmoothBw . next ( k_btarget ) + k_boffset );
int cf = min ( CF_MAX , kSmoothCf . next ( k_cftarget ) + k_cfoffset );
k_leveltarget = min ( LEVEL_MAX , k_leveltarget + k_leveloffset );
k_leveltarget = max ( k_leveltarget , 0 );
//Serial.print(f);Serial.print("\t ");Serial.print(b);Serial.print("\t ");Serial.print(cf);Serial.println();
wavey . set ( f , b , cf );
}
AudioOutput updateAudio () {
int32_t asig = aSmoothLevel . next ( k_leveltarget ) * wavey . next ();
return MonoOutput :: fromNBit ( 23 , asig ); // avoid distortion
}
void loop () {
audioHook (); // required here
}
Risset_Beat_HIFI
…(no recording of this one)
show sketch
hide sketch
/* Example of Risset rhythm generated with Mozzi audio synthesis library.
https://music.stackexchange.com/questions/4708/how-does-the-risset-rhythm-work
Demonstrates Sample(), EventDelay(), Line(), fixed pint numbers and bit-shifting
Important:
This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which
is not available on all boards (among others, it works on the
classic Arduino boards, but not Teensy 3.x and friends).
Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar),
Check the Mozzi core module documentation for others and more detail
3.9k
pin 9 ---WWWW-----|-----output
499k|
pin 10 ---WWWW---- |
|
4.7n ==
|
ground
Resistors are ±0.5%
Circuit: Audio output on digital pins 9 and 10 on a Uno or similar, or
DAC/A14 on Teensy 3.1, or
check the README or http://sensorium.github.io/Mozzi/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2018-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
#define MOZZI_CONTROL_RATE 128
#include <Mozzi.h>
#include <Sample.h> // Sample template
#include <samples/abomb16384_int8.h> // table for Sample
#include <EventDelay.h>
#include <Line.h>
#include <mozzi_fixmath.h> // for fixed-point fractional numbers
// use: Sample <table_size, update_rate> SampleName (wavetable)
Sample < ABOMB_NUM_CELLS , MOZZI_AUDIO_RATE > aSample0 ( ABOMB_DATA );
Sample < ABOMB_NUM_CELLS , MOZZI_AUDIO_RATE > aSample1 ( ABOMB_DATA );
// for scheduling changes
EventDelay kTriggerDelay ;
// use: Line <type> lineName
Line < Q16n16 > kGliss ;
Line < Q15n16 > kLevel0 ;
Line < Q15n16 > kLevel1 ;
#define FULL_VOLUME_FIXEDPOINT Q0n8_to_Q15n16(255)
#define ZERO_VOLUME_FIXEDPOINT Q0n8_to_Q15n16(1)
#define NUM_LOOPS_IN_GLISS 8
#define SAMPLE_LENGTH_SECONDS ((float) ABOMB_SAMPLERATE / (float) ABOMB_NUM_CELLS)
#define SAMPLE_FREQ (1.f/SAMPLE_LENGTH_SECONDS)
#define SAMPLE_FREQ_FIXEDPOINT float_to_Q16n16(SAMPLE_FREQ) // so Line gliss has enough precision
#define GLISS_SECONDS (0.666f*SAMPLE_LENGTH_SECONDS*NUM_LOOPS_IN_GLISS)
#define CONTROL_STEPS_PER_GLISS ((unsigned int)((float)MOZZI_CONTROL_RATE * GLISS_SECONDS))
void setup () {
kTriggerDelay . start ( 0 ); // start trigger before polling in updateControl()
aSample0 . setLoopingOn ();
aSample1 . setLoopingOn ();
startMozzi ();
}
byte alevel0 , alevel1 ;
void updateControl () {
if ( kTriggerDelay . ready ()) {
kGliss . set ( SAMPLE_FREQ_FIXEDPOINT , SAMPLE_FREQ_FIXEDPOINT * 2 , CONTROL_STEPS_PER_GLISS );
kLevel0 . set ( ZERO_VOLUME_FIXEDPOINT , FULL_VOLUME_FIXEDPOINT , CONTROL_STEPS_PER_GLISS );
kLevel1 . set ( FULL_VOLUME_FIXEDPOINT , ZERO_VOLUME_FIXEDPOINT , CONTROL_STEPS_PER_GLISS );
aSample0 . start ();
aSample1 . start ();
kTriggerDelay . start (( int )( GLISS_SECONDS * 1000. f )); // milliseconds
}
Q16n16 gliss = kGliss . next (); // fixed point
float freq = Q16n16_to_float ( gliss ); // convert fixed point to floating point
aSample0 . setFreq ( freq );
aSample1 . setFreq ( freq * 2. f );
alevel0 = Q15n16_to_Q0n8 ( kLevel0 . next ());
alevel1 = Q15n16_to_Q0n8 ( kLevel1 . next ());
}
AudioOutput updateAudio () {
return MonoOutput :: fromNBit ( 17 , (( long ) aSample0 . next () * alevel0 ) + (( long ) aSample1 . next () * alevel1 ));
}
void loop () {
audioHook ();
}
Shepard_Tone_HIFI
…(no recording of this one)
show sketch
hide sketch
/* Plays a basic Shepard tone
using Mozzi sonification library.
https://en.wikipedia.org/wiki/Shepard_tone
Demonstrates audio and control rate updates, Lines, EventDelay.
More oscillators could be added for a more convincing effect.
Important:
This sketch uses MOZZI_OUTPUT_2PIN_PWM (aka HIFI) output mode, which
is not available on all boards (among others, it works on the
classic Arduino boards, but not Teensy 3.x and friends).
Circuit: Audio output on digital pin 9 and 10 (on a Uno or similar),
Check the Mozzi core module documentation for others and more detail
3.9k
pin 9 ---WWWW-----|-----output
499k|
pin 10 ---WWWW---- |
|
4.7n ==
|
ground
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2018-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_2PIN_PWM
#define MOZZI_CONTROL_RATE 128
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/sin8192_int8.h>
#include <tables/triangle512_int8.h>
#include <mozzi_midi.h>
#include <EventDelay.h>
#include <Line.h>
#include <FixMath.h>
// reset and sync vol and freq controls each cycle
EventDelay kTriggerDelay0 ;
EventDelay kTriggerDelay1 ;
const UFix < 7 , 0 > NOTE_CENTRE = 60 , NOTE_RANGE = 12 ;
const UFix < 7 , 0 > NOTE_START_FIXEDPOINT = NOTE_CENTRE + NOTE_RANGE ;
const UFix < 7 , 0 > NOTE_END_FIXEDPOINT = NOTE_CENTRE - NOTE_RANGE ;
#define GLISS_SECONDS 3.f
//#define CONTROL_STEPS_PER_GLISS ((unsigned int)((float)MOZZI_CONTROL_RATE * GLISS_SECONDS))
#define CONTROL_STEPS_PER_GLISS ((unsigned int)((float)MOZZI_CONTROL_RATE * GLISS_SECONDS))
// use: Line <type> lineName
// The lines needs more precision than the notes, as they interpolate in between
// here we optimize by choosing the max precision to stay in 16bits (7+9=16)
// note that for an SFix, we would aim for 15 (plus a sign bit).
Line < UFix < 7 , 9 >> kGliss0 ; // Line to slide frequency
Line < UFix < 7 , 9 >> kGliss1 ; // Line to slide frequency
// harmonics
Oscil < SIN8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos0 ( SIN8192_DATA );
Oscil < SIN8192_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1 ( SIN8192_DATA );
// volume envelope oscils
Oscil < TRIANGLE512_NUM_CELLS , MOZZI_CONTROL_RATE > kVol0 ( TRIANGLE512_DATA );
Oscil < TRIANGLE512_NUM_CELLS , MOZZI_CONTROL_RATE > kVol1 ( TRIANGLE512_DATA );
// audio volumes updated each control interrupt and reused in audio
SFix < 0 , 14 > v0 , v1 ;
//SFix<0,7> v0, v1; // micro-optimization
void setup () {
//Serial.begin(115200);
kVol0 . setFreq ( 0.5 f / GLISS_SECONDS );
kVol1 . setFreq ( 0.5 f / GLISS_SECONDS );
kVol0 . setPhase ( 0 );
kVol1 . setPhase (( unsigned int ) TRIANGLE512_NUM_CELLS / 4 );
kTriggerDelay0 . start ( 0 ); // start trigger before polling in updateControl()
kTriggerDelay1 . start (( int )(( GLISS_SECONDS * 1000. f ) / 2. f ));
startMozzi ();
}
void updateControl ()
{
if ( kTriggerDelay0 . ready ()) {
kGliss0 . set ( NOTE_START_FIXEDPOINT , NOTE_END_FIXEDPOINT , CONTROL_STEPS_PER_GLISS );
kVol0 . setPhase ( 0 );
kTriggerDelay0 . start (( int )( GLISS_SECONDS * 1000. f )); // milliseconds
Serial . println ( "gliss1" );
}
if ( kTriggerDelay1 . ready ()) {
kGliss1 . set ( NOTE_START_FIXEDPOINT , NOTE_END_FIXEDPOINT , CONTROL_STEPS_PER_GLISS );
kVol1 . setPhase ( 0 );
kTriggerDelay1 . start (( int )( GLISS_SECONDS * 1000. f )); // milliseconds
Serial . println ( " \t gliss2" );
}
auto gliss0 = kGliss0 . next (); // fixed point
auto gliss1 = kGliss1 . next (); // fixed point
aCos0 . setFreq ( mtof ( gliss0 ));
aCos1 . setFreq ( mtof ( gliss1 ));
v0 = toSFraction ( kVol0 . next ()); // convert as a pure fractionnal between -1 and 1
v1 = toSFraction ( kVol1 . next ());
// square for perceptual volume (also makes it positive...)
v0 = v0 * v0 ;
v1 = v1 * v1 ;
}
AudioOutput updateAudio () {
auto asig = v0 * toSInt ( aCos0 . next ()) + v1 * toSInt ( aCos1 . next ());
return AudioOutput :: fromSFix ( asig ); // auto-scaling of the output with SFix
}
void loop () {
audioHook ();
}
Stereo
…(no recording of this one)
show sketch
hide sketch
/* Example crudely panning noise to test stereo output,
using Mozzi sonification library.
Tests stereo output.
NOTE: Stereo output is not supported on all platforms / configurations!
Circuit: Audio outputs on digital pins 9 and 10 (on classic Arduino).
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2012-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
// Configure Mozzi for Stereo output. This must be done before #include <Mozzi.h>
// MozziConfigValues.h provides named defines for available config options.
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO
#include <Mozzi.h>
#include <Phasor.h> // for controlling panning position
#include <Oscil.h> // oscil for audio sig
#include <tables/pinknoise8192_int8.h> // table for oscillator
// use: Oscil <table_size, update_rate> oscilName (wavetable)
Oscil < PINKNOISE8192_NUM_CELLS , MOZZI_AUDIO_RATE > aNoise ( PINKNOISE8192_DATA );
//Phasor for panning
Phasor < MOZZI_CONTROL_RATE > kPan ; // outputs an unsigned long 0-max 32 bit positive number
unsigned int pan ; // convey pan from updateControl() to updateAudioStereo();
void setup (){
aNoise . setFreq ( 2.111 f ); // set the frequency with an unsigned int or a float
kPan . setFreq ( 0.25 f ); // take 4 seconds to move left-right
startMozzi (); // :)
Serial . begin ( 115200 );
}
void updateControl (){
pan = kPan . next () >> 16 ;
Serial . println ( pan );
}
AudioOutput updateAudio (){
int asig = aNoise . next ();
return StereoOutput :: fromNBit ( 24 , ( long ) pan * asig , ( long )( 65535 - pan ) * asig );
}
void loop (){
audioHook (); // required here
}
Stereo_Hack
</source>
</source>
Your browser does not support the audio element.
show sketch
hide sketch
/* Example crudely panning noise to test stereo output hack,
* using Mozzi sonification library.
*
* Tests stereo output hack. This requires #define STEREO_HACK true in mozzi_config.h
*
* Circuit: Audio outputs on digital pins 9 and 10.
*
* Mozzi help/discussion/announcements:
* https://groups.google.com/forum/#!forum/mozzi-users
*
* Tim Barrass 2012.
* This example code is in the public domain.
*/
#include <MozziGuts.h>
#include <Phasor.h> // for controlling panning position
#include <Oscil.h> // oscil for audio sig
#include <tables/pinknoise8192_int8.h> // table for oscillator
// use: Oscil <table_size, update_rate> oscilName (wavetable)
Oscil < PINKNOISE8192_NUM_CELLS , AUDIO_RATE > aNoise ( PINKNOISE8192_DATA );
//Phasor for panning
Phasor < CONTROL_RATE > kPan ; // outputs an unsigned long 0-max 32 bit positive number
unsigned int pan ; // convey pan from updateControl() to updateAudioStereo();
void setup (){
aNoise . setFreq ( 2.111 f ); // set the frequency with an unsigned int or a float
kPan . setFreq ( 0.25 f ); // take 4 seconds to move left-right
startMozzi (); // :)
Serial . begin ( 115200 );
}
void updateControl (){
pan = kPan . next () >> 16 ;
Serial . println ( pan );
}
// needed for stereo output
int audio_out_1 , audio_out_2 ;
void updateAudio (){
int asig = aNoise . next ();
audio_out_1 = ( int )((( long ) pan * asig ) >> 16 );
audio_out_2 = ( int )(((( long ) 65535 - pan ) * asig ) >> 16 );
}
void loop (){
audioHook (); // required here
}
Stereo_Hack_Pan
…(no recording of this one)
show sketch
hide sketch
/* Example of constant power panning to test stereo output hack,
using Mozzi sonification library.
Tests stereo output hack. This requires #define STEREO_HACK true in mozzi_config.h
Circuit: Audio outputs on digital pins 9 and 10.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Tim Barrass 2017.
This example code is in the public domain.
*/
#include <MozziGuts.h>
#include <Oscil.h> // oscil for audio sig
#include <tables/pinknoise8192_int8.h> // table for audio oscillator
#include <tables/sin2048_int8.h> // sine table for pan oscillator
// use: Oscil <table_size, update_rate> oscilName (wavetable)
Oscil < PINKNOISE8192_NUM_CELLS , AUDIO_RATE > aNoise ( PINKNOISE8192_DATA );
Oscil < SIN2048_NUM_CELLS , CONTROL_RATE > kPan ( SIN2048_DATA );
byte ampA , ampB ; // convey amplitudes from updateControl() to updateAudioStereo();
void setup ()
{
kPan . setFreq ( 0.25 f );
aNoise . setFreq ( 2.111 f ); // set the frequency with an unsigned int or a float
startMozzi (); // :)
Serial . begin ( 115200 );
}
void updateControl ()
{
// angle 0-90 deg (in rads) (https://dsp.stackexchange.com/questions/21691/algorithm-to-pan-audio/21736)
float pan_angle = ( float )( kPan . next () + 128 ) * ( 1.571 f / 256. f );
// cheap equal power panning from above site, put into 0-255 range for fast audio calcs
ampA = ( char )( sin ( pan_angle ) * 255 );
ampB = ( char )( cos ( pan_angle ) * 255 );
Serial . print ( ampA );
Serial . print ( " " );
Serial . println ( ampB );
}
// needed for stereo output
int audio_out_1 , audio_out_2 ;
void updateAudio () {
int asig = aNoise . next ();
audio_out_1 = ( asig * ampA ) >> 8 ;
audio_out_2 = ( asig * ampB ) >> 8 ;
}
void loop () {
audioHook (); // required here
}
Stereo_Pan
…(no recording of this one)
show sketch
hide sketch
/* Example of constant power panning to test stereo output hack,
using Mozzi sonification library.
Tests stereo output.
NOTE: Stereo output is not supported on all platforms / configurations!
Circuit: Audio outputs on digital pins 9 and 10 (on classic Arduino).
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2017-2024 Tim Barrass and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
// Configure Mozzi for Stereo output. This must be done before #include <Mozzi.h>
// MozziConfigValues.h provides named defines for available config options.
#include <MozziConfigValues.h>
#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO
#include <Mozzi.h>
#include <Oscil.h> // oscil for audio sig
#include <tables/pinknoise8192_int8.h> // table for audio oscillator
#include <tables/sin2048_int8.h> // sine table for pan oscillator
// use: Oscil <table_size, update_rate> oscilName (wavetable)
Oscil < PINKNOISE8192_NUM_CELLS , MOZZI_AUDIO_RATE > aNoise ( PINKNOISE8192_DATA );
Oscil < SIN2048_NUM_CELLS , MOZZI_CONTROL_RATE > kPan ( SIN2048_DATA );
byte ampA , ampB ; // convey amplitudes from updateControl() to updateAudioStereo();
void setup ()
{
kPan . setFreq ( 0.25 f );
aNoise . setFreq ( 2.111 f ); // set the frequency with an unsigned int or a float
startMozzi (); // :)
Serial . begin ( 115200 );
}
void updateControl ()
{
// angle 0-90 deg (in rads) (https://dsp.stackexchange.com/questions/21691/algorithm-to-pan-audio/21736)
float pan_angle = ( float )( kPan . next () + 128 ) * ( 1.571 f / 256. f );
// cheap equal power panning from above site, put into 0-255 range for fast audio calcs
ampA = ( char )( sin ( pan_angle ) * 255 );
ampB = ( char )( cos ( pan_angle ) * 255 );
Serial . print ( ampA );
Serial . print ( " " );
Serial . println ( ampB );
}
AudioOutput updateAudio () {
int asig = aNoise . next ();
return StereoOutput :: from16Bit ( asig * ampA , asig * ampB );
}
void loop () {
audioHook (); // required here
}
13.External_Audio_Output
ESP32_Bluetooth
…(no recording of this one)
show sketch
hide sketch
/* Example of simple and stereo synthesis,
using Mozzi sonification library with output to an A2DP sink
(i.e. a Bluetooth speaker / headphone).
IMPORTANT:
- This example requires the ESP32-A2DP library by Phil Schatzmann:
https://github.com/pschatzmann/ESP32-A2DP/
- This example works on ESP32, only
(Examples for other bluetooth-capable boards will follow, eventually.)
- You will want to adjust at least the "BLUETOOTH_DEVICE"-define, below!
Technical notes:
The BT-lib expects to read samples at its own pace, so we cannot
just "push" samples at the MOZZI_AUDIO_RATE, but rather they get
"pulled" via get_data_frames().
We therefore need a custom buffering scheme, i.e we select
MOZZI_OUTPUT_EXTERNAL_CUSTOM as output mode, and keep an own, custom buffer
(which is visible to Mozzi via the two special functions
canBufferAudioOutput(), and audioOutput()).
Note that the BT default sample rate is 44100, which is not one of the powers
of two that Mozzi likes so much (32768 in this example). Ignoring this would
"work", but everything would essentially play too fast, resulting in an upward
frequency shift. To fix this, we use a very crude sample rate adjustment,
simply by repeating some of the frames to stay in sync.
Support for Bluetooth A2DP is also provided by the Espressif IDF, so this sketch *could*
be made to work without an external library. However this is fairly low level,
and Phil's ESP32-A2DP library does a great job of managing all the scary details.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2024-2024 Thomas Friedrichsmeier and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
// before including Mozzi.h, configure external audio output mode:
#include "MozziConfigValues.h" // for named option values
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM
#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO
#define MOZZI_AUDIO_RATE 32768
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <SPI.h>
#include <BluetoothA2DPSource.h>
// devicce to connect to
#define BLUETOOTH_DEVICE "BKH 274"
#define BLUETOOTH_VOLUME 100
// Synthesis part
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCos2 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kEnv1 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kEnv2 ( COS2048_DATA );
CircularBuffer < AudioOutput > buf ;
void audioOutput ( const AudioOutput f ) {
buf . write ( f );
}
bool canBufferAudioOutput () {
return ! buf . isFull ();
}
BluetoothA2DPSource a2dp_source ;
const int BT_RATE = 44100 ;
const int lag_per_frame = BT_RATE - MOZZI_AUDIO_RATE ;
int lag = 0 ;
AudioOutput last_sample ;
int32_t get_data_frames ( Frame * frame , int32_t frame_count ) {
for ( int i = 0 ; i < frame_count ; ++ i ) {
lag += lag_per_frame ;
if ( lag > BT_RATE ) {
lag -= BT_RATE ;
} else {
if ( ! buf . isEmpty ()) last_sample = buf . read ();
}
frame [ i ]. channel1 = last_sample . l ();
frame [ i ]. channel2 = last_sample . r ();
}
return frame_count ;
}
void setup () {
a2dp_source . set_auto_reconnect ( false );
a2dp_source . start ( BLUETOOTH_DEVICE , get_data_frames );
a2dp_source . set_volume ( BLUETOOTH_VOLUME );
aCos1 . setFreq ( 440. f );
aCos2 . setFreq ( 220. f );
kEnv1 . setFreq ( 0.25 f );
kEnv2 . setFreq ( 0.30 f );
startMozzi ();
}
// Carry enveloppes
int env1 , env2 ;
void updateControl () {
env1 = kEnv1 . next ();
env2 = kEnv2 . next ();
}
AudioOutput_t updateAudio () {
return StereoOutput :: from16Bit ( aCos1 . next () * env1 , aCos2 . next () * env2 );
}
void loop () {
audioHook ();
}
FMsynth_MCP4921_mono_12bits
…(no recording of this one)
show sketch
hide sketch
/* Example of simple FM with the phase modulation technique,
using Mozzi sonification library and an external DAC MCP4921 (original library by Thomas Backman - https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx)
using an user-defined audioOutput() function.
Based on Mozzi's example: FMsynth.
Circuit: (see the DAC library README for details)
MCP4921 // Connect to:
------- -----------
Vdd V+
CS any digital pin defined by SS_PIN (see after), or pin 7 on UNO / 38 on Mega if you are using Portwrite
SCK SCK of Arduino
SDI MOSI of Arduino
VoutA to headphones/loudspeaker
Vss to GND
VrefA to V+ or a clean tension ref between V+ and GND
LDAC to GND
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2020-2024 T. Combriat and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
// before including Mozzi.h, configure external audio output mode:
#include "MozziConfigValues.h" // for named option values
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED
// Note: For demonstration purposes, this sketch does *not* set the following (although it would make sense):
//#define MOZZI_AUDIO_BITS 12 // the default value of 16 for external audio is thus used, instead
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <mozzi_midi.h>
#include <mozzi_fixmath.h>
#include <EventDelay.h>
#include <Smooth.h>
#include <DAC_MCP49xx.h> // https://github.com/tomcombriat/DAC_MCP49XX
// which is an adapted fork from https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx (Thomas Backman)
// Synthesis part
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCarrier ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aModulator ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kModIndex ( COS2048_DATA );
Q8n8 mod_index ;
Q16n16 deviation ;
Q16n16 carrier_freq , mod_freq ;
Q8n8 mod_to_carrier_ratio = float_to_Q8n8 ( 3. f );
EventDelay kNoteChangeDelay ;
// for note changes
Q7n8 target_note , note0 , note1 , note_upper_limit , note_lower_limit , note_change_step , smoothed_note ;
Smooth < int > kSmoothNote ( 0.95 f );
// External audio output parameters and DAC declaration
#define SS_PIN 38 // if you are on AVR and using PortWrite you need still need to put the pin you are actually using: 7 on Uno, 38 on Mega
DAC_MCP49xx dac ( DAC_MCP49xx :: MCP4921 , SS_PIN );
void audioOutput ( const AudioOutput f )
{
// signal is passed as 16 bit, zero-centered, internally. This DAC expects 12 bits unsigned,
// so shift back four bits, and add a bias of 2^(12-1)=2048
uint16_t out = ( f . l () >> 4 ) + 2048 ;
dac . output ( out );
}
void setup () {
dac . init ();
kNoteChangeDelay . set ( 768 ); // ms countdown, taylored to resolution of MOZZI_CONTROL_RATE
kModIndex . setFreq ( .768 f ); // sync with kNoteChangeDelay
target_note = note0 ;
note_change_step = Q7n0_to_Q7n8 ( 3 );
note_upper_limit = Q7n0_to_Q7n8 ( 50 );
note_lower_limit = Q7n0_to_Q7n8 ( 32 );
note0 = note_lower_limit ;
note1 = note_lower_limit + Q7n0_to_Q7n8 ( 5 );
dac . setPortWrite ( true ); //comment this line if you do not want to use PortWrite (for non-AVR platforms)
startMozzi ();
}
void setFreqs ( Q8n8 midi_note ) {
carrier_freq = Q16n16_mtof ( Q8n8_to_Q16n16 ( midi_note )); // convert midi note to fractional frequency
mod_freq = (( carrier_freq >> 8 ) * mod_to_carrier_ratio ) ; // (Q16n16>>8) Q8n8 = Q16n16, beware of overflow
deviation = (( mod_freq >> 16 ) * mod_index ); // (Q16n16>>16) Q8n8 = Q24n8, beware of overflow
aCarrier . setFreq_Q16n16 ( carrier_freq );
aModulator . setFreq_Q16n16 ( mod_freq );
}
void updateControl () {
// change note
if ( kNoteChangeDelay . ready ()) {
if ( target_note == note0 ) {
note1 += note_change_step ;
target_note = note1 ;
}
else {
note0 += note_change_step ;
target_note = note0 ;
}
// change direction
if ( note0 > note_upper_limit ) note_change_step = Q7n0_to_Q7n8 ( - 3 );
if ( note0 < note_lower_limit ) note_change_step = Q7n0_to_Q7n8 ( 3 );
// reset eventdelay
kNoteChangeDelay . start ();
}
// vary the modulation index
mod_index = ( Q8n8 ) 350 + kModIndex . next ();
// here's where the smoothing happens
smoothed_note = kSmoothNote . next ( target_note );
setFreqs ( smoothed_note );
}
AudioOutput updateAudio () {
Q15n16 modulation = deviation * aModulator . next () >> 8 ;
return MonoOutput :: from8Bit ( aCarrier . phMod ( modulation ));
// this example does not really use the full capability of the 12bits of the DAC
}
void loop () {
audioHook ();
}
MCP4922_mono_24bits
…(no recording of this one)
show sketch
hide sketch
/* Example of using the two channels of a DAC to have high fidelity output using the technique described here : http://www.openmusiclabs.com/learning/digital/pwm-dac/dual-pwm-circuits/index.html
using Mozzi sonification library and an external dual DAC MCP4922 (original library by Thomas Backman - https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx)
using an user-defined audioOutput() function.
WARNING: YOU CANNOT ACHEIVE MORE THAN 16BITS ON AN AVR ARDUINO, THIS EXAMPLE WON'T WORK AS IT IS.
Circuit: (see the DAC library README for details)
MCP4921 // Connect to:
------- -----------
Vdd V+
CS any digital pin defined by SS_PIN (see after), or pin 7 on UNO / 38 on Mega if you are using Portwrite
SCK SCK of Arduino
SDI MOSI of Arduino
VoutA/B (see after)
Vss to GND
VrefA/B to V+ or a clean tension ref between V+ and GND
LDAC to GND
Dual DAC electrical connections
-------------------------------
VoutA -------- R1 -----------> To headphones/loudspeaker or anything else
|
VoutB -------- R2 -------
R2 = 2^n * R1 with n the number of bits per stage.
This should be precise, use a trimmer on R1 to adjust it precisely.
Recommended values: R1 around 1k
R2 around 4M
Notes: - int type in Arduino is 16 bits. So you cannot have 24 bits on an Arduino using audioOutput() function. But this does work on 32bits platforms (STM32 for instance)
- 24 bits is a lot. To acheive real 24 bits you need to be very careful on your electronics (good precision on R, buffer after the summing junction)
- this is certainly over-kill, however this technique can prove useful for outputting 16 bits, by combining 2 * 8 bits DACs
- the communication with the DAC takes the same time for 8/10 and 12bits DAC, so 2*8bits should be as fast as 2*1 bits.
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2020-2024 T. Combriat and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
// before including Mozzi.h, configure external audio output mode:
#include "MozziConfigValues.h" // for named option values
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED
#define MOZZI_AUDIO_BITS 24
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <SPI.h>
#include <DAC_MCP49xx.h> // https://github.com/tomcombriat/DAC_MCP49XX
// which is an adapted fork from https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx (Thomas Backman)
// Synthesis part
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCos2 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kEnv1 ( COS2048_DATA );
// External audio output parameters and DAC declaration
#define SS_PIN 38 // if you are on AVR and using PortWrite you need still need to put the pin you are actually using: 7 on Uno, 38 on Mega
#define BITS_PER_CHANNEL 12 // each channel of the DAC is outputting 12 bits
DAC_MCP49xx dac ( DAC_MCP49xx :: MCP4922 , SS_PIN );
void audioOutput ( const AudioOutput f ) // f is a structure containing both channels
{
int out = MOZZI_AUDIO_BIAS + f . l ();
unsigned short lowBits = ( unsigned short ) out ; //
unsigned short highBits = out >> BITS_PER_CHANNEL ;
dac . output2 ( highBits , lowBits ); // outputs the two channels in one call.
}
void setup () {
aCos1 . setFreq ( 440. f );
aCos2 . setFreq ( 220. f );
kEnv1 . setFreq ( 0.1 f );
dac . init (); // start SPI communications
//dac.setPortWrite(true); //comment this line if you do not want to use PortWrite (for non-AVR platforms)
startMozzi ();
}
// Carry enveloppes
int env1 = 0 ;
void updateControl () {
env1 = kEnv1 . next ();
}
AudioOutput updateAudio () {
return MonoOutput :: fromNBit ( 24 , ( int32_t ) aCos1 . next () * aCos2 . next () * env1 ) ; // specify that the audio we are sending here is 24 bits.
}
void loop () {
audioHook ();
}
PT8211_stereo_16bits
…(no recording of this one)
show sketch
hide sketch
/* Example of simple and stereo synthesis,
using Mozzi sonification library and an external dual DAC PT8211 (inspired by: https://sparklogic.ru/code-snipplets/i2s-example-code.html)
using an user-defined audioOutput() function. I2S, the protocol used by this DAC, is here emulated in synced way using SPI.
Circuit:
PT8211 // Connect to:
------- -----------
Vdd V+
BCK SCK
WS any digital pin (defined by WS_pin here, pin 5)
DIN MOSI
GND GND
L/R to audio outputs
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2020-2024 T. Combriat and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
// before including Mozzi.h, configure external audio output mode:
#include "MozziConfigValues.h" // for named option values
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED
#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <SPI.h>
// Synthesis part
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCos2 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kEnv1 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kEnv2 ( COS2048_DATA );
// External audio output parameters
#define WS_pin 5 // channel select pin for the DAC
void audioOutput ( const AudioOutput f ) // f is a structure containing both channels
{
/* Note:
* the digital writes here can be optimised using portWrite if more speed is needed
*/
digitalWrite ( WS_pin , LOW ); //select Right channel
SPI . transfer16 ( f . r ()); // Note: This DAC works on 0-centered samples, no need to add MOZZI_AUDIO_BIAS
digitalWrite ( WS_pin , HIGH ); // select Left channel
SPI . transfer16 ( f . l ());
}
void setup () {
pinMode ( WS_pin , OUTPUT );
// Initialising the SPI connection on default port
SPI . begin ();
SPI . beginTransaction ( SPISettings ( 20000000 , MSBFIRST , SPI_MODE0 )); //MSB first, according to the DAC spec
aCos1 . setFreq ( 440. f );
aCos2 . setFreq ( 220. f );
kEnv1 . setFreq ( 0.25 f );
kEnv2 . setFreq ( 0.30 f );
startMozzi ();
}
// Carry enveloppes
int env1 , env2 ;
void updateControl () {
env1 = kEnv1 . next ();
env2 = kEnv2 . next ();
}
AudioOutput updateAudio () {
return StereoOutput :: from16Bit ( aCos1 . next () * env1 , aCos2 . next () * env2 );
}
void loop () {
audioHook ();
}
PT8211_stereo_16bits_STM32_SPI2
…(no recording of this one)
show sketch
hide sketch
/* Example of simple stereo synthesis,
using Mozzi sonification library and an external dual DAC PT8211 (inspired by: https://sparklogic.ru/code-snipplets/i2s-example-code.html)
using an user-defined audioOutput() function. I2S, the protocol used by this DAC, is here emulated in synced way using SPI.
Circuit:
PT8211 // Connect to:
------- -----------
Vdd V+
BCK SCK (PB13 here, for SPI2)
WS any digital pin (defined by WS_pin here, PB12)
DIN MOSI (PB15 here, for SPI2)
GND GND
L/R to audio outputs
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2020-2024 T. Combriat and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include "MozziConfigValues.h" // for named option values
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED
#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <SPI.h>
// Synthesis part
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCos2 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kEnv1 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kEnv2 ( COS2048_DATA );
// External audio output parameters
#define WS_pin PB12 // channel select pin for the DAC
SPIClass mySPI ( 2 ); // declaration of SPI for using SPI2 and thus freeing all ADC pins
void audioOutput ( const AudioOutput f ) // f is a structure containing both channels
{
digitalWrite ( WS_pin , LOW ); //select Right channel
mySPI . transfer16 ( f . r ()); // Note: This DAC works on 0-centered samples, no need to add MOZZI_AUDIO_BIAS
digitalWrite ( WS_pin , HIGH ); // select Left channel
mySPI . transfer16 ( f . l ());
}
void setup () {
pinMode ( WS_pin , OUTPUT );
mySPI . begin ();
mySPI . beginTransaction ( SPISettings ( 20000000 , MSBFIRST , SPI_MODE0 )); //MSB first, according to the DAC spec
aCos1 . setFreq ( 440. f );
aCos2 . setFreq ( 220. f );
kEnv1 . setFreq ( 0.25 f );
kEnv2 . setFreq ( 0.30 f );
startMozzi ();
}
// Carry enveloppes
int env1 , env2 ;
void updateControl () {
env1 = kEnv1 . next ();
env2 = kEnv2 . next ();
}
AudioOutput updateAudio () {
return StereoOutput :: from16Bit ( aCos1 . next () * env1 , aCos2 . next () * env2 );
}
void loop () {
audioHook ();
}
Sinewave_R2R_DAC
…(no recording of this one)
show sketch
hide sketch
/* Example playing a sinewave at a set frequency,
using Mozzi sonification library and an user-defined
audioOutput() function.
Demonstrates the use of audioOutput() using a R/2R DAC
connected on 6 digital pins of an Arduino.
NOTE: this is for demonstration purpose, this particular way of
outputting sound, using digitalWrite() and a R/2R DAC is less
efficient than the native method. However, this method could be
substantially improved by using registers
(see: https://www.instructables.com/id/Fast-digitalRead-digitalWrite-for-Arduino/)
or even better, using continous registers to update all digital pins
at the same time. One could also use Serial to Parallel converters.
Circuit:
D0/LSB D1 D2 D3 D4 D5/MSB
| | | | | |
2R 2R 2R 2R 2R 2R
|---R---|---R---|---R---|---R---|---R---|-----(to phones)
2R
|
GND
R=10kOhms or around, but all R at the same value
For more details on the R/2R DAC see:
https://hackaday.com/2015/11/05/logic-noise-digital-to-analog-with-an-r-2r-dac/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2020-2024 T. Combriat and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include "MozziConfigValues.h" // for named option values
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED
#define MOZZI_AUDIO_BITS 6
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
// External output parameters for this example
#define R2R_N_PIN MOZZI_AUDIO_BITS // Number of stage of the resistance ladder = number of digits of the DAC, can be defined through MOZZI_AUDIO_BITS
const int r2r_pin [ R2R_N_PIN ] = { 30 , 31 , 32 , 33 , 34 , 35 }; // pins to the resistance ladder, in order,
// starting with LSB (pin closer to GND)
// so D0, D1, etc.
//#define AUDIO_BIAS 32 // we are at 6 bits so we have to bias the signal of 2^(6-1)=32, not needed since PR#98
void audioOutput ( const AudioOutput f ) // f is a structure potentially containing both channels, scaled according to MOZZI_AUDIO_BITS
{
int out = f . l () + MOZZI_AUDIO_BIAS ; // get the audio and make it positive
int mask = 0b00000001 ; // mask for outputting only 1 bit (one per pin)
for ( int i = 0 ; i < R2R_N_PIN ; i ++ )
{
digitalWrite ( r2r_pin [ i ], bool (( out >> i ) & mask )); // write on digital Pins:
} // shift the value to the right
} // apply the mask to get only the last bit
// use that value in digitalWrite()
void setup () {
for ( int i = 0 ; i < R2R_N_PIN ; i ++ ) pinMode ( r2r_pin [ i ], OUTPUT );
startMozzi (); // :)
aSin . setFreq ( 200 ); // set the frequency
}
void updateControl () {
// put changing controls in here
}
AudioOutput updateAudio () {
return MonoOutput :: from8Bit ( aSin . next ()); // return an int signal centred around 0, 8bits wide
}
void loop () {
audioHook (); // required here
}
Sinewave_R2R_DAC_74HC595
…(no recording of this one)
show sketch
hide sketch
/* Example playing a sinewave at a set frequency,
using Mozzi sonification library and an user-defined
audioOutput() function.
Demonstrates the use of audioOutput() using a R/2R DAC
connected on a shift register 74HC595.
Note: the overhead by putting a second one, and thus having a 16bits outputs
would be minimal. The timing part here are the digitalWrite. One could use
writing in the Arduino registers to speed it up.
Circuit:
Qa Qb Qc Qd Qe Qf Qg Qh (from 74HC595)
| | | | | | | |
2R 2R 2R 2R 2R 2R 2R 2R
|---R---|---R---|---R---|---R---|---R---|---R---|---R---|---> (to phones)
2R
|
GND
74HC595 // Connect to:
GND (08) GND
Vcc (16) 3.3/5V
SER (14) MOSI of Arduino
OE (13) GND
RCLK (12) a digital Pin you have to define later by #define LATCH_PIN 31
SRCLK (11) SCK of Arduino
SRCLR (10) Vcc
Qh' (9) Not connected
R=10kOhms or around, but all R at the same value
For more details on the R/2R DAC see:
https://hackaday.com/2015/11/05/logic-noise-digital-to-analog-with-an-r-2r-dac/
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2020-2024 T. Combriat and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include "MozziConfigValues.h" // for named option values
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED
#define MOZZI_AUDIO_BITS 8
#define MOZZI_CONTROL_RATE 64 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <SPI.h> // needed for the shift register
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil < SIN2048_NUM_CELLS , MOZZI_AUDIO_RATE > aSin ( SIN2048_DATA );
// External output parameters for this example
#define LATCH_PIN 31 // Number of stage of the resistance ladder = number of digits of the DAC
void audioOutput ( const AudioOutput f ) // f is a structure potentially containing both channels, scaled according to MOZZI_AUDIO_BITS
{
int out = f . l () + MOZZI_AUDIO_BIAS ; // make the (zero centered) signal positive
digitalWrite ( LATCH_PIN , LOW );
SPI . transfer ( out );
digitalWrite ( LATCH_PIN , HIGH );
}
void setup () {
pinMode ( LATCH_PIN , OUTPUT );
SPI . begin ();
SPI . beginTransaction ( SPISettings ( 2000000000 , MSBFIRST , SPI_MODE0 )); // Qa is the last so we have to set as MSBFIRST
// if you reverse the DAC you should put LSBFIRST
startMozzi (); // :)
aSin . setFreq ( 200 ); // set the frequency
}
void updateControl () {
// put changing controls in here
}
AudioOutput updateAudio () {
return MonoOutput :: from8Bit ( aSin . next ()); // return an int signal centred around 0, 8bits wide
}
void loop () {
audioHook (); // required here
}
Stereo_Pan_MCP4922_stereo_12bits
…(no recording of this one)
show sketch
hide sketch
/* Example of simple panning and stereo,
using Mozzi sonification library and an external dual DAC MCP4922 (original library by Thomas Backman - https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx)
using an user-defined audioOutput() function.
Circuit: (see the DAC library README for details)
MCP4921 // Connect to:
------- -----------
Vdd V+
CS any digital pin defined by SS_PIN (see after), or pin 7 on UNO / 38 on Mega if you are using Portwrite
SCK SCK of Arduino
SDI MOSI of Arduino
VoutA/B to headphones/loudspeaker (right and left channels)
Vss to GND
VrefA/B to V+ or a clean tension ref between V+ and GND
LDAC to GND
Mozzi documentation/API
https://sensorium.github.io/Mozzi/doc/html/index.html
Mozzi help/discussion/announcements:
https://groups.google.com/forum/#!forum/mozzi-users
Copyright 2020-2024 T. Combriat and the Mozzi Team
Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
*/
#include "MozziConfigValues.h" // for named option values
#define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_TIMED
#define MOZZI_AUDIO_CHANNELS MOZZI_STEREO
#define MOZZI_AUDIO_BITS 12
#define MOZZI_CONTROL_RATE 256 // Hz, powers of 2 are most reliable
#include <Mozzi.h>
#include <Oscil.h>
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <SPI.h>
#include <DAC_MCP49xx.h> // https://github.com/tomcombriat/DAC_MCP49XX
// which is an adapted fork from https://github.com/exscape/electronics/tree/master/Arduino/Libraries/DAC_MCP49xx (Thomas Backman)
// Synthesis part
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCos1 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_AUDIO_RATE > aCos2 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kEnv1 ( COS2048_DATA );
Oscil < COS2048_NUM_CELLS , MOZZI_CONTROL_RATE > kEnv2 ( COS2048_DATA );
// External audio output parameters and DAC declaration
#define SS_PIN 7 // if you are on AVR and using PortWrite you need still need to put the pin you are actually using: 7 on Uno, 38 on Mega
//#define AUDIO_BIAS 2048 // we are at 12 bits, so we have to bias the signal of 2^(12-1) = 2048
DAC_MCP49xx dac ( DAC_MCP49xx :: MCP4922 , SS_PIN );
void audioOutput ( const AudioOutput f ) // f is a structure containing both channels
{
int out_l = f . l () + MOZZI_AUDIO_BIAS ; // the DAC wants positive signals only, so we need to add a bias.
int out_r = f . r () + MOZZI_AUDIO_BIAS ;
dac . output2 ( out_l , out_r ); // outputs the two channels in one call.
}
void setup () {
aCos1 . setFreq ( 440. f );
aCos2 . setFreq ( 220. f );
kEnv1 . setFreq ( 0.25 f );
kEnv2 . setFreq ( 4. f );
dac . init (); // start SPI communications
dac . setPortWrite ( true ); //comment this line if you do not want to use PortWrite (for non-AVR platforms)
startMozzi ();
}
// Carry enveloppes
int env1 , env2 ;
void updateControl () {
env1 = kEnv1 . next ();
env2 = kEnv2 . next ();
}
AudioOutput updateAudio () {
return StereoOutput :: fromNBit ( 12 , aCos1 . next () * env1 , aCos2 . next () * env2 );
}
void loop () {
audioHook ();
}