Friday, 23 August 2013

Simple mono synth with groovuino library

Here is a simple example on how to make a monophnic 1-osc synth with the groovuino lib.
I added a low-pass filter and a very light sequencer.

Here is the video :



You just need 4 potentiometers and an audio out as described in this post :
http://groovuino.blogspot.fr/2013/03/the-goal-is-to-build-groovebox-using.html

The potentiometers are plugged on analog inputs 3,4,5 and 6.

Analog 3 : octave of the arpeggio
Analog 4 : filter frequency
Analog 5 : bpm
Analog 6 : choice of the arpeggio



The code :

Incude your libraries. We just need the osc and low-pass filter.


#include <arduino.h>
#include <osc.h>
#include <filter.h>

We will use the Due timer library. I like it. You can download it here https://github.com/ivanseidel/DueTimer, and copy the repository in your arduino library folder.

#include <DueTimer.h>

Now instanciate your oscillator and filter :

Osc osc;
LowPassFilter LP;


Some data we will need for the arpeggiator :

int step = 0;
int numarp = 0;
int count = 0;


The arpeggio sequences (8 sequences of 16 notes). You can build your own sequences.
0 is is A 440 Hz. 2 = B, 3 = C, 12 = A octave...


int nArps[8][16] = {
{0,0,12,0,0,0,3,15,2,14,0,0,-2,-2,0,12},
{0,12,-2,0,1,13,1,1,5,17,5,17,4,16,0,0}, 
{0,-2,0,3,5,3,0,-2,0,-2,0,3,5,6,5,3},
{0,0,12,0,24,22,12,15,0,-2,0,0,24,36,3,-2},
{0,12,0,15,0,19,0,18,0,15,0,12,0,24,0,-2},
{0,0,3,0,0,0,0,-2,0,0,0,0,0,3,5,-2},
{0,0,0,0,0,0,7,7,6,6,6,6,6,6,-2,-2},
{0,0,3,0,0,-2,0,0,0,0,3,0,5,3,0,3}};


Initialize everything :

void setup() 

  Serial.begin(9600); 

The analog inputs :

  pinMode(A6, INPUT);
  pinMode(A5, INPUT);
  pinMode(A4, INPUT);
  pinMode(A3, INPUT);

Start the timers : one 44.1 kHz for audio generation, and on 100 Hz for sequencer :

  Timer0.attachInterrupt(loop1).setFrequency(44100).start();
  Timer8.attachInterrupt(loop2).setFrequency(100).start();

Generate the wavetables. We'll only use Sine, Saw, and Square :

  createSineTable();
  createSawTable();  
  createSqTable();    

Initialize the DAC output.

  analogWrite(DAC1,0); 

Set cutoff and resonance to default values :

  LP.setCutoffFreq(255);
  LP.setResonance(255);

Set the oscillator to default values :

  osc.init();
  osc.setWaveform(0,30);
  osc.setVolOsc(0, 127);
  osc.setNote(50,50);



Read the potentiometers.
analog 6 selects the arpeggio number (8 arrpeggios, so the number is 3 bits long)
analog 4 sets the cutoff frequency

void loop() 

  numarp = analogRead(6)>>7;
  LP.setCutoffFreq(analogRead(4)>>3);
  delay(5);
}


Generate the sound :
One osc with LP filter.

void loop1() 

  int32_t ulOutput=2048;

  osc.next();

  ulOutput += LP.next(osc.output());
   
  if(ulOutput>4095) ulOutput=4095;
  if(ulOutput<0) ulOutput=0;
  dacc_write_conversion_data(DACC_INTERFACE, ulOutput); 
}

The sequencer :
analog 5 fixes the tempo. If the value is high, the time between 2 notes will be long.
analog 3 sets the octave. (it adds an integer * 12 to the note).

void loop2()
{
  if(count>=(analogRead(5)>>4))
  {
    if(step>=15) step = 0;
    else step+=1;
    osc.setNote((analogRead(3)>>7)*12+nArps[numarp][step],100);
    count = 0;
  }
  else count++;
}