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.
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.
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.
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.
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?
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?
Wcalvert: in your stuff, have you come up with something better than cascaded 4channel mixers to handle many voices?
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.
Interesting, I never investigated extending the GUI.
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.
Now you've really got me wondering... what voices are using that are so cpu hungry?
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(); }
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.
Ahhh sweet I get it. Thank you sir!
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(); }
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.
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(); }
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:
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:float detune=1.0f;
Then, in NoteOn, just change oscsB to use the detuning:Code:int cents = 100 * analogRead(Ax) / 1023; detune = pow(2, (cents/1200));
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.Code:oscsB[voiceToUse]->frequency(detune * noteFreqs[note]);
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(); }
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(); }
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:
Here I show the detune being read every time through loop()... it should sound pretty good like that I would imagine.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... }
I was HELPFUL! lol
So I tried this:
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: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]); } }
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(); }