Hi, This is my first time posting here. I'm having an issue trying to build a polyphonic (paraphonic technically) synth using the WaveformMod object on a Teensy 3.2. I am trying to get the polyphony up to 32 voices, but when I get past 16 voices I start getting glitches in the audio. Some of the voices won't play, while others sound like they are being frequency modulated in a weird way. Is there a limit to the number of WaveformMod, envelope, or mixer objects that the Teensy 3.2 or Audio shield can handle?

Any ideas as to what could be causing this issue, or suggestions for how to fix it? I appreciate any input.


Here is the code:



#include "note_frequency.h"
#include "scales.h"
#include <Bounce.h>



// 15 = 15 ms debounce time
Bounce button1 = Bounce(7, 15); // change waveform
Bounce button2 = Bounce(6, 15); // change LFO destination
Bounce button3 = Bounce(26, 15); // Hold/Release
Bounce button4 = Bounce(24, 15);

// The circuit:
// - LED attached from pin 13 to ground
// - pushbutton attached to pin 8 from +5V
// - 10K resistor attached to pin 8 from ground

const int buttonPinHold = 8; // the number of the pushbutton pin // Hold

const int buttonPinRelease = 12; // the number of the pushbutton pin // Release

int buttonStateHold = 0; // variable for reading the pushbutton status
int buttonStateRelease = 0; // variable for reading the pushbutton status

int led1 = 21;
int led2 = 20;
int led3 = 25;
int led4 = 32;

int current_waveform = 0;


//Mux control pins
int s0 = 2; // digital pin 5 is first switch in multiplexer
int s1 = 3;
int s2 = 4;
int s3 = 5;

//Mux in “SIG” pin
int SIG_pin = 1;
int SIG_pin2 = 16;
int SIG_pin3 = 0;

int scale_index = 0;//var to keep track fo which scale is being used
float DeTune = 1.0;

int current_LFO = 0; // variable for LFO routing

int holdstate1 = 0; // current state of the hold button for touch sensor 1
int lastholdstate1 = 0; // variable to change from Hold to Release

int touchstate1 = 0; // current state of the touch sensor 1
int lasttouchstate1 = 0; // previous state of the touch sensor 1
int touchstate2 = 0; // current state of the touch sensor 2
int lasttouchstate2 = 0; // previous state of the touch sensor 2
int touchstate3 = 0; // current state of the touch sensor 3
int lasttouchstate3 = 0; // previous state of the touch sensor 3
int touchstate4 = 0; // current state of the touch sensor 4
int lasttouchstate4 = 0; // previous state of the touch sensor 4
int touchstate5 = 0; // current state of the touch sensor 5
int lasttouchstate5 = 0; // previous state of the touch sensor 5
int touchstate6 = 0; // current state of the touch sensor 6
int lasttouchstate6 = 0; // previous state of the touch sensor 6
int touchstate7 = 0; // current state of the touch sensor 7
int lasttouchstate7 = 0; // previous state of the touch sensor 7
int touchstate8 = 0; // current state of the touch sensor 8
int lasttouchstate8 = 0; // previous state of the touch sensor 8
int touchstate9 = 0; // current state of the touch sensor 9
int lasttouchstate9 = 0; // previous state of the touch sensor 9
int touchstate10 = 0; // current state of the touch sensor 10
int lasttouchstate10 = 0; // previous state of the touch sensor 10
int touchstate11 = 0; // current state of the touch sensor 11
int lasttouchstate11 = 0; // previous state of the touch sensor 11
int touchstate12 = 0; // current state of the touch sensor 12
int lasttouchstate12 = 0; // previous state of the touch sensor 12
int touchstate13 = 0; // current state of the touch sensor 9
int lasttouchstate13 = 0; // previous state of the touch sensor 9
int touchstate14 = 0; // current state of the touch sensor 10
int lasttouchstate14 = 0; // previous state of the touch sensor 10
int touchstate15 = 0; // current state of the touch sensor 11
int lasttouchstate15 = 0; // previous state of the touch sensor 11
int touchstate16 = 0; // current state of the touch sensor 12
int lasttouchstate16 = 0; // previous state of the touch sensor 12

int touchstate17 = 0; // current state of the touch sensor 17
int lasttouchstate17 = 0; // previous state of the touch sensor 17
int touchstate18 = 0; // current state of the touch sensor 18
int lasttouchstate18 = 0; // previous state of the touch sensor 18
int touchstate19 = 0; // current state of the touch sensor 19
int lasttouchstate19 = 0; // previous state of the touch sensor 19
int touchstate20 = 0; // current state of the touch sensor 20
int lasttouchstate20 = 0; // previous state of the touch sensor 20
int touchstate21 = 0; // current state of the touch sensor 21
int lasttouchstate21 = 0; // previous state of the touch sensor 21
int touchstate22 = 0; // current state of the touch sensor 22
int lasttouchstate22 = 0; // previous state of the touch sensor 22
int touchstate23 = 0; // current state of the touch sensor 23
int lasttouchstate23 = 0; // previous state of the touch sensor 23
int touchstate24 = 0; // current state of the touch sensor 24
int lasttouchstate24 = 0; // previous state of the touch sensor 24

int Attacktime = 0; // Envelope Attack Time
int Decayreleasetime = 0; // Envelope Decay & Release time

int fscalefactor1 = -5.8; //adjust this for a linear curve for vibrato rate
int fscalefactor2 = -8; //adjust this for a linear curve for vibrato depth
int fscalefactor3 = -6; //adjust this for a linear curve for filter cutoff frequency
int fscalefactor4 = -4; //adjust this for a linear curve for filter cutoff LFO amount
int fscalefactor5 = -4; //adjust this for a linear curve for filter resonance


const int numReadings = 11; // SMOOTHING VARIABLES
const int numReadings2 = 12; // LFO intensity smoothing
const int numReadings3 = 13; // Tuning knob smoothing

int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average

int readings2[numReadings2]; // the readings from the analog input
int readIndex2 = 0; // the index of the current reading
int total2 = 0; // the running total
int average2 = 0; // the average

int readings3[numReadings3]; // the readings from the analog input
int readIndex3 = 0; // the index of the current reading
int total3 = 0; // the running total
int average3 = 0; // the average





#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveform waveform1; //xy=115.57479095458984,1430.8572034835815
AudioAmplifier amp1; //xy=295.57479095458984,1432.8572034835815
AudioSynthWaveformModulated waveformMod3; //xy=529.2890701293945,308.00000190734863
AudioSynthWaveformModulated waveformMod2; //xy=530.2890701293945,246.00000190734863
AudioSynthWaveformModulated waveformMod1; //xy=533.2890701293945,181.00000190734863
AudioSynthWaveformModulated waveformMod4; //xy=536.2890701293945,370.00000190734863
AudioSynthWaveformModulated waveformMod10; //xy=536.2890701293945,802.0000019073486
AudioSynthWaveformModulated waveformMod7; //xy=537.2890701293945,590.0000019073486
AudioSynthWaveformModulated waveformMod11; //xy=536.2890701293945,855.0000019073486
AudioSynthWaveformModulated waveformMod9; //xy=537.2890701293945,748.0000019073486
AudioSynthWaveformModulated waveformMod12; //xy=537.2890701293945,908.0000019073486
AudioSynthWaveformModulated waveformMod8; //xy=540.2890701293945,646.0000019073486
AudioSynthWaveformModulated waveformMod6; //xy=542.2890701293945,526.0000019073486
AudioSynthWaveformModulated waveformMod5; //xy=546.2890701293945,462.00000190734863
AudioSynthWaveformModulated waveformMod16; //xy=546.2890701293945,1113.0000019073486
AudioSynthWaveformModulated waveformMod17; //xy=546.2890701293945,1169.0000019073486
AudioSynthWaveformModulated waveformMod21; //xy=545.736699785505,1522.8795216424126
AudioSynthWaveformModulated waveformMod14; //xy=549.2890701293945,1009.0000019073486
AudioSynthWaveformModulated waveformMod15; //xy=549.2890701293945,1059.0000019073486
AudioSynthWaveformModulated waveformMod20; //xy=548.5938153948102,1458.5938245228358
AudioSynthWaveformModulated waveformMod18; //xy=551.6840362548828,1342.2395629882812
AudioSynthWaveformModulated waveformMod19; //xy=551.4509789603097,1402.8795760018486
AudioSynthWaveformModulated waveformMod25; //xy=552.5156173706055,1784.0158405303955
AudioSynthWaveformModulated waveformMod22; //xy=553.5156631469727,1630.0156574249268
AudioSynthWaveformModulated waveformMod23; //xy=554.5156784057617,1681.0159015655518
AudioSynthWaveformModulated waveformMod24; //xy=554.5156478881836,1728.0156574249268
AudioEffectEnvelope envelope2; //xy=713.2890701293945,245.00000190734863
AudioEffectEnvelope envelope1; //xy=718.2890701293945,181.00000190734863
AudioEffectEnvelope envelope6; //xy=719.2890701293945,523.0000019073486
AudioEffectEnvelope envelope7; //xy=721.2890701293945,588.0000019073486
AudioEffectEnvelope envelope5; //xy=722.2890701293945,461.00000190734863
AudioEffectEnvelope envelope3; //xy=723.2890701293945,313.00000190734863
AudioEffectEnvelope envelope8; //xy=727.2890701293945,640.0000019073486
AudioEffectEnvelope envelope9; //xy=727.2890701293945,742.0000019073486
AudioEffectEnvelope envelope4; //xy=730.2890701293945,370.00000190734863
AudioEffectEnvelope envelope12; //xy=729.2890701293945,906.0000019073486
AudioEffectEnvelope envelope11; //xy=730.2890701293945,853.0000019073486
AudioEffectEnvelope envelope10; //xy=734.2890701293945,798.0000019073486
AudioEffectEnvelope envelope24; //xy=737.515625,1782.015625
AudioEffectEnvelope envelope21; //xy=741.515625,1630.015625
AudioEffectEnvelope envelope22; //xy=741.5156364440918,1679.015718460083
AudioEffectEnvelope envelope23; //xy=741.5156173706055,1727.015718460083
AudioEffectEnvelope envelope15; //xy=746.2890701293945,1116.0000019073486
AudioEffectEnvelope envelope14; //xy=748.2890701293945,1063.0000019073486
AudioEffectEnvelope envelope18; //xy=747.1652145385742,1402.8795595169067
AudioEffectEnvelope envelope16; //xy=750.2890701293945,1170.0000019073486
AudioEffectEnvelope envelope13; //xy=752.2890701293945,1010.0000019073486
AudioEffectEnvelope envelope17; //xy=751.4509124755859,1342.8795909881592
AudioEffectEnvelope envelope20; //xy=752.8795013427734,1524.3079586029053
AudioEffectEnvelope envelope19; //xy=754.3080520629883,1460.022367477417
AudioMixer4 mixer1; //xy=904.2890701293945,550.0000019073486
AudioMixer4 mixer4; //xy=919.2890701293945,812.0000019073486
AudioMixer4 mixer2; //xy=929.2890701293945,271.00000190734863
AudioMixer4 mixer7; //xy=932.4510440826416,1699.8796730041504
AudioMixer4 mixer6; //xy=935.2890701293945,1080.0000019073486
AudioMixer4 mixer8; //xy=932.8796081542969,1894.3082809448242
AudioMixer4 mixer9; //xy=937.1654090881348,2154.3082847595215
AudioMixer4 mixer5; //xy=942.8795471191406,1427.8796844482422
AudioMixer4 mixer3; //xy=1110.2890701293945,662.0000019073486
AudioMixer4 mixer10; //xy=1167.165241241455,1524.308122907366
AudioMixer4 mixer11; //xy=1435.736607142857,678.5937499999999
AudioSynthWaveformModulated waveformMod13; //xy=1493.57474899292,844.2857494354248
AudioAmplifier amp13; //xy=1530.57474899292,919.2857494354248
AudioAmplifier amp14; //xy=1682.57474899292,879.2857494354248
AudioFilterStateVariable filter1; //xy=1717.57474899292,672.2857494354248
AudioOutputI2S i2s1; //xy=1869.57474899292,660.2857494354248
AudioConnection patchCord1(waveform1, amp1);
AudioConnection patchCord2(amp1, 0, waveformMod1, 0);
AudioConnection patchCord3(amp1, 0, waveformMod2, 0);
AudioConnection patchCord4(amp1, 0, waveformMod3, 0);
AudioConnection patchCord5(amp1, 0, waveformMod4, 0);
AudioConnection patchCord6(amp1, 0, waveformMod5, 0);
AudioConnection patchCord7(amp1, 0, waveformMod6, 0);
AudioConnection patchCord8(amp1, 0, waveformMod7, 0);
AudioConnection patchCord9(amp1, 0, waveformMod8, 0);
AudioConnection patchCord10(amp1, 0, waveformMod9, 0);
AudioConnection patchCord11(amp1, 0, waveformMod10, 0);
AudioConnection patchCord12(amp1, 0, waveformMod11, 0);
AudioConnection patchCord13(amp1, 0, waveformMod12, 0);
AudioConnection patchCord14(amp1, 0, waveformMod14, 0);
AudioConnection patchCord15(amp1, 0, waveformMod15, 0);
AudioConnection patchCord16(amp1, 0, waveformMod16, 0);
AudioConnection patchCord17(amp1, 0, waveformMod17, 0);
AudioConnection patchCord18(amp1, 0, waveformMod19, 0);
AudioConnection patchCord19(amp1, 0, waveformMod20, 0);
AudioConnection patchCord20(amp1, 0, waveformMod21, 0);
AudioConnection patchCord21(amp1, 0, waveformMod18, 0);
AudioConnection patchCord22(amp1, 0, waveformMod22, 0);
AudioConnection patchCord23(amp1, 0, waveformMod23, 0);
AudioConnection patchCord24(amp1, 0, waveformMod24, 0);
AudioConnection patchCord25(amp1, 0, waveformMod25, 0);
AudioConnection patchCord26(waveformMod3, envelope3);
AudioConnection patchCord27(waveformMod2, envelope2);
AudioConnection patchCord28(waveformMod1, envelope1);
AudioConnection patchCord29(waveformMod4, envelope4);
AudioConnection patchCord30(waveformMod10, envelope10);
AudioConnection patchCord31(waveformMod7, envelope7);
AudioConnection patchCord32(waveformMod11, envelope11);
AudioConnection patchCord33(waveformMod9, envelope9);
AudioConnection patchCord34(waveformMod12, envelope12);
AudioConnection patchCord35(waveformMod8, envelope8);
AudioConnection patchCord36(waveformMod6, envelope6);
AudioConnection patchCord37(waveformMod5, envelope5);
AudioConnection patchCord38(waveformMod16, envelope15);
AudioConnection patchCord39(waveformMod17, envelope16);
AudioConnection patchCord40(waveformMod21, envelope20);
AudioConnection patchCord41(waveformMod14, envelope13);
AudioConnection patchCord42(waveformMod15, envelope14);
AudioConnection patchCord43(waveformMod20, envelope19);
AudioConnection patchCord44(waveformMod18, envelope17);
AudioConnection patchCord45(waveformMod19, envelope18);
AudioConnection patchCord46(waveformMod25, envelope24);
AudioConnection patchCord47(waveformMod22, envelope21);
AudioConnection patchCord48(waveformMod23, envelope22);
AudioConnection patchCord49(waveformMod24, envelope23);
AudioConnection patchCord50(envelope2, 0, mixer2, 1);
AudioConnection patchCord51(envelope1, 0, mixer2, 0);
AudioConnection patchCord52(envelope6, 0, mixer1, 1);
AudioConnection patchCord53(envelope7, 0, mixer1, 2);
AudioConnection patchCord54(envelope5, 0, mixer1, 0);
AudioConnection patchCord55(envelope3, 0, mixer2, 2);
AudioConnection patchCord56(envelope8, 0, mixer1, 3);
AudioConnection patchCord57(envelope9, 0, mixer4, 0);
AudioConnection patchCord58(envelope4, 0, mixer2, 3);
AudioConnection patchCord59(envelope12, 0, mixer4, 3);
AudioConnection patchCord60(envelope11, 0, mixer4, 2);
AudioConnection patchCord61(envelope10, 0, mixer4, 1);
AudioConnection patchCord62(envelope24, 0, mixer7, 3);
AudioConnection patchCord63(envelope21, 0, mixer7, 0);
AudioConnection patchCord64(envelope22, 0, mixer7, 1);
AudioConnection patchCord65(envelope23, 0, mixer7, 2);
AudioConnection patchCord66(envelope15, 0, mixer6, 2);
AudioConnection patchCord67(envelope14, 0, mixer6, 1);
AudioConnection patchCord68(envelope18, 0, mixer5, 1);
AudioConnection patchCord69(envelope16, 0, mixer6, 3);
AudioConnection patchCord70(envelope13, 0, mixer6, 0);
AudioConnection patchCord71(envelope17, 0, mixer5, 0);
AudioConnection patchCord72(envelope20, 0, mixer5, 3);
AudioConnection patchCord73(envelope19, 0, mixer5, 2);
AudioConnection patchCord74(mixer1, 0, mixer3, 1);
AudioConnection patchCord75(mixer4, 0, mixer3, 2);
AudioConnection patchCord76(mixer2, 0, mixer3, 0);
AudioConnection patchCord77(mixer7, 0, mixer10, 1);
AudioConnection patchCord78(mixer6, 0, mixer3, 3);
AudioConnection patchCord79(mixer8, 0, mixer10, 2);
AudioConnection patchCord80(mixer9, 0, mixer10, 3);
AudioConnection patchCord81(mixer5, 0, mixer10, 0);
AudioConnection patchCord82(mixer3, 0, mixer11, 0);
AudioConnection patchCord83(mixer10, 0, mixer11, 1);
AudioConnection patchCord84(mixer11, 0, filter1, 0);
AudioConnection patchCord85(waveformMod13, amp13);
AudioConnection patchCord86(amp13, amp14);
AudioConnection patchCord87(amp14, 0, filter1, 1);
AudioConnection patchCord88(filter1, 0, i2s1, 0);
AudioConnection patchCord89(filter1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=775.2890701293945,85.00000190734863
// GUItool: end automatically generated code




void setup() {

Serial.begin(9600);
AudioMemory(20);
sgtl5000_1.enable();
sgtl5000_1.volume(0.9);

//pinMode(2, INPUT_PULLUP); //Button pins
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(26, INPUT_PULLUP);
pinMode(24, INPUT_PULLUP);

pinMode(buttonPinHold, INPUT); // Hold button setup
pinMode(buttonPinRelease, INPUT); // Release button setup

// pinMode(led1, OUTPUT);
// pinMode(led2, OUTPUT);
// pinMode(led3, OUTPUT);
// pinMode(led4, OUTPUT);

current_waveform = WAVEFORM_SAWTOOTH;
waveformMod1.begin(current_waveform);
waveformMod2.begin(current_waveform);
waveformMod3.begin(current_waveform);
waveformMod4.begin(current_waveform);
waveformMod5.begin(current_waveform);
waveformMod6.begin(current_waveform);
waveformMod7.begin(current_waveform);
waveformMod8.begin(current_waveform);
waveformMod9.begin(current_waveform);
waveformMod10.begin(current_waveform);
waveformMod11.begin(current_waveform);
waveformMod12.begin(current_waveform);
waveformMod14.begin(current_waveform);
waveformMod15.begin(current_waveform);
waveformMod16.begin(current_waveform);
waveformMod17.begin(current_waveform);

waveformMod18.begin(current_waveform);
waveformMod19.begin(current_waveform);
waveformMod20.begin(current_waveform);
waveformMod21.begin(current_waveform);
waveformMod22.begin(current_waveform);
waveformMod23.begin(current_waveform);
waveformMod24.begin(current_waveform);
waveformMod25.begin(current_waveform);

waveformMod13.begin(WAVEFORM_TRIANGLE);
waveform1.begin(WAVEFORM_SINE);

pinMode(s0, OUTPUT);
pinMode(s1, OUTPUT);
pinMode(s2, OUTPUT);
pinMode(s3, OUTPUT);

digitalWrite(s0, LOW);
digitalWrite(s1, LOW);
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);


mixer1.gain(0, 0.3);
mixer1.gain(1, 0.3);
mixer1.gain(2, 0.3);
mixer1.gain(3, 0.3);

mixer2.gain(0, 0.3);
mixer2.gain(1, 0.3);
mixer2.gain(2, 0.3);
mixer2.gain(3, 0.3);

mixer4.gain(0, 0.3);
mixer4.gain(1, 0.3);
mixer4.gain(2, 0.3);
mixer4.gain(3, 0.3);

mixer6.gain(0, 0.3);
mixer6.gain(1, 0.3);
mixer6.gain(2, 0.3);
mixer6.gain(3, 0.3);

mixer3.gain(0, 0.3); // First 16 Mixer //
mixer3.gain(1, 0.3);
mixer3.gain(2, 0.3);
mixer3.gain(3, 0.3);


mixer5.gain(0, 0.3);
mixer5.gain(1, 0.3);
mixer5.gain(2, 0.3);
mixer5.gain(3, 0.3);

mixer7.gain(0, 0.3);
mixer7.gain(1, 0.3);
mixer7.gain(2, 0.3);
mixer7.gain(3, 0.3);

mixer8.gain(0, 0.3);
mixer8.gain(1, 0.3);
mixer8.gain(2, 0.3);
mixer8.gain(3, 0.3);

mixer9.gain(0, 0.3);
mixer9.gain(1, 0.3);
mixer9.gain(2, 0.3);
mixer9.gain(3, 0.3);

mixer10.gain(0, 0.3); // Second 16 Mixer //
mixer10.gain(1, 0.3);
mixer10.gain(2, 0.3);
mixer10.gain(3, 0.3);

mixer11.gain(0, 0.3); // Full 32 Mixer //
mixer11.gain(1, 0.3);
mixer11.gain(2, 0);
mixer11.gain(3, 0);

waveform1.frequency(1); //// LFO ////
waveform1.amplitude(0.1);

waveformMod1.frequency(440); //// Voices ////
waveformMod1.amplitude(0.75);
envelope1.attack(1000);
envelope1.hold(1);
envelope1.decay(1500);
envelope1.sustain(0.5);
envelope1.release(1000);

waveformMod2.frequency(440);
waveformMod2.amplitude(0.75);
envelope2.attack(1000);
envelope2.hold(1);
envelope2.decay(1500);
envelope2.sustain(0.5);
envelope2.release(1000);

waveformMod3.frequency(440);
waveformMod3.amplitude(0.75);

envelope3.attack(1000);
envelope3.hold(1);
envelope3.decay(1500);
envelope3.sustain(0.5);
envelope3.release(1000);

waveformMod4.frequency(440);
waveformMod4.amplitude(0.75);

envelope4.attack(1000);
envelope4.hold(1);
envelope4.decay(1500);
envelope4.sustain(0.5);
envelope4.release(1000);

waveformMod5.frequency(440);
waveformMod5.amplitude(0.75);

envelope5.attack(1000);
envelope5.hold(1);
envelope5.decay(1500);
envelope5.sustain(0.5);
envelope5.release(1000);

waveformMod6.frequency(440);
waveformMod6.amplitude(0.75);

envelope6.attack(1000);
envelope6.hold(1);
envelope6.decay(1500);
envelope6.sustain(0.5);
envelope6.release(1000);

waveformMod7.frequency(440);
waveformMod7.amplitude(0.75);

envelope7.attack(1000);
envelope7.hold(1);
envelope7.decay(1500);
envelope7.sustain(0.5);
envelope7.release(1000);

waveformMod8.frequency(440);
waveformMod8.amplitude(0.75);

envelope8.attack(1000);
envelope8.hold(1);
envelope8.decay(1500);
envelope8.sustain(0.5);
envelope8.release(1000);

waveformMod9.frequency(440);
waveformMod9.amplitude(0.75);

envelope9.attack(1000);
envelope9.hold(1);
envelope9.decay(1500);
envelope9.sustain(0.5);
envelope9.release(1000);

waveformMod10.frequency(440);
waveformMod10.amplitude(0.75);

envelope10.attack(1000);
envelope10.hold(1);
envelope10.decay(1500);
envelope10.sustain(0.5);
envelope10.release(1000);

waveformMod11.frequency(440);
waveformMod11.amplitude(0.75);

envelope11.attack(1000);
envelope11.hold(1);
envelope11.decay(1500);
envelope11.sustain(0.5);
envelope11.release(1000);

waveformMod12.frequency(440);
waveformMod12.amplitude(0.75);

envelope12.attack(1000);
envelope12.hold(1);
envelope12.decay(1500);
envelope12.sustain(0.5);
envelope12.release(1000);

envelope13.attack(1000);
envelope13.hold(1);
envelope13.decay(1500);
envelope13.sustain(0.5);
envelope13.release(1000);

waveformMod14.frequency(440);
waveformMod14.amplitude(0.75);

envelope14.attack(1000);
envelope14.hold(1);
envelope14.decay(1500);
envelope14.sustain(0.5);
envelope14.release(1000);

waveformMod15.frequency(440);
waveformMod15.amplitude(0.75);

envelope15.attack(1000);
envelope15.hold(1);
envelope15.decay(1500);
envelope15.sustain(0.5);
envelope15.release(1000);

waveformMod16.frequency(440);
waveformMod16.amplitude(0.75);

envelope16.attack(1000);
envelope16.hold(1);
envelope16.decay(1500);
envelope16.sustain(0.5);
envelope16.release(1000);

waveformMod17.frequency(440);
waveformMod17.amplitude(0.75);


envelope17.attack(1000);
envelope17.hold(1);
envelope17.decay(1500);
envelope17.sustain(0.5);
envelope17.release(1000);

waveformMod18.frequency(440);
waveformMod18.amplitude(0.75);

envelope18.attack(1000);
envelope18.hold(1);
envelope18.decay(1500);
envelope18.sustain(0.5);
envelope18.release(1000);

waveformMod19.frequency(440);
waveformMod19.amplitude(0.75);

envelope20.attack(1000);
envelope20.hold(1);
envelope20.decay(1500);
envelope20.sustain(0.5);
envelope20.release(1000);

waveformMod20.frequency(440);
waveformMod20.amplitude(0.75);

waveformMod21.frequency(440);
waveformMod21.amplitude(0.75);


waveformMod13.frequency(2); // LFO for filter //
waveformMod13.amplitude(1);
waveformMod13.offset(-0.232); ///// use offset to modulate from -1 to 0 so that filter freq doesn't go too high


// amp1.gain(1.); // Stop modulation from affecting pitch when filter mod engaged
amp14.gain(0.); // Stop modulation from affecting filter when pitch mod engaged

filter1.resonance(0.705); // Filter Resonance
filter1.octaveControl(7); // Number of octaves a control sig. of 1 will shift filter



// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
}

int amps_setting = 0;
float FilterResMin = 0.7;


void loop() {


///////////////////////////////////////////////////////////////////////////////////////////
///////////////////// Change Waveform ////////////////

button1.update();

if (button1.fallingEdge()) {
switch (current_waveform) {
case WAVEFORM_SINE:
current_waveform = WAVEFORM_SAWTOOTH;
Serial.println("Sawtooth");
break;
case WAVEFORM_SAWTOOTH:
current_waveform = WAVEFORM_SQUARE;
Serial.println("Square");
break;
case WAVEFORM_SQUARE:
current_waveform = WAVEFORM_TRIANGLE;
Serial.println("Triangle");
break;
case WAVEFORM_TRIANGLE:
current_waveform = WAVEFORM_SINE;
Serial.println("Sine");
break;

}
waveformMod1.begin(current_waveform);
waveformMod2.begin(current_waveform);
waveformMod3.begin(current_waveform);
waveformMod4.begin(current_waveform);
waveformMod5.begin(current_waveform);
waveformMod6.begin(current_waveform);
waveformMod7.begin(current_waveform);
waveformMod8.begin(current_waveform);
waveformMod9.begin(current_waveform);
waveformMod10.begin(current_waveform);
waveformMod11.begin(current_waveform);
waveformMod12.begin(current_waveform);
waveformMod14.begin(current_waveform);
waveformMod15.begin(current_waveform);
waveformMod16.begin(current_waveform);
waveformMod17.begin(current_waveform);

waveformMod18.begin(current_waveform);
waveformMod19.begin(current_waveform);
waveformMod20.begin(current_waveform);
waveformMod21.begin(current_waveform);
waveformMod22.begin(current_waveform);
waveformMod23.begin(current_waveform);
waveformMod24.begin(current_waveform);
waveformMod25.begin(current_waveform);
}

///////////////////////////////////////////////////////////////////////////////////////////
///////////////////// Change LFO destination ////////////////
/* {
digitalWrite(led1, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led1, LOW); // turn the LED off by making the voltage LOW
delay(1000);
}

*/

button2.update();

// Button 2 changes the LFO destination by switching the input levels on mixers feeding mod destinations

if (button2.fallingEdge()) { // LFO to Filter
if (amps_setting == 0) {
amp1.gain(0);
amp14.gain(1); // 2nd LFO amp
FilterResMin = 1.1;
Serial.println("LFO Filter");
amps_setting = 1;
}

else if (amps_setting == 1) { // LFO to Pitch & Filter
amp1.gain(1.);
amp14.gain(1.);
FilterResMin = 1.1;
Serial.println("LFO Pitch & Filter");
amps_setting = 2;
}

else if (amps_setting == 2) { // LFO to Pitch
amp1.gain(1.);
amp14.gain(0);
FilterResMin = 0.7;
Serial.println("LFO Pitch");
amps_setting = 0;
}

}



// read the state of the Hold button value:
buttonStateHold = digitalRead(buttonPinHold);
buttonStateRelease = digitalRead(buttonPinRelease);

//////////////////////////////////////////////////////
//////// Scale ///////////




scale_index = 0; // map(analogRead(A19), 0, 1023, 0, 7); // Change Scale
//Serial.print("Scale = ");
//Serial.println(scale_index);
//DeTune = ((float)readMux2(0) / 1023) + 1; // ((float)average3 / 1023) + 1; // Read Mux 2 input 0 and send value to DeTune Oscilators
DeTune = ((float)average3 / 1023) + 1;
//Serial.print(readMux2(0));
// Serial.print(" P0 = ");
// Serial.println( DeTune);
// delay(100);

waveformMod1.frequency((note_frequency[scale[scale_index][0]] * DeTune)); // Tune up one octave
waveformMod2.frequency((note_frequency[scale[scale_index][1]] * DeTune)); // Tune up one octave
waveformMod3.frequency((note_frequency[scale[scale_index][2]] * DeTune)); // Tune up one octave
waveformMod4.frequency((note_frequency[scale[scale_index][3]] * DeTune)); // Tune up one octave
waveformMod5.frequency((note_frequency[scale[scale_index][4]] * DeTune)); // Tune up one octave
waveformMod6.frequency((note_frequency[scale[scale_index][5]] * DeTune)); // Tune up one octave
waveformMod7.frequency((note_frequency[scale[scale_index][6]] * DeTune)); // Tune up one octave
waveformMod8.frequency((note_frequency[scale[scale_index][7]] * DeTune)); // Tune up one octave
waveformMod9.frequency((note_frequency[scale[scale_index][8]] * DeTune)); // Tune up one octave
waveformMod10.frequency((note_frequency[scale[scale_index][9]] * DeTune)); // Tune up one octave
waveformMod11.frequency((note_frequency[scale[scale_index][10]] * DeTune)); // Tune up one octave
waveformMod12.frequency((note_frequency[scale[scale_index][11]] * DeTune)); // Tune up one octave
waveformMod14.frequency((note_frequency[scale[scale_index][12]] * DeTune)); // Tune up one octave
waveformMod15.frequency((note_frequency[scale[scale_index][13]] * DeTune)); // Tune up one octave
waveformMod16.frequency((note_frequency[scale[scale_index][14]] * DeTune)); // Tune up one octave
waveformMod17.frequency((note_frequency[scale[scale_index][15]] * DeTune)); // Tune up one octave

waveformMod18.frequency((note_frequency[scale[scale_index][16]] * DeTune)); // Tune up one octave
waveformMod19.frequency((note_frequency[scale[scale_index][17]] * DeTune)); // Tune up one octave
waveformMod20.frequency((note_frequency[scale[scale_index][18]] * DeTune)); // Tune up one octave
waveformMod21.frequency((note_frequency[scale[scale_index][19]] * DeTune)); // Tune up one octave
waveformMod22.frequency((note_frequency[scale[scale_index][20]] * DeTune)); // Tune up one octave
waveformMod23.frequency((note_frequency[scale[scale_index][21]] * DeTune)); // Tune up one octave
waveformMod24.frequency((note_frequency[scale[scale_index][22]] * DeTune)); // Tune up one octave
waveformMod25.frequency((note_frequency[scale[scale_index][23]] * DeTune)); // Tune up one octave



///////////////////////////////////////////////////
///// Envelopes /////

//check knob and set value as envelope attack time
Attacktime = map(readMux2(3), 0, 1023, 1, 4000);

envelope1.attack(Attacktime);
envelope2.attack(Attacktime);
envelope3.attack(Attacktime);
envelope4.attack(Attacktime);
envelope5.attack(Attacktime);
envelope6.attack(Attacktime);
envelope7.attack(Attacktime);
envelope8.attack(Attacktime);
envelope9.attack(Attacktime);
envelope10.attack(Attacktime);
envelope11.attack(Attacktime);
envelope12.attack(Attacktime);
envelope13.attack(Attacktime);
envelope14.attack(Attacktime);
envelope15.attack(Attacktime);
envelope16.attack(Attacktime);

envelope17.attack(Attacktime);
envelope18.attack(Attacktime);
envelope19.attack(Attacktime);
envelope20.attack(Attacktime);
envelope21.attack(Attacktime);
envelope22.attack(Attacktime);
envelope23.attack(Attacktime);
envelope24.attack(Attacktime);


//check knob and set value as decay & release times (and scale sustain level so that short decay = low sustain, long decay = high sustain)
Decayreleasetime = map(readMux2(4), 0, 1023, 1, 9000);
//Serial.println(analogRead(A18));
envelope1.decay(Decayreleasetime);
envelope1.release(Decayreleasetime);
envelope2.decay(Decayreleasetime);
envelope2.release(Decayreleasetime);
envelope3.decay(Decayreleasetime);
envelope3.release(Decayreleasetime);
envelope4.decay(Decayreleasetime);
envelope4.release(Decayreleasetime);
envelope5.decay(Decayreleasetime);
envelope5.release(Decayreleasetime);
envelope6.decay(Decayreleasetime);
envelope6.release(Decayreleasetime);
envelope7.decay(Decayreleasetime);
envelope7.release(Decayreleasetime);
envelope8.decay(Decayreleasetime);
envelope8.release(Decayreleasetime);
envelope9.decay(Decayreleasetime);
envelope9.release(Decayreleasetime);
envelope10.decay(Decayreleasetime);
envelope10.release(Decayreleasetime);
envelope11.decay(Decayreleasetime);
envelope11.release(Decayreleasetime);
envelope12.decay(Decayreleasetime);
envelope12.release(Decayreleasetime);
envelope13.decay(Decayreleasetime);
envelope13.release(Decayreleasetime);
envelope14.decay(Decayreleasetime);
envelope14.release(Decayreleasetime);
envelope15.decay(Decayreleasetime);
envelope15.release(Decayreleasetime);
envelope16.decay(Decayreleasetime);
envelope16.release(Decayreleasetime);

envelope17.decay(Decayreleasetime);
envelope17.release(Decayreleasetime);
envelope18.decay(Decayreleasetime);
envelope18.release(Decayreleasetime);
envelope19.decay(Decayreleasetime);
envelope19.release(Decayreleasetime);
envelope20.decay(Decayreleasetime);
envelope20.release(Decayreleasetime);
envelope21.decay(Decayreleasetime);
envelope21.release(Decayreleasetime);
envelope22.decay(Decayreleasetime);
envelope22.release(Decayreleasetime);
envelope23.decay(Decayreleasetime);
envelope23.release(Decayreleasetime);
envelope24.decay(Decayreleasetime);
envelope24.release(Decayreleasetime);

//////////////////////////////////////////////////////////////////////////////////////////////////////////
//// Note ON/OFF ////





////// read the touch sensor 1 //////////

if (readMux(0) > 4500)
{
touchstate1 = 1;
}
if (readMux(0) <= 4500)
{
touchstate1 = 0;
}

if (touchstate1 != lasttouchstate1) { // if the keystate has changed

if (touchstate1 == 1) { // if the button was pressed start noteON
envelope1.noteOn();
Serial.println("noteon 1");
}

else { // if the button was released

if (buttonStateHold == HIGH) { // if BOTH the key is release AND the Hold button is depressed, no NoteOff message
// holdstate1 = 1; // holdstate = 1 if note is held
Serial.println("noteon 1 Held");
}


else // if Hold button is Not pressed note is released
// holdstate1 = 0; // holdstate = 0 if note is NOT held
envelope1.noteOff();
Serial.println("noteoff 1");
}

delay(1);
}
lasttouchstate1 = touchstate1;

lastholdstate1 = holdstate1; // if butttonState changes make lastButtonState hold that value

if (buttonStateRelease == HIGH) { // If release was pressed, send note off


// holdstate1 = 0;
envelope1.noteOff();
Serial.println("release");
}

else {

//Serial.println("Nothing");


}

///////////////////////////////////////// read the touch sensor 2 /////////////

if (readMux(1) > 4500)
{
touchstate2 = 1;
}
if (readMux(1) <= 4500)
{
touchstate2 = 0;
}

if (touchstate2 != lasttouchstate2) { // if the keystate has changed

if (touchstate2 == 1) { // if the button was pressed start noteON
envelope2.noteOn();
Serial.println("noteon 2");
}

else { // if the button was released

if (buttonStateHold == HIGH) { // if BOTH the key is release AND the Hold button is depressed, no NoteOff message
// holdstate2 = 1; // holdstate2 = 1 if note is held
Serial.println("noteon 3 Held");
}


else // if Hold button is Not pressed note is released
// holdstate2 = 0; // holdstate = 0 if note is NOT held
envelope2.noteOff();
Serial.println("noteoff 2");
}

delay(1);
}
lasttouchstate2 = touchstate2;

// lastholdstate2 = holdstate2; // if butttonState changes make lastButtonState hold that value

if (buttonStateRelease == HIGH) { // If release was pressed, send note off


// holdstate1 = 0;
envelope2.noteOff();
Serial.println("release");
}

else {

//Serial.println("Nothing");


}

////// read the touch sensor 3 //////////

if (readMux(2) > 4500)
{
touchstate3 = 1;
}
if (readMux(2) <= 4500)
{
touchstate3 = 0;
}

if (touchstate3 != lasttouchstate3) {

if (touchstate3 == 1) { // if the key was pressed, start noteON
envelope3.noteOn();
Serial.println("noteon 3");
}
else { // if the key was released:
if (buttonStateHold == HIGH) { // if BOTH the key is release AND the Hold button is depressed, NO NoteOff message
Serial.println("noteon 3 Held");
}
else // if Hold button is Not pressed, note is released
envelope3.noteOff();
Serial.println("noteoff 3");
}
delay(1);
}
lasttouchstate3 = touchstate3;

if (buttonStateRelease == HIGH) { // If release was pressed, send note off
envelope3.noteOff();
Serial.println("release");
}
else {
}

///////////////////////////////////////// read the touch sensor 4 /////////////

if (readMux(3) > 4500)
{
touchstate4 = 1;
}
if (readMux(3) <= 4500)
{
touchstate4 = 0;
}

if (touchstate4 != lasttouchstate4) {

if (touchstate4 == 1) { // if the key was pressed, start noteON
envelope4.noteOn();
Serial.println("noteon 4");
}
else { // if the key was released:
if (buttonStateHold == HIGH) { // if BOTH the key is release AND the Hold button is depressed, NO NoteOff message
Serial.println("noteon 4 Held");
}
else // if Hold button is Not pressed, note is released
envelope4.noteOff();
Serial.println("noteoff 4");
}
delay(1);
}
lasttouchstate4 = touchstate4;

if (buttonStateRelease == HIGH) { // If release was pressed, send note off
envelope4.noteOff();
Serial.println("release");
}
else {
}


////// read the touch sensor 5 //////////

if (readMux(4) > 4500)
{
touchstate5 = 1;
}
if (readMux(4) <= 4500)
{
touchstate5 = 0;
}

if (touchstate5 != lasttouchstate5) {
if (touchstate5 == 1) { // if the key was pressed, start noteON
envelope5.noteOn();
Serial.println("noteon 5");
}
else { // if the key was released:
if (buttonStateHold == HIGH) { // if BOTH the key is release AND the Hold button is depressed, NO NoteOff message
Serial.println("noteon 5 Held");
}
else // if Hold button is Not pressed, note is released
envelope5.noteOff();
Serial.println("noteoff 4");
}
delay(1);
}
lasttouchstate5 = touchstate5;

if (buttonStateRelease == HIGH) { // If release was pressed, send note off
envelope5.noteOff();
Serial.println("release");
}
else {
}



///////////////////////////////////////// read the touch sensor 6 /////////////

if (readMux(5) > 4500)
{
touchstate6 = 1;
}
if (readMux(5) <= 4500)
{
touchstate6 = 0;
}

if (touchstate6 != lasttouchstate6) {
if (touchstate6 == 1) {
envelope6.noteOn();
Serial.println("noteon 6");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 6 Held");
}
else
envelope6.noteOff();
Serial.println("noteoff 6");
}
delay(1);
}
lasttouchstate6 = touchstate6;

if (buttonStateRelease == HIGH) {
envelope6.noteOff();
Serial.println("release");
}
else {
}

////// read the touch sensor 7 //////////

if (readMux(6) > 4500)
{
touchstate7 = 1;
}
if (readMux(6) <= 4500)
{
touchstate7 = 0;
}

if (touchstate7 != lasttouchstate7) {
if (touchstate7 == 1) {
envelope7.noteOn();
Serial.println("noteon 7");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 7 Held");
}
else
envelope7.noteOff();
Serial.println("noteoff 7");
}
delay(1);
}
lasttouchstate7 = touchstate7;

if (buttonStateRelease == HIGH) {
envelope7.noteOff();
Serial.println("release");
}
else {
}



///////////////////////////////////////// read the touch sensor 8 /////////////

if (readMux(7) > 4500)
{
touchstate8 = 1;
}
if (readMux(7) <= 4500)
{
touchstate8 = 0;
}

if (touchstate8 != lasttouchstate8) {
if (touchstate8 == 1) {
envelope8.noteOn();
Serial.println("noteon 8");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 8 Held");
}
else
envelope8.noteOff();
Serial.println("noteoff 8");
}
delay(1);
}
lasttouchstate8 = touchstate8;

if (buttonStateRelease == HIGH) {
envelope8.noteOff();
Serial.println("release");
}
else {
}



//////////// read the touch sensor 9 ///////////////////////////////////////////////////////

if (readMux(8) > 4500)
{
touchstate9 = 1;
}
if (readMux(8) <= 4500)
{
touchstate9 = 0;
}

if (touchstate9 != lasttouchstate9) {
if (touchstate9 == 1) {
envelope9.noteOn();
Serial.println("noteon 10");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 9 Held");
}
else
envelope9.noteOff();
Serial.println("noteoff 9");
}
delay(1);
}
lasttouchstate9 = touchstate9;

if (buttonStateRelease == HIGH) {
envelope9.noteOff();
Serial.println("release");
}
else {
}




///////////////////////////////////////// read the touch sensor 10 /////////////

if (readMux(9) > 4500)
{
touchstate10 = 1;
}
if (readMux(9) <= 4500)
{
touchstate10 = 0;
}

if (touchstate10 != lasttouchstate10) {
if (touchstate10 == 1) {
envelope10.noteOn();
Serial.println("noteon 10");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 10 Held");
}
else
envelope10.noteOff();
Serial.println("noteoff 10");
}
delay(1);
}
lasttouchstate10 = touchstate10;

if (buttonStateRelease == HIGH) {
envelope10.noteOff();
Serial.println("release");
}
else {
}


////// read the touch sensor 11 ///////////////////////////////////////////////

if (readMux(10) > 4500)
{
touchstate11 = 1;
}
if (readMux(10) <= 4500)
{
touchstate11 = 0;
}

if (touchstate11 != lasttouchstate11) {
if (touchstate11 == 1) {
envelope11.noteOn();
Serial.println("noteon 11");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 11 Held");
}
else
envelope11.noteOff();
Serial.println("noteoff 11");
}
delay(1);
}
lasttouchstate11 = touchstate11;

if (buttonStateRelease == HIGH) {
envelope11.noteOff();
Serial.println("release");
}
else {
}



///////////////////////////////////////// read the touch sensor 12 /////////////

if (readMux(11) > 4500)
{
touchstate12 = 1;
}
if (readMux(11) <= 4500)
{
touchstate12 = 0;
}

if (touchstate12 != lasttouchstate12) {
if (touchstate12 == 1) {
envelope12.noteOn();
Serial.println("noteon 12");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 12 Held");
}
else
envelope12.noteOff();
Serial.println("noteoff 12");
}
delay(1);
}
lasttouchstate12 = touchstate12;

if (buttonStateRelease == HIGH) {
envelope12.noteOff();
Serial.println("release");
}
else {
}

//////////// read the touch sensor 13 ///////////////////////////////////////////////////////

if (readMux(12) > 4500)
{
touchstate13 = 1;
}
if (readMux(12) <= 4500)
{
touchstate13 = 0;
}

if (touchstate13 != lasttouchstate13) {
if (touchstate13 == 1) {
envelope13.noteOn();
Serial.println("noteon 13");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 13 Held");
}
else
envelope13.noteOff();
Serial.println("noteoff 13");
}
delay(1);
}
lasttouchstate13 = touchstate13;

if (buttonStateRelease == HIGH) {
envelope13.noteOff();
Serial.println("release");
}
else {
}



///////////////////////////////////////// read the touch sensor 14 /////////////

if (readMux(13) > 4500)
{
touchstate14 = 1;
}
if (readMux(13) <= 4500)
{
touchstate14 = 0;
}

if (touchstate14 != lasttouchstate14) {
if (touchstate14 == 1) {
envelope14.noteOn();
Serial.println("noteon 14");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 14 Held");
}
else
envelope14.noteOff();
Serial.println("noteoff 14");
}
delay(1);
}
lasttouchstate14 = touchstate14;

if (buttonStateRelease == HIGH) {
envelope14.noteOff();
Serial.println("release");
}
else {
}

////// read the touch sensor 15 ///////////////////////////////////////////////

if (readMux(14) > 4500)
{
touchstate15 = 1;
}
if (readMux(14) <= 4500)
{
touchstate15 = 0;
}

if (touchstate15 != lasttouchstate15) {
if (touchstate15 == 1) {
envelope15.noteOn();
Serial.println("noteon 10");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 15 Held");
}
else
envelope15.noteOff();
Serial.println("noteoff 15");
}
delay(1);
}
lasttouchstate15 = touchstate15;

if (buttonStateRelease == HIGH) {
envelope15.noteOff();
Serial.println("release");
}
else {
}



///////////////////////////////////////// read the touch sensor 16 /////////////

if (readMux(15) > 4500)
{
touchstate16 = 1;
}
if (readMux(15) <= 4500)
{
touchstate16 = 0;
}

if (touchstate16 != lasttouchstate16) {
if (touchstate16 == 1) {
envelope16.noteOn();
Serial.println("noteon 16");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 16 Held");
}
else
envelope16.noteOff();
Serial.println("noteoff 16");
}
delay(1);
}
lasttouchstate16 = touchstate16;

if (buttonStateRelease == HIGH) {
envelope16.noteOff();
Serial.println("release");
}
else {
}





//////////// read the touch sensor 17 ///////////////////////////////////////////////////////

if (readMux3(0) > 4500)
{
touchstate17 = 1;
}
if (readMux3(0) <= 4500)
{
touchstate17 = 0;
}

if (touchstate17 != lasttouchstate17) {
if (touchstate17 == 1) {
envelope17.noteOn();
Serial.println("noteon 17");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 17 Held");
}
else
envelope17.noteOff();
Serial.println("noteoff 17");
}
delay(1);
}
lasttouchstate17 = touchstate17;

if (buttonStateRelease == HIGH) {
envelope17.noteOff();
Serial.println("release");
}
else {
}



///////////////////////////////////////// read the touch sensor 18 /////////////

if (readMux3(1) > 4500)
{
touchstate18 = 1;
}
if (readMux3(1) <= 4500)
{
touchstate18 = 0;
}

if (touchstate18 != lasttouchstate18) {
if (touchstate18 == 1) {
envelope18.noteOn();
Serial.println("noteon 18");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 18 Held");
}
else
envelope18.noteOff();
Serial.println("noteoff 18");
}
delay(1);
}
lasttouchstate18 = touchstate18;

if (buttonStateRelease == HIGH) {
envelope18.noteOff();
Serial.println("release");
}
else {
}

////// read the touch sensor 19 ///////////////////////////////////////////////

if (readMux3(2) > 4500)
{
touchstate19 = 1;
}
if (readMux3(2) <= 4500)
{
touchstate19 = 0;
}

if (touchstate19 != lasttouchstate19) {
if (touchstate19 == 1) {
envelope19.noteOn();
Serial.println("noteon 19");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 19 Held");
}
else
envelope19.noteOff();
Serial.println("noteoff 19");
}
delay(1);
}
lasttouchstate19 = touchstate19;

if (buttonStateRelease == HIGH) {
envelope19.noteOff();
Serial.println("release");
}
else {
}



///////////////////////////////////////// read the touch sensor 20 /////////////

if (readMux3(3) > 4500)
{
touchstate20 = 1;
}
if (readMux3(3) <= 4500)
{
touchstate20 = 0;
}

if (touchstate20 != lasttouchstate20) {
if (touchstate20 == 1) {
envelope20.noteOn();
Serial.println("noteon 20");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 20 Held");
}
else
envelope20.noteOff();
Serial.println("noteoff 20");
}
delay(1);
}
lasttouchstate20 = touchstate20;

if (buttonStateRelease == HIGH) {
envelope20.noteOff();
Serial.println("release");
}
else {
}

//////////// read the touch sensor 21 ///////////////////////////////////////////////////////

if (readMux3(4) > 4500)
{
touchstate21 = 1;
}
if (readMux3(4) <= 4500)
{
touchstate21 = 0;
}

if (touchstate21 != lasttouchstate21) {
if (touchstate21 == 1) {
envelope21.noteOn();
Serial.println("noteon 21");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 21 Held");
}
else
envelope21.noteOff();
Serial.println("noteoff 21");
}
delay(1);
}
lasttouchstate21 = touchstate21;

if (buttonStateRelease == HIGH) {
envelope21.noteOff();
Serial.println("release");
}
else {
}



///////////////////////////////////////// read the touch sensor 22 /////////////

if (readMux3(5) > 4500)
{
touchstate22 = 1;
}
if (readMux3(5) <= 4500)
{
touchstate22 = 0;
}

if (touchstate22 != lasttouchstate22) {
if (touchstate22 == 1) {
envelope22.noteOn();
Serial.println("noteon 22");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 22 Held");
}
else
envelope22.noteOff();
Serial.println("noteoff 22");
}
delay(1);
}
lasttouchstate22 = touchstate22;

if (buttonStateRelease == HIGH) {
envelope22.noteOff();
Serial.println("release");
}
else {
}

////// read the touch sensor 23 ///////////////////////////////////////////////

if (readMux3(6) > 4500)
{
touchstate23 = 1;
}
if (readMux3(6) <= 4500)
{
touchstate23 = 0;
}

if (touchstate23 != lasttouchstate23) {
if (touchstate23 == 1) {
envelope23.noteOn();
Serial.println("noteon 23");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 23 Held");
}
else
envelope23.noteOff();
Serial.println("noteoff 23");
}
delay(1);
}
lasttouchstate23 = touchstate23;

if (buttonStateRelease == HIGH) {
envelope23.noteOff();
Serial.println("release");
}
else {
}



///////////////////////////////////////// read the touch sensor 24 /////////////

if (readMux3(7) > 4500)
{
touchstate24 = 1;
}
if (readMux3(7) <= 4500)
{
touchstate24 = 0;
}

if (touchstate24 != lasttouchstate24) {
if (touchstate24 == 1) {
envelope24.noteOn();
Serial.println("noteon 24");
}
else {
if (buttonStateHold == HIGH) {
Serial.println("noteon 24 Held");
}
else
envelope24.noteOff();
Serial.println("noteoff 24");
}
delay(1);
}
lasttouchstate24 = touchstate24;

if (buttonStateRelease == HIGH) {
envelope24.noteOff();
Serial.println("release");
}
else {
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////// LFO //////////

/////////////////////////////////////////////// 2nd AVERAGE // to smooth vibrato depth

{
// subtract the last reading:
total2 = total2 - readings2[readIndex2];
// read from the sensor:
readings2[readIndex2] = readMux2(2);
// add the reading to the total:
total2 = total2 + readings2[readIndex2];
// advance to the next position in the array:
readIndex2 = readIndex2 + 1;

// if we're at the end of the array...
if (readIndex2 >= numReadings2) {
// ...wrap around to the beginning:
readIndex2 = 0;
}

// calculate the average :

average2 = total2 / numReadings2;
}

float LFORate = fscale( 0, 1023, 0.08, 65.406, (float)readMux2(1), fscalefactor1); // Scale the vibrato rate
float LFODepth = fscale(0, 1023, 0, 0.6, average2, fscalefactor2); // Scale the vibrato depth
float cutoff = fscale(0, 1023, 70, 13900, average, fscalefactor3); // Scale the filter cutoff freq
float FilterLFOintensity = fscale( 0, 1023, 0, 0.9, average2, fscalefactor4); // Scale the filter LFO intensity


waveform1.frequency(LFORate); // Pitch LFO //
waveform1.amplitude(LFODepth);

waveformMod13.frequency(LFORate); // Filter LFO //
amp13.gain(FilterLFOintensity);
// Serial.println(LFODepth);
///////////////////////////////////////////////////////////////////////////////////////////////////
/////////// Filter /////////////

float FilterRes = fscale( 0, 1023, FilterResMin, 5, readMux2(5), fscalefactor5); // Scale the filter resonance
filter1.resonance(FilterRes); // Filter Resonance


// Serial.print(" Filter Resonance = ");
// Serial.println(FilterRes);

/////////// Smooth values for filter ///////////

// subtract the last reading:
{
total = total - readings[readIndex];
// read from the sensor:
readings[readIndex] = readMux2(6);
// add the reading to the total:
total = total + readings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;

// if we're at the end of the array...
if (readIndex >= numReadings) {
// ...wrap around to the beginning:
readIndex = 0;
}

// calculate the average:
average = total / numReadings;
}
// send it to the computer as ASCII digits
//Serial.println(average);
//delay(1); // delay in between reads for stability

// use the average to change the filter frequency
// int knob = average;

filter1.frequency(cutoff);
//Serial.print("frequency = ");
// Serial.println(cutoff);
// delay(1);


/////////////////////////////////////////////// 3rd AVERAGE // to smooth tuning knob
{
// subtract the last reading:
total3 = total3 - readings3[readIndex3];
// read from the sensor:
readings3[readIndex3] = readMux2(0);
// add the reading to the total:
total3 = total3 + readings3[readIndex3];
// advance to the next position in the array:
readIndex3 = readIndex3 + 1;

// if we're at the end of the array...
if (readIndex3 >= numReadings3) {
// ...wrap around to the beginning:
readIndex3 = 0;
}

// calculate the average :

average3 = total3 / numReadings3;
// Serial.print(average3);
// delay(100);
}



// Serial.print("\t Tune = ");
// Serial.print(readMux2(9));
// Serial.print("\t LFODepth = ");
// Serial.println(readMux2(2));
// Serial.print("\t Cutoff = ");
// Serial.println(readMux2(7));
// delay(1);


}

///////////////////////////////////////////////////////////////////////////////////////////////
//////// Multiplexer /////////////

int readMux(int channel){
int controlPin[] = {s0, s1, s2, s3};

int muxChannel[16][4]={
{0,0,0,0}, //channel 0
{1,0,0,0}, //channel 1
{0,1,0,0}, //channel 2
{1,1,0,0}, //channel 3
{0,0,1,0}, //channel 4
{1,0,1,0}, //channel 5
{0,1,1,0}, //channel 6
{1,1,1,0}, //channel 7
{0,0,0,1}, //channel 8
{1,0,0,1}, //channel 9
{0,1,0,1}, //channel 10
{1,1,0,1}, //channel 11
{0,0,1,1}, //channel 12
{1,0,1,1}, //channel 13
{0,1,1,1}, //channel 14
{1,1,1,1} //channel 15
};

//loop through the 4 sig
for(int i = 0; i < 4; i ++){
digitalWrite(controlPin[i], muxChannel[channel][i]);
}

//Serial.println(readMux(1));
//read the value at the SIG pin
int val = touchRead(SIG_pin);
//return the value
return val;
}

//////////////////////////////////////////////////// MUX 2

int readMux2(int channel2){
int controlPin2[] = {s0, s1, s2, s3};

int muxChannel2[16][4]={
{0,0,0,0}, //channel 0
{1,0,0,0}, //channel 1
{0,1,0,0}, //channel 2
{1,1,0,0}, //channel 3
{0,0,1,0}, //channel 4
{1,0,1,0}, //channel 5
{0,1,1,0}, //channel 6
{1,1,1,0}, //channel 7
{0,0,0,1}, //channel 8
{1,0,0,1}, //channel 9
{0,1,0,1}, //channel 10
{1,1,0,1}, //channel 11
{0,0,1,1}, //channel 12
{1,0,1,1}, //channel 13
{0,1,1,1}, //channel 14
{1,1,1,1} //channel 15
};

//loop through the 4 sig
for(int i = 0; i < 4; i ++){
digitalWrite(controlPin2[i], muxChannel2[channel2][i]);
}

//Serial.println(readMux(1));
//read the value at the SIG pin
int val2 = analogRead(SIG_pin2);
//return the value
return val2;
}

////////////////////////////////////////// MUX 3

int readMux3(int channel3){
int controlPin3[] = {s0, s1, s2, s3};

int muxChannel3[16][4]={
{0,0,0,0}, //channel 0
{1,0,0,0}, //channel 1
{0,1,0,0}, //channel 2
{1,1,0,0}, //channel 3
{0,0,1,0}, //channel 4
{1,0,1,0}, //channel 5
{0,1,1,0}, //channel 6
{1,1,1,0}, //channel 7
{0,0,0,1}, //channel 8
{1,0,0,1}, //channel 9
{0,1,0,1}, //channel 10
{1,1,0,1}, //channel 11
{0,0,1,1}, //channel 12
{1,0,1,1}, //channel 13
{0,1,1,1}, //channel 14
{1,1,1,1} //channel 15
};

//loop through the 4 sig
for(int i = 0; i < 4; i ++){
digitalWrite(controlPin3[i], muxChannel3[channel3][i]);
}

//read the value at the SIG pin
int val3 = touchRead(SIG_pin3);

//return the value
return val3;
}

//////////////////////////////////////////////////////////////////////////////////////
// The rest below is the "fscale" code: ///


float fscale( float originalMin, float originalMax, float newBegin, float
newEnd, float inputValue, float curve){

float OriginalRange = 0;
float NewRange = 0;
float zeroRefCurVal = 0;
float normalizedCurVal = 0;
float rangedValue = 0;
boolean invFlag = 0;


// condition curve parameter
// limit range

if (curve > 10) curve = 10;
if (curve < -10) curve = -10;

curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output
curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function

// Check for out of range inputValues
if (inputValue < originalMin) {
inputValue = originalMin;
}
if (inputValue > originalMax) {
inputValue = originalMax;
}

// Zero Refference the values
OriginalRange = originalMax - originalMin;

if (newEnd > newBegin){
NewRange = newEnd - newBegin;
}
else
{
NewRange = newBegin - newEnd;
invFlag = 1;
}

zeroRefCurVal = inputValue - originalMin;
normalizedCurVal = zeroRefCurVal / OriginalRange; // normalize to 0 - 1 float



// Check for originalMin > originalMax - the math for all other cases i.e. negative numbers seems to work out fine
if (originalMin > originalMax ) {
return 0;
}

if (invFlag == 0){
rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin;

}
else // invert the ranges
{
rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange);
}

return rangedValue;
;
}