home.social

#mozzi — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #mozzi, aggregated by home.social.

fetched live
  1. Ok, starting to get a little silly now, but I thought I'd try to use the AY-3-8910 as a 4-bit DAC for Mozzi synthesis...

    diyelectromusic.com/2025/07/14

    #Arduino #AY38910 #Mozzi #SorryNotSorry

  2. Ok, starting to get a little silly now, but I thought I'd try to use the AY-3-8910 as a 4-bit DAC for Mozzi synthesis...

    diyelectromusic.com/2025/07/14

    #Arduino #AY38910 #Mozzi #SorryNotSorry

  3. Arduino and AY-3-8910 – Part 4

    After Part 3 I started to go back and add MIDI, and changed the waveform on the touch of a button, and then started to wonder if I could add envelopes and so on.

    And then it occurred to me, I didn’t really need to re-implement my own synthesis library, I could probably write a custom audio output function for Mozzi and get it to use the AY-3-8910 as a 4-bit DAC…

    https://makertube.net/w/ast3HQ2a3fCanKy9Pr6qUc

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    These are the key tutorials for the main concepts used in this project:

    If you are new to Arduino, see the Getting Started pages.

    Parts list

    • Arduino Uno.
    • AY-3-8910 chip.
    • Either GadgetReboot’s PCB or patch using solderless breadboard or prototyping boards.
    • 5V compatible MIDI interface.
    • Jumper wires.

    Mozzi Custom Audio Output

    Mozzi supports a wide range of microcontrollers with a range of different output methods from PWM, built-in DACs, I2S, through to custom output options with DMA or something else.

    I’m not going to go over how Mozzi works here, but here are details of how to run with the different audio output modes here: https://sensorium.github.io/Mozzi/learn/output/

    The key option for me is MOZZI_OUTPUT_EXTERNAL_CUSTOM. There are a number of configuration options that must be set prior to include the main Mozzi file as follows:

    #include "MozziConfigValues.h"
    #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM
    #define MOZZI_AUDIO_BITS 8
    #define MOZZI_CONTROL_RATE 64
    #define MOZZI_AUDIO_RATE 16384
    #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE
    #include <Mozzi.h>
    #include <Oscil.h>
    #include <tables/cos2048_int8.h>
    #include <mozzi_midi.h>
    #include <mozzi_fixmath.h>

    This sets up the audio synthesis parameters to 8 bit audio with a sample rate of 16384Hz.

    Implementing a custom audio output this way requires two functions. One for the audio output and one to tell Mozzi when it is time to call the audio output function.

    I would rather have used MOZZI_OUTPUT_EXTERNAL_TIMED which handles the calling at the correct AUDIO_RATE for me, but that relies on the use of the ATMega328’s Timer 1, but in this case Timer 1 is providing the 1MHz clock for the AY-3-3810.

    But rather than implementing yet another timing routine, I just used the micros() counter to decide if it was time to generate audio or not.

    void audioOutput(const AudioOutput f)
    {
    int out = MOZZI_AUDIO_BIAS + f.l();
    ayOutput(0,out);
    }

    unsigned long lastmicros;
    bool canBufferAudioOutput() {
    unsigned long nowmicros = micros();
    if (nowmicros > lastmicros+58) {
    lastmicros=nowmicros;
    return true;
    }
    return false;
    }

    To get samples produced at the required 16384Hz sample rate means there needs to be one sample produced 16384 times a second. There thus needs to be a sample every 60uS. If I implement the above function checking for nowmicros > lastmicros + 60 then the resulting sound is slightly flat (in tuning). I’m guessing this is related to the overheads of the function call and logic, so I’ve gone with lastmicros+58 and that sounds pretty good to me.

    My ayOutput() routine takes an 8-bit sample and cuts it down to the 4-bits required for a level on the AY-3-8910.

    FM Synthesis on the AY-3-8910 (sort of)

    I wanted to try the FM synth mode just to see what would happen and thought it would be interesting to switch between the carrier sine wave signal and the modulated signal by pressing the button.

    Unfortunately, I just could not get the button logic to work, even though I could see the state of the pin (A5) changing.

    Finally after an hour or so of puzzling why such an apparently simple test of logic wasn’t working, I realised what the issue must be. Mozzi, for the AVR microcontrollers, has its own fast ADC routines. It turns out that these were interferrng with using A5 as a digital input pin.

    It is fairly easy to override the Mozzi fast ADC though by setting MOZZI_ANALOG_READ to NONE.

    The Mozzi code has a carrier and modulator waveform running at audio rate and an index running at the control rate to bring the modulator in and out.

    It is just about possible to see the FM modulation on the oscilloscope as shown below.

    Of course, the AY-3-8910 isn’t actually doing FM synthesis itself. It is just acting as a 4-bit DAC, but it is still quite fun to see.

    Find it on GitHub here.

    Closing Thoughts

    This is all getting a little pointless really, as there is nothing being done that the Arduino Nano couldn’t do better on its own, but it is a bit of fun to see where this thread ends up.

    There are a number of interesting angles now. One of which would be to utilise all three channels. This could provide a form of additive synthesis, it could perform some fixed interval additional oscillators, or it could be used for 3-note polyphony.

    Now that Mozzi is running it is also possible to do anything Mozzi can do, and that includes implementing envelope generation.

    Kevin

    #arduinoNano #ay38910 #include #mozzi

  4. Arduino and AY-3-8910 – Part 4

    After Part 3 I started to go back and add MIDI, and changed the waveform on the touch of a button, and then started to wonder if I could add envelopes and so on.

    And then it occurred to me, I didn’t really need to re-implement my own synthesis library, I could probably write a custom audio output function for Mozzi and get it to use the AY-3-8910 as a 4-bit DAC…

    https://makertube.net/w/ast3HQ2a3fCanKy9Pr6qUc

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    These are the key tutorials for the main concepts used in this project:

    If you are new to Arduino, see the Getting Started pages.

    Parts list

    • Arduino Uno.
    • AY-3-8910 chip.
    • Either GadgetReboot’s PCB or patch using solderless breadboard or prototyping boards.
    • 5V compatible MIDI interface.
    • Jumper wires.

    Mozzi Custom Audio Output

    Mozzi supports a wide range of microcontrollers with a range of different output methods from PWM, built-in DACs, I2S, through to custom output options with DMA or something else.

    I’m not going to go over how Mozzi works here, but here are details of how to run with the different audio output modes here: https://sensorium.github.io/Mozzi/learn/output/

    The key option for me is MOZZI_OUTPUT_EXTERNAL_CUSTOM. There are a number of configuration options that must be set prior to include the main Mozzi file as follows:

    #include "MozziConfigValues.h"
    #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_EXTERNAL_CUSTOM
    #define MOZZI_AUDIO_BITS 8
    #define MOZZI_CONTROL_RATE 64
    #define MOZZI_AUDIO_RATE 16384
    #define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE
    #include <Mozzi.h>
    #include <Oscil.h>
    #include <tables/cos2048_int8.h>
    #include <mozzi_midi.h>
    #include <mozzi_fixmath.h>

    This sets up the audio synthesis parameters to 8 bit audio with a sample rate of 16384Hz.

    Implementing a custom audio output this way requires two functions. One for the audio output and one to tell Mozzi when it is time to call the audio output function.

    I would rather have used MOZZI_OUTPUT_EXTERNAL_TIMED which handles the calling at the correct AUDIO_RATE for me, but that relies on the use of the ATMega328’s Timer 1, but in this case Timer 1 is providing the 1MHz clock for the AY-3-3810.

    But rather than implementing yet another timing routine, I just used the micros() counter to decide if it was time to generate audio or not.

    void audioOutput(const AudioOutput f)
    {
    int out = MOZZI_AUDIO_BIAS + f.l();
    ayOutput(0,out);
    }

    unsigned long lastmicros;
    bool canBufferAudioOutput() {
    unsigned long nowmicros = micros();
    if (nowmicros > lastmicros+58) {
    lastmicros=nowmicros;
    return true;
    }
    return false;
    }

    To get samples produced at the required 16384Hz sample rate means there needs to be one sample produced 16384 times a second. There thus needs to be a sample every 60uS. If I implement the above function checking for nowmicros > lastmicros + 60 then the resulting sound is slightly flat (in tuning). I’m guessing this is related to the overheads of the function call and logic, so I’ve gone with lastmicros+58 and that sounds pretty good to me.

    My ayOutput() routine takes an 8-bit sample and cuts it down to the 4-bits required for a level on the AY-3-8910.

    FM Synthesis on the AY-3-8910 (sort of)

    I wanted to try the FM synth mode just to see what would happen and thought it would be interesting to switch between the carrier sine wave signal and the modulated signal by pressing the button.

    Unfortunately, I just could not get the button logic to work, even though I could see the state of the pin (A5) changing.

    Finally after an hour or so of puzzling why such an apparently simple test of logic wasn’t working, I realised what the issue must be. Mozzi, for the AVR microcontrollers, has its own fast ADC routines. It turns out that these were interferrng with using A5 as a digital input pin.

    It is fairly easy to override the Mozzi fast ADC though by setting MOZZI_ANALOG_READ to NONE.

    The Mozzi code has a carrier and modulator waveform running at audio rate and an index running at the control rate to bring the modulator in and out.

    It is just about possible to see the FM modulation on the oscilloscope as shown below.

    Of course, the AY-3-8910 isn’t actually doing FM synthesis itself. It is just acting as a 4-bit DAC, but it is still quite fun to see.

    Find it on GitHub here.

    Closing Thoughts

    This is all getting a little pointless really, as there is nothing being done that the Arduino Nano couldn’t do better on its own, but it is a bit of fun to see where this thread ends up.

    There are a number of interesting angles now. One of which would be to utilise all three channels. This could provide a form of additive synthesis, it could perform some fixed interval additional oscillators, or it could be used for 3-note polyphony.

    Now that Mozzi is running it is also possible to do anything Mozzi can do, and that includes implementing envelope generation.

    Kevin

    #arduinoNano #ay38910 #include #mozzi

  5. First application is now up for my Arduino Nano Mozzi EuroRack module. This is a basic VCO, largely based on HAGIWO's Arduino #Mozzi VCO but reimplemented and with a few extras.

    diyelectromusic.com/2025/01/05

    #SynthDIY #arduino

  6. First application is now up for my Arduino Nano Mozzi EuroRack module. This is a basic VCO, largely based on HAGIWO's Arduino #Mozzi VCO but reimplemented and with a few extras.

    diyelectromusic.com/2025/01/05

    #SynthDIY #arduino

  7. Ok, so first module has been put together. This is #Arduino Nano-based and I'll probably set it up as a #Mozzi oscillator.

    But tbh, I'm still deciding if this is really worth the effort in the end - it was quite a faff...

    But then I've nothing else to compare it with, having not built anything from just protoboard either.

    I now need to decide what to do about labelling - it would be nice to get a proper printed label done somehow.

    Write-up on its way once I've done some code.

    #SynthDIY

  8. Ok, so first module has been put together. This is #Arduino Nano-based and I'll probably set it up as a #Mozzi oscillator.

    But tbh, I'm still deciding if this is really worth the effort in the end - it was quite a faff...

    But then I've nothing else to compare it with, having not built anything from just protoboard either.

    I now need to decide what to do about labelling - it would be nice to get a proper printed label done somehow.

    Write-up on its way once I've done some code.

    #SynthDIY

  9. Finally getting back to playing with pico_test_synth project, this time in Arduino. Working on a new simple handmade GUI after failing to find a GUI widget toolkit for Adafruit_GFX or U8g2 that offered anything beyond text boxes
    #raspberrypipico #arduino #mozzisynth #mozzi

  10. Finally getting back to playing with pico_test_synth project, this time in Arduino. Working on a new simple handmade GUI after failing to find a GUI widget toolkit for Adafruit_GFX or U8g2 that offered anything beyond text boxes
    #raspberrypipico #arduino #mozzisynth #mozzi

  11. I’m pretty proud of my THX Deep Note sound recreation attempt, which I realized I only posted on Twitter (RIP). So I upload it to Youtube & here. The Mozzi synth library is great and it was fun getting it to do this. And thanks to Mike Rugnetta for getting me near the rabbit hole of the THX sound!
    Code: github.com/todbot/mozzi_experi
    Youtube: youtube.com/watch?v=7fX8cBwbOm
    #mozzi #arduino #qtpy #thx #deepnote

  12. I’m pretty proud of my THX Deep Note sound recreation attempt, which I realized I only posted on Twitter (RIP). So I upload it to Youtube & here. The Mozzi synth library is great and it was fun getting it to do this. And thanks to Mike Rugnetta for getting me near the rabbit hole of the THX sound!
    Code: github.com/todbot/mozzi_experi
    Youtube: youtube.com/watch?v=7fX8cBwbOm
    #mozzi #arduino #qtpy #thx #deepnote

  13. I’m continuing my series of experiments with the ESP32 by considering how I might use the twin DACs onboard the WROOM module as a Lo-Fi, 8-bit envelope generator. I’ve not looked at envelope generation before, so this is a good excuse to see what it is all about.

    Important Note: This is NOT an envelope generator circuit or standalone device at present. It just outputs the waveform to the DAC. There is no electronics here that would make that a usable signal in any kind of controlling manner at present. This is mostly thinking about the code to produce the waveforms.

    In short, don’t hook this up to anything else unless you really know what you are doing (unlike me).

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    These are the key tutorials for the main concepts used in this project:

    If you are new to microcontrollers, see the Getting Started pages.

    Parts list

    • ESP32 WROOM DevKit
    • 4x or 8x 10kΩ potentiometers
    • 2x 1kΩ resistors
    • 2x push/toggle switches
    • Breadboard and jumper wires

    The Circuit

    I’ve ended up wiring potentiometers to eight analog inputs, buttons to two digital inputs and put my oscilloscope on each of the DACs to see the output.

    The potentiometers are wired in the usual VCC-signal-GND manner (although only one is shown above). The buttons are pulled down as the signals are meant to be active HIGH signals.

    The Trigger input is a pulse indicating when a key would be pressed and signifying the start of the envelope generation. When triggered the Attack stage of the envelope will begin immediately followed by the Delay phase. The Gate input is held and meant to indicate while the key is pressed and when it is released. Whilst on, the envelope will remain in the Sustain phase. On removal of the Gate signal the Release stage of the envelope will start.

    Note that the plan is for the Trigger to allow retriggering of the envelope at any time and that for removal of the Gate can also happen at any time and start Release. It is also quite possible for there to be several triggers whilst the gate is still active.

    It is also possible for the trigger and gate pin to be the same in which case trigger happens on the rising edge along with gate ON and gate OFF will happen on the falling edge.

    Here is the full GPIO list for this experiment.

    GPIO 25DAC – Envelope 1 outGPIO 26DAC – Envelope 2 outGPIO 12Trigger inputGPIO 13Gate inputGPIO 14Env 1 AttackGPIO 27Env 1 DelayGPIO 33Env 1 SustainGPIO 32Env 1 ReleaseGPIO 35Env 2 AttackGPIO 34Env 2 DelayGPIO 39Env 2 SustainGPIO 36Env 2 Release3V3Pot VCCGNDPot GND

    I’ve used the same GATE and TRIGGER signals for both envelope generators, but it would be quite happy with four independent inputs.

    Everything here is working with 3V3 logic levels, including the envelope voltages produced.

    In the photo below I’ve simplified my wiring by using my Analog IO Board PCB to give me eight potentiometers directly wired into the ESP32.

    Envelopes in Mozzi

    I’ve already used envelopes in my experiments with ESP32 and Mozzi, but they are applied in software to modulate the amplitude of the Mozzi synthesized output. And really, if using a microcontroller for synthesis this is the natural way to do things.

    By way of an example, in Mozzi, envelopes are created on startup, have their parameters changed as part of the control loop, are triggered on and off usually in response to note events, and then have each instantaneous value calculated as part of the audio loop an applied to the sample value.

    The essence of their use in Mozzi is as follows:

    #include <ADSR.h>

    ADSR <CONTROL_RATE, AUDIO_RATE> envelope;

    void HandleNoteOn(byte channel, byte note, byte velocity) {
    envelope.noteOn();
    }

    void HandleNoteOff(byte channel, byte note, byte velocity) {
    envelope.noteOff();
    }

    void setup () {
    envelope.setADLevels(ADSR_ALVL, ADSR_DLVL);
    envelope.setTimes(ADSR_A, ADSR_D, ADSR_S, ADSR_R);
    }

    void updateControl(){
    IF ADSR values have changed THEN
    call setADLevels and setTimes again as required
    }

    AudioOutput_t updateAudio(){
    Calculate new 8-bit sample
    return MonoOutput::from16Bit(envelope.next() * sample);
    }

    All that would be required to get this to output just the envelope would be to change the return statement in updateAudio to return the envelope value directly.

    AudioOutput_t updateAudio(){
    return MonoOutput::from8Bit(envelope.next());
    }

    There are several more example sketches in Examples->Mozzi->07.Envelopes.

    There are several issues with this approach that stop me using this for what I want to do:

    • This only supports one output. I might be able to configure two envelopes and get one output on the “left” channel and one on the “right” channel, which I think then map onto the two DACS…
    • I want to integrate this with some of my ESP32 PWM messing around too, which isn’t easy when Mozzi is determining all the outputs. There is an option to use a user-defined function for the output, but at this point I’m doing a lot more myself anyway…

    And anyway, I wanted to work out how an envelope generator could be implemented myself. So I didn’t use Mozzi and got to work on my own implementation.

    DIY Envelope Generation using Timers

    I had an initial look around at any existing envelope generator implementations for Arduino, having a look at both ADSRduino and the Mozzi ADSR implementation.

    In the end I opted for a simpler design of my own, deciding to manage the ADSR as a state machine in code with calculations for how much the envelope level needs to change per tick of a timer. I’m just implementing simple linear updates for each stage.

    Setting up the timer is the same as for PWM, but this time I’m using a 100kHz timer with an alarm every 10kHz. This gives me a 0.1mS “tick” which is more than adequate for generating an envelope.

    I’ve opted to map the potentiometers onto the ADSR parameters as follows:

    • ADR are mapped using: 1 + potval * 2.
    • S is mapped directly to a value in the 0..255 range, reflecting the 8-bit DAC output.

    The time values are in units of 0.1mS so can specify a duration for any of the three stages between 0.1 and 819.1 mS. For pragmatic reasons, when using these values in calculations, I always add 1 so I don’t ever have a divide by zero (which causes the ESP32 to reset).

    All values relating to a level are in 8.8 fixed point format, so are essentially 256 times larger than they need to be to give more accuracy in calculations.

    The ADSR state machine has the following functionality:

    Idle:
    Do nothing

    Trigger:
    Start Attack

    Attack:
    Increase level to maximum from current level one step at a time
    IF level reaches maximum:
    Move to Delay

    Delay:
    Decrease level to sustain level one step at a time
    IF level reaches sustain level:
    Move to Sustain

    Sustain:
    Stay at same level while Gate is ON
    IF Gate is OFF
    Move to Release

    Release:
    Decrease level down to 0 one step at a time
    IF level reaches zero
    Move back to Idle

    For each stage I maintain a step value, which is how much the level has to change for that specific step. This is calculated as follows:

    Num of Steps for this stage = Time of the stage / SAMPLE RATE

    Usefully, if I’m measuring the time of the stage in mS then I can use a SAMPLE RATE in kHz and the calculation still works. So the step increment itself can be found by:

    Step increment = (Required end level – Starting level) / Num steps

    Step increments can be positive or negative of course depending on whether the output is rising or falling.

    As already mentioned I’m using 8.8 fixed point arithmetic for the levels. The biggest concern was watching out for automatic wrapping of the 16-bit values whilst performing calculations, so I’ve removed that as a possibility by using signed, 32-bit values for the step increment and stored level.

    All the parameters associated with an envelope are stored in a structure:

    struct adsrEnv_s {
    int32_t env_l;
    int32_t steps;
    uint16_t attack_ms;
    uint16_t attack_l;
    uint16_t delay_ms;
    uint16_t sustain_l;
    uint16_t release_ms;
    bool gate;
    adsr_t state;
    } env[NUM_DAC_PINS];

    And there are a number of functions for manipulating the envelope. This is the point where really I ought to be branching over into “proper” C++ and making this an object, but I’ve stuck with C, structures and arrays for now.

    The final implementation has a few extra steps in the state machine corresponding to the transitions between stages. This just makes calculating the new step values clearer at the expense of adding an extra timer “tick”‘s worth of processing time to each stage.

    Two complications come from how the gate and trigger need to be handled.

    The gate has to be checked in each of the stages and if the gate goes to OFF then the state needs to switch over to Release.

    The trigger needs to come externally to the main state machine, but in order to ensure I’m not attempting to update variables at the same time that that they are being manipulated by the interrupt-driven state machine function, the trigger just updates the state to a “trigger” state so that on the next tick, the state machine will update itself.

    The full set of states recognised now stands as follows (stored roughly in the order they progress through):

    // ADSR state machine
    enum adsr_t {
    adsrIdle=0,
    adsrTrigger,
    toAttack,
    adsrAttack,
    toDelay,
    adsrDelay,
    toSustain,
    adsrSustain,
    toRelease,
    adsrRelease,
    adsrReset
    };

    There is the option of configuring a timing pin so that both the time within the interrupt handler, and the period of the timer can be checked.

    There is also a TEST option that manually triggers different stages of the ADSR and dumps the level of one of the envelope generators out to the serial console. This makes tweaking and debugging a bit easier.

    The main loop handles the IO updates:

    Loop:
    FOREACH DAC/EG:
    Read Trigger pin
    IF Trigger pin goes LOW->HIGH THEN
    Trigger ADSR

    Read Gate pin
    IF Gate pin goes LOW->HIGH THEN
    Turn on ADSR Gate
    IF Gate pin goes HIGH->LOW THEN
    Turn off ADSR Gate

    Scan each pot and update ADSR if changed

    Here is a trace of both envelopes with different ADSR values running off the same trigger and gate:

    Find it on GitHub here.

    Closing Thoughts

    To get any practical use out of this will require some electronics. I can’t just hook the DAC up to something else and expect everything to place nicely, so that is something to consider next.

    But for now, although the code is more complex than I original thought, thanks to having to handle the interplay of triggers and gates, it seems to work pretty well.

    Kevin

    https://diyelectromusic.wordpress.com/2024/04/07/esp32-dac-envelope-generator/

    #dac #envelopeGenerator #esp32 #mozzi

  14. I’ve been meaning to do something with the ESP32 for some time. I have some general ESP32-C3 devices, and a range of XIAO ESP32 (S2 and C3) devices too, but what I was particularly interested in was the original ESP32 as it includes two 8-bit DACs.

    This is my first set of experiments using a cheap ESP32-WROOM-32D devkit available from various online sites.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    ESP32 WROOM DevKit

    The ESP32 is a whole range of powerful 32-bit microcontrollers that include Wi-Fi and Bluetooth. They can be programmed via the Arduino IDE using an ESP32 core from Espressif.

    I was particularly after the original ESP32, so not one qualified with a S2, S3, C3, or similar reference. This is based on the dual-core Xtensa 32-bit LX6, running between 80 and 240 MHz. As well as Wi-Fi and Bluetooth there is a full range of embedded peripherals, including two 8-bit DAC outputs alongside a number of ADC inputs, and built-in 4Mb SPI flash.

    Note: these are not recommended for new designs now, as updated and more powerful devices are available, but they are still readily available in a range of formats.

    It should also be noted that 8-bit isn’t particularly great for a DAC for audio. For a more useful audio quality resolution really an I2S peripheral and higher resolution DAC would be much better, but for my messing around, having no additional components is worth it for me.

    Here are the basic references required to get going:

    To install via the Arduino board manager, add in the board URL as described in the installation guide, then when searching for ESP32 the Espressif core should be listed.

    There are a range of devkits around and not all the pinouts are the same. There is an official Espressif DevKit (V4 at the time of writing), but I ended up with one including a ESP32-WROOM-32D module which the listing suggests has the following pinout:

    Warning: I’m not convinced of the accuracy of that pinout! For one thing, there are two sets of pins apparently linked to ADC 1.4 and 1.5. From other pinout diagrams I’ve seen, and going back to the datasheet for the ESP32, the labels for ADC 1.4 to 1.9 on the bottom left should read ADC 2.4 to 2.9.

    I’m now wondering if the one here is more accurate: https://mischianti.org/doit-esp32-dev-kit-v1-high-resolution-pinout-and-specs/. Basically, the GPIO numbers should be checked off against the datasheet when it comes to additional functions. The DAC does appear to be on GPIO 25 and 26 though.

    As a test, once the ESP32 core is installed, select the ESP32-WROOM-DA module from the Arduino board menu, open the blink application and add the following line at the top of the file:

    #define LED_BUILTIN 2

    This is because my DevKit has an LED on D2 (there are two surface mount LEDs labelled PWR and D2 as per the diagram above) but LED_BUILTIN is generally undefined by default.

    The code should build, download, and run and result in the on-board LED flashing as expected.

    Parts list

    • ESP32-WROOM-32D DevKit
    • 1x 10uF electrolytic or non-polar capacitor
    • 2x 1KΩ resistors
    • 1x TRS breakout
    • Breadboard and jumper wires
    • Optional: Several 10KΩ potentiometers

    The Circuit

    These modules are pretty wide, so only just fit onto a solderless breadboard and then only with one row of holes down one side exposed, so they aren’t particularly practical on that front! But that is enough for some simple tests.

    The DAC outputs can be found on GPIO25 and 26. Mozzi treats them both the same when in mono mode. The output of the DAC will be just over 0V to just under 3.3V. Using a coupling capacitor to remove the DC bias could get this to be approx +/- 1.6V. That is a little high for a line level signal so I use a 1K/1K potential divider to half that to around +/- 800mV.

    I believe the current limit for GPIO pins on the ESP32 is 40mA, but a line input should be fairly high impedance anyway so that shouldn’t be an issue as I understand things.

    Pretty much every audio circuit I’ve seen hanging off the DAC pins, pipes them into a small audio amplifier, but with the above circuit, I feel relatively happy plugging it into my sacrificial line-level mini amplifier.

    As an additional test, potentiometers can be connected up to 3V3 and GND and with the wiper easily connected to any of the following pins: GPIO 13, 12, 14, 27. Connecting to 3V3 is a bit more of a challenge, but I used a jumper wire from beneath the ESP32 to connect round to the breadboard’s power rails.

    Note: they must NOT be connected to VIN which is sitting at the USB 5V level.

    The following diagram shows one potentiometer connected to GPIO 13, with extension wires for other pots on 12, 14 and 27.

    The Code

    Once the blink test is successful, then a simple Mozzi test can be performed. By default, Mozzi will output to the DAC with a mono feed going to both pins, so the starting point would be to try the following:

    • Examples/Mozzi/01.Basics/Sinewave
    • Examples/Mozzi/06.Synthesis/FMSynth

    Note that there are a whole lot of additional Arduino examples to explore the capabilities of the ESP32 before getting to Mozzi if required. These are found under the “Examples for ESP32” sub-menu once the core is installed, as detailed here: https://github.com/espressif/arduino-esp32/tree/master/libraries

    To run a potentiometer test requires the use of analogRead with the GPIO pin number. So if the easily accessible GPIOs are used as described previously, then the following code could test that.

    #define NUM_POTS 4
    int potpins[NUM_POTS] = {
    13, 12, 14, 27 // ADC 2.4, 2.5, 2.6, 2.7
    };

    void setup() {
    Serial.begin(9600);
    }

    void loop() {
    for (int i=0; i<NUM_POTS; i++) {
    int aval = analogRead(potpins[i]);

    Serial.print(aval);
    Serial.print("\t");
    }
    Serial.print("\n");
    delay(100);
    }

    The analog to digital converters are 12-bit compared to the Arduino Uno’s 10-bit. This means that the values range from 0..4095 rather than 0..1023.

    Assuming everything is successful so far then it should be possible to use the code from Arduino Multi-pot Mozzi FM Synthesis – Revisited and related projects, but the scaling of the potentiometer will have to reflect the additional range of values.

    One example configuration could be:

    //#define WAVT_PIN 1  // Wavetable
    #define INTS_PIN 13 // FM intensity
    #define RATE_PIN 12 // Modulation Rate
    #define MODR_PIN 14 // Modulation Ratio
    //#define AD_A_PIN 5 // ADSR Attack
    //#define AD_D_PIN 8 // ADSR Delay
    #define FREQ_PIN 27 // Optional Frequency Control

    As mentioned, all the calls to analogRead will need to be shifted down by an extra 2, but as in later versions of the code I’ve used a myAnalogRead function, I can do this all in one place with the following implementation for the ESP32:

    int myAnalogRead (int pot) {
    #ifdef POT_REVERSE
    return 1023 - (mozziAnalogRead(pot)>>2);
    #else
    return mozziAnalogRead(pot)>>2;
    #endif
    }

    One final update once again is to define the MIDI LED to use D2 rather than LED_BUILTIN.

    Adding MIDI

    To add serial MIDI (USB MIDI is not supported on the original ESP32) requires a 3V3 compatible MIDI module (see here, here or here for some options).

    Once again I’ve made connections beneath the ESP32 board for GND, RXD and TXD.

    I’ve used GPIO 3 and 1 which are RXD0 and TXD0 respectively. These are shared with the USB interface, so links here must be removed when reprogramming the ESP32 (just like with an Arduino Uno or Nano). There is a second hardware UART on GPIO 16 and 17 (RXD, TXD) which could be used instead (or in addition to) if required.

    I’ve also highlighted above where additional potentiometers could be added – a further six on GPIO 33, 32, 35, 34, 39 and 36. Consequently an alternative pot configuration using six pots for a fuller synth with MIDI could be:

    #define WAVT_PIN 33  // Wavetable
    #define INTS_PIN 32 // FM intensity
    #define RATE_PIN 35 // Modulation Rate
    #define MODR_PIN 34 // Modulation Ratio
    #define AD_A_PIN 39 // ADSR Attack
    #define AD_D_PIN 36 // ADSR Delay

    The photo at the top of this post shows my Analog IO Board and 3V3 MIDI Module hooked up to provide a nice little MIDI FM synth.

    Find it on GitHub here.

    Closing Thoughts

    This is a really good starting point with a relatively new (to me) architecture. There is a lot of potential use here, with so many ADC inputs, two DAC outputs and even the Wi-Fi for future use. It will also be interesting to see how the dual cores could be used too.

    To really do some more complex experiments though I think I’ll need a ESP32 audio/mozzi experimenter PCB along the lines of my Nano and XIAO boards, especially as these modules are quite wide. If I was feeling really brave, I could even design around the actual EP32-WROOM module itself rather than one of these DevKits…

    But this all proved relatively straight forward to get set up and running so far.

    Kevin

    https://diyelectromusic.wordpress.com/2024/03/19/esp32-and-mozzi/

    #analog #dac #define #else #endif #esp32 #ifdef #mozzi

  15. Arduino Audio and MIDI Frameworks

    I’ve been collecting bookmarks for interesting Arduino audio projects for a while now, and having now played with the XIAO SAMD21 I started looking back over my list for other things to try.  One thing that occurred to me is that there are a now a number of more powerful audio frameworks available for a range of microcontrollers, so in this post I’m doing an introductory “look see” at some of them, largely as “notes to self” to come back to them for some more detailed projects in the future.

    Note: Many of these require a 32-bit processor, which is one of the reasons I’ve not looked at them so far.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    Mozzi

    I’ve spent quite a bit of time with Mozzi of course, the synthesis library for Arduino that supports a large range of microcontrollers, including the “original” 8-bit Arduino ATmega328P, so I won’t go over that again here.

    For a starting point with Mozzi, see: Arduino PWM MIDI Synthesis with Mozzi.  For using Mozzi on a 32-bit SAMD processor, there is more here and here.

    But Mozzi isn’t the only game in town, especially if we’re expanding out to 32-bit microcontrollers.

    The Arduino Sound Library

    https://www.arduino.cc/reference/en/libraries/arduinosound/

    This is an official Arduino library that supports SAMD21 based microcontrollers using an I2S digital to analog converter. It is designed for the MKR series of official Arduino boards.

    Interestingly it appears to only support I2S audio devices for sound input and output.  That seems like a little bit of a missed opportunity to me in that the SAMD21 has a built-in DAC, but I guess analogWrite() deals with access to the DAC relatively easily.

    It is designed for official Arduino SAMD architecture boards – so those in the MKR series.  It might work on other SAMD architecture boards, I haven’t looked into it in detail.

    Phil Schatzmann’s Arduino Audio Tools

    https://github.com/pschatzmann/arduino-audio-tools

    This is a suite of open source code for audio stream processing, providing a range of audio sources (e.g. microphones, Internet streams, files, sensors, and so on) and sinks (e.g. DACs, PWM audio, MP3, codecs, audio modules, etc).

    It can be used to build audio players, processors, effects, file processors, audio visualisers, networked audio tools, and so on.

    I believe it supports the following microcontroller architectures:

    • ESP32 (S and C variants)
    • ESP8266
    • RP2040 (MBED and non-MBED)
    • AVR
    • STM32
    • SAMD

    It supports several audio output boards too, including: ESP32-A1S based boards (ES8388 or AC101 codecs); VS1053 modules; and WM8960 modules.

    I believe this is a library for audio processing, not necessarily audio synthesis.

    Marcel Licence’s ML Synth Tools

    https://github.com/marcel-licence/ML_SynthTools

    This is a comprehensive synth library for producing synthesizers, organs and effects.  Most of the code is open source, but there are certain key elements that are provided only in pre-built library form.

    It provides libraries for the following microcontrollers:

    • ESP32
    • ESP8266
    • XIAO SAMD21
    • Teensy 4.1
    • Daisy Seed
    • Raspberry Pi Pico RP2040
    • STM32F407

    As well as the synthesizer core oscillators there are modules for arpeggiators, effects, meters, scopes, and MIDI file playing.  Here are some example builds using the library:

    Although it isn’t fully open source, this non-the-less looks like it would be worth taking a more detailed look.  The provided videos of Marcel playing are particularly excellent.

    MIDI Controller Libraries

    There are a number of Arduino libraries for building MIDI controllers. Here are a selection of some that I’ve found so far.

    OpenDesk MIDI Platformhttps://github.com/shanteacontrols/OpenDeck

    This is a set of firmware and two official PCB designs for MIDI controllers. In addition to the official boards, it also supports many microcontrollers, including:

    • Arduino Mega 2560
    • Arduino Nano 33 BLE
    • Raspberry Pi Pico
    • XIAO RP2040
    • Teensy++ 2.0

    And many others. It includes a web-based configuration utility for defining the MIDI commands for the controls.  Official boards are available on Tindie and you can read more about them here: https://shanteacontrols.com/.

    It supports a range of buttons, encoders, potentiometers, force sensitive resistors, certain touchscreens and can provided feedback using LEDs and displays.

    Control Surfacehttps://github.com/tttapa/Control-Surface

    This is a general purpose library for building MIDI input and output control devices.  It supports a wide range of microcontrollers, including:

    • AVR (Uno, Mega, Leonardo).
    • Arduino Nano Every and 33.
    • Teensy.
    • ESP8266
    • ESP32
    • Raspberry Pi Pico

    It supports a range of MIDI transports, including serial, USB, “direct serial” (using Hairless MIDI) and MIDI BLE. It also supports a range of buttons, potentiometers, rotary encoders, switches, keyboard matrices, and so on and can provide visual feedback using a range of LEDS and displays.  It has built-in support for multiplexers, shift registers and LED drivers.

    It includes a huge number of example projects to browse.

    MIDIPalhttps://github.com/pichenettes/midipal

    This is a “MIDI Swiss Army Knife” that, with the additional of a display and rotary encoder, can provide a wide range of MIDI processing functions.  It includes an editor application for programming MIDI filters.

    This is a “native” AVR application, not for the Arduino environment.

    Notes and Volts MIDI Controllerhttps://www.notesandvolts.com/2016/04/arduino-midi-controller-buttons.html

    This is provided for completeness as it is a fairly common codebase for people to find and use with an Arduino. It supports a range of potentiometers and buttons and makes the task of configuring them as a MIDI control device relatively straight forward.

    Closing Thoughts

    As I say, this post is really almost a bit of a “to-do list” of things that look interesting and that I might try to take a more detailed look at, at some point.

    If you have experience of any of these frameworks or libraries; or have suggestions of others that might be worth a look, do let me know in the comments!

    Kevin

    #ArduinoAudioTools #ControlSurface #dac #esp32 #fmSynthesis #i2s #midi #midiController #MIDIPal #MLSynthTools #mozzi #OpenDesk #pwm #rp2040 #samd21 #synthesis #xiao
  16. Arduino Audio and MIDI Frameworks

    I’ve been collecting bookmarks for interesting Arduino audio projects for a while now, and having now played with the XIAO SAMD21 I started looking back over my list for other things to try.  One thing that occurred to me is that there are a now a number of more powerful audio frameworks available for a range of microcontrollers, so in this post I’m doing an introductory “look see” at some of them, largely as “notes to self” to come back to them for some more detailed projects in the future.

    Note: Many of these require a 32-bit processor, which is one of the reasons I’ve not looked at them so far.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    Mozzi

    I’ve spent quite a bit of time with Mozzi of course, the synthesis library for Arduino that supports a large range of microcontrollers, including the “original” 8-bit Arduino ATmega328P, so I won’t go over that again here.

    For a starting point with Mozzi, see: Arduino PWM MIDI Synthesis with Mozzi.  For using Mozzi on a 32-bit SAMD processor, there is more here and here.

    But Mozzi isn’t the only game in town, especially if we’re expanding out to 32-bit microcontrollers.

    The Arduino Sound Library

    https://www.arduino.cc/reference/en/libraries/arduinosound/

    This is an official Arduino library that supports SAMD21 based microcontrollers using an I2S digital to analog converter. It is designed for the MKR series of official Arduino boards.

    Interestingly it appears to only support I2S audio devices for sound input and output.  That seems like a little bit of a missed opportunity to me in that the SAMD21 has a built-in DAC, but I guess analogWrite() deals with access to the DAC relatively easily.

    It is designed for official Arduino SAMD architecture boards – so those in the MKR series.  It might work on other SAMD architecture boards, I haven’t looked into it in detail.

    Phil Schatzmann’s Arduino Audio Tools

    https://github.com/pschatzmann/arduino-audio-tools

    This is a suite of open source code for audio stream processing, providing a range of audio sources (e.g. microphones, Internet streams, files, sensors, and so on) and sinks (e.g. DACs, PWM audio, MP3, codecs, audio modules, etc).

    It can be used to build audio players, processors, effects, file processors, audio visualisers, networked audio tools, and so on.

    I believe it supports the following microcontroller architectures:

    • ESP32 (S and C variants)
    • ESP8266
    • RP2040 (MBED and non-MBED)
    • AVR
    • STM32
    • SAMD

    It supports several audio output boards too, including: ESP32-A1S based boards (ES8388 or AC101 codecs); VS1053 modules; and WM8960 modules.

    I believe this is a library for audio processing, not necessarily audio synthesis.

    Marcel Licence’s ML Synth Tools

    https://github.com/marcel-licence/ML_SynthTools

    This is a comprehensive synth library for producing synthesizers, organs and effects.  Most of the code is open source, but there are certain key elements that are provided only in pre-built library form.

    It provides libraries for the following microcontrollers:

    • ESP32
    • ESP8266
    • XIAO SAMD21
    • Teensy 4.1
    • Daisy Seed
    • Raspberry Pi Pico RP2040
    • STM32F407

    As well as the synthesizer core oscillators there are modules for arpeggiators, effects, meters, scopes, and MIDI file playing.  Here are some example builds using the library:

    Although it isn’t fully open source, this non-the-less looks like it would be worth taking a more detailed look.  The provided videos of Marcel playing are particularly excellent.

    MIDI Controller Libraries

    There are a number of Arduino libraries for building MIDI controllers. Here are a selection of some that I’ve found so far.

    OpenDesk MIDI Platformhttps://github.com/shanteacontrols/OpenDeck

    This is a set of firmware and two official PCB designs for MIDI controllers. In addition to the official boards, it also supports many microcontrollers, including:

    • Arduino Mega 2560
    • Arduino Nano 33 BLE
    • Raspberry Pi Pico
    • XIAO RP2040
    • Teensy++ 2.0

    And many others. It includes a web-based configuration utility for defining the MIDI commands for the controls.  Official boards are available on Tindie and you can read more about them here: https://shanteacontrols.com/.

    It supports a range of buttons, encoders, potentiometers, force sensitive resistors, certain touchscreens and can provided feedback using LEDs and displays.

    Control Surfacehttps://github.com/tttapa/Control-Surface

    This is a general purpose library for building MIDI input and output control devices.  It supports a wide range of microcontrollers, including:

    • AVR (Uno, Mega, Leonardo).
    • Arduino Nano Every and 33.
    • Teensy.
    • ESP8266
    • ESP32
    • Raspberry Pi Pico

    It supports a range of MIDI transports, including serial, USB, “direct serial” (using Hairless MIDI) and MIDI BLE. It also supports a range of buttons, potentiometers, rotary encoders, switches, keyboard matrices, and so on and can provide visual feedback using a range of LEDS and displays.  It has built-in support for multiplexers, shift registers and LED drivers.

    It includes a huge number of example projects to browse.

    MIDIPalhttps://github.com/pichenettes/midipal

    This is a “MIDI Swiss Army Knife” that, with the additional of a display and rotary encoder, can provide a wide range of MIDI processing functions.  It includes an editor application for programming MIDI filters.

    This is a “native” AVR application, not for the Arduino environment.

    Notes and Volts MIDI Controllerhttps://www.notesandvolts.com/2016/04/arduino-midi-controller-buttons.html

    This is provided for completeness as it is a fairly common codebase for people to find and use with an Arduino. It supports a range of potentiometers and buttons and makes the task of configuring them as a MIDI control device relatively straight forward.

    Closing Thoughts

    As I say, this post is really almost a bit of a “to-do list” of things that look interesting and that I might try to take a more detailed look at, at some point.

    If you have experience of any of these frameworks or libraries; or have suggestions of others that might be worth a look, do let me know in the comments!

    Kevin

    #ArduinoAudioTools #ControlSurface #dac #esp32 #fmSynthesis #i2s #midi #midiController #MIDIPal #MLSynthTools #mozzi #OpenDesk #pwm #rp2040 #samd21 #synthesis #xiao
  17. @davedarko @adafruit oh and if you like droning wub, then you might like the "eighties_dystopia.ino" that should work on your setup too. No UI! github.com/todbot/mozzi_experi
    Here's what it sounds like
    #mozzi #arduino #synthesizer

  18. @davedarko @adafruit oh and if you like droning wub, then you might like the "eighties_dystopia.ino" that should work on your setup too. No UI! github.com/todbot/mozzi_experi
    Here's what it sounds like
    #mozzi #arduino #synthesizer

  19. The driver board for the JOY decoration is an nano and a very hastily soldered together protoboard circuit for doing experiments with , , and control voltages. I didn't have time to fully test it before driving over to my brother's place where I lack the tools to fix any issues. Amazingly I've found just one badly bodged switch to be the only mistake on the board.

  20. The driver board for the JOY decoration is an #arduino nano and a very hastily soldered together protoboard circuit for doing experiments with #Mozzi, #MIDI, and control voltages. I didn't have time to fully test it before driving over to my brother's place where I lack the tools to fix any issues. Amazingly I've found just one badly bodged switch to be the only mistake on the board.

    #making #electronics #audio #synth

  21. It's the most useless #DTMF phone dialer! Only sequential numbers allowed!
    (this is a test bed for doing multicore stuff on the #ESP32: #Mozzi audio synthesis in "loop()" on core1 and UI stuff on core0). Uses a @adafruit QTPy ESP32, a #PCM5102 I2S DAC, and a #SH1106 OLED display #Arduino code: github.com/todbot/mozzi_experi #adafruit #qtpy

  22. It's the most useless #DTMF phone dialer! Only sequential numbers allowed!
    (this is a test bed for doing multicore stuff on the #ESP32: #Mozzi audio synthesis in "loop()" on core1 and UI stuff on core0). Uses a @adafruit QTPy ESP32, a #PCM5102 I2S DAC, and a #SH1106 OLED display #Arduino code: github.com/todbot/mozzi_experi #adafruit #qtpy

  23. Here's a #DIYSynth idea I'm working on: a really thin & simple #RaspberryPiPico-based synth with only capsense buttons, OLED, reverse-mount NeoPixels and USB & TRS #MIDI In. Less than 7mm thick. (not final artwork ofc) A platform to run #Mozzi synth library & some #CircuitPython sample-based stuff

  24. Here's a #DIYSynth idea I'm working on: a really thin & simple #RaspberryPiPico-based synth with only capsense buttons, OLED, reverse-mount NeoPixels and USB & TRS #MIDI In. Less than 7mm thick. (not final artwork ofc) A platform to run #Mozzi synth library & some #CircuitPython sample-based stuff

  25. The Sampler That Fits In Your Pocket - The future of the music instrument industry lies in synthesizers, and nowhere is this more apparen... more: hackaday.com/2019/05/07/the-sa #crowdfunding #musicalhacks #synthesizer #mozzi #mpc