Code:
#include <Bounce.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
Bounce button0 = Bounce(25, 15);
Bounce button1 = Bounce(26, 15);
Bounce button2 = Bounce(27, 15);
Bounce button3 = Bounce(28, 15);
Bounce button4 = Bounce(29, 15);
Bounce button5 = Bounce(30, 15);
Bounce button6 = Bounce(31, 15);
Bounce button7 = Bounce(32, 15);
// Include USBHost Library
#include <USBHost_t36.h>
USBHost myusb;
MIDIDevice midi1(myusb);
// GUItool: begin automatically generated code
AudioSynthWaveformModulated osc1a; //xy=390.6000061035156,161.00000190734863
AudioSynthWaveformModulated osc1b; //xy=390.6000061035156,197.00000190734863
AudioSynthWaveformModulated osc3a; //xy=390.6000061035156,344
AudioSynthWaveformModulated osc7a; //xy=389.6000061035156,751
AudioSynthWaveformModulated osc3b; //xy=391.6000061035156,381
AudioSynthWaveformModulated osc11a; //xy=388.6000061035156,1164
AudioSynthWaveformModulated osc11b; //xy=388.6000099182129,1199.000018119812
AudioSynthWaveformModulated osc7b; //xy=390.6000061035156,788
AudioSynthWaveformModulated osc4a; //xy=393.6000061035156,421
AudioSynthWaveformModulated osc8a; //xy=392.6000061035156,828
AudioSynthWaveformModulated osc12a; //xy=391.6000061035156,1241
AudioSynthWaveformModulated osc2a; //xy=395.6000061035156,265
AudioSynthWaveformModulated osc6a; //xy=394.6000061035156,672
AudioSynthWaveformModulated osc4b; //xy=395.6000061035156,459
AudioSynthWaveformModulated osc10a; //xy=393.6000099182129,1083.0000162124634
AudioSynthWaveformModulated osc8b; //xy=394.6000061035156,866
AudioSynthWaveformModulated osc12b; //xy=393.6000099182129,1277.0000190734863
AudioSynthWaveformModulated osc2b; //xy=397.6000061035156,300
AudioSynthWaveformModulated osc6b; //xy=396.6000061035156,707
AudioSynthWaveformModulated osc10b; //xy=395.6000061035156,1120
AudioSynthWaveformModulated osc5b; //xy=397.6000061035156,621
AudioSynthWaveformModulated osc9b; //xy=396.6000061035156,1034
AudioSynthWaveformModulated osc5a; //xy=398.6000061035156,587
AudioSynthWaveformModulated osc9a; //xy=397.6000061035156,1000
AudioSynthWaveformModulated osc15a; //xy=398.6000061035156,1568
AudioSynthWaveformModulated osc15b; //xy=399.6000061035156,1605
AudioSynthWaveformModulated osc16a; //xy=401.6000061035156,1645
AudioSynthWaveformModulated osc14a; //xy=403.6000061035156,1489
AudioSynthWaveformModulated osc16b; //xy=403.6000061035156,1683
AudioSynthWaveformModulated osc14b; //xy=405.6000061035156,1524
AudioSynthWaveformModulated osc13b; //xy=406.6000061035156,1438
AudioSynthWaveformModulated osc13a; //xy=407.6000061035156,1404
AudioMixer4 voice1Mixer; //xy=611.6000061035156,202
AudioMixer4 voice2Mixer; //xy=611.6000061035156,281
AudioMixer4 voice5Mixer; //xy=610.599983215332,607.0000095367432
AudioMixer4 voice6Mixer; //xy=610.599983215332,685.0000114440918
AudioMixer4 voice9Mixer; //xy=609.6000061035156,1022
AudioMixer4 voice10Mixer; //xy=609.6000061035156,1101
AudioMixer4 voice3Mixer; //xy=613.6000061035156,356
AudioMixer4 voice7Mixer; //xy=612.6000061035156,763
AudioMixer4 voice11Mixer; //xy=611.6000061035156,1176
AudioMixer4 voice4Mixer; //xy=614.6000061035156,431
AudioMixer4 voice8Mixer; //xy=613.6000061035156,838
AudioMixer4 voice12Mixer; //xy=612.6000061035156,1251
AudioMixer4 voice13Mixer; //xy=619.6000061035156,1426
AudioMixer4 voice14Mixer; //xy=619.6000061035156,1505
AudioMixer4 voice15Mixer; //xy=621.6000061035156,1580
AudioMixer4 voice16Mixer; //xy=622.6000061035156,1655
AudioEffectEnvelope envelope2; //xy=803.6000061035156,280
AudioEffectEnvelope envelope3; //xy=803.6000061035156,350
AudioEffectEnvelope envelope5; //xy=802.6000061035156,687
AudioEffectEnvelope envelope1; //xy=804.6000061035156,207
AudioEffectEnvelope envelope6; //xy=802.6000061035156,757
AudioEffectEnvelope envelope9; //xy=801.6000061035156,1100
AudioEffectEnvelope envelope7; //xy=803.6000061035156,614
AudioEffectEnvelope envelope10; //xy=801.6000061035156,1170
AudioEffectEnvelope envelope4; //xy=804.6000061035156,425
AudioEffectEnvelope envelope11; //xy=802.6000061035156,1027
AudioEffectEnvelope envelope8; //xy=803.6000061035156,832
AudioEffectEnvelope envelope12; //xy=802.6000061035156,1245
AudioEffectEnvelope envelope13; //xy=811.6000061035156,1504
AudioEffectEnvelope envelope14; //xy=811.6000061035156,1574
AudioEffectEnvelope envelope15; //xy=812.6000061035156,1431
AudioEffectEnvelope envelope16; //xy=812.6000061035156,1649
AudioMixer4 voiceMixer1; //xy=992.5999908447266,306.00000381469727
AudioMixer4 voiceMixer2; //xy=991.6000061035156,715
AudioMixer4 voiceMixer3; //xy=990.6000061035156,1128
AudioMixer4 voiceMixer4; //xy=1000.5999908447266,1530.0000228881836
AudioMixer4 lastMixer; //xy=1241.000015258789,877.0000152587891
AudioFilterStateVariable filter1; //xy=1408.600019454956,884.0000123977661
AudioOutputI2S i2s1; //xy=1610.6000213623047,883.0000133514404
AudioConnection patchCord1(osc1a, 0, voice1Mixer, 0);
AudioConnection patchCord2(osc1b, 0, voice1Mixer, 1);
AudioConnection patchCord3(osc3a, 0, voice3Mixer, 0);
AudioConnection patchCord4(osc7a, 0, voice7Mixer, 0);
AudioConnection patchCord5(osc3b, 0, voice3Mixer, 1);
AudioConnection patchCord6(osc11a, 0, voice11Mixer, 0);
AudioConnection patchCord7(osc11b, 0, voice11Mixer, 1);
AudioConnection patchCord8(osc7b, 0, voice7Mixer, 1);
AudioConnection patchCord9(osc4a, 0, voice4Mixer, 0);
AudioConnection patchCord10(osc8a, 0, voice8Mixer, 0);
AudioConnection patchCord11(osc12a, 0, voice12Mixer, 0);
AudioConnection patchCord12(osc2a, 0, voice2Mixer, 0);
AudioConnection patchCord13(osc6a, 0, voice6Mixer, 0);
AudioConnection patchCord14(osc4b, 0, voice4Mixer, 1);
AudioConnection patchCord15(osc10a, 0, voice10Mixer, 0);
AudioConnection patchCord16(osc8b, 0, voice8Mixer, 1);
AudioConnection patchCord17(osc12b, 0, voice12Mixer, 1);
AudioConnection patchCord18(osc2b, 0, voice2Mixer, 1);
AudioConnection patchCord19(osc6b, 0, voice6Mixer, 1);
AudioConnection patchCord20(osc10b, 0, voice10Mixer, 1);
AudioConnection patchCord21(osc5b, 0, voice5Mixer, 1);
AudioConnection patchCord22(osc9b, 0, voice9Mixer, 1);
AudioConnection patchCord23(osc5a, 0, voice5Mixer, 0);
AudioConnection patchCord24(osc9a, 0, voice9Mixer, 0);
AudioConnection patchCord25(osc15a, 0, voice15Mixer, 0);
AudioConnection patchCord26(osc15b, 0, voice15Mixer, 1);
AudioConnection patchCord27(osc16a, 0, voice16Mixer, 0);
AudioConnection patchCord28(osc14a, 0, voice14Mixer, 0);
AudioConnection patchCord29(osc16b, 0, voice16Mixer, 1);
AudioConnection patchCord30(osc14b, 0, voice14Mixer, 1);
AudioConnection patchCord31(osc13b, 0, voice13Mixer, 1);
AudioConnection patchCord32(osc13a, 0, voice13Mixer, 0);
AudioConnection patchCord33(voice1Mixer, envelope1);
AudioConnection patchCord34(voice2Mixer, envelope2);
AudioConnection patchCord35(voice5Mixer, envelope7);
AudioConnection patchCord36(voice6Mixer, envelope5);
AudioConnection patchCord37(voice9Mixer, envelope11);
AudioConnection patchCord38(voice10Mixer, envelope9);
AudioConnection patchCord39(voice3Mixer, envelope3);
AudioConnection patchCord40(voice7Mixer, envelope6);
AudioConnection patchCord41(voice11Mixer, envelope10);
AudioConnection patchCord42(voice4Mixer, envelope4);
AudioConnection patchCord43(voice8Mixer, envelope8);
AudioConnection patchCord44(voice12Mixer, envelope12);
AudioConnection patchCord45(voice13Mixer, envelope15);
AudioConnection patchCord46(voice14Mixer, envelope13);
AudioConnection patchCord47(voice15Mixer, envelope14);
AudioConnection patchCord48(voice16Mixer, envelope16);
AudioConnection patchCord49(envelope2, 0, voiceMixer1, 1);
AudioConnection patchCord50(envelope3, 0, voiceMixer1, 2);
AudioConnection patchCord51(envelope5, 0, voiceMixer2, 1);
AudioConnection patchCord52(envelope1, 0, voiceMixer1, 0);
AudioConnection patchCord53(envelope6, 0, voiceMixer2, 2);
AudioConnection patchCord54(envelope9, 0, voiceMixer3, 1);
AudioConnection patchCord55(envelope7, 0, voiceMixer2, 0);
AudioConnection patchCord56(envelope10, 0, voiceMixer3, 2);
AudioConnection patchCord57(envelope4, 0, voiceMixer1, 3);
AudioConnection patchCord58(envelope11, 0, voiceMixer3, 0);
AudioConnection patchCord59(envelope8, 0, voiceMixer2, 3);
AudioConnection patchCord60(envelope12, 0, voiceMixer3, 3);
AudioConnection patchCord61(envelope13, 0, voiceMixer4, 1);
AudioConnection patchCord62(envelope14, 0, voiceMixer4, 2);
AudioConnection patchCord63(envelope15, 0, voiceMixer4, 0);
AudioConnection patchCord64(envelope16, 0, voiceMixer4, 3);
AudioConnection patchCord65(voiceMixer1, 0, lastMixer, 0);
AudioConnection patchCord66(voiceMixer2, 0, lastMixer, 1);
AudioConnection patchCord67(voiceMixer3, 0, lastMixer, 2);
AudioConnection patchCord68(voiceMixer4, 0, lastMixer, 3);
AudioConnection patchCord69(lastMixer, 0, filter1, 0);
AudioConnection patchCord70(filter1, 0, i2s1, 0);
AudioConnection patchCord71(filter1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=1529.6000213623047,1067.0000133514404
// GUItool: end automatically generated code
#define NUM_VOICES 16
int wave1 = WAVEFORM_SINE;
int wave2 = WAVEFORM_TRIANGLE;
int filterTemp = 10000 * analogRead(A3) / 1023;;
byte globalVelocity = 127;
const float noteFreqs[128] = {8.176, 8.662, 9.177, 9.723, 10.301, 10.913, 11.562, 12.25, 12.978, 13.75, 14.568, 15.434, 16.352, 17.324, 18.354, 19.445, 20.602, 21.827, 23.125, 24.5, 25.957, 27.5, 29.135, 30.868, 32.703, 34.648, 36.708, 38.891, 41.203, 43.654, 46.249, 48.999, 51.913, 55, 58.27, 61.735, 65.406, 69.296, 73.416, 77.782, 82.407, 87.307, 92.499, 97.999, 103.826, 110, 116.541, 123.471, 130.813, 138.591, 146.832, 155.563, 164.814, 174.614, 184.997, 195.998, 207.652, 220, 233.082, 246.942, 261.626, 277.183, 293.665, 311.127, 329.628, 349.228, 369.994, 391.995, 415.305, 440, 466.164, 493.883, 523.251, 554.365, 587.33, 622.254, 659.255, 698.456, 739.989, 783.991, 830.609, 880, 932.328, 987.767, 1046.502, 1108.731, 1174.659, 1244.508, 1318.51, 1396.913, 1479.978, 1567.982, 1661.219, 1760, 1864.655, 1975.533, 2093.005, 2217.461, 2349.318, 2489.016, 2637.02, 2793.826, 2959.955, 3135.963, 3322.438, 3520, 3729.31, 3951.066, 4186.009, 4434.922, 4698.636, 4978.032, 5274.041, 5587.652, 5919.911, 6271.927, 6644.875, 7040, 7458.62, 7902.133, 8372.018, 8869.844, 9397.273, 9956.063, 10548.08, 11175.3, 11839.82, 12543.85};
AudioSynthWaveformModulated *oscsA[NUM_VOICES] = { &osc1a, &osc2a, &osc3a, &osc4a, &osc5a, &osc6a, &osc7a, &osc8a, &osc9a, &osc10a, &osc11a, &osc12a, &osc13a, &osc14a, &osc15a, &osc16a};
AudioSynthWaveformModulated *oscsB[NUM_VOICES] = { &osc1b, &osc2b, &osc3b, &osc4b, &osc5b, &osc6b, &osc7b, &osc8b, &osc9b, &osc10b, &osc11b, &osc12b, &osc13b, &osc14b, &osc15b, &osc16b};
AudioEffectEnvelope *envelopes[NUM_VOICES] = { &envelope1, &envelope2, &envelope3, &envelope4, &envelope5, &envelope6, &envelope7, &envelope8, &envelope9, &envelope10, &envelope11, &envelope12, &envelope13, &envelope14, &envelope15, &envelope16 };
Bounce *mybutton[] = { &button0, &button1, &button2, &button3, &button4, &button5, &button6, &button7};
const float buttonFreqs[8] = {48, 50, 52, 53, 55, 57, 59, 60};
unsigned long voiceOnTimes[NUM_VOICES] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
bool idleVoices[NUM_VOICES] = {true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true };
byte voiceToNote[NUM_VOICES] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}; // Dummy value outside range of valid notes is used to init each.
elapsedMillis readPots = 0;
void NoteOn(byte channel, byte note, byte velocity) {
bool found = false;
int voiceToUse = 0;
// Acquire an idle voice if possible.
for (int i = 0; i < NUM_VOICES; i++) {
if (idleVoices[i]) {
voiceToUse = i;
found = true;
break;
}
}
// Steal voice if needed.
if (!found) {
unsigned long oldest = millis();
for (int i = 0; i < NUM_VOICES; i++) {
if (voiceOnTimes[i] < oldest) {
oldest = voiceOnTimes[i];
voiceToUse = i;
}
}
}
// Now use the acquired voice.
idleVoices[voiceToUse] = false;
voiceToNote[voiceToUse] = note;
AudioNoInterrupts();
oscsA[voiceToUse]->frequency(noteFreqs[note]);
oscsA[voiceToUse]->amplitude(.7f);
oscsB[voiceToUse]->frequency(noteFreqs[note]);
oscsB[voiceToUse]->amplitude(.7f);
envelopes[voiceToUse]->noteOn();
AudioInterrupts();
voiceOnTimes[voiceToUse] = millis();
}
void NoteOff(byte channel, byte note, byte velocity) {
for (int i = 0; i < NUM_VOICES; i++) {
if (voiceToNote[i] == note) {
envelopes[i]->noteOff();
voiceToNote[i] = -1;
}
}
}
void IdleCheck(void) {
for (uint8_t i = 0; i < NUM_VOICES; i++) {
if (!envelopes[i]->isActive()) {
oscsA[i]->amplitude(0);
oscsB[i]->amplitude(0);
idleVoices[i] = true;
} else {
idleVoices[i] = false;
}
}
}
void setup() {
AudioMemory(120);
Serial.begin(115200);
myusb.begin();
pinMode(25, INPUT_PULLUP);
pinMode(26, INPUT_PULLUP);
pinMode(27, INPUT_PULLUP);
pinMode(28, INPUT_PULLUP);
pinMode(29, INPUT_PULLUP);
pinMode(30, INPUT_PULLUP);
pinMode(31, INPUT_PULLUP);
pinMode(32, INPUT_PULLUP);
for (int i = 0; i < 4; i++) {
// Set all mixers.
voice1Mixer.gain(i, .7f);
voice2Mixer.gain(i, .7f);
voice3Mixer.gain(i, .7f);
voice4Mixer.gain(i, .7f);
voice5Mixer.gain(i, .7f);
voice6Mixer.gain(i, .7f);
voice7Mixer.gain(i, .7f);
voice8Mixer.gain(i, .7f);
voice9Mixer.gain(i, .7f);
voice10Mixer.gain(i, .7f);
voice11Mixer.gain(i, .7f);
voice12Mixer.gain(i, .7f);
voice13Mixer.gain(i, .7f);
voice14Mixer.gain(i, .7f);
voice15Mixer.gain(i, .7f);
voice16Mixer.gain(i, .7f);
voiceMixer1.gain(i, .7f);
voiceMixer2.gain(i, .7f);
voiceMixer3.gain(i, .7f);
voiceMixer4.gain(i, .7f);
lastMixer.gain(i, .5f);
// Set oscs to default waves.
oscsA[i]->begin(wave1);
oscsB[i]->begin(wave2);
// Set envelopes to something reasonable.
envelopes[i]->attack(5);
envelopes[i]->decay(10);
envelopes[i]->sustain(.7f);
envelopes[i]->release(1000);
}
// Enable codec
sgtl5000_1.enable();
sgtl5000_1.volume(.7f);
// Set USB MIDI device callbacks.
midi1.setHandleNoteOff(NoteOff);
midi1.setHandleNoteOn(NoteOn);
}
void loop() {
// Only read pots every 50 milliseconds to reduce glitchiness due to noise...
// This could be done with averaging or something instead.
if (readPots >= 50) {
// Reset elapsed time.
readPots = 0;
// Read waveform selection pots.
int wave1Temp = map(analogRead(A14), 0, 1023, WAVEFORM_SINE, WAVEFORM_TRIANGLE);
int wave2Temp = map(analogRead(A16), 0, 1023, WAVEFORM_SINE, WAVEFORM_TRIANGLE);
// Update A oscs only if waveform has changed.
// Oscillator phase will be reset by calling begin(), that's why we only want to do it when knob has changed.
if (wave1Temp != wave1) {
wave1 = wave1Temp;
Serial.printf("Knob 1: %d\n", wave1);
for (int i = 0; i < NUM_VOICES; i++) {
oscsA[i]->begin(wave1);
}
}
// Same thing for B oscs.
if (wave2Temp != wave2) {
wave2 = wave2Temp;
Serial.printf("Knob 2: %d\n", wave2);
for (int i = 0; i < NUM_VOICES; i++) {
oscsB[i]->begin(wave2);
}
}
//Lowpass Filter
int filterKnob = 10000 * analogRead(A3) / 1023;
if (filterTemp != filterKnob) {
filterTemp = filterKnob;
filter1.frequency(filterKnob);
//Resonace will be controlled by its own knob
filter1.resonance(3.8);
}
}
for (int i = 0; i < 8; i++) {
mybutton[i]->update();
if (mybutton[i]->fallingEdge()) {
NoteOn(1, buttonFreqs[i], globalVelocity);
}
if (mybutton[i]->risingEdge()) {
NoteOff(1, buttonFreqs[i], globalVelocity);
}
}
IdleCheck();
midi1.read();
}