DP Synth-00

Reading Time: 3 minutes

How to make a simple and lightweight synth based on Arduino to play everywhere. With this example you can create one audio oscillator with BP Filter, tremolo and vibrato control.

In this example we present how to create a simple synth using Arduino and Mozzi (Sound Synthesis Library for Arduino).

The circuit is made up of six potentiometers connected to the Arduino analog inputs (A0-A5) and the audio output connected to digital pin 9.

First pot is used to control the frequency of the oscillator, the second controls the frequency of the LFO that create the tremolo, the third changes the tremolo depth. Fourth and fifth pots control frequency and depth of vibrato LFO. Finally, pot number six controls the center frequency of the band pass filter.

/*  DP Synth-01 - One audio oscillator with BP Filter, tremolo and vibrato control
  
    This example code is in the public domain.

    Artis Lab - 2017
    www.artislab.it
    info@artislab.it
*/

#include <Oscil.h> // oscillator template
#include <StateVariable.h>

#include <tables/sin2048_int8.h> // sine table for oscillator
#include <tables/saw2048_int8.h> //sawtoth table
//#include <tables/square_no_alias_2048_int8.h> //square table
//#include <tables/triangle2048_int8.h> //triangle table

// audio oscillator 
Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aOscil(SAW2048_DATA);
// audio oscillators for tremelo and vibrato
Oscil<SIN2048_NUM_CELLS, AUDIO_RATE> aTremolo(SIN2048_DATA);
Oscil<SIN2048_NUM_CELLS, AUDIO_RATE> aVibrato(SIN2048_DATA);
//LowPassFilter lpf;
StateVariable <BANDPASS> svf; // can be LOWPASS, BANDPASS, HIGHPASS or NOTCH

// use #define for CONTROL_RATE, not a constant
#define CONTROL_RATE 64 // powers of 2 please

const char FREQ_PIN = 0; // set the input for the Frequency to analog pin 0
const char TREM_PIN = 1;
const char TREMDEP_PIN =2;
const char VIB_PIN =3;
const char VIBDEP_PIN =4;
const char FILTER_PIN = 5; // set the input for the filter cutoff to analog pin 5

byte VibratoDepth=0;
byte TremoloDepth=0;
float alpha = 0.5;
int FreqValue=0;
int CutOffValue=0;
int TremValue=0;
int VibValue=0;
int TremDepValue=0;
int VibDepValue=0;

void setup(){
  startMozzi(CONTROL_RATE); // set a control rate of 64 (powers of 2 please)
  svf.setResonance(120);
  svf.setCentreFreq(2000);
}


void updateControl(){

  int FreqKnob = mozziAnalogRead(FREQ_PIN); // value is 0-1023
  //We use a running average filter to smooth the sensor input
  FreqValue =alpha * FreqKnob + (1. - alpha) * FreqValue;
  Q24n8 oscFreq=float_to_Q24n8(40*pow(10,FreqValue/475.));
  aOscil.setFreq_Q24n8(oscFreq); // set the frequency
   
  int TremKnob = mozziAnalogRead(TREM_PIN); // value is 0-1023
  //We use a running average filter to smooth the sensor input
  TremValue =alpha * TremKnob + (1. - alpha) * TremValue;
  Q24n8 TremFreq=float_to_Q24n8((float)map(TremValue,0,1023,1,301)/10.);
  aTremolo.setFreq_Q24n8(TremFreq);
  
  int TremDepKnob=mozziAnalogRead(TREMDEP_PIN);
  //We use a running average filter to smooth the sensor input
  TremDepValue =alpha * TremDepKnob + (1. - alpha) * TremDepValue;
  TremoloDepth = byte(map(TremDepValue,0,1023,0,255));
  
  int VibKnob = mozziAnalogRead(VIB_PIN); // value is 0-1023
  //We use a running average filter to smooth the sensor input
  VibValue =alpha * VibKnob + (1. - alpha) * VibValue;
  Q24n8 VibFreq=float_to_Q24n8((float)map(VibValue,0,1023,1,301)/10.);
  //Serial.println((float)map(VibValue,0,1023,1,610)/20.);
  aVibrato.setFreq_Q24n8(VibFreq);

  int VibDepKnob=mozziAnalogRead(VIBDEP_PIN);
  //We use a running average filter to smooth the sensor input
  VibDepValue =alpha * VibDepKnob + (1. - alpha) * VibDepValue;
  VibratoDepth = byte(map(VibDepValue,0,1023,0,255));

  int FilterKnob=mozziAnalogRead(FILTER_PIN);
  //We use a running average filter to smooth the sensor input
  CutOffValue =int(alpha * FilterKnob + (1. - alpha) * CutOffValue);
  svf.setCentreFreq(map(CutOffValue,0,1023,50,4000));

}

int updateAudio(){
      Q15n16 vibrato = (Q15n16)VibratoDepth * aVibrato.next();
      int Tremolo=255u-(((128u+aTremolo.next())*TremoloDepth)>>8);
      int Osc=(aOscil.phMod(vibrato) * Tremolo) >> 8;// return an int signal centred around 0
      int Out=int(svf.next(Osc)*0.9); // Apply State Variable filtering
      return Out;
}

void loop(){
  audioHook(); // required here
}

Click here to download the source code (only registered users can browse and download, click here to register, it’s for free!)

If you have any problems, curiosities and suggestions please feel free to contact us.

Security Code:
security code
Please enter the security code:

Submit

Leave a Reply

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