Forum Rule: Always post complete source code & details to reproduce any issue!
Page 3 of 4 FirstFirst 1 2 3 4 LastLast
Results 51 to 75 of 88

Thread: USB Host turning envelopes on and off?

  1. #51
    Senior Member
    Join Date
    Feb 2015
    Posts
    154
    That just reminds the compiler that it's a floating point number rather than a double. It's just one of those little hand optimizations that I always do whether it's really needed or not.

  2. #52
    Quote Originally Posted by tele_player View Post
    I’m thinking out loud here...

    Wouldn’t it be clearer if you wrote a class which encapsulates a voiceless ? oscillators,, amps, filters, envelopes? While the setups produced by the online tool are very handy, for something like this, it seems to me some basic C++ stuff could really clean things up.
    That sounds awesome but my only real C++ experience is super limited to this teensy stuff. :/

  3. #53
    Senior Member
    Join Date
    Feb 2015
    Posts
    154
    Quote Originally Posted by tele_player View Post
    I’m thinking out loud here...

    Wouldn’t it be clearer if you wrote a class which encapsulates a voice? While the setups produced by the online tool are very handy, for something like this, it seems to me Some basic C++ stuff could really clean things up.
    For a larger synth, yeah it is needed. I have an instrument class, and 8 derived classes to encapsulate each instrument type. The derived classes hold the oscillators, envelopes, filters, NoteOn, NoteOff, assignable modulation stuff, parameter saving and loading... and on and on. But for a beginner's demo, object oriented might be a little too much.

  4. #54
    Strictly speaking, a double is a floating point number. But in C and C++, a float is a lower precision FP number than a double.

  5. #55
    Man I thought I was cutting edge here...lol. I feel like an uber n00b...haha.

    Just one last thing wcalvert, the waveform selection thing...

    ... it seems the waveform knobs go through more than two waveform types, even though WAVEFORM_SINE and WAVEFORM_TRIANGLE are the only ones specifically mentioned... why is that? Does the compiler fill in the blanks or am I missing something?

  6. #56
    Senior Member
    Join Date
    Feb 2015
    Posts
    154
    Oh I misunderstood what you were asking when you posted that originally.

    What's happening is the map function is converting the pot reading to four distinct values, 0 - 3. Sine and triangle are the starting and ending values that it uses.

    What waveforms are you wanting it to use instead?

  7. #57
    Wcalvert: in your stuff, have you come up with something better than cascaded 4channel mixers to handle many voices?

  8. #58
    Senior Member
    Join Date
    Feb 2015
    Posts
    154
    I just edited the mixer class to have 8 inputs, it's a simple change. Most of my instruments have only 6 voices, and one has only 3 voices due to how CPU hungry they are.

    Oh, and it's really easy to change the number of inputs in the GUI editor code too. I have added all my additional stuff to the GUI editor so I can still use it, it was very easy.

  9. #59
    Interesting, I never investigated extending the GUI.

  10. #60
    Senior Member
    Join Date
    Feb 2015
    Posts
    154
    Just clone or download the Audio library, open a command prompt, change into the directory where you downloaded it, type "python -m SimpleHTTPServer" and then go to localhost:8000 in your browser, and boom, the GUI editor will be there. Edit index.html starting around line 345, and all the object definitions are in a big blob of JSON data.

  11. #61
    Quote Originally Posted by wcalvert View Post
    Oh I misunderstood what you were asking when you posted that originally.

    What's happening is the map function is converting the pot reading to four distinct values, 0 - 3. Sine and triangle are the starting and ending values that it uses.

    What waveforms are you wanting it to use instead?
    I was thinking 4 different waveforms, WAVEFORM_SINE, WAVEFORM_SQUARE, WAVEFORM_TRIANGLE, WAVEFORM_SAWTOOTH, I think they are the most
    "musical of waveforms. Is that doable?

  12. #62
    Now you've really got me wondering... what voices are using that are so cpu hungry?

  13. #63
    Quote Originally Posted by wcalvert View Post
    Just clone or download the Audio library, open a command prompt, change into the directory where you downloaded it, type "python -m SimpleHTTPServer" and then go to localhost:8000 in your browser, and boom, the GUI editor will be there. Edit index.html starting around line 345, and all the object definitions are in a big blob of JSON data.
    Just FYI on a windows machine with python 3.6 I had to run ' python -m http.server 8000 ' on the AudioTool directory and then I had access to localhost:8000, the other command threw an error. I may be new to this but creating custom audiotool objects is too intriguing not to try!

    Added 16 voices, check to see if filter pot has been moved before updating. That's all for tonight. Thanks again everyone, especially wcalvert!

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

  14. #64
    Senior Member
    Join Date
    Feb 2015
    Posts
    154
    Quote Originally Posted by halogravity View Post
    I was thinking 4 different waveforms, WAVEFORM_SINE, WAVEFORM_SQUARE, WAVEFORM_TRIANGLE, WAVEFORM_SAWTOOTH, I think they are the most
    "musical of waveforms. Is that doable?
    That's how it's setup to work now. Just uncomment the lines "Serial.printf("Knob 1: %d\n", wave1);" and "Serial.printf("Knob 2: %d\n", wave2);" You should see each changing between 0, 1, 2, and 3. 0 is sine, 1 is saw, 2 is square, 3 is triangle.

  15. #65
    Quote Originally Posted by wcalvert View Post
    That's how it's setup to work now. Just uncomment the lines "Serial.printf("Knob 1: %d\n", wave1);" and "Serial.printf("Knob 2: %d\n", wave2);" You should see each changing between 0, 1, 2, and 3. 0 is sine, 1 is saw, 2 is square, 3 is triangle.
    So you can call numbers instead of the full WAVEFORM_SINE? And the compiler knows when you map WAVEFORM_SINE to WAVEFORM_TRIANGLE you mean 0 through 3 as well? I wasn't aware of that.

  16. #66
    Senior Member
    Join Date
    Feb 2015
    Posts
    154
    You can do that, sure. If you look here near the top of the file: https://github.com/PaulStoffregen/Au...nth_waveform.h

    The waveforms have been #define'd, that's how the compiler knows what number corresponds to each waveform type.

  17. #67
    Ahhh sweet I get it. Thank you sir!

  18. #68
    Hey everyone, hope all are enjoying their holiday season!

    So I upped the number of voices to 32, and added an attack and release knob for the envelope!

    I am running into a few strange issues though, if I run up some keys one at a time and there is a little release time active, it seems to skip a note. Like do-re-mi-fa-blank-la-ti-do. There just seems to be a lot of note skipping and some other weird behavior... notes jumping around etc. Any idea what that may be? Do I need to turn off audio interrupts somewhere else in the code? Wcalvert I know you said the synth was showing some strange behavior and I'm beginning to think it wasn't your midi program.

    Also I need a little help implementing detune... I'm having some trouble wrapping my head around where to add the " - detuneKnob" code... in OnNoteOn? In the loop with a for statement and re-begin all the oscillators whenever the detuneKnob variable changes? Sigh... any help on these issues would be hugely appreciated! I posted the new code below. I hope all are well!

    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      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
    AudioEffectEnvelope      envelope17; //xy=812,1896
    AudioEffectEnvelope      envelope18; //xy=812,1966
    AudioEffectEnvelope      envelope21; //xy=811,2303
    AudioEffectEnvelope      envelope19; //xy=813,1823
    AudioEffectEnvelope      envelope22; //xy=811,2373
    AudioEffectEnvelope      envelope25; //xy=810,2716
    AudioEffectEnvelope      envelope23; //xy=812,2230
    AudioEffectEnvelope      envelope26; //xy=810,2786
    AudioEffectEnvelope      envelope20; //xy=813,2041
    AudioEffectEnvelope      envelope27; //xy=811,2643
    AudioEffectEnvelope      envelope24; //xy=812,2448
    AudioEffectEnvelope      envelope28; //xy=811,2861
    AudioEffectEnvelope      envelope29; //xy=820,3120
    AudioEffectEnvelope      envelope30; //xy=820,3190
    AudioEffectEnvelope      envelope31; //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, envelope7);
    AudioConnection          patchCord68(voice6Mixer, envelope5);
    AudioConnection          patchCord69(voice9Mixer, envelope11);
    AudioConnection          patchCord70(voice10Mixer, envelope9);
    AudioConnection          patchCord71(voice3Mixer, envelope3);
    AudioConnection          patchCord72(voice7Mixer, envelope6);
    AudioConnection          patchCord73(voice11Mixer, envelope10);
    AudioConnection          patchCord74(voice4Mixer, envelope4);
    AudioConnection          patchCord75(voice8Mixer, envelope8);
    AudioConnection          patchCord76(voice12Mixer, envelope12);
    AudioConnection          patchCord77(voice13Mixer, envelope15);
    AudioConnection          patchCord78(voice14Mixer, envelope13);
    AudioConnection          patchCord79(voice17Mixer, envelope19);
    AudioConnection          patchCord80(voice18Mixer, envelope17);
    AudioConnection          patchCord81(voice21Mixer, envelope23);
    AudioConnection          patchCord82(voice15Mixer, envelope14);
    AudioConnection          patchCord83(voice22Mixer, envelope21);
    AudioConnection          patchCord84(voice25Mixer, envelope27);
    AudioConnection          patchCord85(voice26Mixer, envelope25);
    AudioConnection          patchCord86(voice16Mixer, envelope16);
    AudioConnection          patchCord87(voice23Mixer, envelope22);
    AudioConnection          patchCord88(voice19Mixer, envelope18);
    AudioConnection          patchCord89(voice27Mixer, envelope26);
    AudioConnection          patchCord90(voice20Mixer, envelope20);
    AudioConnection          patchCord91(voice24Mixer, envelope24);
    AudioConnection          patchCord92(voice28Mixer, envelope28);
    AudioConnection          patchCord93(voice29Mixer, envelope31);
    AudioConnection          patchCord94(voice30Mixer, envelope29);
    AudioConnection          patchCord95(voice31Mixer, envelope30);
    AudioConnection          patchCord96(voice32Mixer, envelope32);
    AudioConnection          patchCord97(envelope2, 0, voiceMixer1, 1);
    AudioConnection          patchCord98(envelope3, 0, voiceMixer1, 2);
    AudioConnection          patchCord99(envelope5, 0, voiceMixer2, 1);
    AudioConnection          patchCord100(envelope1, 0, voiceMixer1, 0);
    AudioConnection          patchCord101(envelope6, 0, voiceMixer2, 2);
    AudioConnection          patchCord102(envelope9, 0, voiceMixer3, 1);
    AudioConnection          patchCord103(envelope7, 0, voiceMixer2, 0);
    AudioConnection          patchCord104(envelope10, 0, voiceMixer3, 2);
    AudioConnection          patchCord105(envelope4, 0, voiceMixer1, 3);
    AudioConnection          patchCord106(envelope11, 0, voiceMixer3, 0);
    AudioConnection          patchCord107(envelope8, 0, voiceMixer2, 3);
    AudioConnection          patchCord108(envelope12, 0, voiceMixer3, 3);
    AudioConnection          patchCord109(envelope13, 0, voiceMixer4, 1);
    AudioConnection          patchCord110(envelope14, 0, voiceMixer4, 2);
    AudioConnection          patchCord111(envelope15, 0, voiceMixer4, 0);
    AudioConnection          patchCord112(envelope16, 0, voiceMixer4, 3);
    AudioConnection          patchCord113(envelope17, 0, voiceMixer5, 1);
    AudioConnection          patchCord114(envelope18, 0, voiceMixer5, 2);
    AudioConnection          patchCord115(envelope21, 0, voiceMixer6, 1);
    AudioConnection          patchCord116(envelope19, 0, voiceMixer5, 0);
    AudioConnection          patchCord117(envelope22, 0, voiceMixer6, 2);
    AudioConnection          patchCord118(envelope25, 0, voiceMixer7, 1);
    AudioConnection          patchCord119(envelope23, 0, voiceMixer6, 0);
    AudioConnection          patchCord120(envelope26, 0, voiceMixer7, 2);
    AudioConnection          patchCord121(envelope20, 0, voiceMixer5, 3);
    AudioConnection          patchCord122(envelope27, 0, voiceMixer7, 0);
    AudioConnection          patchCord123(envelope24, 0, voiceMixer6, 3);
    AudioConnection          patchCord124(envelope28, 0, voiceMixer7, 3);
    AudioConnection          patchCord125(envelope29, 0, voiceMixer8, 1);
    AudioConnection          patchCord126(envelope30, 0, voiceMixer8, 2);
    AudioConnection          patchCord127(envelope31, 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;
    
    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 = 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(.5f);
      oscsB[voiceToUse]->frequency(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] = true;
        } 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(5);
        envelopes[i]->decay(10);
        envelopes[i]->sustain(.5f);
        envelopes[i]->release(1000);
      }
    
      // 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;
    
        // 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();
    }

  19. #69
    Strangely if I play the notes one after another another slowly, this issue doesn't occur. Only if I play one note after another relatively quickly.

  20. #70
    GOT IT! Somehow the envelopes in the Audio Design tool got misnumbered when I added 32 voices... some envelopes were numbered with the wrong oscillators. You can see what I mean if you import the above design tool code. I fixed the numbering issue and it's playing beautifully! Sweet!

    I still could use some help on the detuning question, if you get a moment. Here's the new WORKING 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;
    
    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] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
    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(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);
      }
    
      // 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;
    
        // 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();
    }

  21. #71
    Senior Member
    Join Date
    Feb 2015
    Posts
    154
    Glad you got it working.

    I don't have time to integrate this into the code right now, but it would go something like this. First define a global variable called detune:
    Code:
    float detune=1.0f;
    Let's say we want a max of one semitone (100 cents) of detuning. In the pot reading code, let's convert the pot reading so that full ADC reading is 1 semitone of detune:
    Code:
    int cents = 100 * analogRead(Ax) / 1023;
    detune = pow(2, (cents/1200));
    Then, in NoteOn, just change oscsB to use the detuning:
    Code:
    oscsB[voiceToUse]->frequency(detune * noteFreqs[note]);
    The detuning gets calculated as a ratio, for example 50 cents is 1.0293. So if oscA is playing 440Hz, oscB will be playing 440*1.0293 = 452.8Hz. If we had more than 2 oscs per voice, I believe most synths would divide the detuning up so that the total spacing between all the oscillators would be 1 semitone at most.

  22. #72
    Thanks Wcalvert! I think I implemented it right... but I'm getting a value of 1 for detune even when I turn the pot... I need to keep tweaking here I guess.

    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;
    int cents = 100 * analogRead(A17) / 1023;
    int detune = pow(2, (cents/1200));
    
    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);
      }
    
      // 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;
    
        int cents = 100 * analogRead(A17) / 1023;
        int detune = pow(2, (cents/1200));
        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) {
          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();
    }

  23. #73
    So I think the problem was I set detune as an integer so it was rounding to one, setting it as a float fixed that. Here's the updated code. Next I'll be working on making the detune sweeepable while you are holding down a note, and not just triggered only at OnNoteOn(). Thanks Wcalvert!

    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 cents = 100 * analogRead(A17) / 1023;
    float detune = pow(2, (cents / 1200));
    
    
    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;
        detune = pow(2, (cents / 1200));
        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) {
          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();
    }

  24. #74
    Senior Member
    Join Date
    Feb 2015
    Posts
    154
    Oh, nice catch, pow() needs both arguments to be double or float, that's why it wasn't working.

    Making it continuously sweepable... Hmm, that's a cool idea, I hadn't thought of that. You could probably do something like:
    Code:
    void loop() {
    	// other synth code here...
    
    	float cents = 100 * analogRead(A17) / 1023;
    	float detune = pow(2, (cents / 1200));
    	for(int i=0; i<NUM_VOICES; i++) {
    		if(voiceToNote[i] != 255) {
    			oscsB[i]->frequency(detune * voiceToNote[i]);
    		}
    	}
    
    	// other synth code here...	
    }
    Here I show the detune being read every time through loop()... it should sound pretty good like that I would imagine.

  25. #75
    I was HELPFUL! lol

    So I tried this:

    Code:
          float cents = 100 * analogRead(A17) / 1023;
          float detune = pow(2, (cents / 1200));
          for (int i = 0; i < NUM_VOICES; i++) {
            if (voiceToNote[i] != 255) {
              oscsB[i]->frequency(detune * voiceToNote[i]);
            }    
          }
    And the note is just detuned really low and the second oscillator isnt in tune with the first at all... here's the whole code, I'll keep poking around... the notes seem right and detune is going from 1.0 to 1.06 like before...

    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 = pow(2, (cents / 1200));
    
    
    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));
        for (int i = 0; i < NUM_VOICES; i++) {
          if (voiceToNote[i] != 255) {
            oscsB[i]->frequency(detune * voiceToNote[i]);
            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) {
          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();
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •