Mozzi brings your Arduino to life by allowing it to produce much more complex and interesting growls, sweeps and chorusing atmospherics. These sounds can be quickly and easily constructed from familiar synthesis units like oscillators, delays, filters and envelopes.

One of the strong points of my AudioTools library is, that we also support extensive communication scenarios. In this example we show how we can output the sound generated by Mozzi to a Bluetooth Speaker using an ESP32.

The Sketch

Here is the example Arduino sketch that uses both libraries and sends the generated sound to a Bluetooth Speaker.

#include "AudioTools.h"
#include "AudioLibs/A2DPStream.h"
#include "AudioLibs/MozziStream.h"
#include <Oscil.h>                // oscillator template
#include <tables/sin2048_int8.h>  // sine table for oscillator

const int sample_rate = 44100;
AudioInfo info(sample_rate, 2, 16);  // bluetooth requires 44100, stereo, 16 bits
BluetoothA2DPSource a2dp_source;
MozziStream mozzi;  // audio source
const int16_t BYTES_PER_FRAME = 4;
// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file
// of table #included above
Oscil<SIN2048_NUM_CELLS, sample_rate> aSin(SIN2048_DATA);
// control variable, use the smallest data size you can for anything used in
// audio
byte gain = 255;

// callback used by A2DP to provide the sound data 
int32_t get_sound_data(uint8_t* data, int32_t size) {
  int32_t result = mozzi.readBytes(data, size);
  //LOGI("get_sound_data %d->%d",size, result);
  return result;

// Arduino Setup
void setup(void) {
  AudioLogger::instance().begin(Serial, AudioLogger::Info);

  // setup mozzi
  auto cfg = mozzi.defaultConfig();
  cfg.control_rate = CONTROL_RATE;

  aSin.setFreq(3320);  // set the frequency

  // start the bluetooth
  Serial.println("starting A2DP...");
  a2dp_source.start_raw("LEXON MINO L", get_sound_data);

void updateControl() {
  // as byte, this will automatically roll around to 255 when it passes 0
  gain = gain - 3;

int updateAudio() {
  // shift back to STANDARD audio range, like /256 but faster
  return ( * gain) >> 8;

// Arduino loop - repeated processing
void loop() {

This is basically the same sketch that I have already explained: The only difference is, that we need to make sure to generate stereo 16 bit data with a sample rate of 44100 and we replaced the audio sink wkth a BluetoothA2DPSource where the callback needs to be filled with data from Mozzi.

Do not forget to set the Partition Scheme to Huge App in the Arduino Tools menu because the application is getting quite big.

Source Code

The potentially updated source code of the sketch can be found in the examples directory.



Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *