├── README.md ├── analogread.h ├── arp.h ├── env.h ├── exemple ├── exemple.ino ├── midievent.h ├── monosynth.ino └── poumtac.ino ├── filter.h ├── interface.h ├── lfo.h ├── osc.h ├── sampler.h ├── samplerl.h ├── sequencer.h ├── tables.h ├── timer.h └── waveforms ├── clavinet01.h └── ebass01.h /README.md: -------------------------------------------------------------------------------- 1 | Groovuino 2 | ========= 3 | 4 | Sound library for Arduino Due to make a groovebox 5 | 6 | To use this library with an Arduino Due, you have to plug the DAC1 out of the Arduino to the line IN of an amplifier. 7 | You can put a 500 Ohm resistor between this out and your amplifier to prevent harming your Arduino. 8 | I made a shield, which is used in analogread.h and interface.h, to control Arduino. 9 | You can build this shield (see on my blog below the schematics) and use it, but you can use this other components of the library without this shield. 10 | 11 | 12 | You can use too a MIDI shield and the arduino MIDI library to control your Arduino : http://playground.arduino.cc/Main/MIDILibrary 13 | 14 | 15 | If you want to use a sampler, the samples are stored in a SD card, and Groovuino needs SdFat library. You can find it here : 16 | http://code.google.com/p/sdfatlib/ 17 | 18 | 19 | Thanks to Duane B, which blog permitted to start this library : 20 | http://rcarduino.blogspot.com/2012/12/arduino-due-dds-part-1-sinewaves-and.html 21 | 22 | 23 | Details on library and hardware are on my blog : 24 | http://groovuino.blogspot.com/ 25 | -------------------------------------------------------------------------------- /analogread.h: -------------------------------------------------------------------------------- 1 | const int BUFRIB = 30; 2 | 3 | uint32_t stockribbon[BUFRIB]; 4 | uint32_t indicestock = 0; 5 | 6 | uint32_t volsynth = 127; 7 | 8 | uint32_t pot1save = 0; 9 | uint32_t pot2save = 0; 10 | uint32_t pot3save = 0; 11 | uint32_t pot4save = 0; 12 | boolean noteplay[1]; 13 | 14 | 15 | 16 | int ctrlmode = 2; 17 | 18 | uint32_t moyenneStock() 19 | { 20 | uint32_t ret = 0; 21 | for(int i=0; i300) 91 | { 92 | uint32_t calrib = (ribbondata/84)+36; 93 | volsynth = distdata>>3; 94 | 95 | if(!noteplay[0]) 96 | { 97 | noteplay[0] = true; 98 | notes[0] = calrib; 99 | oscA[0].setNote(notes[0], volsynth); 100 | env1[0].start(); 101 | } 102 | else 103 | { 104 | 105 | if(notes[0] != calrib) 106 | oscA[0].setNote(calrib, volsynth); 107 | } 108 | 109 | } 110 | if(distdata<=300) 111 | { 112 | if(noteplay[0]) 113 | { 114 | env1[0].stop(); 115 | noteplay[0]=false; 116 | } 117 | } 118 | delay(3); 119 | } 120 | // ----- CONTROL MODE 2 121 | if(ctrlmode==2) 122 | { 123 | if(pressdata<1000) 124 | { 125 | uint32_t calrib = (ribbondata/84)+36; 126 | volsynth = (1023-pressdata)>>3; 127 | 128 | if(!noteplay[0]) 129 | { 130 | noteplay[0] = true; 131 | notes[0] = calrib; 132 | oscA[0].setNote(notes[0], volsynth); 133 | env1[0].start(); 134 | } 135 | else 136 | { 137 | 138 | if(notes[0] != calrib) 139 | oscA[0].setNote(calrib, volsynth); 140 | } 141 | 142 | } 143 | if(pressdata>=1000) 144 | { 145 | if(noteplay[0]) 146 | { 147 | env1[0].stop(); 148 | noteplay[0]=false; 149 | } 150 | } 151 | delay(3); 152 | } 153 | } 154 | 155 | //-------------------------------- 156 | // MODE 1 157 | //-------------------------------- 158 | if(mode==1) 159 | { 160 | if(ecartStock(508)>9) 161 | { 162 | if(ecartStock(moyenneStock())<3) 163 | { 164 | transpo = (((int)ribbondata-508)/150)*12; 165 | load_arpeg(); 166 | } 167 | } 168 | if(indicestock == (BUFRIB-1)) indicestock = 0; 169 | else indicestock++; 170 | stockribbon[indicestock] = ribbondata; 171 | delay(3); 172 | 173 | change_length_arpeg((1024-distdata)>>3); 174 | } 175 | 176 | //*************************************************************************** 177 | 178 | uint32_t pot1 = analogRead(3)>>3; 179 | uint32_t pot2 = analogRead(4)>>3; 180 | uint32_t pot3 = analogRead(5)>>3; 181 | uint32_t pot4 = analogRead(6)>>3; 182 | 183 | 184 | //================================ 185 | // POTENTIOMETER 1 186 | //================================ 187 | if(pot1>(pot1save+3)||pot1<(pot1save-3)) 188 | { 189 | Serial.println("pot1"); 190 | //------ SYNTH MODE ------- 191 | if(mode==0) 192 | { 193 | // OSC1 194 | if(function==0) 195 | { 196 | oscA[0].setVolOsc(0,pot1); 197 | } 198 | // OSC2 199 | if(function==1) 200 | { 201 | oscA[0].setVolOsc(1,pot1); 202 | } 203 | // OSC3 204 | if(function==2) 205 | { 206 | oscA[0].setVolOsc(2,pot1); 207 | } 208 | // Attack volume enveloppe 209 | if(function==3) 210 | { 211 | env1[0].setA(pot1); 212 | } 213 | // filter 214 | if(function==6) 215 | { 216 | LP.setCutoffFreq(pot1<<1); 217 | } 218 | } 219 | //------ ARPEGGIATOR MODE -------- 220 | if(mode==1) 221 | { 222 | if(pot1<25) 223 | { 224 | arpmode = 0; 225 | } 226 | 227 | if(pot1>=25 && pot1<50) 228 | { 229 | arpmode = 1; 230 | load_arpeg(); 231 | } 232 | 233 | if(pot1>=50 && pot1<75) 234 | { 235 | arpmode = 2; 236 | load_arpeg(); 237 | } 238 | 239 | if(pot1>=75 && pot1<100) 240 | { 241 | arpmode = 3; 242 | load_arpeg(); 243 | } 244 | 245 | if(pot1>=100 && pot1<128) 246 | { 247 | arpmode = 4; 248 | load_arpeg(); 249 | } 250 | } 251 | pot1save = pot1; 252 | } 253 | 254 | //================================ 255 | // POTENTIOMETER 2 256 | //================================ 257 | if(pot2>(pot2save+3)||pot2<(pot2save-3)) 258 | { 259 | //------ SYNTH MODE ------- 260 | if(mode==0) 261 | { 262 | // OSC1 263 | if(function==0) 264 | { 265 | oscA[0].setWaveform(0,pot2); 266 | } 267 | if(function==1) 268 | { 269 | oscA[0].setWaveform(1,pot2); 270 | } 271 | if(function==2) 272 | { 273 | oscA[0].setWaveform(2,pot2); 274 | } 275 | // Decay volume enveloppe 276 | if(function==3) 277 | { 278 | env1[0].setD(pot2); 279 | } 280 | // filter 281 | if(function==6) 282 | { 283 | LP.setResonance(pot2<<1); 284 | } 285 | if(function==7) 286 | { 287 | bpm = pot2*2+60; 288 | setTimerBPM(); 289 | delay(100); 290 | } 291 | } 292 | //------ ARPEGGIATOR MODE -------- 293 | if(mode==1) 294 | { 295 | if(pot2<20) 296 | { 297 | arpspeed = 1; 298 | load_arpeg(); 299 | } 300 | if(pot2>=20 && pot2<40) 301 | { 302 | arpspeed = 2; 303 | load_arpeg(); 304 | } 305 | if(pot2>=40 && pot2<60) 306 | { 307 | arpspeed = 3; 308 | load_arpeg(); 309 | } 310 | if(pot2>=60 && pot2<80) 311 | { 312 | arpspeed = 4; 313 | load_arpeg(); 314 | } 315 | if(pot2>=80 && pot2<100) 316 | { 317 | arpspeed = 5; 318 | load_arpeg(); 319 | } 320 | if(pot2>=100 && pot2<128) 321 | { 322 | arpspeed = 6; 323 | load_arpeg(); 324 | } 325 | } 326 | pot2save = pot2; 327 | } 328 | 329 | //================================ 330 | // POTENTIOMETER 3 331 | //================================ 332 | if(pot3>(pot3save+3)||pot3<(pot3save-3)) 333 | { 334 | //------ SYNTH MODE ------- 335 | if(mode==0) 336 | { 337 | // OSC1 338 | if(function==0) 339 | { 340 | oscA[0].setFine(0,pot3); 341 | } 342 | if(function==1) 343 | { 344 | oscA[0].setFine(1,pot3); 345 | } 346 | if(function==2) 347 | { 348 | oscA[0].setFine(2,pot3); 349 | } 350 | // Release volume enveloppe 351 | if(function==3) 352 | { 353 | env1[0].setS(pot3); 354 | 355 | } 356 | } 357 | //------ ARPEGGIATOR MODE -------- 358 | if(mode==1) 359 | { 360 | if(pot3<25) 361 | { 362 | arpgamme = 0; 363 | load_arpeg(); 364 | } 365 | if(pot3>=25 && pot3<50) 366 | { 367 | arpgamme = 1; 368 | load_arpeg(); 369 | } 370 | if(pot3>=50 && pot3<75) 371 | { 372 | arpgamme = 2; 373 | load_arpeg(); 374 | } 375 | if(pot3>=75 && pot3<100) 376 | { 377 | arpgamme = 3; 378 | load_arpeg(); 379 | } 380 | if(pot3>=100 && pot3<128) 381 | { 382 | arpgamme = 4; 383 | load_arpeg(); 384 | } 385 | } 386 | pot3save = pot3; 387 | } 388 | 389 | //================================ 390 | // POTENTIOMETER 4 391 | //================================ 392 | if(pot4>(pot4save+3)||pot4<(pot4save-3)) 393 | { 394 | //------ SYNTH MODE ------- 395 | if(mode==0) 396 | { 397 | if(function==3) 398 | { 399 | env1[0].setR(pot4); 400 | } 401 | } 402 | } 403 | } 404 | 405 | 406 | -------------------------------------------------------------------------------- /arp.h: -------------------------------------------------------------------------------- 1 | uint8_t arpmode = 0; 2 | uint8_t arpspeed = 3; 3 | int8_t arphigh = 0; 4 | uint8_t arpgamme = 0; 5 | 6 | int8_t transpo = 0; 7 | 8 | int8_t gamme[8]; 9 | 10 | boolean arpbut[8] = {0,0,0,0,0,0,0,0}; 11 | uint8_t length = 8; 12 | 13 | void fill_gamme() 14 | { 15 | if(arpgamme==0) 16 | { 17 | gamme[0] = 60 + transpo; 18 | gamme[1] = 63 + transpo; 19 | gamme[2] = 65 + transpo; 20 | gamme[3] = 67 + transpo; 21 | gamme[4] = 70 + transpo; 22 | gamme[5] = 72 + transpo; 23 | gamme[6] = 75 + transpo; 24 | gamme[7] = 77 + transpo; 25 | } 26 | if(arpgamme==1) 27 | { 28 | gamme[0] = 60 + transpo; 29 | gamme[1] = 61 + transpo; 30 | gamme[2] = 64 + transpo; 31 | gamme[3] = 65 + transpo; 32 | gamme[4] = 67 + transpo; 33 | gamme[5] = 68 + transpo; 34 | gamme[6] = 70 + transpo; 35 | gamme[7] = 72 + transpo; 36 | } 37 | if(arpgamme==2) 38 | { 39 | gamme[0] = 60 + transpo; 40 | gamme[1] = 62 + transpo; 41 | gamme[2] = 64 + transpo; 42 | gamme[3] = 65 + transpo; 43 | gamme[4] = 67 + transpo; 44 | gamme[5] = 69 + transpo; 45 | gamme[6] = 71 + transpo; 46 | gamme[7] = 72 + transpo; 47 | } 48 | if(arpgamme==3) 49 | { 50 | gamme[0] = 60 + transpo; 51 | gamme[1] = 62 + transpo; 52 | gamme[2] = 63 + transpo; 53 | gamme[3] = 65 + transpo; 54 | gamme[4] = 67 + transpo; 55 | gamme[5] = 68 + transpo; 56 | gamme[6] = 70 + transpo; 57 | gamme[7] = 72 + transpo; 58 | } 59 | if(arpgamme==4) 60 | { 61 | gamme[0] = 60 + transpo; 62 | gamme[1] = 62 + transpo; 63 | gamme[2] = 63 + transpo; 64 | gamme[3] = 65 + transpo; 65 | gamme[4] = 67 + transpo; 66 | gamme[5] = 69 + transpo; 67 | gamme[6] = 70 + transpo; 68 | gamme[7] = 72 + transpo; 69 | } 70 | } 71 | 72 | void load_arpeg() 73 | { 74 | fill_gamme(); 75 | 76 | int modulo = 96; 77 | if(arpspeed==1) modulo = 4; 78 | if(arpspeed==2) modulo = 6; 79 | if(arpspeed==3) modulo = 8; 80 | if(arpspeed==4) modulo = 12; 81 | if(arpspeed==5) modulo = 24; 82 | if(arpspeed==6) modulo = 48; 83 | 84 | int indgamme=0; 85 | 86 | for(int i = 0; i<96; i++) 87 | { 88 | if(i%modulo==0) 89 | { 90 | noteon[i] = true; 91 | seqvol[i] = 100; 92 | seqpit[i] = 50; 93 | seqlen[i] = length; 94 | 95 | for(int j = 0; j<8; j++) 96 | { 97 | if(funcbutState[indgamme]) 98 | { 99 | seqpit[i] = gamme[indgamme]; 100 | j = 9; 101 | 102 | } 103 | if(indgamme<7) indgamme ++; 104 | else indgamme = 0; 105 | } 106 | } 107 | else noteon[i] = false; 108 | } 109 | 110 | } 111 | 112 | void change_length_arpeg(uint32_t clength) 113 | { 114 | if(arpspeed==1) length = clength/26+2; 115 | if(arpspeed==2) length = clength/16+2; 116 | if(arpspeed==3) length = clength/11+2; 117 | if(arpspeed==4) length = clength/7+2; 118 | if(arpspeed==5) length = clength/3+2; 119 | if(arpspeed==6) length = clength+2; 120 | 121 | for(int i = 0; i<96; i++) 122 | { 123 | seqlen[i] = length; 124 | 125 | } 126 | } 127 | 128 | uint8_t cal_nb_notes() 129 | { 130 | uint8_t ret = 0; 131 | for(int i=0; i<8; i++) 132 | { 133 | if(funcbutState[i]) ret++; 134 | } 135 | return ret; 136 | } 137 | -------------------------------------------------------------------------------- /env.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Env 4 | { 5 | 6 | public: 7 | 8 | 9 | uint32_t envA; 10 | uint32_t envD; 11 | uint32_t envS; 12 | uint32_t envR; 13 | 14 | uint32_t accu; 15 | 16 | boolean phaseA; 17 | boolean phaseD; 18 | boolean phaseS; 19 | boolean phaseR; 20 | 21 | void init() 22 | { 23 | envA = 30000; 24 | envD = 20000; 25 | envS = 200000; 26 | envR = 30; 27 | accu = 0; 28 | phaseA = false; 29 | phaseD = false; 30 | phaseS = false; 31 | phaseR = false; 32 | } 33 | 34 | void start() 35 | { 36 | phaseA = true; 37 | phaseD = false; 38 | phaseS = false; 39 | phaseR = false; 40 | } 41 | 42 | 43 | void stop() 44 | { 45 | phaseA = false; 46 | phaseD = false; 47 | phaseS = false; 48 | phaseR = true; 49 | } 50 | 51 | void setA(uint32_t val) 52 | { 53 | envA = 10000/(val*16+1); 54 | } 55 | 56 | void setD(uint32_t val) 57 | { 58 | envD = (524288-envS)*50/((val+1)*44100); 59 | } 60 | 61 | void setS(uint32_t val) 62 | { 63 | envS = val<<12; 64 | } 65 | 66 | void setR(uint32_t val) 67 | { 68 | envR = envS*200/((val+1)*44100); 69 | } 70 | 71 | uint32_t amount() 72 | { 73 | // ATTACK 74 | if(phaseA) 75 | { 76 | if(accu >= 524288) 77 | { 78 | phaseA = false; 79 | phaseD = true; 80 | } 81 | else 82 | { 83 | accu += envA; 84 | } 85 | } 86 | 87 | // SUSTAIN 88 | // We do nothing 89 | 90 | // DECAY 91 | if(phaseD) 92 | { 93 | 94 | accu = accu - envD; 95 | 96 | if(accu<=envS) 97 | { 98 | phaseD = false; 99 | phaseS = true; 100 | } 101 | 102 | } 103 | 104 | 105 | // RELEASE 106 | if(phaseR) 107 | { 108 | if(accu>=envR) 109 | { 110 | accu -= envR; 111 | } 112 | else 113 | { 114 | phaseR = false; 115 | accu = 0; 116 | } 117 | } 118 | 119 | return accu; 120 | } 121 | }; 122 | -------------------------------------------------------------------------------- /exemple/exemple.ino: -------------------------------------------------------------------------------- 1 | // A large part of this code was taken from Duane B on RCArduino forum 2 | // You must have a SD card connected to Arduino Due, with wavfiles samples on it : 3 | // kick1.wav, snare1.wav, hihat1.wav 4 | 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define POLIPHONY 1 13 | 14 | const int samplernumber = 3; 15 | 16 | SdFat sd; 17 | Sampler sampler[samplernumber]; 18 | 19 | 20 | Osc oscA[POLIPHONY]; 21 | Env env1[POLIPHONY]; 22 | 23 | uint32_t notes[POLIPHONY]; 24 | boolean noteplay[POLIPHONY]; 25 | 26 | // Activate monophonic mode 27 | boolean mono = true; 28 | boolean samp = true; 29 | 30 | 31 | void setup() 32 | { 33 | Serial.begin(9600); 34 | 35 | createSineTable(); 36 | createSawTable(); 37 | createSqTable(); 38 | 39 | /* turn on the timer clock in the power management controller */ 40 | pmc_set_writeprotect(false); 41 | pmc_enable_periph_clk(ID_TC4); 42 | 43 | /* we want wavesel 01 with RC */ 44 | TC_Configure(/* clock */TC1,/* channel */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK2); 45 | TC_SetRC(TC1, 1, 235); // sets <> 44.1 Khz interrupt rate 46 | TC_Start(TC1, 1); 47 | 48 | // enable timer interrupts on the timer 49 | TC1->TC_CHANNEL[1].TC_IER=TC_IER_CPCS; 50 | TC1->TC_CHANNEL[1].TC_IDR=~TC_IER_CPCS; 51 | 52 | /* Enable the interrupt in the nested vector interrupt controller */ 53 | /* TC4_IRQn where 4 is the timer number * timer channels (3) + the channel number (=(1*3)+1) for timer1 channel1 */ 54 | NVIC_EnableIRQ(TC4_IRQn); 55 | 56 | // this is a cheat - enable the DAC 57 | analogWrite(DAC1,0); 58 | 59 | sd.begin(chipSelect, SPI_FULL_SPEED); 60 | for(int i=0; i>19; 384 | } 385 | 386 | if(ulOutput>10) ulOutput = nextfilter(ulOutput)/16384; 387 | 388 | for(int i=0; i4095) ulOutput=4095; 399 | 400 | 401 | dacc_write_conversion_data(DACC_INTERFACE, ulOutput); 402 | } 403 | 404 | -------------------------------------------------------------------------------- /exemple/midievent.h: -------------------------------------------------------------------------------- 1 | const uint8_t MIDIVolOsc[NUM_OSC]; 2 | const uint8_t MIDIWaveform[NUM_OSC]; 3 | const uint8_t MIDIFine[NUM_OSC]; 4 | 5 | MIDIVolOsc[0] = 1; 6 | MIDIWaveform[0] = 2; 7 | MIDIFine[0] = 3; 8 | 9 | MIDIVolOsc[1] = 9; 10 | MIDIWaveform[1] = 10; 11 | MIDIFine[1] = 11; 12 | 13 | MIDIVolOsc[2] = 17; 14 | MIDIWaveform[2] = 18; 15 | MIDIFine[2] = 19; 16 | 17 | const uint8_t MIDIEnvA = 69; 18 | const uint8_t MIDIEnvD = 82; 19 | const uint8_t MIDIEnvS = 83; 20 | const uint8_t MIDIEnvR = 84; 21 | 22 | const uint8_t MIDIFilterCut = 91; 23 | const uint8_t MIDIFilterRes = 92; 24 | const uint8_t MIDIFilterType = 93; 25 | 26 | const uint8_t MIDIGlideTime = 97; 27 | 28 | 29 | void midievent() 30 | { 31 | if (MIDI.read()) { // Is there a MIDI message incoming ? 32 | 33 | switch(MIDI.getType()) { // Get the type of the message we caught 34 | uint32_t voldata; 35 | uint32_t notedata; 36 | 37 | /////////////////////////////// 38 | //////// Note On ///////////// 39 | /////////////////////////////// 40 | case NoteOn: // If it is a NoteOn 41 | 42 | voldata = MIDI.getData2(); 43 | notedata = MIDI.getData1(); 44 | 45 | // Monophonic 46 | //----------- 47 | if(mono) 48 | { 49 | if(voldata!=0) 50 | { 51 | if(noteplay[0]) 52 | { 53 | oscA[0].setNote(notedata, voldata); 54 | } 55 | else 56 | { 57 | oscA[0].setNote(notedata, voldata); 58 | env1[0].start(); 59 | noteplay[0]=true; 60 | } 61 | notes[0] = notedata; 62 | } 63 | else 64 | { 65 | if(notes[0]==notedata) 66 | { 67 | env1[0].stop(); 68 | noteplay[0] = false; 69 | } 70 | } 71 | } 72 | 73 | // Polyphonic 74 | //----------- 75 | else 76 | { 77 | if(voldata!=0) 78 | { 79 | for(int i=0; i 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | #define POLIPHONY 1 12 | 13 | Osc oscA[POLIPHONY]; 14 | Env env1[POLIPHONY]; 15 | 16 | uint32_t notes[POLIPHONY]; 17 | boolean noteplay[POLIPHONY]; 18 | 19 | boolean mono = true; 20 | boolean samp = true; 21 | boolean midion = true; 22 | 23 | Filter LP; 24 | 25 | 26 | #include 27 | 28 | void setup() 29 | { 30 | Serial.begin(9600); 31 | 32 | pinMode(A0, INPUT); 33 | 34 | createNoteTable(SAMPLE_RATE); 35 | createSineTable(); 36 | createSawTable(); 37 | createSqTable(); 38 | 39 | Timer0.attachInterrupt(loop1).setFrequency(44100).start(); 40 | 41 | analogWrite(DAC1,0); 42 | 43 | MIDI.begin(); // Launch MIDI with default options 44 | // (input channel is default set to 1) 45 | 46 | LP.setCutoffFreq(255); 47 | LP.setResonance(1); 48 | LP.setType(0); 49 | 50 | for(int i=0; i4095) ulOutput=4095; 79 | if(ulOutput<0) ulOutput=0; 80 | 81 | dacc_write_conversion_data(DACC_INTERFACE, ulOutput); 82 | } 83 | -------------------------------------------------------------------------------- /exemple/poumtac.ino: -------------------------------------------------------------------------------- 1 | // Simple sampler which alternates a kick and a snare 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | SdFat sd; 8 | Sampler sampler; 9 | 10 | void setup() 11 | { 12 | 13 | Timer0.attachInterrupt(loop1).setFrequency(44100).start(); 14 | analogWrite(DAC1,0); 15 | 16 | sd.begin(chipSelect, SPI_FULL_SPEED); 17 | sampler.init(); 18 | } 19 | 20 | void loop() 21 | { 22 | if(to>100000) 23 | { 24 | to=0; 25 | // POUM 26 | sampler.load("kick1.wav"); 27 | sampler.splay(100,1); 28 | } 29 | 30 | if(to==50000) 31 | { 32 | // TCHACK 33 | sampler.load("snare1.wav"); 34 | sampler.splay(100,1); 35 | } 36 | 37 | sampler.buffill(); 38 | 39 | delayMicroseconds(10); 40 | 41 | to++; 42 | } 43 | 44 | void loop1() 45 | { 46 | 47 | // 2048 is the 0 value of audio out. 48 | int16_t ulOutput=2048; 49 | 50 | sampler.next(); 51 | 52 | ulOutput += sampler.output(); 53 | 54 | if(ulOutput>4095) ulOutput=4095; 55 | dacc_write_conversion_data(DACC_INTERFACE, ulOutput); 56 | } 57 | -------------------------------------------------------------------------------- /filter.h: -------------------------------------------------------------------------------- 1 | #ifndef LOWPASS_H_ 2 | #define LOWPASS_H_ 3 | #define FX_SHIFT 8 4 | #define SHIFTED_1 256 5 | 6 | class LowPassFilter 7 | { 8 | 9 | public: 10 | 11 | LowPassFilter(); 12 | 13 | 14 | void setCutoffFreq(unsigned char cutoff) 15 | { 16 | f = cutoff; 17 | setFeedbackf((int)cutoff); 18 | } 19 | 20 | 21 | void setResonance(unsigned char resonance) 22 | { 23 | q = resonance; 24 | setFeedbackq((int)resonance); 25 | } 26 | 27 | void setType(unsigned char filtertype) 28 | { 29 | if(filtertype<40) type = 0; // LP 30 | if(filtertype>=40 && filtertype<80) type = 1; // BP 31 | if(filtertype>=80) type = 2; // HP 32 | } 33 | 34 | inline 35 | 36 | int next(int in) 37 | { 38 | int ret; 39 | hp = in-buf0; 40 | bp = buf0-buf1; 41 | buf0+=fxmul(f, (hp + fxmul(fb, bp))); 42 | buf1+=fxmul(f, buf0-buf1); 43 | if(type==0) ret = buf1; 44 | if(type==1) ret = bp; 45 | if(type==2) ret = hp; 46 | return ret; 47 | } 48 | 49 | 50 | private: 51 | int f; 52 | long fb; 53 | int q; 54 | int buf0,buf1,hp,bp; 55 | unsigned char type; 56 | 57 | inline 58 | void setFeedbackf(long f) 59 | { 60 | fb = q+fxmul(q, (int)SHIFTED_1 - (f/128)); 61 | } 62 | 63 | void setFeedbackq(long q) 64 | { 65 | fb = q+fxmul(q, (int)SHIFTED_1 - (f/128)); 66 | } 67 | 68 | // convert an int into to its fixed representation 69 | inline 70 | long fx(int i) 71 | { 72 | return (i<>FX_SHIFT); 80 | } 81 | 82 | 83 | }; 84 | 85 | #endif /* LOWPASS_H_ */ 86 | -------------------------------------------------------------------------------- /interface.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int funcbut[8] ; 4 | int funcLED[8] ; 5 | boolean funcbutPressed[8]; 6 | boolean funcbutState[8]; 7 | boolean funcbutRead[8]; 8 | 9 | boolean butstate[4][8]; 10 | 11 | 12 | int slider[4] ; 13 | 14 | int modebut[4] ; 15 | int modeLED[4] ; 16 | boolean modebutPressed[4]; 17 | boolean modebutState[4]; 18 | boolean modebutRead[4]; 19 | 20 | 21 | 22 | 23 | 24 | int mode = 0; 25 | int function = 0; 26 | 27 | void init_interface() 28 | { 29 | funcbut[0] = 23; 30 | funcbut[1] = 25; 31 | funcbut[2] = 27; 32 | funcbut[3] = 29; 33 | funcbut[4] = 31; 34 | funcbut[5] = 33; 35 | funcbut[6] = 35; 36 | funcbut[7] = 37; 37 | 38 | funcLED[0] = 22; 39 | funcLED[1] = 24; 40 | funcLED[2] = 26; 41 | funcLED[3] = 28; 42 | funcLED[4] = 30; 43 | funcLED[5] = 32; 44 | funcLED[6] = 34; 45 | funcLED[7] = 36; 46 | 47 | slider[0] = A3; 48 | slider[1] = A4; 49 | slider[2] = A5; 50 | slider[3] = A6; 51 | 52 | modebut[0] = 38; 53 | modebut[1] = 40; 54 | modebut[2] = 42; 55 | modebut[3] = 44; 56 | 57 | modeLED[0] = 39; 58 | modeLED[1] = 41; 59 | modeLED[2] = 43; 60 | modeLED[3] = 45; 61 | 62 | 63 | for (int a = 0; a < 8; a++) 64 | { 65 | pinMode(funcbut[a], INPUT); 66 | pinMode(funcLED[a], OUTPUT); 67 | 68 | funcbutPressed[a] = false; 69 | funcbutState[a] = false; 70 | funcbutRead[a] = false; 71 | 72 | digitalWrite(funcLED[a], LOW); 73 | 74 | } 75 | funcbutState[0] = true; 76 | digitalWrite(funcLED[0], HIGH); 77 | 78 | for (int a = 0; a < 4; a++) 79 | { 80 | pinMode(modebut[a], INPUT); 81 | pinMode(modeLED[a], OUTPUT); 82 | pinMode(slider[a], INPUT); 83 | 84 | modebutPressed[a] = false; 85 | modebutState[a] = false; 86 | modebutRead[a] = false; 87 | 88 | digitalWrite(modeLED[a], LOW); 89 | } 90 | modebutState[0] = true; 91 | digitalWrite(modeLED[0], HIGH); 92 | 93 | for (int a = 0; a < 4; a++) 94 | { 95 | for (int b = 0; b < 8; b++) 96 | { 97 | butstate[a][b] = false; 98 | } 99 | } 100 | butstate[0][0] = true; 101 | } 102 | 103 | void load_funcbut() 104 | { 105 | for (int a = 0; a < 8; a++) 106 | { 107 | digitalWrite(funcLED[a], LOW); 108 | } 109 | 110 | for (int a = 0; a < 8; a++) 111 | { 112 | funcbutState[a] = butstate[mode][a]; 113 | if(funcbutState[a]) digitalWrite(funcLED[a], HIGH); 114 | } 115 | } 116 | 117 | void read_input() 118 | { 119 | for (int a = 0; a < 8; a++) 120 | { 121 | funcbutRead[a] = digitalRead(funcbut[a]); 122 | 123 | if(funcbutRead[a] && !funcbutPressed[a] && !funcbutState[a]) 124 | { 125 | funcbutPressed[a] = true; 126 | funcbutState[a] = true; 127 | butstate[mode][a] = true; 128 | digitalWrite(funcLED[a], HIGH); 129 | 130 | function = a; 131 | 132 | for(int b = 0; b < 8; b++) 133 | { 134 | if(b!=a && funcbutState[b]) 135 | { 136 | funcbutState[b] = false; 137 | butstate[mode][b] = false; 138 | digitalWrite(funcLED[b], LOW); 139 | } 140 | } 141 | } 142 | 143 | if(funcbutRead[a] && !funcbutPressed[a] && funcbutState[a]) 144 | { 145 | funcbutPressed[a] = true; 146 | } 147 | 148 | if(!funcbutRead[a] && funcbutPressed[a]) 149 | { 150 | funcbutPressed[a] = false; 151 | } 152 | } 153 | 154 | 155 | 156 | for (int a = 0; a < 4; a++) 157 | { 158 | modebutRead[a] = digitalRead(modebut[a]); 159 | 160 | if(modebutRead[a] && !modebutPressed[a] && !modebutState[a]) 161 | { 162 | modebutPressed[a] = true; 163 | modebutState[a] = true; 164 | digitalWrite(modeLED[a], HIGH); 165 | 166 | mode = a; 167 | 168 | for(int b = 0; b < 4; b++) 169 | { 170 | if(b!=a && modebutState[b]) 171 | { 172 | modebutState[b] = false; 173 | digitalWrite(modeLED[b], LOW); 174 | } 175 | } 176 | load_funcbut(); 177 | } 178 | 179 | if(modebutRead[a] && !modebutPressed[a] && modebutState[a]) 180 | { 181 | modebutPressed[a] = true; 182 | } 183 | 184 | if(!modebutRead[a] && modebutPressed[a]) 185 | { 186 | modebutPressed[a] = false; 187 | } 188 | } 189 | } 190 | 191 | void read_input_arp() 192 | { 193 | for (int a = 0; a < 8; a++) 194 | { 195 | funcbutRead[a] = digitalRead(funcbut[a]); 196 | 197 | if(funcbutRead[a] && !funcbutPressed[a] && !funcbutState[a]) 198 | { 199 | funcbutPressed[a] = true; 200 | funcbutState[a] = true; 201 | butstate[mode][a] = true; 202 | digitalWrite(funcLED[a], HIGH); 203 | } 204 | 205 | if(funcbutRead[a] && !funcbutPressed[a] && funcbutState[a]) 206 | { 207 | funcbutPressed[a] = true; 208 | funcbutState[a] = false; 209 | butstate[mode][a] = false; 210 | digitalWrite(funcLED[a], LOW); 211 | } 212 | 213 | if(funcbutRead[a] && !funcbutPressed[a] && funcbutState[a]) 214 | { 215 | funcbutPressed[a] = true; 216 | } 217 | 218 | if(!funcbutRead[a] && funcbutPressed[a]) 219 | { 220 | funcbutPressed[a] = false; 221 | } 222 | } 223 | 224 | 225 | 226 | for (int a = 0; a < 4; a++) 227 | { 228 | modebutRead[a] = digitalRead(modebut[a]); 229 | 230 | if(modebutRead[a] && !modebutPressed[a] && !modebutState[a]) 231 | { 232 | modebutPressed[a] = true; 233 | modebutState[a] = true; 234 | digitalWrite(modeLED[a], HIGH); 235 | 236 | mode = a; 237 | 238 | for(int b = 0; b < 4; b++) 239 | { 240 | if(b!=a && modebutState[b]) 241 | { 242 | modebutState[b] = false; 243 | digitalWrite(modeLED[b], LOW); 244 | } 245 | } 246 | load_funcbut(); 247 | } 248 | 249 | if(modebutRead[a] && !modebutPressed[a] && modebutState[a]) 250 | { 251 | modebutPressed[a] = true; 252 | } 253 | 254 | if(!modebutRead[a] && modebutPressed[a]) 255 | { 256 | modebutPressed[a] = false; 257 | } 258 | } 259 | } 260 | -------------------------------------------------------------------------------- /lfo.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define SAMPLE_LFO_RATE 500.0 4 | #define SAMPLES_LFO_PER_CYCLE 600 5 | #define SAMPLES_LFO_PER_CYCLE_FIXEDPOINT (SAMPLES_LFO_PER_CYCLE<<20) 6 | #define TICKS_LFO_PER_CYCLE (float)((float)SAMPLES_LFO_PER_CYCLE_FIXEDPOINT/(float)SAMPLE_LFO_RATE) 7 | 8 | 9 | 10 | class Lfo 11 | { 12 | 13 | public: 14 | uint16_t waveform; 15 | uint32_t ulPhaseAccumulator; 16 | volatile uint32_t ulPhaseIncrement ; 17 | float fFrequency; 18 | boolean play; 19 | uint32_t lfovol; 20 | uint32_t maincutoff; 21 | 22 | void init() 23 | { 24 | 25 | waveform = 0; 26 | 27 | ulPhaseAccumulator = 0; 28 | ulPhaseIncrement = 0; 29 | maincutoff = 64; 30 | 31 | lfovol = 100; 32 | 33 | play=true; 34 | } 35 | 36 | void setfreq(uint32_t freq) 37 | { 38 | fFrequency = (sqrt((float)freq+1.0)*50.0-48.0)/25.0*TICKS_LFO_PER_CYCLE; 39 | ulPhaseIncrement = fFrequency; 40 | } 41 | 42 | void stop() 43 | { 44 | play = false; 45 | } 46 | 47 | void start() 48 | { 49 | play = true; 50 | } 51 | 52 | void setvol(uint32_t _vol) 53 | { 54 | lfovol = _vol; 55 | } 56 | 57 | void setmaincutoff(uint32_t data) 58 | { 59 | maincutoff = data; 60 | } 61 | 62 | void setWaveform(uint32_t val) 63 | { 64 | if(val<40) waveform = 0; 65 | if(val>=40&&val<80) waveform = 1; 66 | if(val>=80) waveform = 2; 67 | } 68 | 69 | void next() 70 | { 71 | if(play) 72 | { 73 | ulPhaseAccumulator += ulPhaseIncrement; 74 | if(ulPhaseAccumulator > SAMPLES_LFO_PER_CYCLE_FIXEDPOINT) 75 | { 76 | ulPhaseAccumulator -= SAMPLES_LFO_PER_CYCLE_FIXEDPOINT; 77 | } 78 | } 79 | } 80 | 81 | 82 | uint16_t output() 83 | { 84 | int32_t ret=0; 85 | if(play) 86 | { 87 | if(waveform == 0) ret+= (((nSineTable[ulPhaseAccumulator>>20]+2048)*lfovol)>>12)+maincutoff; 88 | if(waveform == 1) ret+= (((nSawTable[ulPhaseAccumulator>>20]+2048)*lfovol)>>12)+maincutoff; 89 | if(waveform == 2) ret+= (((nSqTable[ulPhaseAccumulator>>20]+2048)*lfovol)>>12)+maincutoff; 90 | if(ret>=128) ret = 128; 91 | if(ret<=1) ret = 1; 92 | } 93 | return ret; 94 | } 95 | 96 | }; 97 | -------------------------------------------------------------------------------- /osc.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Change this to change the number of oscillators per voice 5 | #define NUM_OSC 1 6 | 7 | // Can adjust the Sample rate 8 | #define SAMPLE_RATE 44100.0 9 | 10 | // Number of samples played in one cycle (a cycle depends on the frequency of the note played) 11 | #define SAMPLES_PER_CYCLE 600 12 | 13 | #define SAMPLES_PER_CYCLE_FIXEDPOINT (SAMPLES_PER_CYCLE<<20) 14 | #define TICKS_PER_CYCLE (float)((float)SAMPLES_PER_CYCLE_FIXEDPOINT/(float)SAMPLE_RATE) 15 | 16 | 17 | // This class represents a voice of synth. It can have several oscillators 18 | class Osc 19 | { 20 | 21 | public: 22 | int32_t volglb; // Volume global 23 | int32_t volglbsave; // Volume global temporary save 24 | uint16_t waveform[NUM_OSC]; // Waveform of each oscillator 25 | int32_t volosc[NUM_OSC]; // Volume of each oscillator 26 | float fine[NUM_OSC]; // Fine of each oscillator 27 | uint32_t ulPhaseAccumulator[NUM_OSC]; // Position in the reading of each oscillator table 28 | volatile uint32_t ulPhaseIncrement[NUM_OSC] ; // Reading speed of each oscillaotr table 29 | int8_t octave[NUM_OSC]; // Octave of each oscillator 30 | 31 | //GLIDE 32 | uint8_t noteplaying; // true : a note is already playing - false : no note is playing 33 | boolean glideon; // true : glide is ON - false : glide is OFF 34 | boolean glidestart; // true : glide already started - false : glide is not started 35 | boolean play; 36 | uint32_t glidetime; // glide time in ms 37 | uint32_t Incrementglide[NUM_OSC]; // glide speed 38 | uint32_t Incrementfin[NUM_OSC]; // target frequency 39 | 40 | 41 | float fFrequency; 42 | 43 | // initialize the synth. Here you can put your default values. 44 | void init() 45 | { 46 | volglb = 0; 47 | volglbsave = 0; 48 | 49 | waveform[0] = 0; 50 | volosc[0] = 64; 51 | fine[0] = 0; 52 | 53 | waveform[1] = 0; 54 | volosc[1] = 0; 55 | fine[1] = 0; 56 | 57 | waveform[2] = 0; 58 | volosc[2] = 0; 59 | fine[2] = 0; 60 | 61 | ulPhaseAccumulator[0] = 0; 62 | ulPhaseAccumulator[1] = 0; 63 | ulPhaseAccumulator[2] = 0; 64 | 65 | ulPhaseIncrement[0] = 0; 66 | ulPhaseIncrement[1] = 0; 67 | ulPhaseIncrement[2] = 0; 68 | 69 | octave[0] = 0; 70 | octave[1] = 0; 71 | octave[2] = -1; 72 | 73 | //GLIDE 74 | glideon = false; 75 | glidestart = false; 76 | Incrementglide[0]=0; 77 | Incrementfin[0]=0; 78 | Incrementglide[1]=0; 79 | Incrementfin[1]=0; 80 | Incrementglide[2]=0; 81 | Incrementfin[2]=0; 82 | noteplaying = 0; 83 | glidetime = 1000; // (en ms) 84 | play = false; 85 | } 86 | 87 | void setFrequency(uint32_t note) 88 | { 89 | for(int i=0; i>1; 139 | } 140 | 141 | // Set the waveform of one oscillator 142 | void setWaveform(uint8_t num, uint32_t val) 143 | { 144 | if(val<40) waveform[num] = 0; 145 | if(val>=40&&val<80) waveform[num] = 1; 146 | if(val>=80) waveform[num] = 2; 147 | } 148 | 149 | // Set the fine tune of one oscillator 150 | void setFine(uint8_t num, uint32_t val) 151 | { 152 | fine[num] = val; 153 | } 154 | 155 | //Set the glide time 156 | void setGlideTime(uint32_t glt) 157 | { 158 | glidetime = glt * 10+1; 159 | } 160 | 161 | // Compute the table position in the wavetable from increment values 162 | void next() 163 | { 164 | for(int i=0; i SAMPLES_PER_CYCLE_FIXEDPOINT) 168 | { 169 | ulPhaseAccumulator[i] -= SAMPLES_PER_CYCLE_FIXEDPOINT; 170 | } 171 | if(ulPhaseIncrement[i]Incrementfin[i]) 180 | { 181 | if((ulPhaseIncrement[i]-Incrementfin[i])<=Incrementglide[i]) 182 | { 183 | ulPhaseIncrement[i] = Incrementfin[i]; 184 | } 185 | else ulPhaseIncrement[i] -= Incrementglide[i]; 186 | } 187 | } 188 | } 189 | 190 | //Return the sample value from the wavetable 191 | int32_t output() 192 | { 193 | int32_t ret=0; 194 | for(int i=0; i>20]* volosc[i])>>7; 197 | if(waveform[i] == 1) ret+= (nSawTable[ulPhaseAccumulator[i]>>20]* volosc[i])>>7; 198 | if(waveform[i] == 2) ret+= (nSqTable[ulPhaseAccumulator[i]>>20]* volosc[i])>>7; 199 | } 200 | return ret; 201 | } 202 | 203 | }; 204 | -------------------------------------------------------------------------------- /sampler.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const int chipSelect = 10; // For Due, the SS of SD Card is on pin 10. See SdFat library 4 | const int bufsize = 1024; // buffer size in bytes. You can change this data. 5 | 6 | // Put here the filenames of your samples on SD card 7 | const char* samplefile[]= {"kick1.wav", "hithat1.wav", "snare1.wav", "snare2.wav"}; 8 | 9 | // Header of a wave file. 10 | // Num_channels will tell us if we are in stereo (2) or mono (1) 11 | typedef struct { 12 | char RIFF[4]; 13 | int32_t chunk_size; 14 | char WAVE[4]; 15 | char fmt_[4]; 16 | int32_t subchunk1_size; 17 | int16_t audio_format; 18 | int16_t num_channels; 19 | int32_t sample_rate; 20 | int32_t byte_rate; 21 | int16_t block_align; 22 | int16_t bits_per_sample; 23 | char DATA[4]; 24 | int32_t subchunk2_size; 25 | } wave_header; 26 | 27 | 28 | 29 | // Here is our sampler class 30 | class Sampler 31 | { 32 | 33 | public: 34 | uint32_t volglobal; // volume max of the sample (when sustain) 35 | boolean play; // is the sample playing or not ? 36 | int indbuf; // buffer number 37 | uint16_t bufread; // buffer being read number 38 | uint16_t lastbuf; // last buffer read number 39 | int16_t buf[2][bufsize]; // buffer 40 | uint32_t possample; // sample position 41 | uint32_t endofsample; // end of sample 42 | uint32_t decrease; // decrease speed 43 | uint16_t samplenote; // sample note 44 | 45 | SdFile myFile; // The wave file 46 | wave_header header; // The wave header 47 | 48 | boolean openfile ; // Are we opening file ? 49 | boolean closefile ; // Are we closing file ? 50 | const char* samplen; // Storing the sample name 51 | 52 | int16_t patternplaying; // The pattern which is currently playing the sample 53 | 54 | 55 | // Init of the sampler object. Here you can put your default values. 56 | void init() 57 | { 58 | indbuf =0; 59 | bufread = 0; 60 | lastbuf = 0; 61 | play = false; 62 | volglobal = 800; 63 | openfile = false; 64 | closefile = false; 65 | patternplaying = -1; 66 | } 67 | 68 | // Play the sample, giving volume and note (volume 0-1024; note 0-128) 69 | void splay(uint32_t vol, uint16_t note) 70 | { 71 | 72 | play=true; 73 | volglobal = vol; 74 | samplenote=note; 75 | } 76 | 77 | // load the wave header in the header data, and the beginning of the wave file in the buffer. 78 | void load(const char* samplename) 79 | { 80 | bufread = 0; 81 | lastbuf = 0; 82 | possample = 0; 83 | samplen = samplename; 84 | closefile = false; 85 | openfile = true; 86 | } 87 | 88 | //Stop playing the sample 89 | void sstop() 90 | { 91 | if(play) 92 | { 93 | closefile = true; 94 | } 95 | } 96 | 97 | 98 | // Set the volume of the sample 99 | void setVol(uint32_t vol) 100 | { 101 | volglobal = vol; 102 | } 103 | 104 | //Set the end of the sample 105 | void setEnd(uint32_t theEnd) 106 | { 107 | endofsample = (endofsample*theEnd)>>7; 108 | } 109 | 110 | // Fill the buffer if it has to be. 111 | // This method must not be called in the main program loop. 112 | // The return of the method indicates that it is reading a sound file 113 | boolean buffill() 114 | { 115 | boolean ret = false; 116 | if(play) 117 | { 118 | // The buffer must be filled only if the previous buffer was finished to be read 119 | if(bufread==lastbuf) 120 | { 121 | ret = true; 122 | // If we the sample read has arrived to the end of the file, we must stop the sample reading 123 | if(possample>=(endofsample-bufsize)) closefile=true; 124 | 125 | // OPEN FILE 126 | if(openfile) 127 | { 128 | myFile.open(samplen, O_READ); 129 | myFile.read(&header, sizeof(header)); 130 | endofsample = header.chunk_size-bufsize; 131 | myFile.read(buf[0], sizeof(buf[0])); 132 | possample = sizeof(buf[0]) + sizeof(header); 133 | openfile = false; 134 | } 135 | else 136 | { 137 | // CLOSE FILE 138 | if(closefile) 139 | { 140 | myFile.close(); 141 | play = false; 142 | } 143 | //READ FILE 144 | else 145 | { 146 | if(lastbuf==0) lastbuf = 1; 147 | else lastbuf = 0; 148 | 149 | int me = myFile.read(buf[lastbuf], sizeof(buf[lastbuf])); 150 | possample += sizeof(buf[lastbuf]); 151 | // If there is an error while reading sample file, we stop the reading and close the file 152 | if(me<=0) 153 | { 154 | play = false; 155 | myFile.close(); 156 | } 157 | } 158 | } 159 | } 160 | } 161 | return ret; 162 | } 163 | 164 | 165 | // Compute the position of the next sample. Must be called in the sound generating loop, before the method "output()" 166 | void next() 167 | { 168 | if(play) 169 | { 170 | // If the wave file is stereo, we take only one side (left). 171 | indbuf += header.num_channels; 172 | 173 | // The reading of the file must stop at the end of file. 174 | if(possample>=(endofsample-bufsize)) 175 | { 176 | closefile = true; 177 | } 178 | 179 | // If a buffer is finished to be read, we read the other buffer. 180 | if(indbuf>=bufsize) 181 | { 182 | if(bufread==0) bufread = 1; 183 | else bufread = 0; 184 | 185 | indbuf=0; 186 | } 187 | } 188 | } 189 | 190 | // Read the wave file at a position. Returns the volume (12 bits) 191 | int16_t output() 192 | { 193 | int16_t ret=0; 194 | 195 | if(play) 196 | { 197 | ret = ((buf[bufread][indbuf]>>4)*volglobal)>>7; 198 | } 199 | 200 | return ret; 201 | } 202 | }; 203 | -------------------------------------------------------------------------------- /samplerl.h: -------------------------------------------------------------------------------- 1 | // If you want to play only one sample per voice, use this samplerl.h 2 | // Else, if you want to swap between several samples on the same voice, use sampler.h 3 | 4 | #include 5 | 6 | const int chipSelect = 10; 7 | const int bufsize = 1024; 8 | uint16_t n = 4; 9 | 10 | const char* samplefile[]= {"kick1.wav","hithat1.wav" , "snare1.wav","snare2.wav", "kick2.wav", "snare3.wav" }; 11 | 12 | bool readChunk(void* buf, uint32_t startBlock, uint16_t blockCount) 13 | { 14 | uint8_t* dst = (uint8_t*)buf; 15 | if(!sd.card()->readStart(startBlock)) return false; 16 | for(uint16_t i = 0; i < blockCount; i++) 17 | { 18 | if(!sd.card()->readData(dst + i*512L)) return false; 19 | } 20 | return sd.card()->readStop(); 21 | } 22 | 23 | 24 | class Samplerl 25 | { 26 | 27 | public: 28 | uint32_t volglobal; 29 | uint32_t ulPhaseAccumulator; 30 | volatile uint32_t ulPhaseIncrement ; 31 | boolean play; 32 | int indbuf; 33 | uint16_t bufread; 34 | uint16_t lastbuf; 35 | int16_t buf[2][bufsize]; 36 | 37 | uint32_t bgnBlock; 38 | uint32_t posBlock; 39 | uint32_t endBlock; 40 | 41 | uint32_t endData; 42 | uint32_t posData; 43 | uint32_t bgnData; 44 | 45 | SdFile myFile; 46 | 47 | boolean openfile ; 48 | boolean closefile ; 49 | const char* samplen; 50 | 51 | 52 | void init() 53 | { 54 | ulPhaseAccumulator = 0; 55 | indbuf =0; 56 | bufread = 0; 57 | lastbuf = 0; 58 | ulPhaseIncrement = 1; 59 | play = false; 60 | volglobal = 800; 61 | openfile = false; 62 | closefile = false; 63 | } 64 | 65 | 66 | void splay(uint32_t vol) 67 | { 68 | bufread = 0; 69 | lastbuf = 0; 70 | 71 | openfile=true; 72 | volglobal = vol; 73 | 74 | posData = 0; 75 | posBlock = bgnBlock; 76 | indbuf = bgnData; 77 | } 78 | 79 | 80 | void load(const char* samplename) 81 | { 82 | bufread = 0; 83 | lastbuf = 0; 84 | samplen = samplename; 85 | 86 | myFile.open(samplen, O_READ); 87 | Serial.println(myFile.contiguousRange(&bgnBlock, &endBlock)); 88 | 89 | posBlock = bgnBlock; 90 | 91 | readChunk(buf[0], posBlock, n); 92 | 93 | int dataind=18; 94 | 95 | if((char)(buf[0][18]&0x00ff) != 'd') 96 | { 97 | for (int i = 18; i < 1023; i++) { 98 | if((char)(buf[0][i]&0x00ff)=='d') if((char)((buf[0][i]&0xff00)>>8)=='a') {dataind = i; i=1025;} 99 | if((char)((buf[0][i]&0xff00)>>8)=='d') if((char)(buf[0][i+1]&0x00ff)=='a') {dataind = i; i=1025;} 100 | } 101 | endData = ((uint16_t)buf[0][dataind+2])>>1; 102 | } 103 | else endData = ((uint16_t)buf[0][20])>>1; 104 | 105 | bgnData = dataind+4; // the buffer is 1024 16 bits integer long. So 4 x 512 bytes. (4 blocks) 106 | posData = 0; 107 | indbuf = bgnData; 108 | 109 | posBlock +=4; 110 | 111 | volglobal = 0; 112 | 113 | } 114 | 115 | 116 | void sstop() 117 | { 118 | play=false; 119 | } 120 | 121 | void setVol(uint32_t vol) 122 | { 123 | volglobal = vol; 124 | } 125 | 126 | boolean buffill() 127 | { 128 | boolean ret = false; 129 | if(play||openfile) 130 | { 131 | if(bufread==lastbuf) 132 | { 133 | ret = true; 134 | if(lastbuf==0) lastbuf = 1; 135 | else lastbuf = 0; 136 | 137 | readChunk(buf[lastbuf], posBlock, n); 138 | posBlock +=4; 139 | 140 | if(openfile) 141 | { 142 | play = true; 143 | openfile=false; 144 | } 145 | } 146 | } 147 | return ret; 148 | } 149 | 150 | 151 | 152 | void next() 153 | { 154 | if(play) 155 | { 156 | 157 | indbuf ++; 158 | posData ++; 159 | 160 | if(posData>=(endData)) play = false; 161 | 162 | if(indbuf>=bufsize) 163 | { 164 | if(bufread==0) bufread = 1; 165 | else bufread = 0; 166 | indbuf=0; 167 | } 168 | } 169 | } 170 | 171 | int16_t output() 172 | { 173 | int16_t ret=0; 174 | if(play) ret = ((buf[bufread][indbuf]>>4)*volglobal)>>7; 175 | return ret; 176 | } 177 | }; 178 | -------------------------------------------------------------------------------- /sequencer.h: -------------------------------------------------------------------------------- 1 | boolean noteon[96]; 2 | uint8_t seqvol[96]; 3 | uint8_t seqpit[96]; 4 | uint8_t seqlen[96]; 5 | uint8_t durrest; 6 | 7 | 8 | 9 | void init_step() 10 | { 11 | for(int i=0; i<96; i++) 12 | { 13 | noteon[i] = false; 14 | seqvol[i] = 0; 15 | seqpit[i] = 0; 16 | seqlen[i] = 0; 17 | } 18 | 19 | noteon[0] = true; 20 | seqvol[0] = 100; 21 | seqpit[0] = 50; 22 | seqlen[0] = 8; 23 | noteon[15] = true; 24 | seqvol[15] = 100; 25 | seqpit[15] = 50; 26 | seqlen[15] = 8; 27 | noteon[31] = true; 28 | seqvol[31] = 100; 29 | seqpit[31] = 50; 30 | seqlen[31] = 8; 31 | } 32 | -------------------------------------------------------------------------------- /tables.h: -------------------------------------------------------------------------------- 1 | #define SAMPLE_RATE 44100.0 2 | #define SAMPLES_PER_CYCLE 600 3 | #define SAMPLES_PER_CYCLE_FIXEDPOINT (SAMPLES_PER_CYCLE<<20) 4 | #define TICKS_PER_CYCLE (float)((float)SAMPLES_PER_CYCLE_FIXEDPOINT/(float)SAMPLE_RATE) 5 | 6 | #define WAVE_SAMPLES 600 7 | int16_t nSineTable[WAVE_SAMPLES]; 8 | int16_t nSawTable[WAVE_SAMPLES]; 9 | int16_t nSqTable[WAVE_SAMPLES]; 10 | 11 | #define MIDI_NOTES 128 12 | uint32_t nMidiPhaseIncrement[MIDI_NOTES]; 13 | 14 | 15 | void createSineTable() 16 | { 17 | for(uint32_t nIndex = 0;nIndex < WAVE_SAMPLES;nIndex++) 18 | { 19 | // normalised to 12 bit range 0-4095 20 | nSineTable[nIndex] = (int16_t) ((sin(((2.0*PI)/WAVE_SAMPLES)*nIndex))*2048.0); 21 | } 22 | } 23 | 24 | void createSawTable() 25 | { 26 | for(uint32_t nIndex = 0;nIndex < WAVE_SAMPLES;nIndex++) 27 | { 28 | nSawTable[nIndex] = (uint16_t) (nIndex*(4095.0/600)-2048); 29 | } 30 | } 31 | 32 | void createSqTable() 33 | { 34 | for(uint32_t nIndex = 0; nIndex < WAVE_SAMPLES; nIndex++) 35 | { 36 | if(nIndex<(WAVE_SAMPLES/2)) nSqTable[nIndex] = -2048; 37 | if(nIndex>=(WAVE_SAMPLES/2)) nSqTable[nIndex] = 2047; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /timer.h: -------------------------------------------------------------------------------- 1 | uint32_t bpm = 120; 2 | 3 | void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) 4 | { 5 | pmc_set_writeprotect(false); 6 | pmc_enable_periph_clk((uint32_t)irq); 7 | TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); 8 | uint32_t rc = VARIANT_MCK/128/frequency; 9 | TC_SetRA(tc, channel, rc/2); 10 | TC_SetRC(tc, channel, rc); 11 | TC_Start(tc, channel); 12 | tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS; 13 | tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS; 14 | NVIC_EnableIRQ(irq); 15 | } 16 | 17 | void setFrequency(Tc *tc, uint32_t channel, uint32_t frequency) 18 | { 19 | uint32_t rc = VARIANT_MCK/128/frequency; 20 | TC_SetRA(tc, channel, rc/2); 21 | TC_SetRC(tc, channel, rc); 22 | TC_Start(tc, channel); 23 | } 24 | 25 | void setTimerBPM() 26 | { 27 | uint32_t bps = bpm*16/60; 28 | setFrequency(TC1, 0, bps); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /waveforms/clavinet01.h: -------------------------------------------------------------------------------- 1 | uint16_t clavinet01[]={2259,2526,2730,2922,3111,3326,3513,3695,3867,4003,4087,4095,4031,3926,3818,3658,3484,3338,3246,3180,3096,2975,2829,2675,2604,2548,2552,2530,2540,2514,2501,2505,2493,2479,2463,2433,2437,2492,2572,2656,2749,2743,2672,2542,2337,2139,1915,1726,1569,1493,1519,1613,1766,2015,2244,2492,2697,2862,3001,3114,3176,3179,3119,3008,2912,2854,2851,2906,2956,2986,2974,2903,2806,2677,2539,2339,2157,1948,1738,1511,1314,1125,945,829,751,705,719,707,731,742,825,916,1042,1143,1204,1243,1222,1203,1195,1182,1192,1231,1295,1365,1480,1577,1640,1635,1588,1513,1380,1252,1150,1053,977,963,999,1079,1200,1357,1495,1672,1795,1894,1939,1944,1898,1815,1742,1622,1519,1390,1276,1192,1125,1105,1105,1122,1153,1202,1269,1370,1442,1546,1620,1720,1783,1860,1944,1985,2035,2086,2147,2223,2244,2268,2266,2266,2258,2263,2258,2245,2252,2249,2242,2261,2298,2316,2332,2347,2364,2378,2381,2354,2336,2322,2331,2334,2322,2335,2329,2329,2326,2352,2374,2396,2382,2363,2337,2336,2337,2347,2333,2317,2314,2328,2336,2359,2399,2425,2442,2433,2432,2444,2421,2407,2408,2385,2389,2415,2403,2390,2371,2381,2383,2379,2360,2328,2277,2266,2250,2238,2219,2190,2157,2125,2085,2094,2104,2110,2086,2088,2064,2067,2065,2060,2022,2024,2011,1995,1980,1964,1950,1924,1920,1927,1960,1957,1958,1954,1955,1976,1979,1978,1959,1955,1952,1955,1972,2007,2062,2092,2106,2106,2095,2090,2094,2084,2088,2049,2039,2050,2076,2063,2020,2005,2028,2021,2025,1997,1981,1973,1998,1974,1978,1976,1978,1976,1979,1984,2018,2057,2063,2052,2089,2103,2115,2110,2077,2050,2068,2086,2084,2067,2054,2048,2052,2090,2121,2138,2103,2069,2053,2094,2138,2159,2137,2083,2088,2120,2175,2197,2218,2201,2191,2202,2220,2217,2186,2140,2106,2093,2080,2082,2064,2034,2016,2047,2078,2088,2048,2029,2002,2029,2030,2010,1971,1973,2011,2031,2043,2056,2069,2086,2039,2042,2052,2069,2048,2024,1989,2008,2011,1984,1972,1972,1993,1968,1954,1956,1975,2008,2008,1985,1988,2001,2007,2024,2026,2028,2026,2003,2002,2018,2061,2075,2062,2041,2023,2051,2105,2100,2065,2006,1968,1973,2009,2011,1996,1982,1992,2030,2055,2068,2056,2008,1974,2016,2094,2107,2073,2025,2010,2020,2049,2039,2025,1989,2009,2023,2067,2102,2099,2077,2019,1989,1953,1971,1977,1946,1923,1970,2053,2118,2131,2127,2126,2156,2164,2147,2093,1991,1935,1875,1884,1892,1932,1909,1901,1919,2000,2136,2194,2217,2218,2265,2347,2402,2454,2511,2520,2475,2377,2245,2191,2173,2163,2171,2139,2101,2115,2160,2208,2210,2129,2011,1889,1888,1996,2088,2074,1979,1913,1960,2087,2239,2271,2192,2135,2149,2209,2253,2160,1997,1787,1623,1587,1661,1745,1861,1994,2101,2242,2382,2416,2378,2257,2187,2142,2084,2041,1973,2009,2117,2329,2531,2720,2877,2932,2931,2886,2805,2640,2376,1988,1625,1341,1135,947,805,693,623,549,542,551,652,777,881,964,1050,1165,1331,1506,1613,1572,1500,1443,1548,1750,1984,2133,2175,2118,2102,2146,2183,2136,1921,1710,1569,1613,1715,1799,1812,1811,1877,2035,2268,2461,2606,2701,2751,2764,2730,2634,2465,2278,2109,1942,1808,1691,1577,1479,1455,1429,1410,1360,1304,1243,1212,1186,1174,1141,1091,1058,1100,1214,1420,1667,1965}; 2 | -------------------------------------------------------------------------------- /waveforms/ebass01.h: -------------------------------------------------------------------------------- 1 | uint16_t ebass01[]={2061,2086,2142,2167,2223,2264,2289,2345,2370,2426,2450,2505,2529,2567,2622,2644,2697,2734,2754,2790,2842,2877,2896,2931,2965,3016,3050,3083,3117,3150,3183,3200,3232,3265,3297,3328,3375,3405,3435,3465,3477,3505,3548,3559,3584,3625,3633,3672,3694,3700,3736,3756,3760,3778,3797,3814,3848,3865,3882,3898,3914,3930,3946,3961,3976,3975,3989,4002,4031,4042,4037,4063,4072,4064,4071,4092,4081,4084,4086,4087,4087,4087,4085,4083,4080,4092,4088,4068,4079,4074,4053,4048,4059,4037,4032,4043,4021,4031,4025,4002,4011,3987,3994,3969,3959,3963,3936,3923,3909,3895,3896,3880,3847,3830,3812,3793,3790,3771,3735,3714,3710,3689,3652,3646,3625,3588,3582,3560,3521,3514,3475,3468,3428,3419,3378,3369,3343,3300,3289,3262,3219,3191,3179,3151,3107,3079,3067,3039,2995,2984,2956,2913,2886,2876,2833,2807,2797,2756,2746,2704,2679,2669,2627,2617,2590,2547,2519,2507,2479,2434,2404,2374,2360,2330,2300,2269,2238,2192,2162,2132,2102,2089,2060,2016,1988,1977,1950,1909,1900,1859,1852,1813,1792,1787,1751,1731,1712,1711,1693,1677,1661,1646,1631,1601,1588,1575,1578,1566,1539,1545,1535,1509,1516,1491,1499,1476,1484,1462,1471,1466,1444,1455,1450,1430,1426,1438,1435,1432,1413,1411,1410,1409,1408,1408,1408,1409,1410,1412,1415,1434,1439,1428,1449,1440,1447,1471,1463,1472,1498,1493,1519,1531,1526,1538,1566,1578,1574,1586,1614,1625,1619,1645,1638,1662,1653,1675,1664,1667,1669,1670,1670,1668,1665,1676,1654,1662,1637,1643,1631,1602,1588,1573,1557,1539,1521,1518,1498,1461,1440,1434,1395,1388,1349,1341,1300,1291,1250,1240,1214,1171,1143,1132,1088,1059,1030,1017,987,957,927,881,850,819,788,757,726,695,663,649,618,587,557,512,483,455,443,401,375,367,344,306,302,283,266,250,237,209,199,207,201,181,180,181,200,206,199,209,239,255,257,278,317,327,356,386,420,455,509,533,591,635,681,729,779,831,868,939,979,1053,1112,1155,1216,1294,1357,1420,1484,1549,1613,1679,1728,1794,1859,1925,1990,2055,2136,2200,2264,2311,2374,2435,2496,2571,2613,2686,2726,2796,2833,2884,2934,2982,3029,3073,3132,3157,3213,3234,3270,3303,3335,3364,3392,3434,3442,3463,3499,3516,3532,3545,3541,3566,3557,3579,3582,3583,3582,3579,3558,3567,3543,3548,3535,3505,3489,3487,3467,3430,3423,3382,3372,3329,3300,3269,3238,3205,3170,3150,3113,3059,3036,2980,2955,2896,2854,2826,2781,2720,2674,2628,2581,2533,2486,2437,2389,2340,2291,2241,2192,2158,2108,2059,2009,1960,1894,1845,1796,1747,1699,1651,1603,1556,1510,1480,1434,1389,1329,1285,1258,1200,1158,1133,1076,1053,998,975,938,885,849,830,796,762,730,698,667,637,593,565,554,512,487,464,457,420,400,396,378,361,345,331,317,288,277,282,257,265,241,251,230,225,238,236,235,235,235,237,224,229,250,240,247,256,281,276,303,316,329,327,342,358,375,408,426,445,449,469,506,512,535,574,582,622,648,658,701,728,741,770,800,847,879,911,928,961,995,1030,1081,1116,1136,1172,1224,1261,1281,1318,1371,1392,1430,1483,1505,1543,1597,1619,1674,1697,1752,1776,1832,1857,1913,1938,1993,2028}; 2 | --------------------------------------------------------------------------------