Skip to content

alxndrdiaz/MeeBleeps-Freaq-FM-Synth

 
 

Repository files navigation

Meebleeps Freaq FM Synth

Arduino Synth with Dual-voice 2-OP FM | Generative 2-track Polymetric Sequencer | Mozzi SDK

NOTE This code is an open-source prototype and is not compatible with the retail version of Freaq FM hardware

An evolution of my first Mozzi synth build, this one features dual independent 2-operator FM voices paired with a 2-track generative sequencer.

Each voice has independent carrier & modulator waveforms, FM ratio, modulation envelope & LFO.

Both tracks share the a single pattern (inspired by the Intellijel Metropolix) and can be stacked in unison or have different polymetric step-counts. Track 1 can be offset 0-3 octaves above track 2 for separate bass & lead.

It started simple... but ended up cramming the 32K flash to the brim with features and wavetables, maxxing out the interface with obscure button combinations, and pushing the 16Mhz Arduino Nano to the edge! Upside is it makes lots of funky noises now!

Source released under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 Copyright (C) 2022 Meebleeps


Important build-notes

  • My builds have used normally-closed switches, so the code assumes this. 09 May 2022: Added complier switches to handle normally-open switches
  • This will probably compile to Arduino Uno, but it won't work properly without extensive modification as it uses all 8 of the Nano's analog input pins
  • If you have issues with the compiled size not fitting in the Nano, this may be due to different compiler (I use VSCode & PlatformIO) or different bootloader in the Arduino (not sure which I have, but am compiling to Elegoo brand arduino nano).
    • Check the compiler options in MutantFMSynthOptions.h to alter switch type or compile size
    • open the file MutantFMSynthOptions.h
    • find the line: //#define COMPILE_SMALLER_BINARY
    • uncomment the line so it looks like this: #define COMPILE_SMALLER_BINARY
    • Then compile. It should now easily fit into the Nano. This omits the semi-random wave tablesbut you probably won't miss it! :)
  • Do not install the Mozzi library from PlatformIO in VSCode, it's outdated and will not build successfully. Instead, install its latest git master branch to lib/mozzi.
  • The default settings target the Nano ATmega328 with the new bootloader. If you have avrdude errors during upload, you might have the old bootloader: change both instances of nanoatmega328new to nanoatmega328 in plaformio.ini.

Voices

  • 2 independent FM voices
  • 2-operator FM (for old-school prince of persia vibes! 😂)
  • Multi-mode FM ratios - quantised, free-multiple, independent
  • Multiple operator waveforms for carrier & modulator - Sine, Saw, Reverse Saw, Square, Noise, Off
  • Modulation level controlled by Attack/Decay envelope and LFO per-voice
  • Multiple LFO waveforms (same tables as the carrier oscillators) Sine, Saw, Reverse Saw, Square, Noise

Sequencer

  • 2/1.5 track polymetric sequencer with up to 16 steps per track (Both tracks use same note sequence but can have different step-counts for polymetric phasing)
  • Multiple generative algorithms - (semi)random notes, (semi)random runs, arpeggio, drone
  • Sequence mutates/evolves at user-defined rate & note-density
  • Selectable tonic, octave & scale quantisation (Major, Minor, Pentatonic, Phrygian (GOA!), Octaves, Fifths)
  • Tap-tempo control
  • Sync input & output (Korg Volca compatible)
  • 16-step parameter-lock recording of synth parameters for track 1 (the Elektron way!)

Hardware

  • Arduino Nano (Elegoo)
  • 8x8 LED display with a MAX7219-based control board
  • Simple Mozzi output circuit
  • Added power filtering caps on DC input and 5V rail
  • Designed to fit into Volca form factor
  • Laser-cut metalisized acrylic faceplate
  • Laser-cut wooden enclosure
  • 7V-12DC DC Power input
  • Access to nano's USB port for firmware upgrades

Pins

These are the defaults defined for the faceplate controls:

Pin Function Name in MutantFMSynth.ino
A0 Mutation ANALOG_INPUT_MUTATION
A1 Wobble ANALOG_INPUT_LFO
A2 Population ANALOG_INPUT_STEPCOUNT
A3 Attack ANALOG_INPUT_MOD_ENVELOPE2
A4 Lifespan ANALOG_INPUT_DECAY
A5 Decay ANALOG_INPUT_MOD_ENVELOPE1
A6 Ratio ANALOG_INPUT_MOD_RATIO
A7 Depth ANALOG_INPUT_MOD_AMOUNT
D3 Start BUTTON_INPUT_START
D4 Voice BUTTON_INPUT_VOICE
D5 Rec BUTTON_INPUT_REC
D6 Scales BUTTON_INPUT_SCALE
D10 Func BUTTON_INPUT_FUNC
D12 Tonic BUTTON_INPUT_TONIC

User Guide

Buttons

  • Tonic - Select tonic through natural notes A - G
    • [Func] + Tonic - Shift base octave from 0 - 5
    • [Func][Rec] + Tonic - Select octave offset to Track 1 (track 1 & 2 can be 0-4 octaves apart)
  • Scales - Select current musical scale
    • [Func] + Scales - Select current generative algorithm
    • [Func][Rec] + Scales - Select the LFO waveform for the current voice
  • Rec + knob - Hold down while moving a knob to record those parameters to the sequence
    • [Func][Rec] + knob - Hold down while moving a knob to delete the recorded sequence for that parameter
    • [Func][Rec] + buttons - Access various secondary functions
  • Start - Start or stop the sequencer
    • [Func] + Start - Tap tempo
    • [Func][Rec] + Start - Select the MODULATOR waveform for the current voice
  • Voice - Select the active track which can be edited using the parameter inputs
    • [Func] + Voice - Select the FM ratio mode for the current voice
    • [Func][Rec] + Voice - Select CARRIER Waveform for the current voice

Rotary Inputs

  • Mutation - Adjust the likelihood that the sequence will change over time
    • [Func] + Mutation - Adjust the liklihood that any given step will be a note or a rest
  • Population - Adjust the number of steps for the active track
    • [Func] + Population - Adjust the number of steps for all tracks
  • Lifespan - Adjust the length of the notes (for all tracks)
  • Ratio - Select the carrier--to-modulator FM ratio (based on the current FM mode)
  • Wobble - Adjust the amount of LFO to apply to the modulator level for the active track
    • [Func] + Wobble - Adjust the LFO rate for the active track
  • Attack - Adjust the attack time for the modulator level envelope
  • Decay - Adjust the decay time for the modulator level envelope
  • Depth - Adjust the amount of envelope to apply to the modulator level for the active track

Issues / Limitations

  • Fair bit of jitter in the sequencer timing when tracking external sync due to somewhat naive approach to the 2-step-per-pulse volca sync
  • Mozzi audio library has 10ms buffer
  • The code is written for NORMALLY CLOSED switches - see latest updates in MutantFMSynth.ino updateButtonControls() for support for NORMALLY OPEN
  • The code may not fit in the Arduino Nano when compiled using the Arduino IDE or using different bootloaders

Compiling on the Arduino IDE

If you have issues with the compiled size not fitting in the Nano, this may be due to different compiler (I use VSCode & PlatformIO) or different bootloader in the Arduino (not sure which I have, but am compiling to Elegoo brand arduino nano).

  • Check the compiler options in MutantFMSynthOptions.h to alter switch type or compile size
  • open the file MutantFMSynthOptions.h
  • find the line: //#define COMPILE_SMALLER_BINARY
  • uncomment the line so it looks like this: #define COMPILE_SMALLER_BINARY
  • Then compile. It should now easily fit into the Nano. This omits the semi-random wave tablesbut you probably won't miss it! :)

Compiling in VSCode / PlatformIO

  • Do not install the Mozzi library from PlatformIO in VSCode, it's outdated and will not build successfully. Instead, install its latest git master branch to lib/mozzi.
  • The default settings target the Nano ATmega328 with the new bootloader. If you have avrdude errors during upload, you might have the old bootloader: change both instances of nanoatmega328new to nanoatmega328 in plaformio.ini.

Thanks

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • G-code 97.5%
  • C++ 1.8%
  • C 0.7%