USB Host turning envelopes on and off?

Status
Not open for further replies.
Oh like, instead of the B oscillator being detuned to a higher frequency, you want it detuned to a lower frequency? You could do:
Code:
oscsB[i]->frequency((1.0f / detune) * noteFreqs[voiceToNote[i]]);

That will invert the detune so 1.0293 will become 0.9715... Not sure if that's what you meant though.
 
Actually I don't know, haha. I've only really heard the old "super saw" oscillators which had like 6 oscillators per voice, it makes such a wall of sound it was hard for me to tell. I'll have to listen again when I have time... maybe it detunes some up, some down?
 
lol those supersaws are amazing! I think this is right now, again Wcalvert saves the day!

I added the code to only execute detune when the knob is turned. Onwards and upwards!

Next is LFO, a noise oscillator, and I'm nearing completion! I am considering trying to teach myself to create new Audio tool modules, though my coding experience is limited. Ultimately I want to add LFO, noise, a wavetable oscillator (on that note, do you think replacing the current oscillators with wavetable oscillators may be a way to go? Like have wavetables for all the classic sine, triangle, etc, but also some cooler ones too? I'm still curious about your comment on not using built in oscillators :) )and have separate envelopes for each... all these mixers seem so unnecessary. Sigh... keep trudging and learning!

Here's the code:

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 osc17a; //xy=399,1777.0000019073486
AudioSynthWaveformModulated osc17b; //xy=399,1813.0000019073486
AudioSynthWaveformModulated osc19a; //xy=399,1960
AudioSynthWaveformModulated osc23a; //xy=398,2367
AudioSynthWaveformModulated osc19b; //xy=400,1997
AudioSynthWaveformModulated osc27a; //xy=397,2780
AudioSynthWaveformModulated osc16a; //xy=401.6000061035156,1645
AudioSynthWaveformModulated osc27b; //xy=397.00000381469727,2815.000018119812
AudioSynthWaveformModulated osc23b; //xy=399,2404
AudioSynthWaveformModulated osc14a; //xy=403.6000061035156,1489
AudioSynthWaveformModulated osc20a; //xy=402,2037
AudioSynthWaveformModulated osc16b; //xy=403.6000061035156,1683
AudioSynthWaveformModulated osc24a; //xy=401,2444
AudioSynthWaveformModulated osc28a; //xy=400,2857
AudioSynthWaveformModulated osc18a; //xy=404,1881
AudioSynthWaveformModulated osc14b; //xy=405.6000061035156,1524
AudioSynthWaveformModulated osc22b; //xy=403.00000762939453,2311.0000343322754
AudioSynthWaveformModulated osc20b; //xy=404,2075
AudioSynthWaveformModulated osc13b; //xy=406.6000061035156,1438
AudioSynthWaveformModulated osc26a; //xy=402.00000381469727,2699.0000162124634
AudioSynthWaveformModulated osc24b; //xy=403,2482
AudioSynthWaveformModulated osc22a; //xy=404.00000381469727,2278.0000343322754
AudioSynthWaveformModulated osc13a; //xy=407.6000061035156,1404
AudioSynthWaveformModulated osc28b; //xy=402.00000381469727,2893.0000190734863
AudioSynthWaveformModulated osc18b; //xy=406.00000381469727,1916.0000286102295
AudioSynthWaveformModulated osc26b; //xy=404,2736
AudioSynthWaveformModulated osc21b; //xy=406,2237
AudioSynthWaveformModulated osc25b; //xy=405,2650
AudioSynthWaveformModulated osc21a; //xy=407,2203
AudioSynthWaveformModulated osc25a; //xy=406,2616
AudioSynthWaveformModulated osc31a; //xy=407,3184
AudioSynthWaveformModulated osc31b; //xy=408,3221
AudioSynthWaveformModulated osc32a; //xy=410,3261
AudioSynthWaveformModulated osc30a; //xy=412,3105
AudioSynthWaveformModulated osc32b; //xy=412,3299
AudioSynthWaveformModulated osc30b; //xy=414,3140
AudioSynthWaveformModulated osc29b; //xy=415,3054
AudioSynthWaveformModulated osc29a; //xy=416,3020
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              voice17Mixer; //xy=620,1818
AudioMixer4              voice18Mixer; //xy=620,1897
AudioMixer4              voice21Mixer; //xy=618.9999771118164,2223.000009536743
AudioMixer4              voice15Mixer; //xy=621.6000061035156,1580
AudioMixer4              voice22Mixer; //xy=619.0000076293945,2299.0000343322754
AudioMixer4              voice25Mixer; //xy=618,2638
AudioMixer4              voice26Mixer; //xy=618,2717
AudioMixer4              voice16Mixer; //xy=622.6000061035156,1655
AudioMixer4              voice23Mixer; //xy=620.0000076293945,2377.0000343322754
AudioMixer4              voice19Mixer; //xy=622,1972
AudioMixer4              voice27Mixer; //xy=620,2792
AudioMixer4              voice20Mixer; //xy=623.0000076293945,2044.0000305175781
AudioMixer4              voice24Mixer; //xy=622.0000076293945,2455.0000343322754
AudioMixer4              voice28Mixer; //xy=621,2867
AudioMixer4              voice29Mixer; //xy=628,3042
AudioMixer4              voice30Mixer; //xy=628,3121
AudioMixer4              voice31Mixer; //xy=630,3196
AudioMixer4              voice32Mixer; //xy=631,3271
AudioEffectEnvelope      envelope2;      //xy=803.6000061035156,280
AudioEffectEnvelope      envelope3;      //xy=803.6000061035156,350
AudioEffectEnvelope      envelope6; //xy=802.6000061035156,687
AudioEffectEnvelope      envelope1;      //xy=804.6000061035156,207
AudioEffectEnvelope      envelope7; //xy=802.6000061035156,757
AudioEffectEnvelope      envelope10; //xy=801.6000061035156,1100
AudioEffectEnvelope      envelope5; //xy=803.6000061035156,614
AudioEffectEnvelope      envelope11; //xy=801.6000061035156,1170
AudioEffectEnvelope      envelope4;      //xy=804.6000061035156,425
AudioEffectEnvelope      envelope9; //xy=802.6000061035156,1027
AudioEffectEnvelope      envelope8; //xy=803.6000061035156,832
AudioEffectEnvelope      envelope12; //xy=802.6000061035156,1245
AudioEffectEnvelope      envelope14; //xy=811.6000061035156,1504
AudioEffectEnvelope      envelope15; //xy=811.6000061035156,1574
AudioEffectEnvelope      envelope13; //xy=812.6000061035156,1431
AudioEffectEnvelope      envelope16; //xy=812.6000061035156,1649
AudioEffectEnvelope      envelope18; //xy=812,1896
AudioEffectEnvelope      envelope19; //xy=812,1966
AudioEffectEnvelope      envelope22; //xy=811,2303
AudioEffectEnvelope      envelope17; //xy=813,1823
AudioEffectEnvelope      envelope23; //xy=811,2373
AudioEffectEnvelope      envelope26; //xy=810,2716
AudioEffectEnvelope      envelope21; //xy=812,2230
AudioEffectEnvelope      envelope27; //xy=810,2786
AudioEffectEnvelope      envelope20; //xy=813,2041
AudioEffectEnvelope      envelope25; //xy=811,2643
AudioEffectEnvelope      envelope24; //xy=812,2448
AudioEffectEnvelope      envelope28; //xy=811,2861
AudioEffectEnvelope      envelope30; //xy=820,3120
AudioEffectEnvelope      envelope31; //xy=820,3190
AudioEffectEnvelope      envelope29; //xy=821,3047
AudioEffectEnvelope      envelope32; //xy=821,3265
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              voiceMixer5; //xy=1000.9999847412109,1922.0000038146973
AudioMixer4              voiceMixer6; //xy=1000,2331
AudioMixer4              voiceMixer7; //xy=999,2744
AudioMixer4              voiceMixer8; //xy=1008.9999847412109,3146.0000228881836
AudioMixer4              subMixer2; //xy=1242.3999938964844,1753.9999771118164
AudioMixer4              subMixer1;         //xy=1244.0000915527344,1658.9999752044678
AudioMixer4              lastMixer;         //xy=1406.599998474121,1708.1999778747559
AudioFilterStateVariable filter1; //xy=1565,1710.9999771118164
AudioOutputI2S           i2s1; //xy=1733,1698.999976158142
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(osc17a, 0, voice17Mixer, 0);
AudioConnection          patchCord28(osc17b, 0, voice17Mixer, 1);
AudioConnection          patchCord29(osc19a, 0, voice19Mixer, 0);
AudioConnection          patchCord30(osc23a, 0, voice23Mixer, 0);
AudioConnection          patchCord31(osc19b, 0, voice19Mixer, 1);
AudioConnection          patchCord32(osc27a, 0, voice27Mixer, 0);
AudioConnection          patchCord33(osc16a, 0, voice16Mixer, 0);
AudioConnection          patchCord34(osc27b, 0, voice27Mixer, 1);
AudioConnection          patchCord35(osc23b, 0, voice23Mixer, 1);
AudioConnection          patchCord36(osc14a, 0, voice14Mixer, 0);
AudioConnection          patchCord37(osc20a, 0, voice20Mixer, 0);
AudioConnection          patchCord38(osc16b, 0, voice16Mixer, 1);
AudioConnection          patchCord39(osc24a, 0, voice24Mixer, 0);
AudioConnection          patchCord40(osc28a, 0, voice28Mixer, 0);
AudioConnection          patchCord41(osc18a, 0, voice18Mixer, 0);
AudioConnection          patchCord42(osc14b, 0, voice14Mixer, 1);
AudioConnection          patchCord43(osc22b, 0, voice22Mixer, 1);
AudioConnection          patchCord44(osc20b, 0, voice20Mixer, 1);
AudioConnection          patchCord45(osc13b, 0, voice13Mixer, 1);
AudioConnection          patchCord46(osc26a, 0, voice26Mixer, 0);
AudioConnection          patchCord47(osc24b, 0, voice24Mixer, 1);
AudioConnection          patchCord48(osc22a, 0, voice22Mixer, 0);
AudioConnection          patchCord49(osc13a, 0, voice13Mixer, 0);
AudioConnection          patchCord50(osc28b, 0, voice28Mixer, 1);
AudioConnection          patchCord51(osc18b, 0, voice18Mixer, 1);
AudioConnection          patchCord52(osc26b, 0, voice26Mixer, 1);
AudioConnection          patchCord53(osc21b, 0, voice21Mixer, 1);
AudioConnection          patchCord54(osc25b, 0, voice25Mixer, 1);
AudioConnection          patchCord55(osc21a, 0, voice21Mixer, 0);
AudioConnection          patchCord56(osc25a, 0, voice25Mixer, 0);
AudioConnection          patchCord57(osc31a, 0, voice31Mixer, 0);
AudioConnection          patchCord58(osc31b, 0, voice31Mixer, 1);
AudioConnection          patchCord59(osc32a, 0, voice32Mixer, 0);
AudioConnection          patchCord60(osc30a, 0, voice30Mixer, 0);
AudioConnection          patchCord61(osc32b, 0, voice32Mixer, 1);
AudioConnection          patchCord62(osc30b, 0, voice30Mixer, 1);
AudioConnection          patchCord63(osc29b, 0, voice29Mixer, 1);
AudioConnection          patchCord64(osc29a, 0, voice29Mixer, 0);
AudioConnection          patchCord65(voice1Mixer, envelope1);
AudioConnection          patchCord66(voice2Mixer, envelope2);
AudioConnection          patchCord67(voice5Mixer, envelope5);
AudioConnection          patchCord68(voice6Mixer, envelope6);
AudioConnection          patchCord69(voice9Mixer, envelope9);
AudioConnection          patchCord70(voice10Mixer, envelope10);
AudioConnection          patchCord71(voice3Mixer, envelope3);
AudioConnection          patchCord72(voice7Mixer, envelope7);
AudioConnection          patchCord73(voice11Mixer, envelope11);
AudioConnection          patchCord74(voice4Mixer, envelope4);
AudioConnection          patchCord75(voice8Mixer, envelope8);
AudioConnection          patchCord76(voice12Mixer, envelope12);
AudioConnection          patchCord77(voice13Mixer, envelope13);
AudioConnection          patchCord78(voice14Mixer, envelope14);
AudioConnection          patchCord79(voice17Mixer, envelope17);
AudioConnection          patchCord80(voice18Mixer, envelope18);
AudioConnection          patchCord81(voice21Mixer, envelope21);
AudioConnection          patchCord82(voice15Mixer, envelope15);
AudioConnection          patchCord83(voice22Mixer, envelope22);
AudioConnection          patchCord84(voice25Mixer, envelope25);
AudioConnection          patchCord85(voice26Mixer, envelope26);
AudioConnection          patchCord86(voice16Mixer, envelope16);
AudioConnection          patchCord87(voice23Mixer, envelope23);
AudioConnection          patchCord88(voice19Mixer, envelope19);
AudioConnection          patchCord89(voice27Mixer, envelope27);
AudioConnection          patchCord90(voice20Mixer, envelope20);
AudioConnection          patchCord91(voice24Mixer, envelope24);
AudioConnection          patchCord92(voice28Mixer, envelope28);
AudioConnection          patchCord93(voice29Mixer, envelope29);
AudioConnection          patchCord94(voice30Mixer, envelope30);
AudioConnection          patchCord95(voice31Mixer, envelope31);
AudioConnection          patchCord96(voice32Mixer, envelope32);
AudioConnection          patchCord97(envelope2, 0, voiceMixer1, 1);
AudioConnection          patchCord98(envelope3, 0, voiceMixer1, 2);
AudioConnection          patchCord99(envelope6, 0, voiceMixer2, 1);
AudioConnection          patchCord100(envelope1, 0, voiceMixer1, 0);
AudioConnection          patchCord101(envelope7, 0, voiceMixer2, 2);
AudioConnection          patchCord102(envelope10, 0, voiceMixer3, 1);
AudioConnection          patchCord103(envelope5, 0, voiceMixer2, 0);
AudioConnection          patchCord104(envelope11, 0, voiceMixer3, 2);
AudioConnection          patchCord105(envelope4, 0, voiceMixer1, 3);
AudioConnection          patchCord106(envelope9, 0, voiceMixer3, 0);
AudioConnection          patchCord107(envelope8, 0, voiceMixer2, 3);
AudioConnection          patchCord108(envelope12, 0, voiceMixer3, 3);
AudioConnection          patchCord109(envelope14, 0, voiceMixer4, 1);
AudioConnection          patchCord110(envelope15, 0, voiceMixer4, 2);
AudioConnection          patchCord111(envelope13, 0, voiceMixer4, 0);
AudioConnection          patchCord112(envelope16, 0, voiceMixer4, 3);
AudioConnection          patchCord113(envelope18, 0, voiceMixer5, 1);
AudioConnection          patchCord114(envelope19, 0, voiceMixer5, 2);
AudioConnection          patchCord115(envelope22, 0, voiceMixer6, 1);
AudioConnection          patchCord116(envelope17, 0, voiceMixer5, 0);
AudioConnection          patchCord117(envelope23, 0, voiceMixer6, 2);
AudioConnection          patchCord118(envelope26, 0, voiceMixer7, 1);
AudioConnection          patchCord119(envelope21, 0, voiceMixer6, 0);
AudioConnection          patchCord120(envelope27, 0, voiceMixer7, 2);
AudioConnection          patchCord121(envelope20, 0, voiceMixer5, 3);
AudioConnection          patchCord122(envelope25, 0, voiceMixer7, 0);
AudioConnection          patchCord123(envelope24, 0, voiceMixer6, 3);
AudioConnection          patchCord124(envelope28, 0, voiceMixer7, 3);
AudioConnection          patchCord125(envelope30, 0, voiceMixer8, 1);
AudioConnection          patchCord126(envelope31, 0, voiceMixer8, 2);
AudioConnection          patchCord127(envelope29, 0, voiceMixer8, 0);
AudioConnection          patchCord128(envelope32, 0, voiceMixer8, 3);
AudioConnection          patchCord129(voiceMixer1, 0, subMixer1, 0);
AudioConnection          patchCord130(voiceMixer2, 0, subMixer1, 1);
AudioConnection          patchCord131(voiceMixer3, 0, subMixer1, 2);
AudioConnection          patchCord132(voiceMixer4, 0, subMixer1, 3);
AudioConnection          patchCord133(voiceMixer5, 0, subMixer2, 0);
AudioConnection          patchCord134(voiceMixer6, 0, subMixer2, 1);
AudioConnection          patchCord135(voiceMixer7, 0, subMixer2, 2);
AudioConnection          patchCord136(voiceMixer8, 0, subMixer2, 3);
AudioConnection          patchCord137(subMixer2, 0, lastMixer, 1);
AudioConnection          patchCord138(subMixer1, 0, lastMixer, 0);
AudioConnection          patchCord139(lastMixer, 0, filter1, 0);
AudioConnection          patchCord140(filter1, 0, i2s1, 0);
AudioConnection          patchCord141(filter1, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=1713.599998474121,1614.0000190734863
// GUItool: end automatically generated code

#define NUM_VOICES 32

int wave1 = WAVEFORM_SINE;
int wave2 = WAVEFORM_TRIANGLE;
int filterTemp = 10000 * analogRead(A3) / 1023;;
byte globalVelocity = 127;

int attackTemp = 11880 *  analogRead(A0) / 1023;
int releaseTemp = analogRead(A1) / 1023;
int attackKnob = 11880 *  analogRead(A0) / 1023;
int releaseKnob = 11880 * analogRead(A1) / 1023;
float centsTemp = 100 * analogRead(A17) / 1023;
float cents = 100 * analogRead(A17) / 1023;
float detune = 1.0;

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, &osc17a, &osc18a, &osc19a, &osc20a, &osc21a, &osc22a, &osc23a, &osc24a, &osc25a, &osc26a, &osc27a, &osc28a, &osc29a, &osc30a, &osc31a, &osc32a };
AudioSynthWaveformModulated *oscsB[NUM_VOICES] = { &osc1b, &osc2b, &osc3b, &osc4b, &osc5b, &osc6b, &osc7b, &osc8b, &osc9b, &osc10b, &osc11b, &osc12b, &osc13b, &osc14b, &osc15b, &osc16b, &osc17b, &osc18b, &osc19b, &osc20b, &osc21b, &osc22b, &osc23b, &osc24b, &osc25b, &osc26b, &osc27b, &osc28b, &osc29b, &osc30b, &osc31b, &osc32b};
AudioEffectEnvelope *envelopes[NUM_VOICES] = { &envelope1, &envelope2, &envelope3, &envelope4, &envelope5, &envelope6, &envelope7, &envelope8, &envelope9, &envelope10, &envelope11, &envelope12, &envelope13, &envelope14, &envelope15, &envelope16, &envelope17, &envelope18, &envelope19, &envelope20, &envelope21, &envelope22, &envelope23, &envelope24, &envelope25, &envelope26, &envelope27, &envelope28, &envelope29, &envelope30, &envelope31, &envelope32 };
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, 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, 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, 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 = 1;
      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(.5f);
  oscsB[voiceToUse]->frequency(detune * noteFreqs[note]);
  oscsB[voiceToUse]->amplitude(.5f);
  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] = 1;
    } else {
      idleVoices[i] = false;
    }
  }
}

void setup() {
  AudioMemory(160);
  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, .5f);
    voice2Mixer.gain(i, .5f);
    voice3Mixer.gain(i, .5f);
    voice4Mixer.gain(i, .5f);
    voice5Mixer.gain(i, .5f);
    voice6Mixer.gain(i, .5f);
    voice7Mixer.gain(i, .5f);
    voice8Mixer.gain(i, .5f);
    voice9Mixer.gain(i, .5f);
    voice10Mixer.gain(i, .5f);
    voice11Mixer.gain(i, .5f);
    voice12Mixer.gain(i, .5f);
    voice13Mixer.gain(i, .5f);
    voice14Mixer.gain(i, .5f);
    voice15Mixer.gain(i, .5f);
    voice16Mixer.gain(i, .5f);
    voice17Mixer.gain(i, .5f);
    voice18Mixer.gain(i, .5f);
    voice19Mixer.gain(i, .5f);
    voice20Mixer.gain(i, .5f);
    voice21Mixer.gain(i, .5f);
    voice22Mixer.gain(i, .5f);
    voice23Mixer.gain(i, .5f);
    voice24Mixer.gain(i, .5f);
    voice25Mixer.gain(i, .5f);
    voice26Mixer.gain(i, .5f);
    voice27Mixer.gain(i, .5f);
    voice28Mixer.gain(i, .5f);
    voice29Mixer.gain(i, .5f);
    voice30Mixer.gain(i, .5f);
    voice31Mixer.gain(i, .5f);
    voice32Mixer.gain(i, .5f);

    voiceMixer1.gain(i, .5f);
    voiceMixer2.gain(i, .5f);
    voiceMixer3.gain(i, .5f);
    voiceMixer4.gain(i, .5f);
    voiceMixer5.gain(i, .5f);
    voiceMixer6.gain(i, .5f);
    voiceMixer7.gain(i, .5f);
    voiceMixer8.gain(i, .5f);

    subMixer1.gain(i, .5f);
    subMixer2.gain(i, .5f);

    lastMixer.gain(i, .6f);

    // Set oscs to default waves.
    oscsA[i]->begin(wave1);
    oscsB[i]->begin(wave2);

    // Set envelopes to something reasonable.
    envelopes[i]->attack(attackKnob);
    envelopes[i]->decay(10);
    envelopes[i]->sustain(.5f);
    envelopes[i]->release(releaseKnob);

    //Set default filter value
    int filterKnob = 10000 * analogRead(A3) / 1023;
    filter1.frequency(filterKnob);
  }

  // Enable codec
  sgtl5000_1.enable();
  sgtl5000_1.volume(.5f);

  // 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;

    float cents = 100 * analogRead(A17) / 1023;
    float detune = pow(2, (cents / 1200));
    if (centsTemp != cents) {
      for (int i = 0; i < NUM_VOICES; i++) {
        if (voiceToNote[i] != 255) {
          oscsB[i]->frequency((1.0f / detune) * noteFreqs[voiceToNote[i]]);
          Serial.println(voiceToNote[i]);
          Serial.println(detune);
        }
      }
      centsTemp = cents;
    }

    // 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);
    }

    //Attack and Release
    int attackKnob = 11880 *  analogRead(A0) / 1023;
    int releaseKnob = 11880 * analogRead(A1) / 1023;
    if (attackTemp != attackKnob) {
      attackTemp = attackKnob;
      for (int i = 0; i < NUM_VOICES; i++) {
        envelopes[i]->attack(attackKnob);
      }
    }
    if (releaseTemp != releaseKnob) {
      releaseTemp = releaseKnob;
      for (int i = 0; i < NUM_VOICES; i++) {
        envelopes[i]->release(releaseKnob);
      }
    }
  }
  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();
}
 
The benefit of wavetables, at least as I understand it, is that you get to have samples recorded at different pitches. This helps make things more realistic because, for example, resonance effects change as the pitch changes. With the simple waveforms (sine, saw, square) there's not a lot of benefit there. You can pitch them up and down without any problem.

If you wanted to write your own audio modules... well, I think the sky is the limit. One idea I have been messing with over the past few days is taking a single-cycle sample of a waveform and looping it to make a new "oscillator". This could be used to make analog-ish squares and saws for example, which sound 'sweeter' than traditional digital squares and saws.
 
Hey Wcalvert! I hope all is well with you, brother. I am in the process of commenting the crap out of my code, 1. So I can understand it better and 2. For future users to get as much as possible out of it. I may have overcommented a bit, but I wanted to be thorough. I was wondering if you had a moment sometime if you could comment your code contributions a little deeper than you already have? I started to, I'm about 95% of the way there, but I got a little lost when you started using millis()... around that area (is that starting a timer, or grabbing an already running timers value?). Just kind of breakdown whats happening in your part of the code. If you get a chance and feel so inclined I think it would not only help me but future beginner coders as well. Thanks my friend! Here's what I've done so far.

Code:
// Includes
#include <Bounce.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// My synth has 8 onboard buttons. Bounce my Buttons :)
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>

// Setup USBHost objects
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 osc17a; //xy=399,1777.0000019073486
AudioSynthWaveformModulated osc17b; //xy=399,1813.0000019073486
AudioSynthWaveformModulated osc19a; //xy=399,1960
AudioSynthWaveformModulated osc23a; //xy=398,2367
AudioSynthWaveformModulated osc19b; //xy=400,1997
AudioSynthWaveformModulated osc27a; //xy=397,2780
AudioSynthWaveformModulated osc16a; //xy=401.6000061035156,1645
AudioSynthWaveformModulated osc27b; //xy=397.00000381469727,2815.000018119812
AudioSynthWaveformModulated osc23b; //xy=399,2404
AudioSynthWaveformModulated osc14a; //xy=403.6000061035156,1489
AudioSynthWaveformModulated osc20a; //xy=402,2037
AudioSynthWaveformModulated osc16b; //xy=403.6000061035156,1683
AudioSynthWaveformModulated osc24a; //xy=401,2444
AudioSynthWaveformModulated osc28a; //xy=400,2857
AudioSynthWaveformModulated osc18a; //xy=404,1881
AudioSynthWaveformModulated osc14b; //xy=405.6000061035156,1524
AudioSynthWaveformModulated osc22b; //xy=403.00000762939453,2311.0000343322754
AudioSynthWaveformModulated osc20b; //xy=404,2075
AudioSynthWaveformModulated osc13b; //xy=406.6000061035156,1438
AudioSynthWaveformModulated osc26a; //xy=402.00000381469727,2699.0000162124634
AudioSynthWaveformModulated osc24b; //xy=403,2482
AudioSynthWaveformModulated osc22a; //xy=404.00000381469727,2278.0000343322754
AudioSynthWaveformModulated osc13a; //xy=407.6000061035156,1404
AudioSynthWaveformModulated osc28b; //xy=402.00000381469727,2893.0000190734863
AudioSynthWaveformModulated osc18b; //xy=406.00000381469727,1916.0000286102295
AudioSynthWaveformModulated osc26b; //xy=404,2736
AudioSynthWaveformModulated osc21b; //xy=406,2237
AudioSynthWaveformModulated osc25b; //xy=405,2650
AudioSynthWaveformModulated osc21a; //xy=407,2203
AudioSynthWaveformModulated osc25a; //xy=406,2616
AudioSynthWaveformModulated osc31a; //xy=407,3184
AudioSynthWaveformModulated osc31b; //xy=408,3221
AudioSynthWaveformModulated osc32a; //xy=410,3261
AudioSynthWaveformModulated osc30a; //xy=412,3105
AudioSynthWaveformModulated osc32b; //xy=412,3299
AudioSynthWaveformModulated osc30b; //xy=414,3140
AudioSynthWaveformModulated osc29b; //xy=415,3054
AudioSynthWaveformModulated osc29a; //xy=416,3020
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              voice17Mixer; //xy=620,1818
AudioMixer4              voice18Mixer; //xy=620,1897
AudioMixer4              voice21Mixer; //xy=618.9999771118164,2223.000009536743
AudioMixer4              voice15Mixer; //xy=621.6000061035156,1580
AudioMixer4              voice22Mixer; //xy=619.0000076293945,2299.0000343322754
AudioMixer4              voice25Mixer; //xy=618,2638
AudioMixer4              voice26Mixer; //xy=618,2717
AudioMixer4              voice16Mixer; //xy=622.6000061035156,1655
AudioMixer4              voice23Mixer; //xy=620.0000076293945,2377.0000343322754
AudioMixer4              voice19Mixer; //xy=622,1972
AudioMixer4              voice27Mixer; //xy=620,2792
AudioMixer4              voice20Mixer; //xy=623.0000076293945,2044.0000305175781
AudioMixer4              voice24Mixer; //xy=622.0000076293945,2455.0000343322754
AudioMixer4              voice28Mixer; //xy=621,2867
AudioMixer4              voice29Mixer; //xy=628,3042
AudioMixer4              voice30Mixer; //xy=628,3121
AudioMixer4              voice31Mixer; //xy=630,3196
AudioMixer4              voice32Mixer; //xy=631,3271
AudioEffectEnvelope      envelope2;      //xy=803.6000061035156,280
AudioEffectEnvelope      envelope3;      //xy=803.6000061035156,350
AudioEffectEnvelope      envelope6; //xy=802.6000061035156,687
AudioEffectEnvelope      envelope1;      //xy=804.6000061035156,207
AudioEffectEnvelope      envelope7; //xy=802.6000061035156,757
AudioEffectEnvelope      envelope10; //xy=801.6000061035156,1100
AudioEffectEnvelope      envelope5; //xy=803.6000061035156,614
AudioEffectEnvelope      envelope11; //xy=801.6000061035156,1170
AudioEffectEnvelope      envelope4;      //xy=804.6000061035156,425
AudioEffectEnvelope      envelope9; //xy=802.6000061035156,1027
AudioEffectEnvelope      envelope8; //xy=803.6000061035156,832
AudioEffectEnvelope      envelope12; //xy=802.6000061035156,1245
AudioEffectEnvelope      envelope14; //xy=811.6000061035156,1504
AudioEffectEnvelope      envelope15; //xy=811.6000061035156,1574
AudioEffectEnvelope      envelope13; //xy=812.6000061035156,1431
AudioEffectEnvelope      envelope16; //xy=812.6000061035156,1649
AudioEffectEnvelope      envelope18; //xy=812,1896
AudioEffectEnvelope      envelope19; //xy=812,1966
AudioEffectEnvelope      envelope22; //xy=811,2303
AudioEffectEnvelope      envelope17; //xy=813,1823
AudioEffectEnvelope      envelope23; //xy=811,2373
AudioEffectEnvelope      envelope26; //xy=810,2716
AudioEffectEnvelope      envelope21; //xy=812,2230
AudioEffectEnvelope      envelope27; //xy=810,2786
AudioEffectEnvelope      envelope20; //xy=813,2041
AudioEffectEnvelope      envelope25; //xy=811,2643
AudioEffectEnvelope      envelope24; //xy=812,2448
AudioEffectEnvelope      envelope28; //xy=811,2861
AudioEffectEnvelope      envelope30; //xy=820,3120
AudioEffectEnvelope      envelope31; //xy=820,3190
AudioEffectEnvelope      envelope29; //xy=821,3047
AudioEffectEnvelope      envelope32; //xy=821,3265
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              voiceMixer5; //xy=1000.9999847412109,1922.0000038146973
AudioMixer4              voiceMixer6; //xy=1000,2331
AudioMixer4              voiceMixer7; //xy=999,2744
AudioMixer4              voiceMixer8; //xy=1008.9999847412109,3146.0000228881836
AudioMixer4              subMixer2; //xy=1242.3999938964844,1753.9999771118164
AudioMixer4              subMixer1;         //xy=1244.0000915527344,1658.9999752044678
AudioMixer4              lastMixer;         //xy=1406.599998474121,1708.1999778747559
AudioFilterStateVariable filter1; //xy=1565,1710.9999771118164
AudioOutputI2S           i2s1; //xy=1733,1698.999976158142
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(osc17a, 0, voice17Mixer, 0);
AudioConnection          patchCord28(osc17b, 0, voice17Mixer, 1);
AudioConnection          patchCord29(osc19a, 0, voice19Mixer, 0);
AudioConnection          patchCord30(osc23a, 0, voice23Mixer, 0);
AudioConnection          patchCord31(osc19b, 0, voice19Mixer, 1);
AudioConnection          patchCord32(osc27a, 0, voice27Mixer, 0);
AudioConnection          patchCord33(osc16a, 0, voice16Mixer, 0);
AudioConnection          patchCord34(osc27b, 0, voice27Mixer, 1);
AudioConnection          patchCord35(osc23b, 0, voice23Mixer, 1);
AudioConnection          patchCord36(osc14a, 0, voice14Mixer, 0);
AudioConnection          patchCord37(osc20a, 0, voice20Mixer, 0);
AudioConnection          patchCord38(osc16b, 0, voice16Mixer, 1);
AudioConnection          patchCord39(osc24a, 0, voice24Mixer, 0);
AudioConnection          patchCord40(osc28a, 0, voice28Mixer, 0);
AudioConnection          patchCord41(osc18a, 0, voice18Mixer, 0);
AudioConnection          patchCord42(osc14b, 0, voice14Mixer, 1);
AudioConnection          patchCord43(osc22b, 0, voice22Mixer, 1);
AudioConnection          patchCord44(osc20b, 0, voice20Mixer, 1);
AudioConnection          patchCord45(osc13b, 0, voice13Mixer, 1);
AudioConnection          patchCord46(osc26a, 0, voice26Mixer, 0);
AudioConnection          patchCord47(osc24b, 0, voice24Mixer, 1);
AudioConnection          patchCord48(osc22a, 0, voice22Mixer, 0);
AudioConnection          patchCord49(osc13a, 0, voice13Mixer, 0);
AudioConnection          patchCord50(osc28b, 0, voice28Mixer, 1);
AudioConnection          patchCord51(osc18b, 0, voice18Mixer, 1);
AudioConnection          patchCord52(osc26b, 0, voice26Mixer, 1);
AudioConnection          patchCord53(osc21b, 0, voice21Mixer, 1);
AudioConnection          patchCord54(osc25b, 0, voice25Mixer, 1);
AudioConnection          patchCord55(osc21a, 0, voice21Mixer, 0);
AudioConnection          patchCord56(osc25a, 0, voice25Mixer, 0);
AudioConnection          patchCord57(osc31a, 0, voice31Mixer, 0);
AudioConnection          patchCord58(osc31b, 0, voice31Mixer, 1);
AudioConnection          patchCord59(osc32a, 0, voice32Mixer, 0);
AudioConnection          patchCord60(osc30a, 0, voice30Mixer, 0);
AudioConnection          patchCord61(osc32b, 0, voice32Mixer, 1);
AudioConnection          patchCord62(osc30b, 0, voice30Mixer, 1);
AudioConnection          patchCord63(osc29b, 0, voice29Mixer, 1);
AudioConnection          patchCord64(osc29a, 0, voice29Mixer, 0);
AudioConnection          patchCord65(voice1Mixer, envelope1);
AudioConnection          patchCord66(voice2Mixer, envelope2);
AudioConnection          patchCord67(voice5Mixer, envelope5);
AudioConnection          patchCord68(voice6Mixer, envelope6);
AudioConnection          patchCord69(voice9Mixer, envelope9);
AudioConnection          patchCord70(voice10Mixer, envelope10);
AudioConnection          patchCord71(voice3Mixer, envelope3);
AudioConnection          patchCord72(voice7Mixer, envelope7);
AudioConnection          patchCord73(voice11Mixer, envelope11);
AudioConnection          patchCord74(voice4Mixer, envelope4);
AudioConnection          patchCord75(voice8Mixer, envelope8);
AudioConnection          patchCord76(voice12Mixer, envelope12);
AudioConnection          patchCord77(voice13Mixer, envelope13);
AudioConnection          patchCord78(voice14Mixer, envelope14);
AudioConnection          patchCord79(voice17Mixer, envelope17);
AudioConnection          patchCord80(voice18Mixer, envelope18);
AudioConnection          patchCord81(voice21Mixer, envelope21);
AudioConnection          patchCord82(voice15Mixer, envelope15);
AudioConnection          patchCord83(voice22Mixer, envelope22);
AudioConnection          patchCord84(voice25Mixer, envelope25);
AudioConnection          patchCord85(voice26Mixer, envelope26);
AudioConnection          patchCord86(voice16Mixer, envelope16);
AudioConnection          patchCord87(voice23Mixer, envelope23);
AudioConnection          patchCord88(voice19Mixer, envelope19);
AudioConnection          patchCord89(voice27Mixer, envelope27);
AudioConnection          patchCord90(voice20Mixer, envelope20);
AudioConnection          patchCord91(voice24Mixer, envelope24);
AudioConnection          patchCord92(voice28Mixer, envelope28);
AudioConnection          patchCord93(voice29Mixer, envelope29);
AudioConnection          patchCord94(voice30Mixer, envelope30);
AudioConnection          patchCord95(voice31Mixer, envelope31);
AudioConnection          patchCord96(voice32Mixer, envelope32);
AudioConnection          patchCord97(envelope2, 0, voiceMixer1, 1);
AudioConnection          patchCord98(envelope3, 0, voiceMixer1, 2);
AudioConnection          patchCord99(envelope6, 0, voiceMixer2, 1);
AudioConnection          patchCord100(envelope1, 0, voiceMixer1, 0);
AudioConnection          patchCord101(envelope7, 0, voiceMixer2, 2);
AudioConnection          patchCord102(envelope10, 0, voiceMixer3, 1);
AudioConnection          patchCord103(envelope5, 0, voiceMixer2, 0);
AudioConnection          patchCord104(envelope11, 0, voiceMixer3, 2);
AudioConnection          patchCord105(envelope4, 0, voiceMixer1, 3);
AudioConnection          patchCord106(envelope9, 0, voiceMixer3, 0);
AudioConnection          patchCord107(envelope8, 0, voiceMixer2, 3);
AudioConnection          patchCord108(envelope12, 0, voiceMixer3, 3);
AudioConnection          patchCord109(envelope14, 0, voiceMixer4, 1);
AudioConnection          patchCord110(envelope15, 0, voiceMixer4, 2);
AudioConnection          patchCord111(envelope13, 0, voiceMixer4, 0);
AudioConnection          patchCord112(envelope16, 0, voiceMixer4, 3);
AudioConnection          patchCord113(envelope18, 0, voiceMixer5, 1);
AudioConnection          patchCord114(envelope19, 0, voiceMixer5, 2);
AudioConnection          patchCord115(envelope22, 0, voiceMixer6, 1);
AudioConnection          patchCord116(envelope17, 0, voiceMixer5, 0);
AudioConnection          patchCord117(envelope23, 0, voiceMixer6, 2);
AudioConnection          patchCord118(envelope26, 0, voiceMixer7, 1);
AudioConnection          patchCord119(envelope21, 0, voiceMixer6, 0);
AudioConnection          patchCord120(envelope27, 0, voiceMixer7, 2);
AudioConnection          patchCord121(envelope20, 0, voiceMixer5, 3);
AudioConnection          patchCord122(envelope25, 0, voiceMixer7, 0);
AudioConnection          patchCord123(envelope24, 0, voiceMixer6, 3);
AudioConnection          patchCord124(envelope28, 0, voiceMixer7, 3);
AudioConnection          patchCord125(envelope30, 0, voiceMixer8, 1);
AudioConnection          patchCord126(envelope31, 0, voiceMixer8, 2);
AudioConnection          patchCord127(envelope29, 0, voiceMixer8, 0);
AudioConnection          patchCord128(envelope32, 0, voiceMixer8, 3);
AudioConnection          patchCord129(voiceMixer1, 0, subMixer1, 0);
AudioConnection          patchCord130(voiceMixer2, 0, subMixer1, 1);
AudioConnection          patchCord131(voiceMixer3, 0, subMixer1, 2);
AudioConnection          patchCord132(voiceMixer4, 0, subMixer1, 3);
AudioConnection          patchCord133(voiceMixer5, 0, subMixer2, 0);
AudioConnection          patchCord134(voiceMixer6, 0, subMixer2, 1);
AudioConnection          patchCord135(voiceMixer7, 0, subMixer2, 2);
AudioConnection          patchCord136(voiceMixer8, 0, subMixer2, 3);
AudioConnection          patchCord137(subMixer2, 0, lastMixer, 1);
AudioConnection          patchCord138(subMixer1, 0, lastMixer, 0);
AudioConnection          patchCord139(lastMixer, 0, filter1, 0);
AudioConnection          patchCord140(filter1, 0, i2s1, 0);
AudioConnection          patchCord141(filter1, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=1713.599998474121,1614.0000190734863
// GUItool: end automatically generated code

// GLOBAL VARIABLES
#define NUM_VOICES 32

int wave1 = WAVEFORM_SINE;
int wave2 = WAVEFORM_TRIANGLE;
int filterTemp = 10000 * analogRead(A3) / 1023;;
byte globalVelocity = 127;
int attackTemp = 11880 *  analogRead(A0) / 1023;
int releaseTemp = analogRead(A1) / 1023;
int attackKnob = 11880 *  analogRead(A0) / 1023;
int releaseKnob = 11880 * analogRead(A1) / 1023;
float centsTemp = 100 * analogRead(A17) / 1023;
float cents = 100 * analogRead(A17) / 1023;
float detune = 1.0;

// Array to convert MIDI notes to thier corresponding frequency. Super useful
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};

// Pointer Arrays for Oscillators, envelopes, and buttons
AudioSynthWaveformModulated *oscsA[NUM_VOICES] = { &osc1a, &osc2a, &osc3a, &osc4a, &osc5a, &osc6a, &osc7a, &osc8a, &osc9a, &osc10a, &osc11a, &osc12a, &osc13a, &osc14a, &osc15a, &osc16a, &osc17a, &osc18a, &osc19a, &osc20a, &osc21a, &osc22a, &osc23a, &osc24a, &osc25a, &osc26a, &osc27a, &osc28a, &osc29a, &osc30a, &osc31a, &osc32a };
AudioSynthWaveformModulated *oscsB[NUM_VOICES] = { &osc1b, &osc2b, &osc3b, &osc4b, &osc5b, &osc6b, &osc7b, &osc8b, &osc9b, &osc10b, &osc11b, &osc12b, &osc13b, &osc14b, &osc15b, &osc16b, &osc17b, &osc18b, &osc19b, &osc20b, &osc21b, &osc22b, &osc23b, &osc24b, &osc25b, &osc26b, &osc27b, &osc28b, &osc29b, &osc30b, &osc31b, &osc32b};
AudioEffectEnvelope *envelopes[NUM_VOICES] = { &envelope1, &envelope2, &envelope3, &envelope4, &envelope5, &envelope6, &envelope7, &envelope8, &envelope9, &envelope10, &envelope11, &envelope12, &envelope13, &envelope14, &envelope15, &envelope16, &envelope17, &envelope18, &envelope19, &envelope20, &envelope21, &envelope22, &envelope23, &envelope24, &envelope25, &envelope26, &envelope27, &envelope28, &envelope29, &envelope30, &envelope31, &envelope32 };
Bounce *mybutton[]  = { &button0, &button1, &button2, &button3, &button4, &button5, &button6, &button7};

// My synth has 8 onboard buttons. This sets the MIDI notes for each button
const float buttonFreqs[8] = {48, 50, 52, 53, 55, 57, 59, 60};

// Array to store how long a voice is playing, in milliseconds
unsigned long voiceOnTimes[NUM_VOICES] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

// A bool array. Boolean arrays hold either a true or false value at each array position. 0's and 1's also work
bool idleVoices[NUM_VOICES] = {true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true };

// Array to hold played note frequency values. 255 is jammed in there as a place holder
byte voiceToNote[NUM_VOICES] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 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.

// Millisecond timer variable set to zero to start
elapsedMillis readPots = 0;

// Function named NoteOn, receives 3 variables that can be use in the function. MIDI channel, MIDI note, and note velocity
void NoteOn(byte channel, byte note, byte velocity) {

  // Set a boolean variable named 'found' to false, or zero. Boolean values can only be true or false, 0 or 1.
  bool found = false;

  // Set an integer variable named voiceToUse to 0
  int voiceToUse = 0;

  // Acquire an idle voice if possible.
  for (int i = 0; i < NUM_VOICES; i++) {
    // if the next idleVoices entry is TRUE...
    if (idleVoices[i]) {
      // ...set voice to use variable to the number corresponding to that idleVoices entry
      voiceToUse = i;
      // Set found to 1 or true
      found = 1;
      // Kill this loop
      break;
    }
  }

  // Steal voice if needed.
  // If found is FALSE...
  if (!found) {
    // ...create a variable named oldest and set its value to milliseconds clock
    unsigned long oldest = millis();
    for (int i = 0; i < NUM_VOICES; i++) {
      // if the current voiceOnTimes is less than oldest
      if (voiceOnTimes[i] < oldest) {
        // Set that voiceOnTime value to the current oldest value
        oldest = voiceOnTimes[i];
        // Increment voiceToUse value
        voiceToUse = i;
      }
    }
  }

  // Now use the acquired voice.
  //Set that voice entry to false
  idleVoices[voiceToUse] = false;

  // Set voiceToUse entry to MIDI note value that was just pressed
  voiceToNote[voiceToUse] = note;
  AudioNoInterrupts();
  oscsA[voiceToUse]->frequency(noteFreqs[note]);
  oscsA[voiceToUse]->amplitude(.5f);
  oscsB[voiceToUse]->frequency(detune * noteFreqs[note]);
  oscsB[voiceToUse]->amplitude(.5f);
  envelopes[voiceToUse]->noteOn();
  AudioInterrupts();
  voiceOnTimes[voiceToUse] = millis();
}

// Function named NoteOff, receives 3 variables that can be use in the function. MIDI channel, MIDI note, and note velocity
void NoteOff(byte channel, byte note, byte velocity) {
  for (int i = 0; i < NUM_VOICES; i++) {
    // Do this 32(NUM_VOICES value) times
    if (voiceToNote[i] == note) {
      envelopes[i]->noteOff();
      voiceToNote[i] = -1;
    }
  }
}

void IdleCheck(void) {
  for (uint8_t i = 0; i < NUM_VOICES; i++) {
    // Checks all 32 envelopes, if an envelope IS NOT ACTIVE ( thats the "!" ) set that envelopes corresponding oscillators amplitude to zero
    if (!envelopes[i]->isActive()) {
      oscsA[i]->amplitude(0);
      oscsB[i]->amplitude(0);
      // Set the voices corresponding entry in the idleVoices array to 1, or true
      idleVoices[i] = 1;
    } else {
      // Otherwise set the voices corresponding entry in the idleVoices array to 0, or false
      idleVoices[i] = false;
    }
  }
}

void setup() {

  // Audio programs need memory to be allocated. 160 is probably a lot more than I need
  AudioMemory(160);

  // Start serial and start usb object.
  Serial.begin(115200);
  myusb.begin();

  // Set the pin mode of my 8 buttons
  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);

  // Each mixer has 4 inputs. This cycles through all my mixers setting the gain 4 times so I only have to type them out once :)
  for (int i = 0; i < 4; i++) {
    // Set all mixers.
    voice1Mixer.gain(i, .5f);
    voice2Mixer.gain(i, .5f);
    voice3Mixer.gain(i, .5f);
    voice4Mixer.gain(i, .5f);
    voice5Mixer.gain(i, .5f);
    voice6Mixer.gain(i, .5f);
    voice7Mixer.gain(i, .5f);
    voice8Mixer.gain(i, .5f);
    voice9Mixer.gain(i, .5f);
    voice10Mixer.gain(i, .5f);
    voice11Mixer.gain(i, .5f);
    voice12Mixer.gain(i, .5f);
    voice13Mixer.gain(i, .5f);
    voice14Mixer.gain(i, .5f);
    voice15Mixer.gain(i, .5f);
    voice16Mixer.gain(i, .5f);
    voice17Mixer.gain(i, .5f);
    voice18Mixer.gain(i, .5f);
    voice19Mixer.gain(i, .5f);
    voice20Mixer.gain(i, .5f);
    voice21Mixer.gain(i, .5f);
    voice22Mixer.gain(i, .5f);
    voice23Mixer.gain(i, .5f);
    voice24Mixer.gain(i, .5f);
    voice25Mixer.gain(i, .5f);
    voice26Mixer.gain(i, .5f);
    voice27Mixer.gain(i, .5f);
    voice28Mixer.gain(i, .5f);
    voice29Mixer.gain(i, .5f);
    voice30Mixer.gain(i, .5f);
    voice31Mixer.gain(i, .5f);
    voice32Mixer.gain(i, .5f);

    voiceMixer1.gain(i, .5f);
    voiceMixer2.gain(i, .5f);
    voiceMixer3.gain(i, .5f);
    voiceMixer4.gain(i, .5f);
    voiceMixer5.gain(i, .5f);
    voiceMixer6.gain(i, .5f);
    voiceMixer7.gain(i, .5f);
    voiceMixer8.gain(i, .5f);

    subMixer1.gain(i, .5f);
    subMixer2.gain(i, .5f);

    lastMixer.gain(i, .6f);

    // Set oscs to default waves
    oscsA[i]->begin(wave1);
    oscsB[i]->begin(wave2);

    // Set envelopes to something reasonable
    envelopes[i]->attack(attackKnob);
    envelopes[i]->decay(10);
    envelopes[i]->sustain(.5f);
    envelopes[i]->release(releaseKnob);

    // Set default filter value
    int filterKnob = 10000 * analogRead(A3) / 1023;
    filter1.frequency(filterKnob);
  }

  // Enable codec
  sgtl5000_1.enable();
  sgtl5000_1.volume(.5f);

  // Set USB MIDI device callbacks. Each time a note is pressed call NoteOn function, each time its released call NoteOff function.
  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;

    // Set variables to knob values
    float cents = 100 * analogRead(A17) / 1023;
    float detune = pow(2, (cents / 1200));

    // Only execute this code if knob has been moved
    if (centsTemp != cents) {
      // Reset variable to knob value
      centsTemp = cents;
      for (int i = 0; i < NUM_VOICES; i++) {
        if (voiceToNote[i] != 255) {
          oscsB[i]->frequency((1.0f / detune) * noteFreqs[voiceToNote[i]]);
          // Uncomment to see value in serial monitor
          // Serial.println(voiceToNote[i]);
          // Serial.println(detune);
        }
      }
    }

    // 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) {
      //Reset variable to knob value
      wave1 = wave1Temp;
      // Uncomment to see value in serial monitor
      // Serial.printf("Knob 1: %d\n", wave1);

      // Cycle through all oscA pointer array values and restart them with the new wave value. FYI when working with pointers -> means put a . after the array value
      // So this essentially executes osc1a.begin(value of wave1); then osc2a.begin(value of wave1) and so on
      for (int i = 0; i < NUM_VOICES; i++) {
        oscsA[i]->begin(wave1);
      }
    }

    // Same thing for B oscs
    if (wave2Temp != wave2) {
      wave2 = wave2Temp;
      // Uncomment to see value in serial monitor
      // Serial.printf("Knob 2: %d\n", wave2);
      for (int i = 0; i < NUM_VOICES; i++) {
        oscsB[i]->begin(wave2);
      }
    }

    //Lowpass Filter
    // Set variables to knob values
    int filterKnob = 10000 * analogRead(A3) / 1023;

    // Only execute this code if knob has been moved
    if (filterTemp != filterKnob) {
      //Reset variable to knob value
      filterTemp = filterKnob;
      filter1.frequency(filterKnob);
      //Resonance will be controlled by its own knob eventually. Set a resonable value for now
      filter1.resonance(3.8);
    }

    //Attack and Release
    // Set variables to knob values
    int attackKnob = 11880 *  analogRead(A0) / 1023;
    int releaseKnob = 11880 * analogRead(A1) / 1023;

    // Only execute this code if knob has been moved
    if (attackTemp != attackKnob) {
      attackTemp = attackKnob;
      // Cycle through all envelopes pointer array values and sets new attack value. FYI when working with pointers -> means put a . after the array value
      // So this essentially executes envelope1.attack(value of attackKnob); then envelope1.attack(value of attackKnob) and so on
      for (int i = 0; i < NUM_VOICES; i++) {
        envelopes[i]->attack(attackKnob);
      }
    }
    // Same as Attack code
    if (releaseTemp != releaseKnob) {
      releaseTemp = releaseKnob;
      for (int i = 0; i < NUM_VOICES; i++) {
        envelopes[i]->release(releaseKnob);
      }
    }
  }
  // Do this 8 times for my 8 buttons
  for (int i = 0; i < 8; i++) {
    
    // button1.update(); button2.update(); button3.update()...
    mybutton[i]->update();

    // button1.fallingEdge(); button2.fallingEdge(); button3.fallingEdge()...
    if (mybutton[i]->fallingEdge()) {
      // When button is pressed send channel 1, corresponding buttonFreqs array value, and globalVelocity value to NoteOn() function
      NoteOn(1, buttonFreqs[i], globalVelocity);
    }
    // button1.risingEdge(); button2.risingEdge(); button3.risingEdge()...
    if (mybutton[i]->risingEdge()) {
      // When button is released send channel 1, corresponding buttonFreqs array value, and globalVelocity value to NoteOff() function
      NoteOff(1, buttonFreqs[i], globalVelocity);
    }
  }
  // Run idleCheck function to see if any voices are not running and then turn them off
  IdleCheck();

  // Check incoming MIDI
  midi1.read();
}
 
Comments are good. Comments that state the obvious just add clutter. It's a fine line.

The loop in your NoteOff() function should terminate on first match:

Code:
// Function named NoteOff, receives 3 variables that can be use in the function. MIDI channel, MIDI note, and note velocity
void NoteOff(byte channel, byte note, byte velocity) {
 for (int i = 0; i < NUM_VOICES; i++) {
   // Do this 32(NUM_VOICES value) times
   if (voiceToNote[i] == note) {
     envelopes[i]->noteOff();
     voiceToNote[i] = -1;
     break;  // Exit loop on first match
   }
 }
}

It's a bit esoteric, since this might never happen...
 
Last edited:
Thats a good point. I thought I went a bit overboard, lol. Thanks for your addition, I will definitely slim down the comments.
 
Hey, well I can explain the voice stealing part pretty quickly. Millis() returns the time in milliseconds since power on. So to find the voice that has been on the longest (so we can steal it), we need to find the *lowest* value in the voiceOnTimes array. To find the lowest value, just iterate through the voiceOnTimes array and keep track of the smallest value ('oldest') and the array index of the voice we'll steal from ('voiceToUse'). At the end of NoteOn, I store millis() into the voiceOnTimes array for the voice that was acquired or stolen. That's where that array gets populated. Anyway, hope that helps.
 
Thanks Wcalvert, that helped a lot! You have been very generous with your time and I cant thank you enough. Happy Holidays!
 
Status
Not open for further replies.
Back
Top