#include #include #include #include #include #include #include // #include conflicts with Adafruit_NeoTrellisM4.h due to MIDI USB #define BPM 160 // GUItool: begin automatically generated code AudioPlayFSWav playMem1; //xy=275,499 AudioPlayFSWav playMem2; //xy=284,532.5 AudioPlayFSWav playMem3; //xy=294,566.5 AudioPlayFSWav playMem4; //xy=302,599.5 AudioMixer4 mixer1; //xy=491,517 AudioSynthWaveformDc dc1; //xy=507,581 AudioFilterStateVariable filter1; //xy=649,502 AudioOutputAnalogStereo dacs1; //xy=830,510 AudioConnection patchCord1(playMem1, 0, mixer1, 0); AudioConnection patchCord2(playMem2, 0, mixer1, 1); AudioConnection patchCord3(playMem3, 0, mixer1, 2); AudioConnection patchCord4(playMem4, 0, mixer1, 3); AudioConnection patchCord5(mixer1, 0, filter1, 0); AudioConnection patchCord6(dc1, 0, dacs1, 1); AudioConnection patchCord7(filter1, 0, dacs1, 0); // GUItool: end automatically generated code //Flash memory stuff Adafruit_FlashTransport_QSPI flashTransport(PIN_QSPI_SCK, PIN_QSPI_CS, PIN_QSPI_IO0, PIN_QSPI_IO1, PIN_QSPI_IO2, PIN_QSPI_IO3); Adafruit_SPIFlash flash(&flashTransport); FatFileSystem fatfs; /*FatFile root; //related to USB Mass Storage FatFile file; Adafruit_USBD_MSC usb_msc;*/ Adafruit_NeoTrellisM4 trellis = Adafruit_NeoTrellisM4(); Adafruit_ADXL343 accel = Adafruit_ADXL343(50, &Wire1); //50 does not mean anything here, just a random id int colors[] = { 0x180000, 0x100800, 0x180000, 0x100800 }; int timeToClick; int G1[] = {0,1,8,9,16,17,24,25}; int G2[] = {2,3,10,11,18,19,26,27}; int G3[] = {4,5,12,13,20,21,28,29}; int G4[] = {6,7,14,15,22,23,30,31}; int G1Select = 7; int G1Trigger = 0; int G2Select = 7; int G2Trigger = 0; int G3Select = 7; int G3Trigger = 0; int G4Select = 7; int G4Trigger = 0; int EighthNote = 60000 / (BPM * 2); int clickOn; //bool USBFlash = false; File sample1; File sample2; File sample3; File sample4; void setup() { Serial.begin(115200); trellis.begin(); trellis.setBrightness(127); accel.begin(); AudioMemory(32); redrawAndPlay(); filter1.resonance(2.2); //from 0.7 to 5 flash.begin(); /*if (USBFlash) { //related to USB Mass Storage usb_msc.setID("Adafruit", "External Flash", "1.0"); usb_msc.setReadWriteCallback(msc_read_cb, msc_write_cb, msc_flush_cb); usb_msc.setCapacity(flash.size()/512, 512); usb_msc.setUnitReady(true); usb_msc.begin(); }*/ fatfs.begin(&flash); }; void clockTick(){ if(millis() >= timeToClick) { timeToClick = millis() + EighthNote; //214 should be ~1/8 at 140 bpm //Serial.println(timeToClick); dc1.amplitude(1); //turn Korg click on clickOn = millis(); updatePlay(); } } void clickOff() { if (millis()-clickOn>15) { dc1.amplitude(0); //turn Korg click off } } void updatePlay() { //if there's less than 30ms until the end of the sample, retriger it to prevent gap if (playMem1.lengthMillis() - playMem1.positionMillis() < 30) { G1Trigger = 1; } if (G1Select < 7 && G1Trigger == 1) { G1Trigger = 0; switch (G1Select) { case 6: sample1 = fatfs.open("G1_1.wav"); playMem1.play(sample1); break; case 4: sample1 = fatfs.open("G1_2.wav"); playMem1.play(sample1); break; case 2: sample1 = fatfs.open("G1_3.wav"); playMem1.play(sample1); break; case 0: sample1 = fatfs.open("G1_4.wav"); playMem1.play(sample1); break; case 1: sample1 = fatfs.open("G1_5.wav"); playMem1.play(sample1); break; case 3: sample1 = fatfs.open("G1_6.wav"); playMem1.play(sample1); break; case 5: sample1 = fatfs.open("G1_7.wav"); playMem1.play(sample1); break; } } if (playMem2.lengthMillis() - playMem2.positionMillis() < 30) { G2Trigger = 1; } if (G2Select < 7 && G2Trigger == 1) { G2Trigger = 0; switch (G2Select) { case 6: sample2 = fatfs.open("G2_1.wav"); playMem2.play(sample2); break; case 4: sample2 = fatfs.open("G2_2.wav"); playMem2.play(sample2); break; case 2: sample2 = fatfs.open("G2_3.wav"); playMem2.play(sample2); break; case 0: sample2 = fatfs.open("G2_4.wav"); playMem2.play(sample2); break; case 1: sample2 = fatfs.open("G2_5.wav"); playMem2.play(sample2); break; case 3: sample2 = fatfs.open("G2_6.wav"); playMem2.play(sample2); break; case 5: sample2 = fatfs.open("G2_7.wav"); playMem2.play(sample2); break; } } if (playMem3.lengthMillis() - playMem3.positionMillis() < 30) { G3Trigger = 1; } if (G3Select < 7 && G3Trigger == 1) { G3Trigger = 0; switch (G3Select) { case 6: sample3= fatfs.open("G3_1.wav"); playMem3.play(sample3); break; case 4: sample3= fatfs.open("G3_2.wav"); playMem3.play(sample3); break; case 2: sample3= fatfs.open("G3_3.wav"); playMem3.play(sample3); break; case 0: sample3= fatfs.open("G3_4.wav"); playMem3.play(sample3); break; case 1: sample3= fatfs.open("G3_5.wav"); playMem3.play(sample3); break; case 3: sample3= fatfs.open("G3_6.wav"); playMem3.play(sample3); break; case 5: sample3= fatfs.open("G3_7.wav"); playMem3.play(sample3); break; } } if (playMem4.lengthMillis() - playMem4.positionMillis() < 30) { G4Trigger = 1; } if (G4Select < 7 && G4Trigger == 1) { G4Trigger = 0; switch (G4Select) { case 6: sample4= fatfs.open("G4_1.wav"); playMem4.play(sample4); break; case 4: sample4= fatfs.open("G4_2.wav"); playMem4.play(sample4); break; case 2: sample4= fatfs.open("G4_3.wav"); playMem4.play(sample4); break; case 0: sample4= fatfs.open("G4_4.wav"); playMem4.play(sample4); break; case 1: sample4= fatfs.open("G4_5.wav"); playMem4.play(sample4); break; case 3: sample4= fatfs.open("G4_6.wav"); playMem4.play(sample4); break; case 5: sample4= fatfs.open("G4_7.wav"); playMem4.play(sample4); break; } } } void redrawAndPlay() { for (int r=0; r<4; r++) { for (int c=0; c<4; c++) { for (int g=0; g<2; g++) { if (r==3 && g==1) { trellis.setPixelColor(c*2 + g + r*8, 0x000000); } else { trellis.setPixelColor(c*2 + g + r*8, colors[c]); } }; }; }; if (G1Select != 7) { trellis.setPixelColor(G1[G1Select], 0x333333); } else { playMem1.stop(); trellis.setPixelColor(G1[G1Select], 0x000000); } if (G2Select != 7) { trellis.setPixelColor(G2[G2Select], 0x333333); } else { playMem2.stop(); trellis.setPixelColor(G2[G2Select], 0x000000); } if (G3Select != 7) { trellis.setPixelColor(G3[G3Select], 0x333333); } else { playMem3.stop(); trellis.setPixelColor(G3[G3Select], 0x000000); } if (G4Select != 7) { trellis.setPixelColor(G4[G4Select], 0x333333); } else { playMem4.stop(); trellis.setPixelColor(G4[G4Select], 0x000000); } } /*Flash related functions int32_t msc_read_cb (uint32_t lba, void* buffer, uint32_t bufsize) { return flash.readBlocks(lba, (uint8_t*) buffer, bufsize/512) ? bufsize : -1; } int32_t msc_write_cb (uint32_t lba, uint8_t* buffer, uint32_t bufsize) { digitalWrite(LED_BUILTIN, HIGH); return flash.writeBlocks(lba, buffer, bufsize/512) ? bufsize : -1; } void msc_flush_cb (void) { flash.syncBlocks(); fatfs.cacheClear(); }*/ void loop() { trellis.tick(); clockTick(); clickOff(); while (trellis.available()){ keypadEvent e = trellis.read(); if (e.bit.EVENT == KEY_JUST_PRESSED) { int key = e.bit.KEY; for (int i=0; i<8; i++) { if (key == G1[i]) { G1Select = i; G1Trigger = 1; redrawAndPlay(); break; } else if (key == G2[i]) { G2Select = i; G2Trigger = 1; redrawAndPlay(); break; } if (key == G3[i]) { G3Select = i; G3Trigger = 1; redrawAndPlay(); break; } else if (key == G4[i]) { G4Select = i; G4Trigger = 1; redrawAndPlay(); break; } } } } //Accelerometer and filter sensors_event_t event; accel.getEvent(&event); if (event.acceleration.y < 0) { filter1.frequency(1000 * (event.acceleration.y+10)); } else { filter1.frequency(10000); } }