Thursday, 18 April 2013

Let's code a simple sampler

Using the groovuino library, we'll make a simple sampler, which will play a "poum-tchack" rythm.

You can hear the result here :
https://soundcloud.com/gaetino/poumtchack

First of all, you will have to wire a SD card to the SPI port, and making an audio out on the Arduino. Please refer to this post if you don't know how to connect the hardware :
http://groovuino.blogspot.com/2013/03/the-goal-is-to-build-groovebox-using.html

On the SD card, you will transfer 2 one-shot wave files (44 kHz), named "kick1.wav" and "snare1.wav".

Download groovuino library and SdFat lib :
https://github.com/Gaetino/Groovuino
https://code.google.com/p/sdfatlib/
Then put them in your favorite arduino library repository.

As usual, we'll begin the code by importing libraries :


#include <SdFat.h>
#include <sampler.h>
#include <timer.h> 

Now instanciate a Sd and a sampler object :


SdFat sd;
Sampler sampler;


To make the beat, we'll use a simple timer :

int to = 0;

Now the setup method to initialize our data :

void setup() 


// Start the audio engine
  startTimer(TC1, 1, TC4_IRQn, 44100);
  analogWrite(DAC1,0); 


    sd.begin(chipSelect, SPI_FULL_SPEED);
    sampler.init();
}

We'll use the loop() method to compute the beat, and to fill the wave buffer if necessary.
Of course, if you want to make a groovebox, you will need another timer to get the beat and trigger the samples.


void loop() 
{
   if(to>100000) 
   {
     to=0;
 // POUM
     sampler.load("kick1.wav");
     sampler.splay(100,1);
   }
   
   if(to==50000) 
   {
 // TCHACK
     sampler.load("snare1.wav");
     sampler.splay(100,1);
   }
   
   sampler.buffill();
   
   delayMicroseconds(10);
   
   to++;


And finally, as usual, the audio engine :


void TC4_Handler() 

   TC_GetStatus(TC1, 1); 

// 2048 is the 0 value of audio out.
   int16_t ulOutput=2048;

   sampler.next();
   
   ulOutput += sampler.output();

   if(ulOutput>4095) ulOutput=4095;
   dacc_write_conversion_data(DACC_INTERFACE, ulOutput); 
}


That's it. If all is good, you can hear a "poum-tchack".

Wednesday, 3 April 2013

Build a groove box with Arduino Due, Post3 : Let's code a simple synth

After explaining the project in posts 1 and 2, now let's code into the Arduino Due.
Please refer to the main post : http://groovuino.blogspot.fr/2013/03/the-goal-is-to-build-groovebox-using.html
You can use the USB cable with Programming Port. For now, no need to external power supply. all components used have very low power needs. When we'll add LCD, it will be necessary.

First of all, download the groovuino library on guithub :
https://github.com/Gaetino/Groovuino

Then copy the folder into the library of your arduino folder.

If you haven't got yet, download the latest arduino environment here :
http://arduino.cc/en/Main/Software

Be careful to take the one working with Arduino Due.


Now, we'll code a synth which is working with the groovuino hardware.

Libraries

First, before making any code, import all the libraries you need :


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

#define POLIPHONY 1
int notes[POLIPHONY];

#include <interface.h>
#include <arp.h> 
#include <timer.h> 



Now we instantiate the voices and their volume envelopes, and the filter. For the moment, there will be just 1 voice, we'll make a mono synth.

Osc oscA[POLIPHONY];
Env env1[POLIPHONY];

LowPassFilter LP;

We need some status :


boolean play = false;
boolean mono = true;


We have to include the analogread.h function AFTER having instantiated envelopes, oscillators and filter, because it's using these objects.

#include <analogread.h>


Initialization (setup function)

void setup() 


// Defining pots and sensors  
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A4, INPUT);
  pinMode(A5, INPUT);
  pinMode(A6, INPUT);

// Loading osc tables
  createSineTable();
  createSawTable();  
  createSqTable();  

// Start the audio engine
  startTimer(TC1, 1, TC4_IRQn, 44100);
  analogWrite(DAC1,0); 
  
// Set filter default values
  LP.setCutoffFreq(255);
  LP.setResonance(1);
  
  for(int i=0; i<POLIPHONY; i++)
  {
    oscA[i].init();
    env1[i].init();
    notes[i]=0;
  }

  play=false;
  
  analogcontroller_init();

// Set the glide time at 2 ms
  oscA[0].setGlideTime(2);
  
  init_interface();
}   

The loop function will be only used to read sensor and potentiometers data.


void loop() 

  read_input();
  analogcontroller_read();
}



Finally, the 44 kHz loop, where we have to read oscillators values


void TC4_Handler() 


 TC_GetStatus(TC1, 1); 

 int32_t ulOutput=2048;

// load oscillator value  
 oscA[0].next();
 ulOutput += oscA[0].output();

// apply filter effect
  if(ulOutput>10) ulOutput = LP.next(ulOutput);

// apply envelope 
  ulOutput = (ulOutput * env1[0].amount())>>19;

// apply global volume
  ulOutput = (ulOutput*volsynth)>>7;

  
  if(ulOutput>4095) ulOutput=4095;
   
  dacc_write_conversion_data(DACC_INTERFACE, ulOutput); 
}



To be continued...



Build a groove box with Arduino Due, Post2 : Main functionnalities

Here I will describe how the interface will act on software. I wanted a simple interface, with no menus.
If it's convincing, I will make a more elaborate interface.

Please refer to the main post : http://groovuino.blogspot.fr/2013/03/the-goal-is-to-build-groovebox-using.html




4 Mode buttons with LED to choose the way you want to use the groovebox
8 Function buttons with LED to choose which function you want to act to
4 Pots to change the value of the function parameters.

3 sensors : 1 ribbon sensor, 1 pressure sensor, 1 distance sensor.

Here a list of the modes and parameters we can act on :



Mode 1 : Synth parameters
Mode 2 : Arppegiator
Mode 3 : Sampler
Mode 4 : Free play

Mode 1

button 1 : OSC1
-         Pot1 : Volume
-         Pot2 : Waveform
-         Pot3 : Fine 

button 2 : OSC2
-         Pot1 : Volume
-         Pot2 : Waveform
-         Pot3 : Fine 

button 3 : OSC3
-         Pot1 : Volume
-         Pot2 : Waveform
-         Pot3 : Fine 

button 4 : Enveloppe volume
-         Pot1 : A
-         Pot2 : D
-         Pot3 : S
-         Pot4 : R 

button 5 : EnveloppeA
-         Pot1 : A
-         Pot2 : D
-         Pot3 : S
-         Pot4 : R 

button 6 : LFOA
-         Pot1 : speed
-         Pot2 : waveform
-         Pot3 : amplitude

button 7 : filter
-         Pot1 : f
-         Pot2 : q
-         Pot3 : modulation (off, LFOA, EnvA)
-         Modulation power

button 8 : General
-         Pot1 : volume
-         Pot2 : Tempo
-         Pot3 : Mode (monophonique / polyphonique)



Mode 2

button 1 to 8 : notes
-         Pot1 : arpegiator mode (OFF – UP – DOWN – UP/DOWN - random)
-         Pot2 : arpegiator speed (1/4T - 1/4 – 1/2T - 1/2 – 1 – 2)
-         Pot3 : arpeggiator range (-4 à 4)
-         Pot4 : scale (Pentatonic, arabic, major, minor, Dorian)



Mode 3

button 1 : Sampler1
-         Pot1 : sample num
-         Pot2 : sample pitch
-         Pot3 : sample beginning
-         Pot4 : sample ending

button 2 : Sampler2

-         Pot1 : sample num
-         Pot2 : sample pitch
-         Pot3 : sample beginning
-         Pot4 : sample ending

button 3 : Sampler3
-         Pot1 : sample num
-         Pot2 : sample pitch
-         Pot3 : sample beginning
-         Pot4 : sample ending

button 4 : Sampler4


-         Pot1 : sample num
-         Pot2 : sample pitch
-         Pot3 : sample beginning
-         Pot4 : sample ending

Arppegiator


The scales of arppegiator will be simple, as we have only 8 buttons. So no chromatic scale, for example.
I will use the most common.

Here is a table which indicates the notes corresponding to each button, and the value of the MIDI note (beginning by C3)




Penta
Arabe
Majeure
Mineure
Dorienne
button1
C
60
C
60
C
60
C
60
C
60
button2
Eb
63
C#
61
D
62
D
62
D
62
button3
F
65
E
64
E
64
Eb
63
Eb
63
button4
G
67
F
65
F
65
F
65
F
65
button5
Bb
70
G
67
G
67
G
67
G
67
button6
C
72
G#
68
A
69
Ab
68
A
69
button7
Eb
75
Bb
70
B
71
Bb
70
Bb
70
button8
F
77
C
72
C
72
C
72
C
72