After making a simple sampler, let's code a polyphonic sampler now.
First of all, it's necessary to copy samples on a SD card. The samples need to be consecutive, so the best to do is to format SD card before copying the samples.
As usual, the groovuino library will be used.
The names of the samples used have to be changed in the samplerl.h file.
Here is the code.
First, call groovuino library elements you will need, and instanciate objects :
Now, the setup function where you initialize your data. This is here you will enter a drum sequence.
There are 96 steps in a measure. So 24 steps for each time, 12 steps for a quaver...
The sample buffers are filled in the main loop :
The 44 kHz loop to generate the sample sound :
The sequencer loop :
First of all, it's necessary to copy samples on a SD card. The samples need to be consecutive, so the best to do is to format SD card before copying the samples.
As usual, the groovuino library will be used.
The names of the samples used have to be changed in the samplerl.h file.
Here is the code.
First, call groovuino library elements you will need, and instanciate objects :
#include <arduino.h>
#include <sequencer.h>
const int samplernumber = 6; // polyphony
Pattern drumpat[samplernumber];
#include <SdFat.h>
SdFat sd;
Sd2Card *card = sd.card();
#include <samplerl.h>
#include <DueTimer.h>
Samplerl samp[samplernumber];
uint32_t step = 0;
int bpm=120;
#include <sequencer.h>
const int samplernumber = 6; // polyphony
Pattern drumpat[samplernumber];
#include <SdFat.h>
SdFat sd;
Sd2Card *card = sd.card();
#include <samplerl.h>
#include <DueTimer.h>
Samplerl samp[samplernumber];
uint32_t step = 0;
int bpm=120;
Now, the setup function where you initialize your data. This is here you will enter a drum sequence.
There are 96 steps in a measure. So 24 steps for each time, 12 steps for a quaver...
void setup()
{
Serial.begin(9600);
bpm = 120;
Timer0.attachInterrupt(loop1).setFrequency(44100).start();
Timer4.attachInterrupt(loop2).setFrequency((bpm*24/60)).start();
analogWrite(DAC1,0);
sd.begin(chipSelect, SPI_FULL_SPEED);
for(int i=0; i<samplernumber; i++)
{
samp[i].init();
samp[i].load(samplefile[i]);
delay(5);
}
for(int i=0; i<samplernumber; i++)
{
drumpat[i].init();
}
// Drum sequence
drumpat[0].noteon[0] = true;
drumpat[0].seqvol[0] = 50;
drumpat[0].noteon[12] = true;
drumpat[0].seqvol[12] = 50;
drumpat[2].noteon[48] = true;
drumpat[2].seqvol[48] = 50;
drumpat[3].noteon[48] = true;
drumpat[3].seqvol[48] = 50;
drumpat[3].noteon[24] = true;
drumpat[3].seqvol[24] = 50;
drumpat[3].noteon[72] = true;
drumpat[3].seqvol[72] = 50;
drumpat[2].noteon[72] = true;
drumpat[2].seqvol[72] = 50;
drumpat[0].noteon[72] = true;
drumpat[0].seqvol[72] = 50;
drumpat[4].noteon[48] = true;
drumpat[4].seqvol[48] = 80;
drumpat[5].noteon[48] = true;
drumpat[5].seqvol[48] = 80;
drumpat[5].noteon[36] = true;
drumpat[5].seqvol[36] = 80;
drumpat[0].noteon[24] = true;
drumpat[0].seqvol[24] = 50;
drumpat[1].noteon[24] = true;
drumpat[1].seqvol[24] = 50;
drumpat[1].noteon[0] = true;
drumpat[1].seqvol[0] = 80;
drumpat[1].noteon[12] = true;
drumpat[1].seqvol[12] = 20;
drumpat[1].noteon[24] = true;
drumpat[1].seqvol[24] = 80;
drumpat[1].noteon[36] = true;
drumpat[1].seqvol[36] = 20;
drumpat[1].noteon[48] = true;
drumpat[1].seqvol[48] = 80;
drumpat[1].noteon[60] = true;
drumpat[1].seqvol[60] = 20;
drumpat[1].noteon[72] = true;
drumpat[1].seqvol[72] = 80;
drumpat[1].noteon[84] = true;
drumpat[1].seqvol[84] = 20;
}
{
Serial.begin(9600);
bpm = 120;
Timer0.attachInterrupt(loop1).setFrequency(44100).start();
Timer4.attachInterrupt(loop2).setFrequency((bpm*24/60)).start();
analogWrite(DAC1,0);
sd.begin(chipSelect, SPI_FULL_SPEED);
for(int i=0; i<samplernumber; i++)
{
samp[i].init();
samp[i].load(samplefile[i]);
delay(5);
}
for(int i=0; i<samplernumber; i++)
{
drumpat[i].init();
}
// Drum sequence
drumpat[0].noteon[0] = true;
drumpat[0].seqvol[0] = 50;
drumpat[0].noteon[12] = true;
drumpat[0].seqvol[12] = 50;
drumpat[2].noteon[48] = true;
drumpat[2].seqvol[48] = 50;
drumpat[3].noteon[48] = true;
drumpat[3].seqvol[48] = 50;
drumpat[3].noteon[24] = true;
drumpat[3].seqvol[24] = 50;
drumpat[3].noteon[72] = true;
drumpat[3].seqvol[72] = 50;
drumpat[2].noteon[72] = true;
drumpat[2].seqvol[72] = 50;
drumpat[0].noteon[72] = true;
drumpat[0].seqvol[72] = 50;
drumpat[4].noteon[48] = true;
drumpat[4].seqvol[48] = 80;
drumpat[5].noteon[48] = true;
drumpat[5].seqvol[48] = 80;
drumpat[5].noteon[36] = true;
drumpat[5].seqvol[36] = 80;
drumpat[0].noteon[24] = true;
drumpat[0].seqvol[24] = 50;
drumpat[1].noteon[24] = true;
drumpat[1].seqvol[24] = 50;
drumpat[1].noteon[0] = true;
drumpat[1].seqvol[0] = 80;
drumpat[1].noteon[12] = true;
drumpat[1].seqvol[12] = 20;
drumpat[1].noteon[24] = true;
drumpat[1].seqvol[24] = 80;
drumpat[1].noteon[36] = true;
drumpat[1].seqvol[36] = 20;
drumpat[1].noteon[48] = true;
drumpat[1].seqvol[48] = 80;
drumpat[1].noteon[60] = true;
drumpat[1].seqvol[60] = 20;
drumpat[1].noteon[72] = true;
drumpat[1].seqvol[72] = 80;
drumpat[1].noteon[84] = true;
drumpat[1].seqvol[84] = 20;
}
The sample buffers are filled in the main loop :
void loop()
{
for(int i=0; i<samplernumber; i++)
{
if(samp[i].buffill()) i= 100;
}
}
{
for(int i=0; i<samplernumber; i++)
{
if(samp[i].buffill()) i= 100;
}
}
The 44 kHz loop to generate the sample sound :
void loop1()
{
int32_t ulOutput=2048;
for(int i=0; i<samplernumber; i++)
{
samp[i].next();
ulOutput += samp[i].output();
}
if(ulOutput>4095) ulOutput=4095;
if(ulOutput<0) ulOutput=0;
dacc_write_conversion_data(DACC_INTERFACE, ulOutput);
}
{
int32_t ulOutput=2048;
for(int i=0; i<samplernumber; i++)
{
samp[i].next();
ulOutput += samp[i].output();
}
if(ulOutput>4095) ulOutput=4095;
if(ulOutput<0) ulOutput=0;
dacc_write_conversion_data(DACC_INTERFACE, ulOutput);
}
The sequencer loop :
void loop2()
{
if(step>=95) step = 0;
else step++;
for(int i=0; i<samplernumber; i++)
{
if(drumpat[i].noteon[step])
{
samp[i].splay(drumpat[i].seqvol[step], 1);
}
}
}
{
if(step>=95) step = 0;
else step++;
for(int i=0; i<samplernumber; i++)
{
if(drumpat[i].noteon[step])
{
samp[i].splay(drumpat[i].seqvol[step], 1);
}
}
}