Wierd and frustrating ?bugs?

Status
Not open for further replies.

RogerD

Well-known member
I've been developing my synth project for a while now and have had some ongoing problems that I just can't iron out after trying for months. The description of these are in the top of my following code listing. I was hoping to post this when I had my code better documented and cleaned up more but it has been frustrating me a lot lately and I suspect some of these issues may point to some basic bugs in some of the modules.
The design is at this point fairly basic. An 8 key poly synth with 3 base waveform gens, a SineFM, a PWM and a multiply derived from them and recently noise. These feed to a simple filter envelope and also an amplitude envelope before passing to a flange. There are other bits and pieces in there but that is basically it.
I have a hunch that the main problems I am having all relate to a common source mistake somewhere. It could be that I have been going over and over this for so long that I have just gotten into the habit of missing something that I have done wrong.
There is a fair bit of rubbish code here that I have commented out but hopefully it will make reasonable sense.
I would be grateful for any assistance or ideas and of course, feel free to use any code that I have built here for your own projects. Just about everything here works except for the listed issues.
Oh, and the midi library was one of the earlier versions (2.4 I think) on the principle of if it ain't broke, don't fix it.

EDIT: I should note also that I am using a Teensy 3.6 with the mighty audio card and have also tested these problems on a Teensy 3.5. I have also three audio cards that I have swapped out to see if that helped. The IDE is currently version 1.8.1. on my system.

Code:
/* -===================================================
NOISE OBJECTS DON'T WORK PROPERLY, lock up beyond 4 or 5 simultaneous notes, basic waveforms still work well to 8 notes.
Once these notes have been reached, response is either intermitent on alternating keystrokes or noise doesn't work at all.
Noise can also raise in pitch about half an octave during note duration in some configurations unintentionally
ODD RESPONSES FROM SineFM, PWM and Multiply objects the same as the Noise objects.  More than 4 notes and intermittent failure
state persistes from that point on until reboot.
These problems could be dependent on the detune routine but there is no problem with the standard waveform objects at this time so
I doubt it.

When noise object was introduced recently to the inputMix (commented out below) it was found that this instance of the mixer
wasn't working silencing anything connected through it including any other connections of these objects going to other points.
It originally managed the LineIn and the pink and white noise objects.  Moving the noise objects to other link points
in the design fixed them (but not the problem listed above) but the line in still doesn't work at all.

CPU consumption sits roughly at a stable 50% in this setup.
Audio MEMORY peaks at 192, idles at 168
Compiles to 10% program storage space
Compiles to 66% dynamic memory

Increasing Audio memory has no effect.
Using AudioNoInterrupts(); commands at beginning and closing out at the end of the midi to notes section has no effect.

Inconsitent system volume status from one compilation to the next with no modifications to code or hardware.
All connections have been checked several times.
New Audio board seems to have failed, refusing to respond to main volume control.  Replacing the board worked but the inconistency
in the volume from compilation to compilation and sometimes boot to boot remains.

Sending velocity data to any of the sound generation objects doesn't work and hasn't since I downloaded the library that offered
the great envelope shaper improvement.  Sound is either all on or all off with no gradient in between.

Is there a limit to the number of mixer objects in a build?

___________________________________________________________________________________________________________________________________
TODO  2017-11-18
Fix detune ratio through keyboard scale
Setup delays for MUX set - Pot read delay (seems unessesary but pots still aren't right)
Work out phase control settings better
Work out a better LFO modulation effect
Allocate selection routine for various controls to the Mod wheel  (Modulation, Filter depth etc.)
   -=================================================== */

// float int y;  float int x;  float int n;
// y = (x * (x + 1)) >> n  // where n is the resolution and x and y are positive integers

#include <MIDI.h>
//#include <Bounce.h>
//#include <synth_simple_drum.h>
// #include <CmdMessenger.h>  // CmdMessenger


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

// GUItool: begin automatically generated code
AudioSynthWaveform       wave_1_01;      //xy=65,20
AudioSynthWaveform       wave_2_01;      //xy=65,52
AudioSynthWaveform       wave_3_01;      //xy=65,84

AudioSynthWaveform       wave_1_02;      //xy=65,220
AudioSynthWaveform       wave_2_02;      //xy=65,252
AudioSynthWaveform       wave_3_02;      //xy=65,284

AudioSynthWaveform       wave_1_03;      //xy=65,420
AudioSynthWaveform       wave_2_03;      //xy=65,452
AudioSynthWaveform       wave_3_03;      //xy=65,484

AudioSynthWaveform       wave_1_04;      //xy=65,620
AudioSynthWaveform       wave_2_04;      //xy=65,652
AudioSynthWaveform       wave_3_04;      //xy=65,684

AudioSynthWaveform       wave_1_05;      //xy=65,820
AudioSynthWaveform       wave_2_05;      //xy=65,852
AudioSynthWaveform       wave_3_05;      //xy=65,884

AudioSynthWaveform       wave_1_06;      //xy=65,1020
AudioSynthWaveform       wave_2_06;      //xy=65,1052
AudioSynthWaveform       wave_3_06;      //xy=65,1084

AudioSynthWaveform       wave_1_07;      //xy=65,1220
AudioSynthWaveform       wave_2_07;      //xy=65,1252
AudioSynthWaveform       wave_3_07;      //xy=65,1284

AudioSynthWaveform       wave_1_08;      //xy=65,1420
AudioSynthWaveform       wave_2_08;      //xy=65,1452
AudioSynthWaveform       wave_3_08;      //xy=65,1484

AudioInputI2S            i2s_in;         //xy=55,1681

AudioSynthNoisePink      pink_noise;     //xy=65,1617
AudioSynthNoiseWhite     white_noise;    //xy=69,1649
AudioMixer4              noise_mix;      //xy=218,1666

AudioEffectEnvelope      noise_env_01;   //xy=180,180
AudioEffectEnvelope      noise_env_02;   //xy=180,380
AudioEffectEnvelope      noise_env_03;   //xy=180,580
AudioEffectEnvelope      noise_env_04;   //xy=180,780
AudioEffectEnvelope      noise_env_05;   //xy=180,980
AudioEffectEnvelope      noise_env_06;   //xy=180,1180
AudioEffectEnvelope      noise_env_07;   //xy=180,1380
AudioEffectEnvelope      noise_env_08;   //xy=180,1580

AudioMixer4              pwmMix_01;      //xy=410,170
AudioMixer4              pwmMix_02;      //xy=410,370
AudioMixer4              pwmMix_03;      //xy=410,570
AudioMixer4              pwmMix_04;      //xy=410,770
AudioMixer4              pwmMix_05;      //xy=410,970
AudioMixer4              pwmMix_06;      //xy=410,1170
AudioMixer4              pwmMix_07;      //xy=410,1370
AudioMixer4              pwmMix_08;      //xy=410,1570

AudioMixer4              fmMix_01;       //xy=411,108
AudioMixer4              fmMix_02;       //xy=411,308
AudioMixer4              fmMix_03;       //xy=411,508
AudioMixer4              fmMix_04;       //xy=411,708
AudioMixer4              fmMix_05;       //xy=411,908
AudioMixer4              fmMix_06;       //xy=411,1108
AudioMixer4              fmMix_07;       //xy=411,1308
AudioMixer4              fmMix_08;       //xy=411,1508

//AudioMixer4              inputMix_01;    //xy=488,38
//AudioMixer4              inputMix_02;    //xy=488,237
//AudioMixer4              inputMix_03;    //xy=488,437
//AudioMixer4              inputMix_04;    //xy=488,637
//AudioMixer4              inputMix_05;    //xy=488,837
//AudioMixer4              inputMix_06;    //xy=488,1037
//AudioMixer4              inputMix_07;    //xy=488,1237
//AudioMixer4              inputMix_08;    //xy=488,1437

AudioSynthWaveformPWM    pwm_01;         //xy=563,148
AudioSynthWaveformPWM    pwm_02;         //xy=563,348
AudioSynthWaveformPWM    pwm_03;         //xy=563,548
AudioSynthWaveformPWM    pwm_04;         //xy=563,748
AudioSynthWaveformPWM    pwm_05;         //xy=563,948
AudioSynthWaveformPWM    pwm_06;         //xy=563,1148
AudioSynthWaveformPWM    pwm_07;         //xy=563,1348
AudioSynthWaveformPWM    pwm_08;         //xy=563,1548

AudioEffectMultiply      multiply_01;    //xy=564,84
AudioEffectMultiply      multiply_02;    //xy=564,284
AudioEffectMultiply      multiply_03;    //xy=564,484
AudioEffectMultiply      multiply_04;    //xy=564,684
AudioEffectMultiply      multiply_05;    //xy=564,884
AudioEffectMultiply      multiply_06;    //xy=564,1084
AudioEffectMultiply      multiply_07;    //xy=564,1284
AudioEffectMultiply      multiply_08;    //xy=564,1484

AudioSynthWaveformSineModulated sine_fm_01;     //xy=564.5,116
AudioSynthWaveformSineModulated sine_fm_02;     //xy=564.5,316
AudioSynthWaveformSineModulated sine_fm_03;     //xy=564.5,516
AudioSynthWaveformSineModulated sine_fm_04;     //xy=564.5,716
AudioSynthWaveformSineModulated sine_fm_05;     //xy=564.5,916
AudioSynthWaveformSineModulated sine_fm_06;     //xy=564.5,1116
AudioSynthWaveformSineModulated sine_fm_07;     //xy=564.5,1316
AudioSynthWaveformSineModulated sine_fm_08;     //xy=564.5,1516

//AudioEffectWaveshaper    waveshape_01;   //xy=565,180
//AudioEffectWaveshaper    waveshape_02;   //xy=565,380
//AudioEffectWaveshaper    waveshape_03;   //xy=565,580
//AudioEffectWaveshaper    waveshape_04;   //xy=565,780
//AudioEffectWaveshaper    waveshape_05;   //xy=565,980
//AudioEffectWaveshaper    waveshape_06;   //xy=565,1180
//AudioEffectWaveshaper    waveshape_07;   //xy=565,1380
//AudioEffectWaveshaper    waveshape_08;   //xy=565,1580

AudioMixer4              osc_mixA_01;    //xy=760,35
AudioMixer4              osc_mixB_01;    //xy=760,97

AudioMixer4              osc_mixA_02;    //xy=760,235
AudioMixer4              osc_mixB_02;    //xy=760,297

AudioMixer4              osc_mixA_03;    //xy=760,435
AudioMixer4              osc_mixB_03;    //xy=760,497

AudioMixer4              osc_mixA_04;    //xy=760,635
AudioMixer4              osc_mixB_04;    //xy=760,697

AudioMixer4              osc_mixA_05;    //xy=760,835
AudioMixer4              osc_mixB_05;    //xy=760,897

AudioMixer4              osc_mixA_06;    //xy=760,1035
AudioMixer4              osc_mixB_06;    //xy=760,1097

AudioMixer4              osc_mixA_07;    //xy=760,1235
AudioMixer4              osc_mixB_07;    //xy=760,1297

AudioMixer4              osc_mixA_08;    //xy=760,1435
AudioMixer4              osc_mixB_08;    //xy=760,1497

AudioSynthWaveformDc     filtDC;         //xy=905,1669

AudioMixer4              velocityMix_01; //xy=1010,80
AudioMixer4              velocityMix_02; //xy=1010,280
AudioMixer4              velocityMix_03; //xy=1010,480
AudioMixer4              velocityMix_04; //xy=1010,680
AudioMixer4              velocityMix_05; //xy=1010,880
AudioMixer4              velocityMix_06; //xy=1010,1080
AudioMixer4              velocityMix_07; //xy=1010,1280
AudioMixer4              velocityMix_08; //xy=1010,1480

AudioEffectEnvelope      filtEnv_01;     //xy=1095,130
AudioEffectEnvelope      filtEnv_02;     //xy=1095,330
AudioEffectEnvelope      filtEnv_03;     //xy=1095,530
AudioEffectEnvelope      filtEnv_04;     //xy=1095,730
AudioEffectEnvelope      filtEnv_05;     //xy=1095,930
AudioEffectEnvelope      filtEnv_06;     //xy=1095,1130
AudioEffectEnvelope      filtEnv_07;     //xy=1095,1330
AudioEffectEnvelope      filtEnv_08;     //xy=1095,1530

AudioFilterStateVariable filt_01;        //xy=1240,73
AudioFilterStateVariable filt_02;        //xy=1240,273
AudioFilterStateVariable filt_03;        //xy=1240,473
AudioFilterStateVariable filt_04;        //xy=1240,673
AudioFilterStateVariable filt_05;        //xy=1240,873
AudioFilterStateVariable filt_06;        //xy=1240,1073
AudioFilterStateVariable filt_07;        //xy=1240,1273
AudioFilterStateVariable filt_08;        //xy=1240,1473

AudioMixer4              filtMix_01;     //xy=1370,80
AudioMixer4              filtMix_02;     //xy=1370,280
AudioMixer4              filtMix_03;     //xy=1370,480
AudioMixer4              filtMix_04;     //xy=1370,680
AudioMixer4              filtMix_05;     //xy=1370,880
AudioMixer4              filtMix_06;     //xy=1370,1080
AudioMixer4              filtMix_07;     //xy=1370,1280
AudioMixer4              filtMix_08;     //xy=1370,1480

AudioEffectEnvelope      env_01;         //xy=1508,80
AudioEffectEnvelope      env_02;         //xy=1508,280
AudioEffectEnvelope      env_03;         //xy=1508,480
AudioEffectEnvelope      env_04;         //xy=1508,680
AudioEffectEnvelope      env_05;         //xy=1508,880
AudioEffectEnvelope      env_06;         //xy=1508,1080
AudioEffectEnvelope      env_07;         //xy=1508,1280
AudioEffectEnvelope      env_08;         //xy=1508,1480

AudioMixer4              osc_sum_01;     //xy=1680,380
AudioMixer4              osc_sum_02;     //xy=1680,1180

AudioMixer4              osc_main_mix;   //xy=1700,780

AudioSynthWaveform       LFO;            //xy=1902,833
AudioSynthWaveformDc     LFO_dc;         //xy=1902,865
AudioEffectMultiply      LFO_bias_mult;  //xy=2045,848
AudioMixer4              LFO_mix;        //xy=2048,765
AudioEffectMultiply      LFO_blend;      //xy=2104,813

AudioEffectDelay         L_delayGen;     //xy=2378,645
AudioEffectDelay         R_delayGen;     //xy=2378,930

AudioMixer4              L_outMix;       //xy=2380,739
AudioMixer4              R_outMix;       //xy=2380,836

AudioMixer4              L_delayMix;     //xy=2530,618
AudioMixer4              R_delayMix;     //xy=2530,903

AudioEffectFlange        L_flange;       //xy=2500,320
AudioEffectFlange        R_flange;       //xy=2500,352

AudioOutputI2S           i2s_out;        //xy=2775,785

AudioConnection          patchCord1(i2s_in, 0, noise_mix, 2);
AudioConnection          patchCord2(i2s_in, 1, noise_mix, 3);

//AudioConnection          patchCord1(i2s_in, 0, inputMix_08, 2);
//AudioConnection          patchCord2(i2s_in, 0, inputMix_01, 2);
//AudioConnection          patchCord3(i2s_in, 0, inputMix_02, 2);
//AudioConnection          patchCord4(i2s_in, 0, inputMix_03, 2);
//AudioConnection          patchCord5(i2s_in, 0, inputMix_04, 2);
//AudioConnection          patchCord6(i2s_in, 0, inputMix_05, 2);
//AudioConnection          patchCord7(i2s_in, 0, inputMix_06, 2);
//AudioConnection          patchCord8(i2s_in, 0, inputMix_07, 2);

//AudioConnection          patchCord9(i2s_in, 1, inputMix_01, 3);
//AudioConnection          patchCord10(i2s_in, 1, inputMix_02, 3);
//AudioConnection          patchCord11(i2s_in, 1, inputMix_03, 3);
//AudioConnection          patchCord12(i2s_in, 1, inputMix_04, 3);
//AudioConnection          patchCord13(i2s_in, 1, inputMix_05, 3);
//AudioConnection          patchCord14(i2s_in, 1, inputMix_06, 3);
//AudioConnection          patchCord15(i2s_in, 1, inputMix_07, 3);
//AudioConnection          patchCord16(i2s_in, 1, inputMix_08, 3);

AudioConnection          patchCord17(wave_1_01, 0, osc_mixA_01, 0);
AudioConnection          patchCord18(wave_2_01, 0, osc_mixA_01, 1);
AudioConnection          patchCord19(wave_3_01, 0, osc_mixA_01, 2);

AudioConnection          patchCord20(wave_1_02, 0, osc_mixA_02, 0);
AudioConnection          patchCord21(wave_2_02, 0, osc_mixA_02, 1);
AudioConnection          patchCord22(wave_3_02, 0, osc_mixA_02, 2);

AudioConnection          patchCord23(wave_1_03, 0, osc_mixA_03, 0);
AudioConnection          patchCord24(wave_2_03, 0, osc_mixA_03, 1);
AudioConnection          patchCord25(wave_3_03, 0, osc_mixA_03, 2);

AudioConnection          patchCord26(wave_1_04, 0, osc_mixA_04, 0);
AudioConnection          patchCord27(wave_2_04, 0, osc_mixA_04, 1);
AudioConnection          patchCord28(wave_3_04, 0, osc_mixA_04, 2);

AudioConnection          patchCord29(wave_1_05, 0, osc_mixA_05, 0);
AudioConnection          patchCord30(wave_2_05, 0, osc_mixA_05, 1);
AudioConnection          patchCord31(wave_3_05, 0, osc_mixA_05, 2);

AudioConnection          patchCord32(wave_1_06, 0, osc_mixA_06, 0);
AudioConnection          patchCord33(wave_2_06, 0, osc_mixA_06, 1);
AudioConnection          patchCord34(wave_3_06, 0, osc_mixA_06, 2);

AudioConnection          patchCord35(wave_1_07, 0, osc_mixA_07, 0);
AudioConnection          patchCord36(wave_2_07, 0, osc_mixA_07, 1);
AudioConnection          patchCord37(wave_3_07, 0, osc_mixA_07, 2);

AudioConnection          patchCord38(wave_1_08, 0, osc_mixA_08, 0);
AudioConnection          patchCord39(wave_2_08, 0, osc_mixA_08, 1);
AudioConnection          patchCord40(wave_3_08, 0, osc_mixA_08, 2);

AudioConnection          patchCord41(wave_1_01, 0, multiply_01, 0);
AudioConnection          patchCord42(wave_2_01, 0, multiply_01, 1);

AudioConnection          patchCord43(wave_1_02, 0, multiply_02, 0);
AudioConnection          patchCord44(wave_2_02, 0, multiply_02, 1);

AudioConnection          patchCord45(wave_1_03, 0, multiply_03, 0);
AudioConnection          patchCord46(wave_2_03, 0, multiply_03, 1);

AudioConnection          patchCord47(wave_1_04, 0, multiply_04, 0);
AudioConnection          patchCord48(wave_2_04, 0, multiply_04, 1);

AudioConnection          patchCord49(wave_1_05, 0, multiply_05, 0);
AudioConnection          patchCord50(wave_2_05, 0, multiply_05, 1);

AudioConnection          patchCord51(wave_1_06, 0, multiply_06, 0);
AudioConnection          patchCord52(wave_2_06, 0, multiply_06, 1);

AudioConnection          patchCord53(wave_1_07, 0, multiply_07, 0);
AudioConnection          patchCord54(wave_2_07, 0, multiply_07, 1);

AudioConnection          patchCord55(wave_1_08, 0, multiply_08, 0);
AudioConnection          patchCord56(wave_2_08, 0, multiply_08, 1);

AudioConnection          patchCord57(wave_1_01, 0, fmMix_01, 0);
AudioConnection          patchCord58(wave_2_01, 0, fmMix_01, 1);
AudioConnection          patchCord59(wave_3_01, 0, fmMix_01, 2);

AudioConnection          patchCord60(wave_1_02, 0, fmMix_02, 0);
AudioConnection          patchCord61(wave_2_02, 0, fmMix_02, 1);
AudioConnection          patchCord62(wave_3_02, 0, fmMix_02, 2);

AudioConnection          patchCord63(wave_1_03, 0, fmMix_03, 0);
AudioConnection          patchCord64(wave_2_03, 0, fmMix_03, 1);
AudioConnection          patchCord65(wave_3_03, 0, fmMix_03, 2);

AudioConnection          patchCord66(wave_1_04, 0, fmMix_04, 0);
AudioConnection          patchCord67(wave_2_04, 0, fmMix_04, 1);
AudioConnection          patchCord68(wave_3_04, 0, fmMix_04, 2);

AudioConnection          patchCord69(wave_1_05, 0, fmMix_05, 0);
AudioConnection          patchCord70(wave_2_05, 0, fmMix_05, 1);
AudioConnection          patchCord71(wave_3_05, 0, fmMix_05, 2);

AudioConnection          patchCord72(wave_1_06, 0, fmMix_06, 0);
AudioConnection          patchCord73(wave_2_06, 0, fmMix_06, 1);
AudioConnection          patchCord74(wave_3_06, 0, fmMix_06, 2);

AudioConnection          patchCord75(wave_1_07, 0, fmMix_07, 0);
AudioConnection          patchCord76(wave_2_07, 0, fmMix_07, 1);
AudioConnection          patchCord77(wave_3_07, 0, fmMix_07, 2);

AudioConnection          patchCord78(wave_1_08, 0, fmMix_08, 0);
AudioConnection          patchCord79(wave_2_08, 0, fmMix_08, 1);
AudioConnection          patchCord80(wave_3_08, 0, fmMix_08, 2);

AudioConnection          patchCord81(wave_1_01, 0, pwmMix_01, 0);
AudioConnection          patchCord82(wave_2_01, 0, pwmMix_01, 1);
AudioConnection          patchCord83(wave_3_01, 0, pwmMix_01, 2);

AudioConnection          patchCord84(wave_1_02, 0, pwmMix_02, 0);
AudioConnection          patchCord85(wave_2_02, 0, pwmMix_02, 1);
AudioConnection          patchCord86(wave_3_02, 0, pwmMix_02, 2);

AudioConnection          patchCord87(wave_1_03, 0, pwmMix_03, 0);
AudioConnection          patchCord88(wave_2_03, 0, pwmMix_03, 1);
AudioConnection          patchCord89(wave_3_03, 0, pwmMix_03, 2);

AudioConnection          patchCord90(wave_1_04, 0, pwmMix_04, 0);
AudioConnection          patchCord91(wave_2_04, 0, pwmMix_04, 1);
AudioConnection          patchCord92(wave_3_04, 0, pwmMix_04, 2);

AudioConnection          patchCord93(wave_1_05, 0, pwmMix_05, 0);
AudioConnection          patchCord94(wave_2_05, 0, pwmMix_05, 1);
AudioConnection          patchCord95(wave_3_05, 0, pwmMix_05, 2);

AudioConnection          patchCord96(wave_1_06, 0, pwmMix_06, 0);
AudioConnection          patchCord97(wave_2_06, 0, pwmMix_06, 1);
AudioConnection          patchCord98(wave_3_06, 0, pwmMix_06, 2);

AudioConnection          patchCord99(wave_1_07, 0, pwmMix_07, 0);
AudioConnection          patchCord100(wave_2_07, 0, pwmMix_07, 1);
AudioConnection          patchCord101(wave_3_07, 0, pwmMix_07, 2);

AudioConnection          patchCord102(wave_1_08, 0, pwmMix_08, 0);
AudioConnection          patchCord103(wave_2_08, 0, pwmMix_08, 1);
AudioConnection          patchCord104(wave_3_08, 0, pwmMix_08, 2);

AudioConnection          patchCord105(pink_noise, 0, noise_mix, 0);
AudioConnection          patchCord106(white_noise, 0, noise_mix, 1);

AudioConnection          patchCord107(noise_mix, noise_env_01);
AudioConnection          patchCord108(noise_mix, noise_env_02);
AudioConnection          patchCord109(noise_mix, noise_env_03);
AudioConnection          patchCord110(noise_mix, noise_env_04);
AudioConnection          patchCord111(noise_mix, noise_env_05);
AudioConnection          patchCord112(noise_mix, noise_env_06);
AudioConnection          patchCord113(noise_mix, noise_env_07);
AudioConnection          patchCord114(noise_mix, noise_env_08);

AudioConnection          patchCord115(noise_env_01, 0, fmMix_01, 3);
AudioConnection          patchCord116(noise_env_02, 0, fmMix_02, 3);
AudioConnection          patchCord117(noise_env_03, 0, fmMix_03, 3);
AudioConnection          patchCord118(noise_env_04, 0, fmMix_04, 3);
AudioConnection          patchCord119(noise_env_05, 0, fmMix_05, 3);
AudioConnection          patchCord120(noise_env_06, 0, fmMix_06, 3);
AudioConnection          patchCord121(noise_env_07, 0, fmMix_07, 3);
AudioConnection          patchCord122(noise_env_08, 0, fmMix_08, 3);

AudioConnection          patchCord123(pwmMix_01, pwm_01);
AudioConnection          patchCord124(pwmMix_02, pwm_02);
AudioConnection          patchCord125(pwmMix_03, pwm_03);
AudioConnection          patchCord126(pwmMix_04, pwm_04);
AudioConnection          patchCord127(pwmMix_05, pwm_05);
AudioConnection          patchCord128(pwmMix_06, pwm_06);
AudioConnection          patchCord129(pwmMix_07, pwm_07);
AudioConnection          patchCord130(pwmMix_08, pwm_08);

AudioConnection          patchCord131(fmMix_01, sine_fm_01);
AudioConnection          patchCord132(fmMix_02, sine_fm_02);
AudioConnection          patchCord133(fmMix_03, sine_fm_03);
AudioConnection          patchCord134(fmMix_04, sine_fm_04);
AudioConnection          patchCord135(fmMix_05, sine_fm_05);
AudioConnection          patchCord136(fmMix_06, sine_fm_06);
AudioConnection          patchCord137(fmMix_07, sine_fm_07);
AudioConnection          patchCord138(fmMix_08, sine_fm_08);

AudioConnection          patchCord139(noise_env_01, 0, pwmMix_01, 3);
AudioConnection          patchCord140(noise_env_02, 0, pwmMix_02, 3);
AudioConnection          patchCord141(noise_env_03, 0, pwmMix_03, 3);
AudioConnection          patchCord142(noise_env_04, 0, pwmMix_04, 3);
AudioConnection          patchCord143(noise_env_05, 0, pwmMix_05, 3);
AudioConnection          patchCord144(noise_env_06, 0, pwmMix_06, 3);
AudioConnection          patchCord145(noise_env_07, 0, pwmMix_07, 3);
AudioConnection          patchCord146(noise_env_08, 0, pwmMix_08, 3);

//AudioConnection          patchCord147(noise_env_01, 0, velocityMix_01, 3);
//AudioConnection          patchCord148(noise_env_02, 0, velocityMix_02, 3);
//AudioConnection          patchCord149(noise_env_03, 0, velocityMix_03, 3);
//AudioConnection          patchCord150(noise_env_04, 0, velocityMix_04, 3);
//AudioConnection          patchCord151(noise_env_05, 0, velocityMix_05, 3);
//AudioConnection          patchCord152(noise_env_06, 0, velocityMix_06, 3);
//AudioConnection          patchCord153(noise_env_07, 0, velocityMix_07, 3);
//AudioConnection          patchCord154(noise_env_08, 0, velocityMix_08, 3);

//AudioConnection          patchCord147(inputMix_01, 0, fmMix_01, 3);
//AudioConnection          patchCord148(inputMix_02, 0, fmMix_02, 3);
//AudioConnection          patchCord149(inputMix_03, 0, fmMix_03, 3);
//AudioConnection          patchCord150(inputMix_04, 0, fmMix_04, 3);
//AudioConnection          patchCord151(inputMix_08, 0, fmMix_05, 3);
//AudioConnection          patchCord152(inputMix_06, 0, fmMix_06, 3);
//AudioConnection          patchCord153(inputMix_07, 0, fmMix_07, 3);
//AudioConnection          patchCord154(inputMix_08, 0, fmMix_08, 3);

//AudioConnection          patchCord155(inputMix_01, 0, osc_mixA_01, 3);
//AudioConnection          patchCord156(inputMix_02, 0, osc_mixA_02, 3);
//AudioConnection          patchCord157(inputMix_03, 0, osc_mixA_03, 3);
//AudioConnection          patchCord158(inputMix_04, 0, osc_mixA_04, 3);
//AudioConnection          patchCord159(inputMix_05, 0, osc_mixA_05, 3);
//AudioConnection          patchCord160(inputMix_06, 0, osc_mixA_06, 3);
//AudioConnection          patchCord161(inputMix_07, 0, osc_mixA_07, 3);
//AudioConnection          patchCord162(inputMix_08, 0, osc_mixA_08, 3);

AudioConnection          patchCord155(noise_env_01, 0, osc_mixA_01, 3);
AudioConnection          patchCord156(noise_env_02, 0, osc_mixA_02, 3);
AudioConnection          patchCord157(noise_env_03, 0, osc_mixA_03, 3);
AudioConnection          patchCord158(noise_env_04, 0, osc_mixA_04, 3);
AudioConnection          patchCord159(noise_env_05, 0, osc_mixA_05, 3);
AudioConnection          patchCord160(noise_env_06, 0, osc_mixA_06, 3);
AudioConnection          patchCord161(noise_env_07, 0, osc_mixA_07, 3);
AudioConnection          patchCord162(noise_env_08, 0, osc_mixA_08, 3);

//AudioConnection          patchCord163(waveshape_01, 0, osc_mixB_01, 3);
//AudioConnection          patchCord164(waveshape_02, 0, osc_mixB_02, 3);
//AudioConnection          patchCord165(waveshape_03, 0, osc_mixB_03, 3);
//AudioConnection          patchCord166(waveshape_04, 0, osc_mixB_04, 3);
//AudioConnection          patchCord167(waveshape_05, 0, osc_mixB_05, 3);
//AudioConnection          patchCord168(waveshape_06, 0, osc_mixB_06, 3);
//AudioConnection          patchCord169(waveshape_07, 0, osc_mixB_07, 3);
//AudioConnection          patchCord170(waveshape_08, 0, osc_mixB_08, 3);

AudioConnection          patchCord171(multiply_01, 0, osc_mixB_01, 0);
AudioConnection          patchCord172(multiply_02, 0, osc_mixB_02, 0);
AudioConnection          patchCord173(multiply_03, 0, osc_mixB_03, 0);
AudioConnection          patchCord174(multiply_04, 0, osc_mixB_04, 0);
AudioConnection          patchCord175(multiply_05, 0, osc_mixB_05, 0);
AudioConnection          patchCord176(multiply_06, 0, osc_mixB_06, 0);
AudioConnection          patchCord177(multiply_07, 0, osc_mixB_07, 0);
AudioConnection          patchCord178(multiply_08, 0, osc_mixB_08, 0);

AudioConnection          patchCord179(pwm_01, 0, osc_mixB_01, 2);
AudioConnection          patchCord180(pwm_02, 0, osc_mixB_02, 2);
AudioConnection          patchCord181(pwm_03, 0, osc_mixB_03, 2);
AudioConnection          patchCord182(pwm_04, 0, osc_mixB_04, 2);
AudioConnection          patchCord183(pwm_05, 0, osc_mixB_05, 2);
AudioConnection          patchCord184(pwm_06, 0, osc_mixB_06, 2);
AudioConnection          patchCord185(pwm_07, 0, osc_mixB_07, 2);
AudioConnection          patchCord186(pwm_08, 0, osc_mixB_08, 2);

AudioConnection          patchCord187(sine_fm_01, 0, osc_mixB_01, 1);
AudioConnection          patchCord188(sine_fm_02, 0, osc_mixB_02, 1);
AudioConnection          patchCord189(sine_fm_03, 0, osc_mixB_03, 1);
AudioConnection          patchCord190(sine_fm_04, 0, osc_mixB_04, 1);
AudioConnection          patchCord191(sine_fm_05, 0, osc_mixB_05, 1);
AudioConnection          patchCord192(sine_fm_06, 0, osc_mixB_06, 1);
AudioConnection          patchCord193(sine_fm_07, 0, osc_mixB_07, 1);
AudioConnection          patchCord194(sine_fm_08, 0, osc_mixB_08, 1);

AudioConnection          patchCord195(osc_mixA_01, 0, velocityMix_01, 0);
AudioConnection          patchCord196(osc_mixA_02, 0, velocityMix_02, 0);
AudioConnection          patchCord197(osc_mixA_03, 0, velocityMix_03, 0);
AudioConnection          patchCord198(osc_mixA_04, 0, velocityMix_04, 0);
AudioConnection          patchCord199(osc_mixA_05, 0, velocityMix_05, 0);
AudioConnection          patchCord200(osc_mixA_06, 0, velocityMix_06, 0);
AudioConnection          patchCord201(osc_mixA_07, 0, velocityMix_07, 0);
AudioConnection          patchCord202(osc_mixA_08, 0, velocityMix_08, 0);

AudioConnection          patchCord203(osc_mixB_01, 0, velocityMix_01, 1);
AudioConnection          patchCord204(osc_mixB_02, 0, velocityMix_02, 1);
AudioConnection          patchCord205(osc_mixB_03, 0, velocityMix_03, 1);
AudioConnection          patchCord206(osc_mixB_04, 0, velocityMix_04, 1);
AudioConnection          patchCord207(osc_mixB_05, 0, velocityMix_05, 1);
AudioConnection          patchCord208(osc_mixB_06, 0, velocityMix_06, 1);
AudioConnection          patchCord209(osc_mixB_07, 0, velocityMix_07, 1);
AudioConnection          patchCord210(osc_mixB_08, 0, velocityMix_08, 1);

//AudioConnection          patchCord211(velocityMix_01, waveshape_01);
//AudioConnection          patchCord212(velocityMix_02, waveshape_02);
//AudioConnection          patchCord213(velocityMix_03, waveshape_03);
//AudioConnection          patchCord214(velocityMix_04, waveshape_04);
//AudioConnection          patchCord215(velocityMix_05, waveshape_05);
//AudioConnection          patchCord216(velocityMix_06, waveshape_06);
//AudioConnection          patchCord217(velocityMix_07, waveshape_07);
//AudioConnection          patchCord218(velocityMix_08, waveshape_08);

AudioConnection          patchCord219(filtDC, filtEnv_01);
AudioConnection          patchCord220(filtDC, filtEnv_02);
AudioConnection          patchCord221(filtDC, filtEnv_03);
AudioConnection          patchCord222(filtDC, filtEnv_04);
AudioConnection          patchCord223(filtDC, filtEnv_05);
AudioConnection          patchCord224(filtDC, filtEnv_06);
AudioConnection          patchCord225(filtDC, filtEnv_07);
AudioConnection          patchCord226(filtDC, filtEnv_08);

AudioConnection          patchCord227(velocityMix_01, 0, filt_01, 0);
AudioConnection          patchCord228(velocityMix_02, 0, filt_02, 0);
AudioConnection          patchCord229(velocityMix_03, 0, filt_03, 0);
AudioConnection          patchCord230(velocityMix_04, 0, filt_04, 0);
AudioConnection          patchCord231(velocityMix_05, 0, filt_05, 0);
AudioConnection          patchCord232(velocityMix_06, 0, filt_06, 0);
AudioConnection          patchCord233(velocityMix_07, 0, filt_07, 0);
AudioConnection          patchCord234(velocityMix_08, 0, filt_08, 0);

AudioConnection          patchCord235(velocityMix_01, 0, filtMix_01, 3);
AudioConnection          patchCord236(velocityMix_02, 0, filtMix_02, 3);
AudioConnection          patchCord237(velocityMix_03, 0, filtMix_03, 3);
AudioConnection          patchCord238(velocityMix_04, 0, filtMix_04, 3);
AudioConnection          patchCord239(velocityMix_05, 0, filtMix_05, 3);
AudioConnection          patchCord240(velocityMix_06, 0, filtMix_06, 3);
AudioConnection          patchCord241(velocityMix_07, 0, filtMix_07, 3);
AudioConnection          patchCord242(velocityMix_08, 0, filtMix_08, 3);

AudioConnection          patchCord243(filtEnv_01, 0, filt_01, 1);
AudioConnection          patchCord244(filtEnv_02, 0, filt_02, 1);
AudioConnection          patchCord245(filtEnv_03, 0, filt_03, 1);
AudioConnection          patchCord246(filtEnv_04, 0, filt_04, 1);
AudioConnection          patchCord247(filtEnv_05, 0, filt_05, 1);
AudioConnection          patchCord248(filtEnv_06, 0, filt_06, 1);
AudioConnection          patchCord249(filtEnv_07, 0, filt_07, 1);
AudioConnection          patchCord250(filtEnv_08, 0, filt_08, 1);

AudioConnection          patchCord251(filt_01, 0, filtMix_01, 0);
AudioConnection          patchCord252(filt_01, 1, filtMix_01, 1);
AudioConnection          patchCord253(filt_01, 2, filtMix_01, 2);

AudioConnection          patchCord254(filt_02, 0, filtMix_02, 0);
AudioConnection          patchCord255(filt_02, 1, filtMix_02, 1);
AudioConnection          patchCord256(filt_02, 2, filtMix_02, 2);

AudioConnection          patchCord257(filt_03, 0, filtMix_03, 0);
AudioConnection          patchCord258(filt_03, 1, filtMix_03, 1);
AudioConnection          patchCord259(filt_03, 2, filtMix_03, 2);

AudioConnection          patchCord260(filt_04, 0, filtMix_04, 0);
AudioConnection          patchCord261(filt_04, 1, filtMix_04, 1);
AudioConnection          patchCord262(filt_04, 2, filtMix_04, 2);

AudioConnection          patchCord263(filt_05, 0, filtMix_05, 0);
AudioConnection          patchCord264(filt_05, 1, filtMix_05, 1);
AudioConnection          patchCord265(filt_05, 2, filtMix_05, 2);

AudioConnection          patchCord266(filt_06, 0, filtMix_06, 0);
AudioConnection          patchCord267(filt_06, 1, filtMix_06, 1);
AudioConnection          patchCord268(filt_06, 2, filtMix_06, 2);

AudioConnection          patchCord269(filt_07, 0, filtMix_07, 0);
AudioConnection          patchCord270(filt_07, 1, filtMix_07, 1);
AudioConnection          patchCord271(filt_07, 2, filtMix_07, 2);

AudioConnection          patchCord272(filt_08, 0, filtMix_08, 0);
AudioConnection          patchCord273(filt_08, 1, filtMix_08, 1);
AudioConnection          patchCord274(filt_08, 2, filtMix_08, 2);

AudioConnection          patchCord275(filtMix_01, env_01);
AudioConnection          patchCord276(filtMix_02, env_02);
AudioConnection          patchCord277(filtMix_03, env_03);
AudioConnection          patchCord278(filtMix_04, env_04);
AudioConnection          patchCord279(filtMix_05, env_05);
AudioConnection          patchCord280(filtMix_06, env_06);
AudioConnection          patchCord281(filtMix_07, env_07);
AudioConnection          patchCord282(filtMix_08, env_08);

AudioConnection          patchCord283(env_01, 0, osc_sum_01, 0);
AudioConnection          patchCord284(env_02, 0, osc_sum_01, 1);
AudioConnection          patchCord285(env_03, 0, osc_sum_01, 2);
AudioConnection          patchCord286(env_04, 0, osc_sum_01, 3);
AudioConnection          patchCord287(env_05, 0, osc_sum_02, 0);
AudioConnection          patchCord288(env_06, 0, osc_sum_02, 1);
AudioConnection          patchCord289(env_07, 0, osc_sum_02, 2);
AudioConnection          patchCord290(env_08, 0, osc_sum_02, 3);

AudioConnection          patchCord291(osc_sum_01, 0, osc_main_mix, 0);
AudioConnection          patchCord292(osc_sum_02, 0, osc_main_mix, 1);

AudioConnection          patchCord293(osc_main_mix, 0, LFO_blend, 1);
AudioConnection          patchCord294(osc_main_mix, 0, LFO_mix, 0);

AudioConnection          patchCord295(LFO, 0, LFO_bias_mult, 0);
AudioConnection          patchCord296(LFO_dc, 0, LFO_bias_mult, 1);

AudioConnection          patchCord297(LFO_bias_mult, 0, LFO_blend, 0);

AudioConnection          patchCord298(LFO_mix, 0, L_outMix, 0);
AudioConnection          patchCord299(LFO_mix, 0, R_outMix, 0);

AudioConnection          patchCord300(LFO_blend, 0, LFO_mix, 1);

AudioConnection          patchCord301(L_delayGen, 0, L_delayMix, 0);
AudioConnection          patchCord302(L_delayGen, 1, L_delayMix, 1);
AudioConnection          patchCord303(L_delayGen, 2, L_delayMix, 2);
AudioConnection          patchCord304(L_delayGen, 3, L_delayMix, 3);

AudioConnection          patchCord305(R_delayGen, 0, R_delayMix, 0);
AudioConnection          patchCord306(R_delayGen, 1, R_delayMix, 1);
AudioConnection          patchCord307(R_delayGen, 2, R_delayMix, 2);
AudioConnection          patchCord308(R_delayGen, 3, R_delayMix, 3);

AudioConnection          patchCord309(L_outMix, L_delayGen);
AudioConnection          patchCord310(R_outMix, R_delayGen);

AudioConnection          patchCord311(L_delayMix, 0, L_outMix, 1);
AudioConnection          patchCord312(R_delayMix, 0, R_outMix, 1);

//AudioConnection          patchCord313(L_outMix, 0, i2s_out, 0);
//AudioConnection          patchCord314(R_outMix, 0, i2s_out, 1);

AudioConnection          patchCord315(L_outMix, L_flange);
AudioConnection          patchCord316(R_outMix, R_flange);

AudioConnection          patchCord317(L_flange, 0, i2s_out, 0);
AudioConnection          patchCord318(R_flange, 0, i2s_out, 1);

//AudioConnection          patchCord315(inputMix_01, 0, osc_main_mix, 3);
//AudioConnection          patchCord315(inputMix_01, 0, velocityMix_01, 3);
//AudioConnection          patchCord315(noise_env_01, 0, velocityMix_01, 3);

AudioControlSGTL5000     sgtl5000;       //xy=2776,818
// GUItool: end automatically generated code


/*
=================================================================================================================================
TEENSY 3.6 PINOUT MAP WITH SOUND BREAKOUT INSTALLED
        |       |       |       |       |       |       |   ____|____   |       |       |       |       |       |       |       |
                                        GND         GND o--|         |  o Vin
                        MIDI IN                   RX1 0 o  |         |  o Analog gnd
                        MIDI OUT                  TX1 1 o  |         |--o 3.3v out      3.3v
[FREE PIN]                                         -  2 o  |         |--o 23 A9  X      LR-CLK
[FREE PIN]                                         -  3 o  |         |--o 22 A8  X      TX
[FREE PIN]                                         -  4 o  |         |  o 21 A7  -                                     [FREE PIN]
[FREE PIN]                                         -  5 o  |         |  o 20 A6  -                                     [FREE PIN]
                                        MEM-CS     X  6 o--|MEM      |--o 19 A5  X      SCL
                                        MOSI       X  7 o--|SD\MEM   |--o 18 A4  X      SDA
[FREE PIN]    TX3 keep for display data            X  8 o  |         |  o 17 A3  -                                     [FREE PIN]
                                        B-CLK      X  9 o--|         |  o 16 A2  -
[FREE PIN IF NO SD READER?]             SD-CS      X 10 o--|SD       |--o 15 A1  X      VOL
                                        M-CLK      X 11 o--|   MEM\SD|--o 14 A0  X      S-CLK
                                        MIS0       X 12 o--|SD\MEM_??|--o 13     ?      RX              LED   [MIGHT BE FREE PIN]
                                               3.3v out o               o GND
[FREE PIN]                                         - 24 o               o    A22 -                                     [FREE PIN]
[FREE PIN]                                         - 25 o               o    A21 -                                     [FREE PIN]
[FREE PIN]                                         - 26 o               o 39 A20 -                                     [FREE PIN]
[FREE PIN]                                         - 27 o               o 38 A19                MUX pot return H
                                MUX S0               28 o               o 37 A18                MUX pot return G
                                MUX S1               29 o               o 36 A17                MUX pot return F
                                MUX S2               30 o               o 35 A16                MUX pot return E
                                MUX pot return A A12 31 o               o 34 A15                MUX pot return D
                                MUX pot return B A13 32 o               o 33 A14                MUX pot return C
=================================================================================================================================
---------------------------------------------------------------------------------------------------------------------------------
POTENTIOMETER MAP
=================
 OSC1 LEVEL       OSC1 F-TUNE      OSC1 OCT         OSC1 WAVE        AMP ATTACK       AMP DECAY        AMP RELEASE
 LIN [0.0-0.1]    LOG              ROT [7 POS]      ROT [6 POS]      LIN [0.0-10K]    LIN [0.0-5K]     LIN [0.0-10K]
 POT 19 Y4 white  POT 19 Y0 grey   SWT 12 Y5 grey   SWT 18 Y2 grey   POT 17 blue      POT 17 blue      POT 16 Y0 blue

 OSC2 LEVEL       OSC2 F-TUNE      OSC2 OCT         OSC2 WAVE        AMP HOLD         AMP SUSTAIN      DELAY LEVEL
 LIN [0.0-0.1]    LOG              ROT [7 POS]      ROT [6 POS]      LIN [0.0-5K]     LIN [0.0-1.0]    LIN [0.0-1.0]
 POT 19 Y5 white  POT 19 Y1 grey   SWT 12 Y6 grey   SWT 18 Y3 grey   POT 18 Y0 blue   POT 17 blue      POT 16 Y1 green

 OSC3 LEVEL       RING MOD LEVEL   OSC3 OCT         0SC3 WAVE        FILT ATTACK      FILT DECAY       FILT RELEASE
 LIN [0.0-0.1]    LOG              ROT [7 POS]      ROT [6 POS]      LIN [0.0-10K]    LIN [0.0-5K]     LIN [0.0-10K]
 POT 19 Y6 white  POT 19 Y2 white  SWT 12 Y7 grey   SWT 12 Y4 grey   POT red 18 Y1    POT 17 red       POT 16 Y2 red

 SINE FM LEVEL    PWM LEVEL        FILT BAND        LFO WAVE         FILT HOLD        FILT SUSTAIN     FILT DEPTH
 LIN [0.0-0.1]    LOG [0.0-0.1]    ROT [7 POS]      ROT [6 POS]      LIN [0.0-5K]     LIN [0.0-1.0]    LIN [0.0-1.0]
 POT 19 Y7 white  POT 19 Y3 white  SWT 16 Y7 grey   SWT 16 Y6 grey   POT 16 Y5 red    POT 16 Y4 red    POT 16 Y3 green

 -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
 -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
                                   NOISE LEVEL      LFO FREQ                                           PULSE WIDTH
 LIN [0.0-0.1]    LIN [0-1.0]      LIN [0-1.0]      LIN [6 POS]      LIN [0.0-10K]    LIN [0.0-5K]     LIN [0.0-1.0]
 MUX 15 Y6 red    MUX 15 Y2 grey   MUX 14 Y6 white  MUX 14 Y  orange MUX 16 Y6 blue   MUX 17 Y         MUX 16 Y6 grey

                  Waveshape LEV    NOISE TYPE PAN
 LIN [0.0-0.1]    LIN [0-1.0]      LIN [0-1.0]      LIN [6 POS]      LIN [0.0-5K]     LIN [0.0-1.0]    LIN [0.0-1.0]
 MUX 15 Y7 red    MUX 15 Y3 grey   MUX 14 Y7 white  MUX 14 Y  grey   MUX 16 Y7 blue   MUX 17 Y         MUX 16 Y7

                                   NOISE ATTACK     DELAY PAN                                          LINE IN LEVEL
 LIN [0.0-0.1]    LIN              LIN [     ]      LIN [6 POS]      LIN [0.0-10K]    LIN [0.0-5K]     LIN [0.0-15.0]
 MUX 15 Y4 red    MUX 15 Y4 grey   MUX 14 Y4 white  MUX 14 Y  blue   MUX 16 Y4 blue   MUX 17 Y         MUX 16 Y4 red

 TEST POT                          NOISE RELEASE    DELAY PAN                                          MAIN VOLUME
 LIN [0.0-0.1]    LIN [0.0-0.1]    LIN [     ]      LIN [6 POS]      LIN [0.0-5K]     LIN [0.0-1.0]    LIN [0.0-1.0]
 MUX 15 Y5 red    MUX 15 Y5 grey   MUX 14 Y5 white  MUX 14 Y  blue   MUX 16 Y5 blue   MUX 16 Y  red    MUX 16 Y5 red

---------------------------------------------------------------------------------------------------------------------------------
*/

int butt;
byte buttonTog = 0;
//byte panicBTg = 0;
byte testNTog = 0;

// ============================================================================================== POTENTIOMETERS
// Pot Multiplex breakouts  (teensy pins in sequence)
const byte S0 = 28;
const byte S1 = 29;
const byte S2 = 30;
const int muxPot_12 = A12;
const int muxPot_13 = A13;
const int muxPot_14 = A14;
const int muxPot_15 = A15;
const int muxPot_16 = A16;
const int muxPot_17 = A17;
const int muxPot_18 = A18;
const int muxPot_19 = A19;

// For temporary routines to test midi input
const byte LED = 13;              // LED pin on Arduino Uno

// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv FLANGE initiators
// Number of samples in each delay line
#define FLANGE_DELAY_LENGTH (6*AUDIO_BLOCK_SAMPLES)
// Allocate the delay lines for left and right channels
short l_delayline[FLANGE_DELAY_LENGTH];
short r_delayline[FLANGE_DELAY_LENGTH];

// Default is to just pass the audio through. Grounding this pin applies the flange effect
// Don't use any of the pins listed above
//#define PASSTHRU_PIN 5
float s_idx = FLANGE_DELAY_LENGTH/4;      float s_idx_mod = s_idx;        float old_s_idx = s_idx;        float i_pot = 0;
float s_depth = FLANGE_DELAY_LENGTH/4;    float s_depth_mod = s_depth;    float old_s_depth = s_depth;    float d_pot = 0;
double s_freq = 0.5;                      double s_freq_mod = s_freq;     double old_s_freq = s_freq;     double f_pot = 0;
byte flangeTog = 0;
float detDepth;  float detFreq;         // L/R flanger detune variables 
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FLANGE initiators

byte fltBypass = 1;                     // counter for filter button
byte fltSwitch = 0;
 
int wave_1_type = WAVEFORM_PULSE;
int wave_2_type = WAVEFORM_PULSE;
int wave_3_type = WAVEFORM_PULSE;
int LFO_type = WAVEFORM_SINE;
//int L_fwave_type = WAVEFORM_SINE;
//int R_fwave_type = WAVEFORM_SINE;

byte dataDisplay = 0;                   // toggle for serial data display [TEMP]

//int note_on = 0;
byte monoPoly = 1;                      // toggle for MONO/POLY button
byte fmMod = 1;                         // allocation count for fmMod source button
byte pwmMod = 1;                        // allocation count for pwmMod source button
byte channelLock[8];                    // locks note playing occupation for 1 of 8 channels
byte keyArray[8];
int keyShift1;                          // octave key shift value from knob to note play on OSC 1
int oldKeyShift1 = 1.0;                 // old key shift variable within knob routine
int keyShift2;                          // octave key shift value from knob to note play on OSC 2
int oldKeyShift2 = 1.0;                 // old key shift variable within knob routine
int keyShift3;                          // octave key shift value from knob to note play on OSC 3
int oldKeyShift3 = 1.0;                 // old key shift variable within knob routine
float fineTune = 1.0;                   // master fine tune variable
float fineTune_1 = 1.0;                 // fine tune variable sent to OSC 1
float fineTune_2 = 1.0;                 // fine tune variable sent to OSC 3
int nF1;  int nF2;  int nF3;  int nF4;  int nF5;  int nF6;  int nF7;  int nF8;   // note frequency currently being played per channel
int nP1;  int nP2;  int nP3;  int nP4;  int nP5;  int nP6;  int nP7;  int nP8;   // note pitch currently being played per channel
float pitchBend = 1.0;                  // pitch bend value sent from pitch wheel to oscilators through note channels 
byte PBOct = 1;                         // Octave range for Pitch Bend   1 = 1 oct + or -    2 = 2 oct + or -
float vel;                              // calculated velocity for mixer because of failure of core oscilator velocity responses
byte velBypass = 1;                     // toggle for velocity from keyboard bypass button
float velCap = 0.50;                    // velocity cap, bypassed velocity level
float pot;                              // general purpose returned value from potentiometers
long potLog;                            // general LOG correction value for potentiometers
byte VCO1 = 0;  byte oldVCO1 = 0;
byte VCO2 = 0;  byte oldVCO2 = 0;
byte VCO3 = 0;  byte oldVCO3 = 0;
byte LFO1 = 0;  byte oldLFO = 0;

float clickDelay;

unsigned long Ticker;                   // TEMP  Variables for calculation and display of time
unsigned long difTicker;                // TEMP  used to execute the main loop.
unsigned long oldTicker;                // TEMP
unsigned long maxMicro;                 // TEMP
unsigned long maxMilli;                 // TEMP
unsigned long maxSecond;                // TEMP

float modulation;                       // modulation variable

//float detDepth;  float detFreq;       // L/R flanger detune variables

float env_att;   float env_hld;   float env_dec;   float env_sus;   float env_rel;    // Variables used in envelope pot routines
float fenv_att;  float fenv_hld;  float fenv_dec;  float fenv_sus;  float fenv_rel;   // Should be replaced with "pot" tag.

//float WAVESHAPE_EXAMPLE[17] = { -0.588, -0.579, -0.549, -0.488, -0.396, -0.320, -0.228, -0.122, 0,
//                                 0.122,  0.228,  0.320,  0.396,  0.488,  0.549,  0.579,  0.588};

//   A#         B          C          C#         D          D#         E          F          F#         G          G#         A
const float noteFreq[140] = {                           // ALLOCATE FREQUENCIES TO NOTE EVENTS       (TODO - recheck accuracy)
                          8.176,     8.662,     9.177,     9.7225,   10.301,    10.9135,   11.5625,   12.250,    12.9785,   13.750,
   14.5675,   15.434,    16.352,    17.324,    18.354,    19.445,    20.602,    21.827,    23.125,    24.500,    25.957,    27.500, // 11
   29.135,    30.868,    32.703,    34.648,    36.708,    38.891,    41.203,    43.654,    46.249,    48.999,    51.913,    55.000, // 23
   58.270,    61.735,    65.406,    69.296,    73.416,    77.782,    82.407,    87.307,    92.499,    97.999,   103.826,   110.000, // 35
  116.541,   123.471,   130.813,   138.591,   146.832,   155.563,   164.814,   174.614,   184.997,   195.998,   207.652,   220.000, // 47
  233.082,   246.942,   261.626,   277.183,   293.665,   311.127,   329.628,   349.228,   369.994,   391.995,   415.305,   440.000, // 59
  466.164,   493.883,   523.251,   554.365,   587.330,   622.254,   659.255,   698.456,   739.989,   783.991,   830.609,   880.000, // 71
  932.328,   987.767,  1046.502,  1108.730,  1174.659,  1244.508,  1318.510,  1396.913,  1479.978,  1567.982,  1661.219,  1760.000, // 83
 1864.655,  1975.533,  2093.004,  2217.461,  2349.318,  2489.016,  2637.020,  2793.826,  2959.955,  3135.963,  3322.438,  3520.000, // 95
 3729.310,  3951.066,  4186.009,  4434.922,  4698.636,  4978.032,  5274.041,  5587.652,  5919.911,  6271.927,  6644.875,  7040.000, // 107
 7458.620,  7902.133,  8372.018,  8869.844,  9397.272,  9956.063, 10548.082, 11175.303, 11839.821, 12543.854, 13289.750, 14080.000, // 119
14917.240, 15804.266, 16744.035, 17739.688, 18794.544, 19912.126, 21096.163, 22350.606, 23679.642, 25087.708  };                    // 128

/*
//  Attempt to maintain consistent harmonic oscilation rate resulting from waveform detune control throughout the keyboard scale.
//  Doesn't work but who knows?
//   10         11                    1          2          3          4          5          6          7         8           9
const float fine[140] = {
                         0.0313,    0.0339,    0.0365,    0.0391,    0.0417,    0.0443,    0.0469,    0.0495,    0.0521,    0.0547,
   0.0573,    0.0599,    0.0625,    0.0677,    0.0729,    0.0781,    0.0833,    0.0885,    0.0937,    0.099 ,    0.1042,    0.1094, // 11
   0.1146,    0.1198,     0.125,    0.1354,    0.1458,    0.1563,    0.1667,    0.1771,    0.1875,    0.1979,    0.2083,    0.2188, // 23
   0.2292,    0.2396,      0.25,    0.2708,    0.2917,    0.3125,    0.3333,    0.3542,    0.375 ,    0.3958,    0.4767,    0.4375, // 35
   0.4583,    0.4792,       0.5,    0.5417,    0.5833,    0.625 ,    0.6667,    0.7083,    0.75  ,    0.7917,    0.8333,    0.875 , // 47
   0.9167,    0.9583,       1.0,    1.0833,    1.1667,    1.25  ,    1.3333,    1.4167,    1.5   ,    1.5833,    1.6667,    1.75  , // 59
   1.8333,    1.9167,       2.0,    2.1667,    2.3333,    2.5   ,    2.6667,    2.8333,    3.0   ,    3.1667,    3.3333,    3.5   , // 71
   3.6667,    3.8333,       4.0,    4.3333,    4.6667,    5.0   ,    5.3333,    5.6667,    6.0   ,    6.3333,    6.6667,    7.0   , // 83
   7.3333,    7.6667,       8.0,    8.6667,    9.3333,   10.0   ,   10.6667,   11.3333,   12.0   ,   12.6667,   13.3333,   14.0   , // 95
  14.6667,   15.3333,      16.0,   17.3333,   18.6667,   20.0   ,   21.3333,   22.6667,   24.0   ,   25.3333,   26.6667,   28.0   , // 107
  29.3333,   30.6667,      32.0,   34.6667,   37.3333,   40.0   ,   42.6667,   45.3333,   48.0   ,   50.6667,   53.3333,   56.0   , // 119
  58.6667,   61.3333,      64.0,   69.3333,   74.6667,   80.0   ,   85.3333,   90.6667,   96.0   ,  101.3333  };                    // 128
*/

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% velocity calculation to compensate for
//                                                                 the failure of the waveform object to
//                                                                 manage the velocity
// Calculate velocity sent to Vel mixer
void velocityCalc(byte velocity)
{
  vel = (float)velocity * 0.007874;
//  Serial.println(vel);
}

// ********************************************************************************************************************************
// ********************************************************** HANDLE MIDI NOTE MESSAGES
// ******************************************************************************************************************* MIDI NOTE ON
void handleNoteOn(byte channel, byte pitch, byte velocity)
{

//AudioNoInterrupts();

if (monoPoly == 1) {

if (velocity == 0) handleNoteOff(channel, pitch, velocity); else {

  if (channelLock[0] == 0)  {  // =================================================== 1 on
  channelLock[0] = pitch;  keyArray[0] = pitch;
if (dataDisplay == 1) { Serial.print("NOTE ON  key 1 - ");    noteDisp(channel, pitch, velocity); }
  if (velBypass == 0) { 
      velocityCalc(velocity);
      velocityMix_01.gain(0, vel);
      velocityMix_01.gain(1, vel);
//      velocityMix_01.gain(2, vel);
      velocityMix_01.gain(3, vel);
      }
      else  { 
        velocityMix_01.gain(0, velCap);
        velocityMix_01.gain(1, velCap);
//        velocityMix_01.gain(2, velCap);
        velocityMix_01.gain(3, velCap);
        }
  wave_1_01.frequency((noteFreq[pitch+keyShift1] * fineTune_1) * pitchBend);
//wave_1_01.phase(0);
  wave_1_01.amplitude(velocity);
  wave_2_01.frequency((noteFreq[pitch+keyShift2] * fineTune_2) * pitchBend);
//wave_2_01.phase(0);
  wave_2_01.amplitude(velocity);
  wave_3_01.frequency((noteFreq[pitch+keyShift3]) * pitchBend);
//wave_3_01.phase(0);
  wave_3_01.amplitude(velocity);
  sine_fm_01.frequency((noteFreq[pitch]) * pitchBend);
//sine_fm_01.phase(0);
  sine_fm_01.amplitude(velocity);
  pwm_01.frequency((noteFreq[pitch]) * pitchBend);
  pwm_01.amplitude(velocity);
//    pink_noise.amplitude(velocity);
//    white_noise.amplitude(velocity);

  env_01.noteOn();  filtEnv_01.noteOn();  noise_env_01.noteOn();
//if (AudioProcessorUsage() >= 99.0) HandleSystemReset();
  nF1 = noteFreq[pitch];
  nP1 = pitch;
//  Serial.print("Key 1  ");  Serial.println((noteFreq[pitch]) * pitchBend);
  }
  else

    if (channelLock[1] == 0)  {  // =================================================== 2 on
    channelLock[1] = pitch;  keyArray[1] = pitch;
if (dataDisplay == 1) { Serial.print("NOTE ON  key 2 - ");    noteDisp(channel, pitch, velocity); }
  if (velBypass == 0) { 
      velocityCalc(velocity);
      velocityMix_02.gain(0, vel);
      velocityMix_02.gain(1, vel);
//      velocityMix_02.gain(2, vel);
      velocityMix_02.gain(3, vel);
      }
      else  { 
        velocityMix_02.gain(0, velCap);
        velocityMix_02.gain(1, velCap);
//        velocityMix_02.gain(2, velCap);
        velocityMix_02.gain(3, velCap);
        }
  wave_1_02.frequency((noteFreq[pitch+keyShift1] * fineTune_1) * pitchBend);
//wave_1_02.phase(0);
  wave_1_02.amplitude(velocity);
  wave_2_02.frequency((noteFreq[pitch+keyShift2] * fineTune_2) * pitchBend);
//wave_2_02.phase(0);
  wave_2_02.amplitude(velocity);
  wave_3_02.frequency((noteFreq[pitch+keyShift3]) * pitchBend);
//wave_3_02.phase(0);
  wave_3_02.amplitude(velocity);
  sine_fm_02.frequency((noteFreq[pitch]) * pitchBend);
//sine_fm_02.phase(0);
  sine_fm_02.amplitude(velocity);
  pwm_02.frequency((noteFreq[pitch]) * pitchBend);
  pwm_02.amplitude(velocity);
//    pink_noise.amplitude(velocity);
//    white_noise.amplitude(velocity);

  env_02.noteOn();  filtEnv_02.noteOn();  noise_env_02.noteOn();
//if (AudioProcessorUsage() >= 99.0) HandleSystemReset();
  nF2 = noteFreq[pitch];
  nP2 = pitch;
//  Serial.print("Key 2  ");  Serial.println((noteFreq[pitch]) * pitchBend);
  }
  else

    if (channelLock[2] == 0)  {  // =================================================== 3 on
    channelLock[2] = pitch;  keyArray[2] = pitch;
if (dataDisplay == 1) { Serial.print("NOTE ON  key 3 - ");    noteDisp(channel, pitch, velocity); }
  if (velBypass == 0) { 
      velocityCalc(velocity);
      velocityMix_03.gain(0, vel);
      velocityMix_03.gain(1, vel);
//      velocityMix_03.gain(2, vel);
      velocityMix_03.gain(3, vel);
      }
      else  { 
        velocityMix_03.gain(0, velCap);
        velocityMix_03.gain(1, velCap);
//        velocityMix_03.gain(2, velCap);
        velocityMix_03.gain(3, velCap);
        }
  wave_1_03.frequency((noteFreq[pitch+keyShift1] * fineTune_1) * pitchBend);
//wave_1_03.phase(0);
  wave_1_03.amplitude(velocity);
  wave_2_03.frequency((noteFreq[pitch+keyShift2] * fineTune_2) * pitchBend);
//wave_2_03.phase(0);
  wave_2_03.amplitude(velocity);
  wave_3_03.frequency((noteFreq[pitch+keyShift3]) * pitchBend);
//wave_3_03.phase(0);
  wave_3_03.amplitude(velocity);
  sine_fm_03.frequency((noteFreq[pitch]) * pitchBend);
//sine_fm_03.phase(0);
  sine_fm_03.amplitude(velocity);
  pwm_03.frequency((noteFreq[pitch]) * pitchBend);
  pwm_03.amplitude(velocity);
//    pink_noise.amplitude(velocity);
//    white_noise.amplitude(velocity);

  env_03.noteOn();  filtEnv_03.noteOn();  noise_env_03.noteOn();
//if (AudioProcessorUsage() >= 99.0) HandleSystemReset();
  nF3 = noteFreq[pitch];
  nP3 = pitch;
//  Serial.print("Key 3  ");  Serial.println((noteFreq[pitch]) * pitchBend);
  }
  else

    if (channelLock[3] == 0)  {  // =================================================== 4 on
    channelLock[3] = pitch;  keyArray[3] = pitch;
if (dataDisplay == 1) { Serial.print("NOTE ON  key 4 - ");    noteDisp(channel, pitch, velocity); }
  if (velBypass == 0) { 
      velocityCalc(velocity);
      velocityMix_04.gain(0, vel);
      velocityMix_04.gain(1, vel);
//      velocityMix_04.gain(2, vel);
      velocityMix_04.gain(3, vel);
  }
      else  { 
        velocityMix_04.gain(0, velCap);
        velocityMix_04.gain(1, velCap);
//        velocityMix_04.gain(2, velCap);
        velocityMix_04.gain(3, velCap);
        }
  wave_1_04.frequency((noteFreq[pitch+keyShift1] * fineTune_1) * pitchBend);
//wave_1_04.phase(0);
  wave_1_04.amplitude(velocity);
  wave_2_04.frequency((noteFreq[pitch+keyShift2] * fineTune_2) * pitchBend);
//wave_2_04.phase(0);
  wave_2_04.amplitude(velocity);
  wave_3_04.frequency((noteFreq[pitch+keyShift3]) * pitchBend);
//wave_3_04.phase(0);
  wave_3_04.amplitude(velocity);
  sine_fm_04.frequency((noteFreq[pitch]) * pitchBend);
//sine_fm_04.phase(0);
  sine_fm_04.amplitude(velocity);
  pwm_04.frequency((noteFreq[pitch]) * pitchBend);
  pwm_04.amplitude(velocity);
//    pink_noise.amplitude(velocity);
//    white_noise.amplitude(velocity);

  env_04.noteOn();  filtEnv_04.noteOn();  noise_env_04.noteOn();
//if (AudioProcessorUsage() >= 99.0) HandleSystemReset();
  nF4 = noteFreq[pitch];
  nP4 = pitch;
//  Serial.print("Key 4  ");  Serial.println((noteFreq[pitch]) * pitchBend);
  }
  else

    if (channelLock[4] == 0)  {  // =================================================== 5 on
    channelLock[4] = pitch;  keyArray[4] = pitch;
if (dataDisplay == 1) { Serial.print("NOTE ON  key 5 - ");    noteDisp(channel, pitch, velocity); }
  if (velBypass == 0) { 
      velocityCalc(velocity);
      velocityMix_05.gain(0, vel);
      velocityMix_05.gain(1, vel);
//      velocityMix_05.gain(2, vel);
      velocityMix_05.gain(3, vel);
      }
      else  { 
        velocityMix_05.gain(0, velCap);
        velocityMix_05.gain(1, velCap);
//        velocityMix_05.gain(2, velCap);
        velocityMix_05.gain(3, velCap);
        }
  wave_1_05.frequency((noteFreq[pitch+keyShift1] * fineTune_1) * pitchBend);
//wave_1_05.phase(0);
  wave_1_05.amplitude(velocity);
  wave_2_05.frequency((noteFreq[pitch+keyShift2] * fineTune_2) * pitchBend);
//wave_2_05.phase(0);
  wave_2_05.amplitude(velocity);
  wave_3_05.frequency((noteFreq[pitch+keyShift3]) * pitchBend);
//wave_3_05.phase(0);
  wave_3_05.amplitude(velocity);
  sine_fm_05.frequency((noteFreq[pitch]) * pitchBend);
//sine_fm_05.phase(0);
  sine_fm_05.amplitude(velocity);
  pwm_05.frequency((noteFreq[pitch]) * pitchBend);
  pwm_05.amplitude(velocity);
//    pink_noise.amplitude(velocity);
//    white_noise.amplitude(velocity);

  env_05.noteOn();  filtEnv_05.noteOn();  noise_env_05.noteOn();
//if (AudioProcessorUsage() >= 99.0) HandleSystemReset();
  nF5 = noteFreq[pitch];
  nP5 = pitch;
//  Serial.print("Key 5  ");  Serial.println((noteFreq[pitch]) * pitchBend);
  }
  else

    if (channelLock[5] == 0)  {  // =================================================== 6 on
    channelLock[5] = pitch;  keyArray[5] = pitch;
if (dataDisplay == 1) { Serial.print("NOTE ON  key 6 - ");    noteDisp(channel, pitch, velocity); }
  if (velBypass == 0) { 
      velocityCalc(velocity);
      velocityMix_06.gain(0, vel);
      velocityMix_06.gain(1, vel);
//      velocityMix_06.gain(2, vel);
      velocityMix_06.gain(3, vel);
      }
      else  { 
        velocityMix_06.gain(0, velCap);
        velocityMix_06.gain(1, velCap);
//        velocityMix_06.gain(2, velCap);
        velocityMix_06.gain(3, velCap);
        }
  wave_1_06.frequency((noteFreq[pitch+keyShift1] * fineTune_1) * pitchBend);
//wave_1_06.phase(0);
  wave_1_06.amplitude(velocity);
  wave_2_06.frequency((noteFreq[pitch+keyShift2] * fineTune_2) * pitchBend);
//wave_2_06.phase(0);
  wave_2_06.amplitude(velocity);
  wave_3_06.frequency((noteFreq[pitch+keyShift3]) * pitchBend);
//wave_3_06.phase(0);
  wave_3_06.amplitude(velocity);
  sine_fm_06.frequency((noteFreq[pitch]) * pitchBend);
//sine_fm_06.phase(0);
  sine_fm_06.amplitude(velocity);
  pwm_06.frequency((noteFreq[pitch]) * pitchBend);
  pwm_06.amplitude(velocity);
//    pink_noise.amplitude(velocity);
//    white_noise.amplitude(velocity);

  env_06.noteOn();  filtEnv_06.noteOn();  noise_env_06.noteOn();
//if (AudioProcessorUsage() >= 99.0) HandleSystemReset();
  nF6 = noteFreq[pitch];
  nP6 = pitch;
//  Serial.print("Key 6  ");  Serial.println((noteFreq[pitch]) * pitchBend);
  }
  else

    if (channelLock[6] == 0)  {  // =================================================== 7 on
    channelLock[6] = pitch;  keyArray[6] = pitch;
if (dataDisplay == 1) { Serial.print("NOTE ON  key 7 - ");    noteDisp(channel, pitch, velocity); }
  if (velBypass == 0) { 
      velocityCalc(velocity);
      velocityMix_07.gain(0, vel);
      velocityMix_07.gain(1, vel);
//      velocityMix_07.gain(2, vel);
      velocityMix_07.gain(3, vel);
      }
      else  { 
        velocityMix_07.gain(0, velCap);
        velocityMix_07.gain(1, velCap);
//        velocityMix_07.gain(2, velCap);
        velocityMix_07.gain(3, velCap);
        }
  wave_1_07.frequency((noteFreq[pitch+keyShift1] * fineTune_1) * pitchBend);
//wave_1_07.phase(0);
  wave_1_07.amplitude(velocity);
  wave_2_07.frequency((noteFreq[pitch+keyShift2] * fineTune_2) * pitchBend);
//wave_2_07.phase(0);
  wave_2_07.amplitude(velocity);
  wave_3_07.frequency((noteFreq[pitch+keyShift3]) * pitchBend);
//wave_3_07.phase(0);
  wave_3_07.amplitude(velocity);
  sine_fm_07.frequency((noteFreq[pitch]) * pitchBend);
//sine_fm_07.phase(0);
  sine_fm_07.amplitude(velocity);
  pwm_07.frequency((noteFreq[pitch]) * pitchBend);
  pwm_07.amplitude(velocity);
//    pink_noise.amplitude(velocity);
//    white_noise.amplitude(velocity);

  env_07.noteOn();  filtEnv_07.noteOn();  noise_env_07.noteOn();
//if (AudioProcessorUsage() >= 99.0) HandleSystemReset();
  nF7 = noteFreq[pitch];
  nP7 = pitch;
//  Serial.print("Key 7  ");  Serial.println((noteFreq[pitch]) * pitchBend);
  }
  else

    if (channelLock[7] == 0)  {  // =================================================== 8 on
    channelLock[7] = pitch;  keyArray[7] = pitch;
if (dataDisplay == 1) { Serial.print("NOTE ON  key 8 - ");    noteDisp(channel, pitch, velocity); }
  if (velBypass == 0) { 
      velocityCalc(velocity);
      velocityMix_08.gain(0, vel);
      velocityMix_08.gain(1, vel);
//      velocityMix_08.gain(2, vel);
      velocityMix_08.gain(3, vel);
      }
      else  { 
        velocityMix_08.gain(0, velCap);
        velocityMix_08.gain(1, velCap);
//        velocityMix_08.gain(2, velCap);
        velocityMix_08.gain(3, velCap);
        }
  wave_1_08.frequency((noteFreq[pitch+keyShift1] * fineTune_1) * pitchBend);
//wave_1_08.phase(0);
  wave_1_08.amplitude(velocity);
  wave_2_08.frequency((noteFreq[pitch+keyShift2] * fineTune_2) * pitchBend);
//wave_2_08.phase(0);
  wave_2_08.amplitude(velocity);
  wave_3_08.frequency((noteFreq[pitch+keyShift3]) * pitchBend);
//wave_3_08.phase(0);
  wave_3_08.amplitude(velocity);
  sine_fm_08.frequency((noteFreq[pitch]) * pitchBend);
//sine_fm_08.phase(0);
  sine_fm_08.amplitude(velocity);
  pwm_08.frequency((noteFreq[pitch]) * pitchBend);
  pwm_08.amplitude(velocity);
//    pink_noise.amplitude(velocity);
//    white_noise.amplitude(velocity);

  env_08.noteOn();  filtEnv_08.noteOn();  noise_env_08.noteOn();
//if (AudioProcessorUsage() >= 99.0) HandleSystemReset();
  nF8 = noteFreq[pitch];
  nP8 = pitch;
//  Serial.print("Key 8  ");  Serial.println((noteFreq[pitch]) * pitchBend);
  }
}
//Serial.print(pitch);    Serial.print("  Velocity - ");    Serial.print(velocity);    Serial.print("  Frequency - ");    Serial.println(noteFreq[pitch]);
digitalWrite(LED, HIGH);

}
else

if (velocity == 0) handleNoteOff(channel, pitch, velocity); else {

//  if (channelLock[0] == 0)  {  // =================================================== 1 on
  channelLock[0] = pitch;  keyArray[0] = pitch;
if (dataDisplay == 1) { Serial.print("NOTE ON  key 1 - ");    noteDisp(channel, pitch, velocity); }
  if (velBypass == 0) { 
      velocityCalc(velocity);
      velocityMix_01.gain(0, vel);
      velocityMix_01.gain(1, vel);
//      velocityMix_01.gain(2, vel);
      velocityMix_01.gain(3, vel);
      }
      else  { 
        velocityMix_01.gain(0, velCap);
        velocityMix_01.gain(1, velCap);
//        velocityMix_01.gain(2, velCap);
        velocityMix_01.gain(3, velCap);
        }
  wave_1_01.frequency((noteFreq[pitch+keyShift1] * fineTune_1) * pitchBend);
//wave_1_01.phase(0);
  wave_1_01.amplitude(velocity);
  wave_2_01.frequency((noteFreq[pitch+keyShift2] * fineTune_2) * pitchBend);
//wave_2_01.phase(0);
  wave_2_01.amplitude(velocity);
  wave_3_01.frequency((noteFreq[pitch+keyShift3]) * pitchBend);
//wave_3_01.phase(0);
  wave_3_01.amplitude(velocity);
  sine_fm_01.frequency((noteFreq[pitch]) * pitchBend);
//sine_fm_01.phase(0);
  sine_fm_01.amplitude(velocity);
  pwm_01.frequency((noteFreq[pitch]) * pitchBend);
  pwm_01.amplitude(velocity);
//    pink_noise.amplitude(velocity);
//    white_noise.amplitude(velocity);

  env_01.noteOn();  filtEnv_01.noteOn();  noise_env_01.noteOn();
//if (AudioProcessorUsage() >= 99.0) HandleSystemReset();
  nF1 = noteFreq[pitch];
  nP1 = pitch;
  Serial.print("Key 1  ");  Serial.println((noteFreq[pitch]) * pitchBend);
  }
//AudioInterrupts();
//delay(10);
}

void noteDisp(byte channel, byte pitch, byte velocity)
{
if (dataDisplay == 1) { Serial.print(pitch);  Serial.print("  Channel - ");  Serial.print(channel);  Serial.print("  Velocity - ");  Serial.print(velocity);  Serial.print("  Frequency - ");  Serial.println(noteFreq[pitch]);  }
}

// ****************************************************************************************************************** MIDI NOTE OFF
void handleNoteOff(byte channel, byte pitch, byte velocity)
{
//  if (monoPoly == 1)  {
  if (channelLock[0] == pitch)  {  // =================================================== 1 off
if (dataDisplay == 1) { Serial.print("NOTE OFF key 1 - ");    Serial.println(pitch); }
  env_01.noteOff();  filtEnv_01.noteOff(); // noise_env_01.noteOff();
//  wave_1_01.amplitude(0.0);
//  wave_2_01.amplitude(0.0);
//  wave_3_01.amplitude(0.0);
//  sine_fm_01.amplitude(0.0);
//  pwm_01.amplitude(0.0);
//  pink_noise.amplitude(0.0);
//  white_noise.amplitude(0.0);

  channelLock[0] = 0;
  }
  else
    if (channelLock[1] == pitch)  {  // =================================================== 2 off
if (dataDisplay == 1) { Serial.print("NOTE OFF key 2 - ");    Serial.println(pitch); }
  env_02.noteOff();  filtEnv_02.noteOff();  noise_env_02.noteOff();
//  wave_1_02.amplitude(0.0);
//  wave_2_02.amplitude(0.0);
//  wave_3_02.amplitude(0.0);
//  sine_fm_02.amplitude(0.0);
//  pwm_02.amplitude(0.0);
//  pink_noise.amplitude(0.0);
//  white_noise.amplitude(0.0);

  channelLock[1] = 0;
  }
  else
    if (channelLock[2] == pitch)  {  // =================================================== 3 off
if (dataDisplay == 1) { Serial.print("NOTE OFF key 3 - ");    Serial.println(pitch); }
  env_03.noteOff();  filtEnv_03.noteOff();  noise_env_03.noteOff();
//  wave_1_03.amplitude(0.0);
//  wave_2_03.amplitude(0.0);
//  wave_3_03.amplitude(0.0);
//  sine_fm_03.amplitude(0.0);
//  pwm_03.amplitude(0.0);
//  pink_noise.amplitude(0.0);
//  white_noise.amplitude(0.0);

  channelLock[2] = 0;
  }
  else
    if (channelLock[3] == pitch)  {  // =================================================== 4 off
if (dataDisplay == 1) { Serial.print("NOTE OFF key 4 - ");    Serial.println(pitch); }
  env_04.noteOff();  filtEnv_04.noteOff();  noise_env_04.noteOff();
//  wave_1_04.amplitude(0.0);
//  wave_2_04.amplitude(0.0);
//  wave_3_04.amplitude(0.0);
//  sine_fm_04.amplitude(0.0);
//  pwm_04.amplitude(0.0);
//  pink_noise.amplitude(0.0);
//  white_noise.amplitude(0.0);

  channelLock[3] = 0;
  }
  else
    if (channelLock[4] == pitch)  {  // =================================================== 5 off
if (dataDisplay == 1) { Serial.print("NOTE OFF key 5 - ");    Serial.println(pitch); }
  env_05.noteOff();  filtEnv_05.noteOff();  noise_env_05.noteOff();
//  wave_1_05.amplitude(0.0);
//  wave_2_05.amplitude(0.0);
//  wave_3_05.amplitude(0.0);
//  sine_fm_05.amplitude(0.0);
//  pwm_05.amplitude(0.0);
//  pink_noise.amplitude(0.0);
//  white_noise.amplitude(0.0);

  channelLock[4] = 0;
  }
  else
    if (channelLock[5] == pitch)  {  // =================================================== 6 off
if (dataDisplay == 1) { Serial.print("NOTE OFF key 6 - ");    Serial.println(pitch); }
  env_06.noteOff();  filtEnv_06.noteOff();  noise_env_06.noteOff();
//  wave_1_06.amplitude(0.0);
//  wave_2_06.amplitude(0.0);
//  wave_3_06.amplitude(0.0);
//  sine_fm_06.amplitude(0.0);
//  pwm_06.amplitude(0.0);
//  pink_noise.amplitude(0.0);
//  white_noise.amplitude(0.0);

  channelLock[5] = 0;
  }
  else
    if (channelLock[6] == pitch)  {  // =================================================== 7 off
if (dataDisplay == 1) { Serial.print("NOTE OFF key 7 - ");    Serial.println(pitch); }
  env_07.noteOff();  filtEnv_07.noteOff();  noise_env_07.noteOff();
//  wave_1_07.amplitude(0.0);
//  wave_2_07.amplitude(0.0);
//  wave_3_07.amplitude(0.0);
//  sine_fm_07.amplitude(0.0);
//  pwm_07.amplitude(0.0);
//  pink_noise.amplitude(0.0);
//  white_noise.amplitude(0.0);

  channelLock[6] = 0;
  }
  else
    if (channelLock[7] == pitch)  {  // =================================================== 8 off
if (dataDisplay == 1) { Serial.print("NOTE OFF key 8 - ");    Serial.println(pitch); } 
  env_08.noteOff();  filtEnv_08.noteOff();  noise_env_08.noteOff();
//  wave_1_08.amplitude(0.0);
//  wave_2_08.amplitude(0.0);
//  wave_3_08.amplitude(0.0);
//  sine_fm_08.amplitude(0.0);
//  pwm_08.amplitude(0.0);
//  pink_noise.amplitude(0.0);
//  white_noise.amplitude(0.0);

  channelLock[7] = 0;
  }

digitalWrite(LED, LOW);
}

// ************************************************************************************************************ MIDI CONTROL CHANGE
void HandlePitchBend(byte channel, int bend)
{
 if (PBOct == 1)  {
  if (bend > 0.0) pitchBend =(float(bend) + 8191.0) / 8191.0; else                   // Pitch bend -1 Oct to +1 Oct
  if (bend < 0.0) pitchBend =((float(bend) + 8191.0) / 16382.0) + 0.5; else
  pitchBend = 1.0;
 }
 else
 {
  if (bend > 0.0) pitchBend =(float(bend * 3.0) + 8191.0) / 8191.0; else             // Pitch bend -2 Oct to +2 Oct
  if (bend < 0.0) pitchBend =((float(bend * 1.5) + 8191.0) / 16382.0) + 0.5; else
  pitchBend = 1.0;
 }
  
  Serial.print("Pitch bend  ");  Serial.print(pitchBend);  Serial.print(" from ");  Serial.println(bend);
  
  wave_1_01.frequency((noteFreq[nP1 + keyShift1] * fineTune_1) * pitchBend);
  wave_2_01.frequency((noteFreq[nP1 + keyShift2] * fineTune_2) * pitchBend);
  wave_3_01.frequency((noteFreq[nP1 + keyShift3]) * pitchBend);
  sine_fm_01.frequency(noteFreq[nP1] * pitchBend);
  pwm_01.frequency(noteFreq[nP1] * pitchBend);

  wave_1_02.frequency((noteFreq[nP2 + keyShift1] * fineTune_1) * pitchBend);
  wave_2_02.frequency((noteFreq[nP2 + keyShift2] * fineTune_2) * pitchBend);
  wave_3_02.frequency((noteFreq[nP2 + keyShift3]) * pitchBend);
  sine_fm_02.frequency(noteFreq[nP2] * pitchBend);
  pwm_02.frequency(noteFreq[nP2] * pitchBend);

  wave_1_03.frequency((noteFreq[nP3 + keyShift1] * fineTune_1) * pitchBend);
  wave_2_03.frequency((noteFreq[nP3 + keyShift2] * fineTune_2) * pitchBend);
  wave_3_03.frequency((noteFreq[nP3 + keyShift3]) * pitchBend);
  sine_fm_03.frequency((noteFreq[nP3]) * pitchBend);
  pwm_03.frequency(noteFreq[nP3] * pitchBend);

  wave_1_04.frequency((noteFreq[nP4 + keyShift1] * fineTune_1) * pitchBend);
  wave_2_04.frequency((noteFreq[nP4 + keyShift2] * fineTune_2) * pitchBend);
  wave_3_04.frequency((noteFreq[nP4 + keyShift3]) * pitchBend);
  sine_fm_04.frequency((noteFreq[nP4]) * pitchBend);
  pwm_04.frequency(noteFreq[nP4] * pitchBend);

  wave_1_05.frequency((noteFreq[nP5 + keyShift1] * fineTune_1) * pitchBend);
  wave_2_05.frequency((noteFreq[nP5 + keyShift2] * fineTune_2) * pitchBend);
  wave_3_05.frequency((noteFreq[nP5 + keyShift3]) * pitchBend);
  sine_fm_05.frequency((noteFreq[nP5]) * pitchBend);
  pwm_05.frequency(noteFreq[nP5] * pitchBend);

  wave_1_06.frequency((noteFreq[nP6 + keyShift1] * fineTune_1) * pitchBend);
  wave_2_06.frequency((noteFreq[nP6 + keyShift2] * fineTune_2) * pitchBend);
  wave_3_06.frequency((noteFreq[nP6 + keyShift3]) * pitchBend);
  sine_fm_06.frequency(noteFreq[nP6] * pitchBend);
  pwm_06.frequency(noteFreq[nP6] * pitchBend);

  wave_1_07.frequency((noteFreq[nP7 + keyShift1] * fineTune_1) * pitchBend);
  wave_2_07.frequency((noteFreq[nP7 + keyShift2] * fineTune_2) * pitchBend);
  wave_3_07.frequency((noteFreq[nP7 + keyShift3]) * pitchBend);
  sine_fm_07.frequency(noteFreq[nP7] * pitchBend);
  pwm_07.frequency(noteFreq[nP7] * pitchBend);

  wave_1_08.frequency((noteFreq[nP8 + keyShift1] * fineTune_1) * pitchBend);
  wave_2_08.frequency((noteFreq[nP8 + keyShift2] * fineTune_2) * pitchBend);
  wave_3_08.frequency((noteFreq[nP8 + keyShift3]) * pitchBend);
  sine_fm_08.frequency((noteFreq[nP8]) * pitchBend);
  pwm_08.frequency(noteFreq[nP8] * pitchBend);

/*
Serial.print("  bend = ");  Serial.print(bend);
Serial.print("  pitch bend = ");  Serial.print(pitchBend);
Serial.print("  wave 1 = ");  Serial.print((nF1 * fineTune_1) * pitchBend);
Serial.print("  wave 2 = ");  Serial.print((noteFreq[nP1 + keyShift]) * pitchBend);
Serial.print("  wave 3 = ");  Serial.print((nF1 * fineTune_2) * pitchBend);
Serial.print("  sine_fm = ");  Serial.print((noteFreq[nP1]) * pitchBend);
Serial.print("  PWM = ");  Serial.println((noteFreq[nP1]) * pitchBend);
*/
}
//==============================================================

// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void buttRead()  {
//if (dataDisplay == 3) {  Serial.print(butt);  Serial.print(" - ");  }
//Serial.println(butt);

if (butt > 5)  {                                         // 12
if (butt > 1016) {  butt = 0;  buttonTog = 0;  }  else
if (butt > 998) {  butt = 9;  }  else                     // 1010
if (butt > 963) {  butt = 8;  }  else                     // 987
if (butt > 907) {  butt = 7;  }  else                     // 939
if (butt > 809) {  butt = 6;  }  else                     // 876
if (butt > 653) {  butt = 5;  }  else                     // 743
if (butt > 459) {  butt = 4;  }  else                     // 564
if (butt > 255) {  butt = 3;  }  else                     // 355
if (butt > 83) {  butt = 2;  }  else                     // 155
{  butt = 1;  } }
//if (dataDisplay == 3) {  Serial.print(butt);  Serial.print(" toggle - ");  Serial.println(buttonTog);  }
/*
1  Test note 440 Hz
2  Select source waveforms for PWM
3  Select source waveforms for Sine_FM
4  Mono/Poly
5  Pitch bend range toggle 1 or 2 octaves
6  Filter envelope on/off
7  Flange on/off
8  Keyboard velocity on/off
  TODO    Needs corrections
9  DISPLAY toggle 0 = Controls only     1 = MIDI input data     2 - CPU loads and Memory  4 - Timing data from main loop
*/
}

void HandleControlChange(byte channel, byte number, byte value)
{
  if (number == 7)  {                                                       // Sound board volume
/*
  pot = (float)value / 127.0;
//  pot = ((float)value / 255.0) + 0.5;
//  if (pot == 0.5) pot = 0.0;
  sgtl5000.volume(pot);
//  osc_main_mix.gain(0, pot / 2);  osc_main_mix.gain(1, pot / 2);
    Serial.print("Channel - ");                Serial.print(channel);
    Serial.print("  Control number - ");       Serial.print(number);
    Serial.print("  Volume set - ");           Serial.println(pot);
*/
  }
  else

  if  (number == 74)  {                                                     // Flanger frequency
  s_freq_mod = ((float)value * 0.0314) + 0.01;
    Serial.print("Channel - ");                Serial.print(channel);
    Serial.print("  Control number - ");       Serial.print(number);
    Serial.print("  Raw value recieved - ");   Serial.print((float)value);
    Serial.print("  Flange frequency - ");     Serial.println(s_freq_mod);
  }
  else

  if  (number == 71)  {                                                     // Flanger depth
  s_depth_mod = ((float)value) * 1.5118;
    Serial.print("Channel - ");                Serial.print(channel);
    Serial.print("  Control number - ");       Serial.print(number);
    Serial.print("  Raw value recieved - ");   Serial.print((float)value);
    Serial.print("  Flange depth - ");         Serial.println(s_depth_mod);
  }
  else

  if  (number == 73)  {                                                     // Flanger L/R detune
  detDepth = ((float)value * 1.5118) - 96;
  detFreq = ((float)value * 0.0314) - 2;
    Serial.print("Channel - ");                Serial.print(channel);
    Serial.print("  Control number - ");       Serial.print(number);
    Serial.print("  Raw value recieved - ");   Serial.print((float)value);
    Serial.print("  Flange detune depth - ");  Serial.print(detDepth);
    Serial.print("  Flange detune freq - ");   Serial.println(detFreq);
  }
  else

  if  (number == 1)  {                                                      // Mod wheel depth
  modulation = ((float)value) * 0.0078740;

  LFO_mix.gain(0, 0.5 - (modulation / 2));
  LFO_mix.gain(1, modulation / 2);
  if (modulation == 0.0) LFO.amplitude(0.0); else LFO.amplitude(0.9);

    Serial.print("Channel - ");                Serial.print(channel);
    Serial.print("  Control number - ");       Serial.print(number);
    Serial.print("  Raw value recieved - ");   Serial.print((float)value);
    Serial.print("  Modulation - ");           Serial.println(modulation);
  }
  else

  {
    Serial.print("Un-allocated MIDI controller = ");
    Serial.print("Channel - ");                Serial.print(channel);
    Serial.print("  Control number - ");       Serial.print(number);
    Serial.print("  Value set - ");            Serial.println((float)value);
  }
}

// Set FM phase called on wave shape change
void sinefmPhase()  {
    sine_fm_01.phase(0.0);      sine_fm_02.phase(0.0);    sine_fm_03.phase(0.0);    sine_fm_04.phase(0.0);
    sine_fm_05.phase(0.0);      sine_fm_06.phase(0.0);    sine_fm_07.phase(0.0);    sine_fm_08.phase(0.0);
}

// ================================================================================================================================
// ******************************************************************************** SETUP
// ================================================================================================================================
void setup() {
  // put your setup code here, to run once:
//analogReference(EXTERNAL);
//analogReference(INTERNAL);
//analogReference(DEFAULT);
  Serial.begin(31250);

delay(600);
  Serial.println("==== SYNTH  BOOTING ====");

  MIDI.begin(MIDI_CHANNEL_OMNI);
  MIDI.turnThruOn(Full);
    MIDI.setHandleNoteOn(handleNoteOn);               //  (byte channel, byte note, byte velocity)
    MIDI.setHandleNoteOff(handleNoteOff);             //  (byte channel, byte note, byte velocity)
    MIDI.setHandlePitchBend(HandlePitchBend);         //  (byte channel, int bend)
    MIDI.setHandleControlChange(HandleControlChange); //  (byte channel, byte number, byte value)
//    MIDI.setHandleSystemReset(HandleSystemReset);
  pinMode(LED, OUTPUT);
  digitalWrite(LED, HIGH);
  
  sgtl5000.enable();
  sgtl5000.volume(0.5);
  sgtl5000.unmuteLineout();
  sgtl5000.inputSelect(AUDIO_INPUT_LINEIN);
  sgtl5000.lineInLevel(15, 15);
//  sgtl5000.lineInLevel(0, 0);                         // (0-15)   (5 DEFAULT)
//  sgtl5000.lineOutLevel(29);                          // (13-31)  (29 DEFAULT)
  sgtl5000.lineOutLevel(13);
  sgtl5000.micGain(0);                                // (0-63)
  sgtl5000.audioPostProcessorEnable();
//  sgtl5000.audioProcessorDisable();
  sgtl5000.surroundSoundEnable();
//  sgtl5000.surroundSoundDisable();
//  sgtl5000.surroundSound(7);                          // (0 to 7)
  sgtl5000.surroundSound(7, 3);                       // (0 to 7, 1 off 2 mono 3 stereo)  (input I think)
//  sgtl5000.enhanceBassEnable();
//  sgtl5000.enhanceBassDisable();
//  sgtl5000.enhanceBass(lr_lev, bass_lev, hpf_bypass, cutoff);
  sgtl5000.eqSelect(3);                               // (0 FlatFreq  1 Para  2 Tone  3 GraphicEQ)
//  sgtl5000.eqBands(bass, treble);
  sgtl5000.eqBands(1.0, 0.7, 0.2, 0, 0.7);            //(bass, mid_bass, midrange, mid_treble, treble)   -1.0 - 1.0
//  sgtl5000.eqBand(bandNum, n);
//  sgtl5000.eqFilter(filterNum, filterParameters);
//  sgtl5000.eqFilterCount(n);

/*
waveshape_01.shape(WAVESHAPE_EXAMPLE, 17);
waveshape_02.shape(WAVESHAPE_EXAMPLE, 17);
waveshape_03.shape(WAVESHAPE_EXAMPLE, 17);
waveshape_04.shape(WAVESHAPE_EXAMPLE, 17);
waveshape_05.shape(WAVESHAPE_EXAMPLE, 17);
waveshape_06.shape(WAVESHAPE_EXAMPLE, 17);
waveshape_07.shape(WAVESHAPE_EXAMPLE, 17);
waveshape_08.shape(WAVESHAPE_EXAMPLE, 17);
*/
// Un-used pins
  pinMode(2, OUTPUT);   pinMode(3, OUTPUT);   pinMode(4, OUTPUT);   pinMode(5, OUTPUT);   pinMode(8, OUTPUT);
  pinMode(15, OUTPUT);  pinMode(16, OUTPUT);  pinMode(17, OUTPUT);  pinMode(20, OUTPUT);  pinMode(21, OUTPUT);
  pinMode(A10, OUTPUT); pinMode(A11, OUTPUT); pinMode(24, OUTPUT);  pinMode(25, OUTPUT);  pinMode(26, OUTPUT);
  pinMode(27, OUTPUT);  pinMode(39, OUTPUT);  pinMode(A21, OUTPUT); pinMode(A22, OUTPUT);

  pinMode(40, OUTPUT);  pinMode(41, OUTPUT);  pinMode(42, OUTPUT);  pinMode(43, OUTPUT);  pinMode(44, OUTPUT);  // Underside
  pinMode(45, OUTPUT);  pinMode(46, OUTPUT);  pinMode(47, OUTPUT);  pinMode(48, OUTPUT);  pinMode(49, OUTPUT);  // Underside
  pinMode(50, OUTPUT);  pinMode(51, OUTPUT);  pinMode(52, OUTPUT);  pinMode(53, OUTPUT);  pinMode(54, OUTPUT);  // Underside
  pinMode(55, OUTPUT);  pinMode(56, OUTPUT);  pinMode(57, OUTPUT);  // Underside

// Setup multiplexers
  pinMode(S0, OUTPUT);  pinMode(S1, OUTPUT);  pinMode(S2, OUTPUT);
  pinMode(muxPot_12, INPUT_PULLUP);
  pinMode(muxPot_13, INPUT_PULLUP);
  pinMode(muxPot_14, INPUT_PULLUP);
  pinMode(muxPot_15, INPUT_PULLUP);
  pinMode(muxPot_16, INPUT_PULLUP);
  pinMode(muxPot_17, INPUT_PULLUP);
  pinMode(muxPot_18, INPUT_PULLUP);
  pinMode(muxPot_19, INPUT_PULLUP);

  // Set up the flange effect:
  //   address of delayline                                            total number of samples in the delay line
  //   Index (in samples) into the delay line for the added voice      Depth of the flange effect
  //   frequency of the flange effect
  L_flange.begin(l_delayline,FLANGE_DELAY_LENGTH,s_idx,s_depth,s_freq);
  R_flange.begin(r_delayline,FLANGE_DELAY_LENGTH,s_idx,s_depth,s_freq);
  // Initially the effect is off. It is switched on when the PASSTHRU button is pushed.
  L_flange.voices(FLANGE_DELAY_PASSTHRU,0,0);
  R_flange.voices(FLANGE_DELAY_PASSTHRU,0,0);


  int oscLevel0 = 0.25;    int oscLevel1 = 0.25;    int oscLevel2 = 0.25;    int oscLevel3 = 0.25;  // TODO - set into permanent values in final version
  osc_mixA_01.gain(0, oscLevel0);  osc_mixA_01.gain(1, oscLevel1);  osc_mixA_01.gain(2, oscLevel2);  osc_mixA_01.gain(3, oscLevel3);
  osc_mixA_02.gain(0, oscLevel0);  osc_mixA_02.gain(1, oscLevel1);  osc_mixA_02.gain(2, oscLevel2);  osc_mixA_02.gain(3, oscLevel3);
  osc_mixA_03.gain(0, oscLevel0);  osc_mixA_03.gain(1, oscLevel1);  osc_mixA_03.gain(2, oscLevel2);  osc_mixA_03.gain(3, oscLevel3);
  osc_mixA_04.gain(0, oscLevel0);  osc_mixA_04.gain(1, oscLevel1);  osc_mixA_04.gain(2, oscLevel2);  osc_mixA_04.gain(3, oscLevel3);
  osc_mixA_05.gain(0, oscLevel0);  osc_mixA_05.gain(1, oscLevel1);  osc_mixA_05.gain(2, oscLevel2);  osc_mixA_05.gain(3, oscLevel3);
  osc_mixA_06.gain(0, oscLevel0);  osc_mixA_06.gain(1, oscLevel1);  osc_mixA_06.gain(2, oscLevel2);  osc_mixA_06.gain(3, oscLevel3);
  osc_mixA_07.gain(0, oscLevel0);  osc_mixA_07.gain(1, oscLevel1);  osc_mixA_07.gain(2, oscLevel2);  osc_mixA_07.gain(3, oscLevel3);
  osc_mixA_08.gain(0, oscLevel0);  osc_mixA_08.gain(1, oscLevel1);  osc_mixA_08.gain(2, oscLevel2);  osc_mixA_08.gain(3, oscLevel3);


  int vMixB0 = 0.25;  int vMixB1 = 0.25;  int vMixB2 = 0.25;  int vMixB3 = 0.25;  // TODO - set into permanent values in final version
  osc_mixB_01.gain(0, vMixB0);  osc_mixB_01.gain(1, vMixB1);  osc_mixB_01.gain(2, vMixB2);  osc_mixB_01.gain(3, vMixB3);
  osc_mixB_02.gain(0, vMixB0);  osc_mixB_02.gain(1, vMixB1);  osc_mixB_02.gain(2, vMixB2);  osc_mixB_02.gain(3, vMixB3);
  osc_mixB_03.gain(0, vMixB0);  osc_mixB_03.gain(1, vMixB1);  osc_mixB_03.gain(2, vMixB2);  osc_mixB_03.gain(3, vMixB3);
  osc_mixB_04.gain(0, vMixB0);  osc_mixB_04.gain(1, vMixB1);  osc_mixB_04.gain(2, vMixB2);  osc_mixB_04.gain(3, vMixB3);
  osc_mixB_05.gain(0, vMixB0);  osc_mixB_05.gain(1, vMixB1);  osc_mixB_05.gain(2, vMixB2);  osc_mixB_05.gain(3, vMixB3);
  osc_mixB_06.gain(0, vMixB0);  osc_mixB_06.gain(1, vMixB1);  osc_mixB_06.gain(2, vMixB2);  osc_mixB_06.gain(3, vMixB3);
  osc_mixB_07.gain(0, vMixB0);  osc_mixB_07.gain(1, vMixB1);  osc_mixB_07.gain(2, vMixB2);  osc_mixB_07.gain(3, vMixB3);
  osc_mixB_08.gain(0, vMixB0);  osc_mixB_08.gain(1, vMixB1);  osc_mixB_08.gain(2, vMixB2);  osc_mixB_08.gain(3, vMixB3);


  int vMixA0 = 0.0;  int vMixA1 = 0.0;  int vMixA2 = 0.0;  int vMixA3 = 0.0;  // TODO - set into permanent values in final version
  velocityMix_01.gain(0, vMixA0);  velocityMix_01.gain(1, vMixA1);  velocityMix_01.gain(2, vMixA2);  velocityMix_01.gain(3, vMixA3);
  velocityMix_02.gain(0, vMixA0);  velocityMix_02.gain(1, vMixA1);  velocityMix_02.gain(2, vMixA2);  velocityMix_02.gain(3, vMixA3);
  velocityMix_03.gain(0, vMixA0);  velocityMix_03.gain(1, vMixA1);  velocityMix_03.gain(2, vMixA2);  velocityMix_03.gain(3, vMixA3);
  velocityMix_04.gain(0, vMixA0);  velocityMix_04.gain(1, vMixA1);  velocityMix_04.gain(2, vMixA2);  velocityMix_04.gain(3, vMixA3);
  velocityMix_05.gain(0, vMixA0);  velocityMix_05.gain(1, vMixA1);  velocityMix_05.gain(2, vMixA2);  velocityMix_05.gain(3, vMixA3);
  velocityMix_06.gain(0, vMixA0);  velocityMix_06.gain(1, vMixA1);  velocityMix_06.gain(2, vMixA2);  velocityMix_06.gain(3, vMixA3);
  velocityMix_07.gain(0, vMixA0);  velocityMix_07.gain(1, vMixA1);  velocityMix_07.gain(2, vMixA2);  velocityMix_07.gain(3, vMixA3);
  velocityMix_08.gain(0, vMixA0);  velocityMix_08.gain(1, vMixA1);  velocityMix_08.gain(2, vMixA2);  velocityMix_08.gain(3, vMixA3);

  osc_sum_01.gain(0, 0.25);  osc_sum_01.gain(1, 0.25);  osc_sum_01.gain(2, 0.25);  osc_sum_01.gain(3, 0.25);
  osc_sum_02.gain(0, 0.25);  osc_sum_02.gain(1, 0.25);  osc_sum_02.gain(2, 0.25);  osc_sum_02.gain(3, 0.25);

  osc_main_mix.gain(0, 0.5);  osc_main_mix.gain(1, 0.5);  osc_main_mix.gain(2, 0.0);  osc_main_mix.gain(3, 0.5);

  LFO_mix.gain(0, 0.5);  LFO_mix.gain(1, 0.5);  LFO_mix.gain(2, 0.0);  LFO_mix.gain(3, 0.0);
  LFO_dc.amplitude(0.5);

  int fmMix0 = 0.5;  int fmMix1 = 0.0;  int fmMix2 = 0.0;  int fmMix3 = 0.0;  // TODO - set into permanent values in final version
  fmMix_01.gain(0, fmMix0);      fmMix_01.gain(1, fmMix1);      fmMix_01.gain(2, fmMix2);      fmMix_01.gain(3, fmMix3);
  fmMix_02.gain(0, fmMix0);      fmMix_02.gain(1, fmMix1);      fmMix_02.gain(2, fmMix2);      fmMix_02.gain(3, fmMix3);
  fmMix_03.gain(0, fmMix0);      fmMix_03.gain(1, fmMix1);      fmMix_03.gain(2, fmMix2);      fmMix_03.gain(3, fmMix3);
  fmMix_04.gain(0, fmMix0);      fmMix_04.gain(1, fmMix1);      fmMix_04.gain(2, fmMix2);      fmMix_04.gain(3, fmMix3);
  fmMix_05.gain(0, fmMix0);      fmMix_05.gain(1, fmMix1);      fmMix_05.gain(2, fmMix2);      fmMix_05.gain(3, fmMix3);
  fmMix_06.gain(0, fmMix0);      fmMix_06.gain(1, fmMix1);      fmMix_06.gain(2, fmMix2);      fmMix_06.gain(3, fmMix3);
  fmMix_07.gain(0, fmMix0);      fmMix_07.gain(1, fmMix1);      fmMix_07.gain(2, fmMix2);      fmMix_07.gain(3, fmMix3);
  fmMix_08.gain(0, fmMix0);      fmMix_08.gain(1, fmMix1);      fmMix_08.gain(2, fmMix2);      fmMix_08.gain(3, fmMix3);

  int pwmMix0 = 0.5;  int pwmMix1 = 0.0;  int pwmMix2 = 0.0;  int pwmMix3 = 0.0;  // TODO - set into permanent values in final version
  pwmMix_01.gain(0, pwmMix0);      pwmMix_01.gain(1, pwmMix1);      pwmMix_01.gain(2, pwmMix2);      pwmMix_01.gain(3, pwmMix3);
  pwmMix_02.gain(0, pwmMix0);      pwmMix_02.gain(1, pwmMix1);      pwmMix_02.gain(2, pwmMix2);      pwmMix_02.gain(3, pwmMix3);
  pwmMix_03.gain(0, pwmMix0);      pwmMix_03.gain(1, pwmMix1);      pwmMix_03.gain(2, pwmMix2);      pwmMix_03.gain(3, pwmMix3);
  pwmMix_04.gain(0, pwmMix0);      pwmMix_04.gain(1, pwmMix1);      pwmMix_04.gain(2, pwmMix2);      pwmMix_04.gain(3, pwmMix3);
  pwmMix_05.gain(0, pwmMix0);      pwmMix_05.gain(1, pwmMix1);      pwmMix_05.gain(2, pwmMix2);      pwmMix_05.gain(3, pwmMix3);
  pwmMix_06.gain(0, pwmMix0);      pwmMix_06.gain(1, pwmMix1);      pwmMix_06.gain(2, pwmMix2);      pwmMix_06.gain(3, pwmMix3);
  pwmMix_07.gain(0, pwmMix0);      pwmMix_07.gain(1, pwmMix1);      pwmMix_07.gain(2, pwmMix2);      pwmMix_07.gain(3, pwmMix3);
  pwmMix_08.gain(0, pwmMix0);      pwmMix_08.gain(1, pwmMix1);      pwmMix_08.gain(2, pwmMix2);      pwmMix_08.gain(3, pwmMix3);

//  float clickDelay = 4.0;    // Envelope delay to hide clicks
//  env_01.delay(clickDelay);  env_02.delay(clickDelay);  env_03.delay(clickDelay);  env_04.delay(clickDelay);
//  env_05.delay(clickDelay);  env_06.delay(clickDelay);  env_07.delay(clickDelay);  env_08.delay(clickDelay);
//  filtEnv_01.delay(clickDelay);  filtEnv_02.delay(clickDelay);  filtEnv_03.delay(clickDelay);  filtEnv_04.delay(clickDelay);
//  filtEnv_05.delay(clickDelay);  filtEnv_06.delay(clickDelay);  filtEnv_07.delay(clickDelay);  filtEnv_08.delay(clickDelay);

  int amp = 0.0;  int freq = 440.0;  // TODO - set into permanent values in final version
  wave_1_01.begin(amp, freq, wave_1_type);  wave_2_01.begin(amp, freq, wave_2_type);  wave_3_01.begin(amp, freq, wave_3_type);
  wave_1_02.begin(amp, freq, wave_1_type);  wave_2_02.begin(amp, freq, wave_2_type);  wave_3_02.begin(amp, freq, wave_3_type);
  wave_1_03.begin(amp, freq, wave_1_type);  wave_2_03.begin(amp, freq, wave_2_type);  wave_3_03.begin(amp, freq, wave_3_type);
  wave_1_04.begin(amp, freq, wave_1_type);  wave_2_04.begin(amp, freq, wave_2_type);  wave_3_04.begin(amp, freq, wave_3_type);
  wave_1_05.begin(amp, freq, wave_1_type);  wave_2_05.begin(amp, freq, wave_2_type);  wave_3_05.begin(amp, freq, wave_3_type);
  wave_1_06.begin(amp, freq, wave_1_type);  wave_2_06.begin(amp, freq, wave_2_type);  wave_3_06.begin(amp, freq, wave_3_type);
  wave_1_07.begin(amp, freq, wave_1_type);  wave_2_07.begin(amp, freq, wave_2_type);  wave_3_07.begin(amp, freq, wave_3_type);
  wave_1_08.begin(amp, freq, wave_1_type);  wave_2_08.begin(amp, freq, wave_2_type);  wave_3_08.begin(amp, freq, wave_3_type);
  LFO.begin(0.0, 20.0, LFO_type);

  noise_mix.gain(0, 0.25);  noise_mix.gain(1, 0.25);  noise_mix.gain(2, 0.25);  noise_mix.gain(3, 0.25);

  pink_noise.amplitude(1.0);  white_noise.amplitude(1.0);

  int nAtt = 0.0;  int nHld = 10.0;  int nDec = 0.0;  int nSus = 1.0;  int nRel = 0.0;  // TODO - set into permanent values in final version
  noise_env_01.attack(nAtt);  noise_env_01.hold(nHld);  noise_env_01.decay(nDec);  noise_env_01.sustain(nSus);  noise_env_01.release(nRel);
  noise_env_02.attack(nAtt);  noise_env_02.hold(nHld);  noise_env_02.decay(nDec);  noise_env_02.sustain(nSus);  noise_env_02.release(nRel);
  noise_env_03.attack(nAtt);  noise_env_03.hold(nHld);  noise_env_03.decay(nDec);  noise_env_03.sustain(nSus);  noise_env_03.release(nRel);
  noise_env_04.attack(nAtt);  noise_env_04.hold(nHld);  noise_env_04.decay(nDec);  noise_env_04.sustain(nSus);  noise_env_04.release(nRel);
  noise_env_05.attack(nAtt);  noise_env_05.hold(nHld);  noise_env_05.decay(nDec);  noise_env_05.sustain(nSus);  noise_env_05.release(nRel);
  noise_env_06.attack(nAtt);  noise_env_06.hold(nHld);  noise_env_06.decay(nDec);  noise_env_06.sustain(nSus);  noise_env_06.release(nRel);
  noise_env_07.attack(nAtt);  noise_env_07.hold(nHld);  noise_env_07.decay(nDec);  noise_env_07.sustain(nSus);  noise_env_07.release(nRel);
  noise_env_08.attack(nAtt);  noise_env_08.hold(nHld);  noise_env_08.decay(nDec);  noise_env_08.sustain(nSus);  noise_env_08.release(nRel);
/*
  int inMix0 = 0.33;  int inMix1 = 0.0;  int inMix2 = 0.33;  int inMix3 = 0.33;  // TODO - set into permanent values in final version
  inputMix_01.gain(0, inMix0);  inputMix_01.gain(1, inMix1);  inputMix_01.gain(2, inMix2);  inputMix_01.gain(3, inMix3);
  inputMix_02.gain(0, inMix0);  inputMix_02.gain(1, inMix1);  inputMix_02.gain(2, inMix2);  inputMix_02.gain(3, inMix3);
  inputMix_03.gain(0, inMix0);  inputMix_03.gain(1, inMix1);  inputMix_03.gain(2, inMix2);  inputMix_03.gain(3, inMix3);
  inputMix_04.gain(0, inMix0);  inputMix_04.gain(1, inMix1);  inputMix_04.gain(2, inMix2);  inputMix_04.gain(3, inMix3);
  inputMix_05.gain(0, inMix0);  inputMix_05.gain(1, inMix1);  inputMix_05.gain(2, inMix2);  inputMix_05.gain(3, inMix3);
  inputMix_06.gain(0, inMix0);  inputMix_06.gain(1, inMix1);  inputMix_06.gain(2, inMix2);  inputMix_06.gain(3, inMix3);
  inputMix_07.gain(0, inMix0);  inputMix_07.gain(1, inMix1);  inputMix_07.gain(2, inMix2);  inputMix_07.gain(3, inMix3);
  inputMix_08.gain(0, inMix0);  inputMix_08.gain(1, inMix1);  inputMix_08.gain(2, inMix2);  inputMix_08.gain(3, inMix3);
*/

  int fGain0 = 0.0;  int fGain1 = 0.0;  int fGain2 = 0.0;  int fGain3 = 1.0;  // TODO - set into permanent values in final version
  filtMix_01.gain(0, fGain0);  filtMix_01.gain(1, fGain1);  filtMix_01.gain(2, fGain2);  filtMix_01.gain(3, fGain3);
  filtMix_02.gain(0, fGain0);  filtMix_02.gain(1, fGain1);  filtMix_02.gain(2, fGain2);  filtMix_02.gain(3, fGain3);
  filtMix_03.gain(0, fGain0);  filtMix_03.gain(1, fGain1);  filtMix_03.gain(2, fGain2);  filtMix_03.gain(3, fGain3);
  filtMix_04.gain(0, fGain0);  filtMix_04.gain(1, fGain1);  filtMix_04.gain(2, fGain2);  filtMix_04.gain(3, fGain3);
  filtMix_05.gain(0, fGain0);  filtMix_05.gain(1, fGain1);  filtMix_05.gain(2, fGain2);  filtMix_05.gain(3, fGain3);
  filtMix_06.gain(0, fGain0);  filtMix_06.gain(1, fGain1);  filtMix_06.gain(2, fGain2);  filtMix_06.gain(3, fGain3);
  filtMix_07.gain(0, fGain0);  filtMix_07.gain(1, fGain1);  filtMix_07.gain(2, fGain2);  filtMix_07.gain(3, fGain3);
  filtMix_08.gain(0, fGain0);  filtMix_08.gain(1, fGain1);  filtMix_08.gain(2, fGain2);  filtMix_08.gain(3, fGain3);

  float filtF = 2000.0;  float filtR = 5.0;  float filtO = 5.0;  // TODO - set into permanent values in final version
  filt_01.frequency(filtF);  filt_01.resonance(filtR);  filt_01.octaveControl(filtO);
  filt_02.frequency(filtF);  filt_02.resonance(filtR);  filt_02.octaveControl(filtO);
  filt_03.frequency(filtF);  filt_03.resonance(filtR);  filt_03.octaveControl(filtO);
  filt_04.frequency(filtF);  filt_04.resonance(filtR);  filt_04.octaveControl(filtO);
  filt_05.frequency(filtF);  filt_05.resonance(filtR);  filt_05.octaveControl(filtO);
  filt_06.frequency(filtF);  filt_06.resonance(filtR);  filt_06.octaveControl(filtO);
  filt_07.frequency(filtF);  filt_07.resonance(filtR);  filt_07.octaveControl(filtO);
  filt_08.frequency(filtF);  filt_08.resonance(filtR);  filt_08.octaveControl(filtO);

  L_outMix.gain(0, 0.5);  L_outMix.gain(1, 0.0);  L_outMix.gain(2, 0.0);  L_outMix.gain(3, 0.0);
  R_outMix.gain(0, 0.5);  R_outMix.gain(1, 0.0);  R_outMix.gain(2, 0.0);  R_outMix.gain(3, 0.0);

  float D0 = 0.0;  float D1 = 0.4;  float D2 = 0.6;  float D3 = 0.0;  // TODO - set into permanent values in final version
  L_delayMix.gain(0, D0);  L_delayMix.gain(1, D1);  L_delayMix.gain(2, D2);  L_delayMix.gain(3, D3);
  R_delayMix.gain(0, D0);  R_delayMix.gain(1, D1);  R_delayMix.gain(2, D2);  R_delayMix.gain(3, D3);

//  AudioMemory(700);
//  AudioMemory(650);
  AudioMemory(550);
//  AudioMemory(450);
//  AudioMemory(350);
//  AudioMemory(250);
//  AudioMemory(150);
//  AudioMemory(60);

//  L_delayGen.delay(0, 80);
  L_delayGen.delay(1, 100);
  L_delayGen.delay(2, 250);
//  L_delayGen.delay(3, 320);

  L_delayGen.disable(0);
//  L_delayGen.disable(1);
//  L_delayGen.disable(2);
  L_delayGen.disable(3); 

//  R_delayGen.delay(0, 60);
  R_delayGen.delay(1, 150);
  R_delayGen.delay(2, 200);
//  R_delayGen.delay(3, 180);

  R_delayGen.disable(0);
//  R_delayGen.disable(1);
//  R_delayGen.disable(2);
  R_delayGen.disable(3); 

  L_delayGen.disable(4);  L_delayGen.disable(5);  L_delayGen.disable(6);  L_delayGen.disable(7); 
  R_delayGen.disable(4);  R_delayGen.disable(5);  R_delayGen.disable(6);  R_delayGen.disable(7); 

    pink_noise.amplitude(1.0);
    white_noise.amplitude(1.0);

delay(600);
  AudioProcessorUsageMaxReset();
  AudioMemoryUsageMaxReset();
  Serial.println("===== SYNTH  READY =====");
}

// ================================================================================================================================
// ******************************************************************** MAIN PROGRAM LOOP
// ================================================================================================================================
void loop() {
//  AudioProcessorUsageMax();
if (dataDisplay == 2) { Serial.print("Audio CPU - ");  Serial.print(AudioProcessorUsage());  Serial.print("  CPU Max - ");  Serial.print(AudioProcessorUsageMax());  }
if (dataDisplay == 2) { Serial.print("  Audio MEM ");  Serial.print(AudioMemoryUsage());  Serial.print("  MEM Max - ");  Serial.print(AudioMemoryUsageMax());  }
if (dataDisplay == 2) Serial.println();
//if (dataDisplay == 2) { Serial.print("  Filter 01 - ");  Serial.print(filt_01.processorUsage());  Serial.print("  Filter Max - ");  Serial.println(filt_01.processorUsageMax());  }
//anyObject.processorUsage();

// float y;
// long x = pot;
// long n = 10;
// y = (x * (x + 1)) >> n;  // where n is the resolution and x and y are positive integers
//Serial.println(y);

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, HIGH);  digitalWrite(S1, HIGH);  digitalWrite(S2, HIGH); //  logic Y7 on 15
  for (int i=0; i <= 4; i++) butt = (float)analogRead(muxPot_12);                              // Button block master read

  buttRead();

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
// TEMP routine to play test note without MIDI
//   int test = digitalRead(testNote);
   if ((butt == 1) && (testNTog == 0)) {                                                       // Button 1                 Test note
     handleNoteOn(0, 69, 127);
     Serial.println("Test note played - Channel 0, Note 64, Velocity 127");
     testNTog = 1;
   }
   else
   if ((butt == 0) && (testNTog == 1)) {
     handleNoteOn(0, 69, 0);
     Serial.println("Test note stopped - Channel 0, Note 64, Velocity 0");
     testNTog = 0;
   }

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);  digitalWrite(S2, HIGH); // POT     logic Y5 on 17
//  delay(4);
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_17);                                // Red                Main Volume
//  potLog = (float)analogRead(muxPot_17);
  pot = ((potLog * (potLog + 1)) >> 10) / 1023.0;  // LOG correction

    sgtl5000.volume(pot);
//Serial.print("Main volume level, pot, MUX 17 Y5 - ");  Serial.println(pot);                        // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, LOW);  digitalWrite(S1, LOW);  digitalWrite(S2, LOW); // POT 17  logic Y0 on 18
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_18);                                // White 1            OSC 1 level
  pot = ((potLog * (potLog + 1)) >> 10) / 4092.0;  // LOG correction

    osc_mixA_01.gain(0, pot);  osc_mixA_02.gain(0, pot);  osc_mixA_03.gain(0, pot);  osc_mixA_04.gain(0, pot);
    osc_mixA_05.gain(0, pot);  osc_mixA_06.gain(0, pot);  osc_mixA_07.gain(0, pot);  osc_mixA_08.gain(0, pot);
//Serial.print("OSC 1 level, pot 17, MUX C Y0 - ");  Serial.println(pot);                        // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);  digitalWrite(S2, LOW); // POT 18  logic Y1 on 18
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_18);                                 // White 2           OSC 2 level
  pot = ((potLog * (potLog + 1)) >> 10) / 4092.0;  // LOG correction

    osc_mixA_01.gain(1, pot);  osc_mixA_02.gain(1, pot);  osc_mixA_03.gain(1, pot);  osc_mixA_04.gain(1, pot);
    osc_mixA_05.gain(1, pot);  osc_mixA_06.gain(1, pot);  osc_mixA_07.gain(1, pot);  osc_mixA_08.gain(1, pot);
//Serial.print("OSC 2 level, pot 18, MUX C Y1 - ");  Serial.println(pot);                      // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW);  // POT 19  logic Y2 on 19
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_18);                               // White 3             OSC 3 level
  pot = ((potLog * (potLog + 1)) >> 10) / 4092.0;  // LOG correction

    osc_mixA_01.gain(2, pot);  osc_mixA_02.gain(2, pot);  osc_mixA_03.gain(2, pot);  osc_mixA_04.gain(2, pot);
    osc_mixA_05.gain(2, pot);  osc_mixA_06.gain(2, pot);  osc_mixA_07.gain(2, pot);  osc_mixA_08.gain(2, pot);
//Serial.print("OSC 3 level, pot 19, MUX C Y2 - ");  Serial.println(pot);                    // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW); // POT ext logic Y6 on 12
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_12);                               // Ext pot 1        Ring mod level
  pot = ((potLog * (potLog + 1)) >> 10) / 2046.0;  // LOG correction
//  if (pot < 0.0) pot = 0.0;
//  if (pot > 1.0) pot = 1.0;
//  pot = pot / 2;
    osc_mixB_01.gain(0, pot);  osc_mixB_02.gain(0, pot);  osc_mixB_03.gain(0, pot);  osc_mixB_04.gain(0, pot);
    osc_mixB_05.gain(0, pot);  osc_mixB_06.gain(0, pot);  osc_mixB_07.gain(0, pot);  osc_mixB_08.gain(0, pot);
//Serial.print("Ring modulation level, pot 23 - ");  Serial.println(pot);    // [FIX]

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, HIGH);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW); // POT 20  logic Y3 on 18
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_18);                               // White 4           SINE FM level
  pot = ((potLog * (potLog + 1)) >> 10) / 2046.0;  // LOG correction

    osc_mixB_01.gain(1, pot);  osc_mixB_02.gain(1, pot);  osc_mixB_03.gain(1, pot);  osc_mixB_04.gain(1, pot);
    osc_mixB_05.gain(1, pot);  osc_mixB_06.gain(1, pot);  osc_mixB_07.gain(1, pot);  osc_mixB_08.gain(1, pot);
//Serial.print("Sine FM level, pot 20, MUX C Y3 - ");  Serial.println(pot);                    // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, HIGH);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW); // POT 16  logic Y3 on 19
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_12);// / 990.0) - 0.02;              // White 5             PWM level
  pot = ((potLog * (potLog + 1)) >> 10) / 4092.0;  // LOG correction

    osc_mixB_01.gain(2, pot);  osc_mixB_02.gain(2, pot);  osc_mixB_03.gain(2, pot);  osc_mixB_04.gain(2, pot);
    osc_mixB_05.gain(2, pot);  osc_mixB_06.gain(2, pot);  osc_mixB_07.gain(2, pot);  osc_mixB_08.gain(2, pot);
//Serial.print("PWM level, pot 16, MUX B Y7 - ");  Serial.println(pot);                    // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, HIGH);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW); // POT 16  logic Y3 on 15
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_15);// / 990.0) - 0.02;              // Grey          Waveshape level
  pot = ((potLog * (potLog + 1)) >> 10) / 1023.0;  // LOG correction

    osc_mixB_01.gain(3, pot);  osc_mixB_02.gain(3, pot);  osc_mixB_03.gain(3, pot);  osc_mixB_04.gain(3, pot);
    osc_mixB_05.gain(3, pot);  osc_mixB_06.gain(3, pot);  osc_mixB_07.gain(3, pot);  osc_mixB_08.gain(3, pot);
//Serial.print("WAVESHAPE level, pot MUX 15 Y3 - ");  Serial.println(pot);                    // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
  if ((butt == 5) && (buttonTog == 0))  {                                                      // Button 5  Pitch bend 1 or 2 octave
    buttonTog = 1;
    if (PBOct == 2)  {
      PBOct = 1;
      Serial.println("Pitch bend goes to 1 octave");
    }
    else  {
      PBOct = 2;
      Serial.println("Pitch bend goes to 2 octaves");
    }
  }
 MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
  if ((butt == 3) && (buttonTog == 0))  {                                                      // Button 3 SINE FM MODULATION source
    buttonTog = 1;
    if (fmMod == 0)  {
      fmMod = 1;
      fmMix_01.gain(0, 0.5);      fmMix_01.gain(1, 0.0);      fmMix_01.gain(2, 0.0);      fmMix_01.gain(3, 0.0);
      fmMix_02.gain(0, 0.5);      fmMix_02.gain(1, 0.0);      fmMix_02.gain(2, 0.0);      fmMix_02.gain(3, 0.0);
      fmMix_03.gain(0, 0.5);      fmMix_03.gain(1, 0.0);      fmMix_03.gain(2, 0.0);      fmMix_03.gain(3, 0.0);
      fmMix_04.gain(0, 0.5);      fmMix_04.gain(1, 0.0);      fmMix_04.gain(2, 0.0);      fmMix_04.gain(3, 0.0);
      fmMix_05.gain(0, 0.5);      fmMix_05.gain(1, 0.0);      fmMix_05.gain(2, 0.0);      fmMix_05.gain(3, 0.0);
      fmMix_06.gain(0, 0.5);      fmMix_06.gain(1, 0.0);      fmMix_06.gain(2, 0.0);      fmMix_06.gain(3, 0.0);
      fmMix_07.gain(0, 0.5);      fmMix_07.gain(1, 0.0);      fmMix_07.gain(2, 0.0);      fmMix_07.gain(3, 0.0);
      fmMix_08.gain(0, 0.5);      fmMix_08.gain(1, 0.0);      fmMix_08.gain(2, 0.0);      fmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("0 fm Mod source = OSC1");
    }
    else
    if (fmMod == 1)  {
      fmMod = 2;
      fmMix_01.gain(0, 0.0);      fmMix_01.gain(1, 0.5);      fmMix_01.gain(2, 0.0);      fmMix_01.gain(3, 0.0);
      fmMix_02.gain(0, 0.0);      fmMix_02.gain(1, 0.5);      fmMix_02.gain(2, 0.0);      fmMix_02.gain(3, 0.0);
      fmMix_03.gain(0, 0.0);      fmMix_03.gain(1, 0.5);      fmMix_03.gain(2, 0.0);      fmMix_03.gain(3, 0.0);
      fmMix_04.gain(0, 0.0);      fmMix_04.gain(1, 0.5);      fmMix_04.gain(2, 0.0);      fmMix_04.gain(3, 0.0);
      fmMix_05.gain(0, 0.0);      fmMix_05.gain(1, 0.5);      fmMix_05.gain(2, 0.0);      fmMix_05.gain(3, 0.0);
      fmMix_06.gain(0, 0.0);      fmMix_06.gain(1, 0.5);      fmMix_06.gain(2, 0.0);      fmMix_06.gain(3, 0.0);
      fmMix_07.gain(0, 0.0);      fmMix_07.gain(1, 0.5);      fmMix_07.gain(2, 0.0);      fmMix_07.gain(3, 0.0);
      fmMix_08.gain(0, 0.0);      fmMix_08.gain(1, 0.5);      fmMix_08.gain(2, 0.0);      fmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("1 fm Mod source = OSC2");
    }
    else
    if (fmMod == 2)  {
      fmMod = 3;
      fmMix_01.gain(0, 0.0);      fmMix_01.gain(1, 0.0);      fmMix_01.gain(2, 0.5);      fmMix_01.gain(3, 0.0);
      fmMix_02.gain(0, 0.0);      fmMix_02.gain(1, 0.0);      fmMix_02.gain(2, 0.5);      fmMix_02.gain(3, 0.0);
      fmMix_03.gain(0, 0.0);      fmMix_03.gain(1, 0.0);      fmMix_03.gain(2, 0.5);      fmMix_03.gain(3, 0.0);
      fmMix_04.gain(0, 0.0);      fmMix_04.gain(1, 0.0);      fmMix_04.gain(2, 0.5);      fmMix_04.gain(3, 0.0);
      fmMix_05.gain(0, 0.0);      fmMix_05.gain(1, 0.0);      fmMix_05.gain(2, 0.5);      fmMix_05.gain(3, 0.0);
      fmMix_06.gain(0, 0.0);      fmMix_06.gain(1, 0.0);      fmMix_06.gain(2, 0.5);      fmMix_06.gain(3, 0.0);
      fmMix_07.gain(0, 0.0);      fmMix_07.gain(1, 0.0);      fmMix_07.gain(2, 0.5);      fmMix_07.gain(3, 0.0);
      fmMix_08.gain(0, 0.0);      fmMix_08.gain(1, 0.0);      fmMix_08.gain(2, 0.5);      fmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("2 fm Mod source = OSC3");
    }
    else
    if (fmMod == 3)  {
      fmMod = 4;
      fmMix_01.gain(0, 0.5);      fmMix_01.gain(1, 0.5);      fmMix_01.gain(2, 0.0);      fmMix_01.gain(3, 0.0);
      fmMix_02.gain(0, 0.5);      fmMix_02.gain(1, 0.5);      fmMix_02.gain(2, 0.0);      fmMix_02.gain(3, 0.0);
      fmMix_03.gain(0, 0.5);      fmMix_03.gain(1, 0.5);      fmMix_03.gain(2, 0.0);      fmMix_03.gain(3, 0.0);
      fmMix_04.gain(0, 0.5);      fmMix_04.gain(1, 0.5);      fmMix_04.gain(2, 0.0);      fmMix_04.gain(3, 0.0);
      fmMix_05.gain(0, 0.5);      fmMix_05.gain(1, 0.5);      fmMix_05.gain(2, 0.0);      fmMix_05.gain(3, 0.0);
      fmMix_06.gain(0, 0.5);      fmMix_06.gain(1, 0.5);      fmMix_06.gain(2, 0.0);      fmMix_06.gain(3, 0.0);
      fmMix_07.gain(0, 0.5);      fmMix_07.gain(1, 0.5);      fmMix_07.gain(2, 0.0);      fmMix_07.gain(3, 0.0);
      fmMix_08.gain(0, 0.5);      fmMix_08.gain(1, 0.5);      fmMix_08.gain(2, 0.0);      fmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("3 fm Mod source = OSC1 + OSC2");
    }
    else
    if (fmMod == 4)  {
      fmMod = 5;
      fmMix_01.gain(0, 0.0);      fmMix_01.gain(1, 0.0);      fmMix_01.gain(2, 0.5);      fmMix_01.gain(3, 0.5);
      fmMix_02.gain(0, 0.0);      fmMix_02.gain(1, 0.0);      fmMix_02.gain(2, 0.5);      fmMix_02.gain(3, 0.5);
      fmMix_03.gain(0, 0.0);      fmMix_03.gain(1, 0.0);      fmMix_03.gain(2, 0.5);      fmMix_03.gain(3, 0.5);
      fmMix_04.gain(0, 0.0);      fmMix_04.gain(1, 0.0);      fmMix_04.gain(2, 0.5);      fmMix_04.gain(3, 0.5);
      fmMix_05.gain(0, 0.0);      fmMix_05.gain(1, 0.0);      fmMix_05.gain(2, 0.5);      fmMix_05.gain(3, 0.5);
      fmMix_06.gain(0, 0.0);      fmMix_06.gain(1, 0.0);      fmMix_06.gain(2, 0.5);      fmMix_06.gain(3, 0.5);
      fmMix_07.gain(0, 0.0);      fmMix_07.gain(1, 0.0);      fmMix_07.gain(2, 0.5);      fmMix_07.gain(3, 0.5);
      fmMix_08.gain(0, 0.0);      fmMix_08.gain(1, 0.0);      fmMix_08.gain(2, 0.5);      fmMix_08.gain(3, 0.5);
      if (dataDisplay < 3) Serial.println("4 fm Mod source = OSC2 + OSC3");
    }
    else
    if (fmMod == 5)  {
      fmMod = 6;
      fmMix_01.gain(0, 0.5);      fmMix_01.gain(1, 0.0);      fmMix_01.gain(2, 0.5);      fmMix_01.gain(3, 0.0);
      fmMix_02.gain(0, 0.5);      fmMix_02.gain(1, 0.0);      fmMix_02.gain(2, 0.5);      fmMix_02.gain(3, 0.0);
      fmMix_03.gain(0, 0.5);      fmMix_03.gain(1, 0.0);      fmMix_03.gain(2, 0.5);      fmMix_03.gain(3, 0.0);
      fmMix_04.gain(0, 0.5);      fmMix_04.gain(1, 0.0);      fmMix_04.gain(2, 0.5);      fmMix_04.gain(3, 0.0);
      fmMix_05.gain(0, 0.5);      fmMix_05.gain(1, 0.0);      fmMix_05.gain(2, 0.5);      fmMix_05.gain(3, 0.0);
      fmMix_06.gain(0, 0.5);      fmMix_06.gain(1, 0.0);      fmMix_06.gain(2, 0.5);      fmMix_06.gain(3, 0.0);
      fmMix_07.gain(0, 0.5);      fmMix_07.gain(1, 0.0);      fmMix_07.gain(2, 0.5);      fmMix_07.gain(3, 0.0);
      fmMix_08.gain(0, 0.5);      fmMix_08.gain(1, 0.0);      fmMix_08.gain(2, 0.5);      fmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("5 fm Mod source = OSC1 + OSC3");
    }
    else
    if (fmMod == 6)  {
      fmMod = 7;
      fmMix_01.gain(0, 0.33);      fmMix_01.gain(1, 0.33);      fmMix_01.gain(2, 0.33);      fmMix_01.gain(3, 0.0);
      fmMix_02.gain(0, 0.33);      fmMix_02.gain(1, 0.33);      fmMix_02.gain(2, 0.33);      fmMix_02.gain(3, 0.0);
      fmMix_03.gain(0, 0.33);      fmMix_03.gain(1, 0.33);      fmMix_03.gain(2, 0.33);      fmMix_03.gain(3, 0.0);
      fmMix_04.gain(0, 0.33);      fmMix_04.gain(1, 0.33);      fmMix_04.gain(2, 0.33);      fmMix_04.gain(3, 0.0);
      fmMix_05.gain(0, 0.33);      fmMix_05.gain(1, 0.33);      fmMix_05.gain(2, 0.33);      fmMix_05.gain(3, 0.0);
      fmMix_06.gain(0, 0.33);      fmMix_06.gain(1, 0.33);      fmMix_06.gain(2, 0.33);      fmMix_06.gain(3, 0.0);
      fmMix_07.gain(0, 0.33);      fmMix_07.gain(1, 0.33);      fmMix_07.gain(2, 0.33);      fmMix_07.gain(3, 0.0);
      fmMix_08.gain(0, 0.33);      fmMix_08.gain(1, 0.33);      fmMix_08.gain(2, 0.33);      fmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("6 fm Mod source = OSC1 + OSC2 + OSC3");
    }
    else
    if (fmMod == 7)  {
      fmMod = 0;
      fmMix_01.gain(0, 0.0);      fmMix_01.gain(1, 0.0);      fmMix_01.gain(2, 0.0);      fmMix_01.gain(3, 0.5);
      fmMix_02.gain(0, 0.0);      fmMix_02.gain(1, 0.0);      fmMix_02.gain(2, 0.0);      fmMix_02.gain(3, 0.5);
      fmMix_03.gain(0, 0.0);      fmMix_03.gain(1, 0.0);      fmMix_03.gain(2, 0.0);      fmMix_03.gain(3, 0.5);
      fmMix_04.gain(0, 0.0);      fmMix_04.gain(1, 0.0);      fmMix_04.gain(2, 0.0);      fmMix_04.gain(3, 0.5);
      fmMix_05.gain(0, 0.0);      fmMix_05.gain(1, 0.0);      fmMix_05.gain(2, 0.0);      fmMix_05.gain(3, 0.5);
      fmMix_06.gain(0, 0.0);      fmMix_06.gain(1, 0.0);      fmMix_06.gain(2, 0.0);      fmMix_06.gain(3, 0.5);
      fmMix_07.gain(0, 0.0);      fmMix_07.gain(1, 0.0);      fmMix_07.gain(2, 0.0);      fmMix_07.gain(3, 0.5);
      fmMix_08.gain(0, 0.0);      fmMix_08.gain(1, 0.0);      fmMix_08.gain(2, 0.0);      fmMix_08.gain(3, 0.5);
      if (dataDisplay < 3) Serial.println("7 fm Mod source = line input mix and noise");
    }
  }
    
 MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
  if ((butt == 2) && (buttonTog == 0))  {                                                      // Button 2     PWM MODULATION source
    buttonTog = 1;
    if (pwmMod == 0)  {
      pwmMod = 1;
      pwmMix_01.gain(0, 0.5);      pwmMix_01.gain(1, 0.0);      pwmMix_01.gain(2, 0.0);      pwmMix_01.gain(3, 0.0);
      pwmMix_02.gain(0, 0.5);      pwmMix_02.gain(1, 0.0);      pwmMix_02.gain(2, 0.0);      pwmMix_02.gain(3, 0.0);
      pwmMix_03.gain(0, 0.5);      pwmMix_03.gain(1, 0.0);      pwmMix_03.gain(2, 0.0);      pwmMix_03.gain(3, 0.0);
      pwmMix_04.gain(0, 0.5);      pwmMix_04.gain(1, 0.0);      pwmMix_04.gain(2, 0.0);      pwmMix_04.gain(3, 0.0);
      pwmMix_05.gain(0, 0.5);      pwmMix_05.gain(1, 0.0);      pwmMix_05.gain(2, 0.0);      pwmMix_05.gain(3, 0.0);
      pwmMix_06.gain(0, 0.5);      pwmMix_06.gain(1, 0.0);      pwmMix_06.gain(2, 0.0);      pwmMix_06.gain(3, 0.0);
      pwmMix_07.gain(0, 0.5);      pwmMix_07.gain(1, 0.0);      pwmMix_07.gain(2, 0.0);      pwmMix_07.gain(3, 0.0);
      pwmMix_08.gain(0, 0.5);      pwmMix_08.gain(1, 0.0);      pwmMix_08.gain(2, 0.0);      pwmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("0 pwm Mod source = OSC1");
    }
    else
    if (pwmMod == 1)  {
      pwmMod = 2;
      pwmMix_01.gain(0, 0.0);      pwmMix_01.gain(1, 0.5);      pwmMix_01.gain(2, 0.0);      pwmMix_01.gain(3, 0.0);
      pwmMix_02.gain(0, 0.0);      pwmMix_02.gain(1, 0.5);      pwmMix_02.gain(2, 0.0);      pwmMix_02.gain(3, 0.0);
      pwmMix_03.gain(0, 0.0);      pwmMix_03.gain(1, 0.5);      pwmMix_03.gain(2, 0.0);      pwmMix_03.gain(3, 0.0);
      pwmMix_04.gain(0, 0.0);      pwmMix_04.gain(1, 0.5);      pwmMix_04.gain(2, 0.0);      pwmMix_04.gain(3, 0.0);
      pwmMix_05.gain(0, 0.0);      pwmMix_05.gain(1, 0.5);      pwmMix_05.gain(2, 0.0);      pwmMix_05.gain(3, 0.0);
      pwmMix_06.gain(0, 0.0);      pwmMix_06.gain(1, 0.5);      pwmMix_06.gain(2, 0.0);      pwmMix_06.gain(3, 0.0);
      pwmMix_07.gain(0, 0.0);      pwmMix_07.gain(1, 0.5);      pwmMix_07.gain(2, 0.0);      pwmMix_07.gain(3, 0.0);
      pwmMix_08.gain(0, 0.0);      pwmMix_08.gain(1, 0.5);      pwmMix_08.gain(2, 0.0);      pwmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("1 pwm Mod source = OSC2");
    }
    else
    if (pwmMod == 2)  {
      pwmMod = 3;
      pwmMix_01.gain(0, 0.0);      pwmMix_01.gain(1, 0.0);      pwmMix_01.gain(2, 0.5);      pwmMix_01.gain(3, 0.0);
      pwmMix_02.gain(0, 0.0);      pwmMix_02.gain(1, 0.0);      pwmMix_02.gain(2, 0.5);      pwmMix_02.gain(3, 0.0);
      pwmMix_03.gain(0, 0.0);      pwmMix_03.gain(1, 0.0);      pwmMix_03.gain(2, 0.5);      pwmMix_03.gain(3, 0.0);
      pwmMix_04.gain(0, 0.0);      pwmMix_04.gain(1, 0.0);      pwmMix_04.gain(2, 0.5);      pwmMix_04.gain(3, 0.0);
      pwmMix_05.gain(0, 0.0);      pwmMix_05.gain(1, 0.0);      pwmMix_05.gain(2, 0.5);      pwmMix_05.gain(3, 0.0);
      pwmMix_06.gain(0, 0.0);      pwmMix_06.gain(1, 0.0);      pwmMix_06.gain(2, 0.5);      pwmMix_06.gain(3, 0.0);
      pwmMix_07.gain(0, 0.0);      pwmMix_07.gain(1, 0.0);      pwmMix_07.gain(2, 0.5);      pwmMix_07.gain(3, 0.0);
      pwmMix_08.gain(0, 0.0);      pwmMix_08.gain(1, 0.0);      pwmMix_08.gain(2, 0.5);      pwmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("2 pwm Mod source = OSC3");
    }
    else
    if (pwmMod == 3)  {
      pwmMod = 4;
      pwmMix_01.gain(0, 0.5);      pwmMix_01.gain(1, 0.5);      pwmMix_01.gain(2, 0.0);      pwmMix_01.gain(3, 0.0);
      pwmMix_02.gain(0, 0.5);      pwmMix_02.gain(1, 0.5);      pwmMix_02.gain(2, 0.0);      pwmMix_02.gain(3, 0.0);
      pwmMix_03.gain(0, 0.5);      pwmMix_03.gain(1, 0.5);      pwmMix_03.gain(2, 0.0);      pwmMix_03.gain(3, 0.0);
      pwmMix_04.gain(0, 0.5);      pwmMix_04.gain(1, 0.5);      pwmMix_04.gain(2, 0.0);      pwmMix_04.gain(3, 0.0);
      pwmMix_05.gain(0, 0.5);      pwmMix_05.gain(1, 0.5);      pwmMix_05.gain(2, 0.0);      pwmMix_05.gain(3, 0.0);
      pwmMix_06.gain(0, 0.5);      pwmMix_06.gain(1, 0.5);      pwmMix_06.gain(2, 0.0);      pwmMix_06.gain(3, 0.0);
      pwmMix_07.gain(0, 0.5);      pwmMix_07.gain(1, 0.5);      pwmMix_07.gain(2, 0.0);      pwmMix_07.gain(3, 0.0);
      pwmMix_08.gain(0, 0.5);      pwmMix_08.gain(1, 0.5);      pwmMix_08.gain(2, 0.0);      pwmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("3 pwm Mod source = OSC1 + OSC2");
    }
    else
    if (pwmMod == 4)  {
      pwmMod = 5;
      pwmMix_01.gain(0, 0.0);      pwmMix_01.gain(1, 0.5);      pwmMix_01.gain(2, 0.5);      pwmMix_01.gain(3, 0.0);
      pwmMix_02.gain(0, 0.0);      pwmMix_02.gain(1, 0.5);      pwmMix_02.gain(2, 0.5);      pwmMix_02.gain(3, 0.0);
      pwmMix_03.gain(0, 0.0);      pwmMix_03.gain(1, 0.5);      pwmMix_03.gain(2, 0.5);      pwmMix_03.gain(3, 0.0);
      pwmMix_04.gain(0, 0.0);      pwmMix_04.gain(1, 0.5);      pwmMix_04.gain(2, 0.5);      pwmMix_04.gain(3, 0.0);
      pwmMix_05.gain(0, 0.0);      pwmMix_05.gain(1, 0.5);      pwmMix_05.gain(2, 0.5);      pwmMix_05.gain(3, 0.0);
      pwmMix_06.gain(0, 0.0);      pwmMix_06.gain(1, 0.5);      pwmMix_06.gain(2, 0.5);      pwmMix_06.gain(3, 0.0);
      pwmMix_07.gain(0, 0.0);      pwmMix_07.gain(1, 0.5);      pwmMix_07.gain(2, 0.5);      pwmMix_07.gain(3, 0.0);
      pwmMix_08.gain(0, 0.0);      pwmMix_08.gain(1, 0.5);      pwmMix_08.gain(2, 0.5);      pwmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("4 pwm Mod source = OSC2 + OSC3");
    }
    else
    if (pwmMod == 5)  {
      pwmMod = 6;
      pwmMix_01.gain(0, 0.5);      pwmMix_01.gain(1, 0.0);      pwmMix_01.gain(2, 0.5);      pwmMix_01.gain(3, 0.0);
      pwmMix_02.gain(0, 0.5);      pwmMix_02.gain(1, 0.0);      pwmMix_02.gain(2, 0.5);      pwmMix_02.gain(3, 0.0);
      pwmMix_03.gain(0, 0.5);      pwmMix_03.gain(1, 0.0);      pwmMix_03.gain(2, 0.5);      pwmMix_03.gain(3, 0.0);
      pwmMix_04.gain(0, 0.5);      pwmMix_04.gain(1, 0.0);      pwmMix_04.gain(2, 0.5);      pwmMix_04.gain(3, 0.0);
      pwmMix_05.gain(0, 0.5);      pwmMix_05.gain(1, 0.0);      pwmMix_05.gain(2, 0.5);      pwmMix_05.gain(3, 0.0);
      pwmMix_06.gain(0, 0.5);      pwmMix_06.gain(1, 0.0);      pwmMix_06.gain(2, 0.5);      pwmMix_06.gain(3, 0.0);
      pwmMix_07.gain(0, 0.5);      pwmMix_07.gain(1, 0.0);      pwmMix_07.gain(2, 0.5);      pwmMix_07.gain(3, 0.0);
      pwmMix_08.gain(0, 0.5);      pwmMix_08.gain(1, 0.0);      pwmMix_08.gain(2, 0.5);      pwmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("5 pwm Mod source = OSC1 + OSC3");
    }
    else
    if (pwmMod == 6)  {
      pwmMod = 7;
      pwmMix_01.gain(0, 0.33);      pwmMix_01.gain(1, 0.33);      pwmMix_01.gain(2, 0.33);      pwmMix_01.gain(3, 0.0);
      pwmMix_02.gain(0, 0.33);      pwmMix_02.gain(1, 0.33);      pwmMix_02.gain(2, 0.33);      pwmMix_02.gain(3, 0.0);
      pwmMix_03.gain(0, 0.33);      pwmMix_03.gain(1, 0.33);      pwmMix_03.gain(2, 0.33);      pwmMix_03.gain(3, 0.0);
      pwmMix_04.gain(0, 0.33);      pwmMix_04.gain(1, 0.33);      pwmMix_04.gain(2, 0.33);      pwmMix_04.gain(3, 0.0);
      pwmMix_05.gain(0, 0.33);      pwmMix_05.gain(1, 0.33);      pwmMix_05.gain(2, 0.33);      pwmMix_05.gain(3, 0.0);
      pwmMix_06.gain(0, 0.33);      pwmMix_06.gain(1, 0.33);      pwmMix_06.gain(2, 0.33);      pwmMix_06.gain(3, 0.0);
      pwmMix_07.gain(0, 0.33);      pwmMix_07.gain(1, 0.33);      pwmMix_07.gain(2, 0.33);      pwmMix_07.gain(3, 0.0);
      pwmMix_08.gain(0, 0.33);      pwmMix_08.gain(1, 0.33);      pwmMix_08.gain(2, 0.33);      pwmMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("6 pwm Mod source = OSC1 + OSC2 + OSC3");
    }
    else
    if (pwmMod == 7)  {
      pwmMod = 0;
      pwmMix_01.gain(0, 0.0);      pwmMix_01.gain(1, 0.0);      pwmMix_01.gain(2, 0.0);      pwmMix_01.gain(3, 0.5);
      pwmMix_02.gain(0, 0.0);      pwmMix_02.gain(1, 0.0);      pwmMix_02.gain(2, 0.0);      pwmMix_02.gain(3, 0.5);
      pwmMix_03.gain(0, 0.0);      pwmMix_03.gain(1, 0.0);      pwmMix_03.gain(2, 0.0);      pwmMix_03.gain(3, 0.5);
      pwmMix_04.gain(0, 0.0);      pwmMix_04.gain(1, 0.0);      pwmMix_04.gain(2, 0.0);      pwmMix_04.gain(3, 0.5);
      pwmMix_05.gain(0, 0.0);      pwmMix_05.gain(1, 0.0);      pwmMix_05.gain(2, 0.0);      pwmMix_05.gain(3, 0.5);
      pwmMix_06.gain(0, 0.0);      pwmMix_06.gain(1, 0.0);      pwmMix_06.gain(2, 0.0);      pwmMix_06.gain(3, 0.5);
      pwmMix_07.gain(0, 0.0);      pwmMix_07.gain(1, 0.0);      pwmMix_07.gain(2, 0.0);      pwmMix_07.gain(3, 0.5);
      pwmMix_08.gain(0, 0.0);      pwmMix_08.gain(1, 0.0);      pwmMix_08.gain(2, 0.0);      pwmMix_08.gain(3, 0.5);
      if (dataDisplay < 3) Serial.println("7 pwm Mod source = line input mix and noise");
    }
  }
    
 MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, LOW);  digitalWrite(S1, LOW);  digitalWrite(S2, HIGH); // POT ext logic Y4 on 17
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_17);// / 61.0) - 0.55;             // Ext pot 2         line in level
  pot = ((potLog * (potLog + 1)) >> 10) / 68.2;  // LOG correction
  sgtl5000.lineInLevel(pot, pot);
//    velocityMix_01.gain(3, pot);  velocityMix_02.gain(3, pot);  velocityMix_03.gain(3, pot);  velocityMix_04.gain(3, pot);
//    velocityMix_05.gain(3, pot);  velocityMix_06.gain(3, pot);  velocityMix_07.gain(3, pot);  velocityMix_08.gain(3, pot);
//Serial.print("Line in level, pot Y4 MUX 17 - ");  Serial.println(pot);                    // Reads on right ext pot  Needs calibration

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
// ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) DELAY
digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);  digitalWrite(S2, LOW);  // POT D2  logic Y1 on 13
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_13);                               // Green 1             Delay level
  pot = ((potLog * (potLog + 1)) >> 10) / 1023.0;  // LOG correction

  L_outMix.gain(1, pot);
  R_outMix.gain(1, pot);
  
//Serial.println(pot);                    // Reads on pot D2

  MIDI.read();  //**************************
// ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) DELAY

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, LOW);   digitalWrite(S1, LOW);   digitalWrite(S2, LOW); // POT  logic Y0 on 16
  for (int i=0; i <= 4; i++) potLog = analogRead(muxPot_14);                                       // Blue 1 box 2    Delay 1 amount
  pot = ((potLog * (potLog + 1)) >> 10) / 2046.0;  // LOG correction
//  L_delayGen.delay(0, pot);
//  R_delayGen.delay(0, pot);
  L_delayMix.gain(1, pot);
  R_delayMix.gain(1, 0.5 - pot);

//Serial.print("Delay 1 amount, blue pot, MUX 16 Y6 - ");  Serial.println(pot);                        // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);   digitalWrite(S2, LOW); // POT  logic Y1 on 16
  for (int i=0; i <= 4; i++) potLog = analogRead(muxPot_14);                                       // Blue 2 box 2    Delay 2 amount
  pot = ((potLog * (potLog + 1)) >> 10) / 2046.0;  // LOG correction
//  L_delayGen.delay(1, pot);
//  R_delayGen.delay(1, pot);
  L_delayMix.gain(2, 0.5 - pot);
  R_delayMix.gain(2, pot);

//Serial.print("Delay 2 amount, blue pot, MUX 16 Y7 - ");  Serial.println(pot);                        // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-
/*
//_________________________________________________________________________________________________________________________________
digitalWrite(S0, LOW);   digitalWrite(S1, LOW);   digitalWrite(S2, HIGH); // POT  logic Y4 on 16
  for (int i=0; i <= 4; i++) potLog = analogRead(muxPot_16);                                       // Blue 3 box 2    Delay 3 amount
  pot = ((potLog * (potLog + 1)) >> 10) / 1023.0;  // LOG correction
//  L_delayGen.delay(2, pot);
//  R_delayGen.delay(2, pot);
  L_delayMix.gain(2, pot);
  R_delayMix.gain(2, pot);

//Serial.print("Delay 3 amount, blue pot, MUX 16 Y6 - ");  Serial.println(pot);                        // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);   digitalWrite(S2, HIGH); // POT  logic Y5 on 16
  for (int i=0; i <= 4; i++) potLog = analogRead(muxPot_16);                                       // Blue 4 box 2    Delay 4 amount
  pot = ((potLog * (potLog + 1)) >> 10) / 1023.0;  // LOG correction
//  L_delayGen.delay(3, pot);
//  R_delayGen.delay(3, pot);
  L_delayMix.gain(3, pot);
  R_delayMix.gain(3, pot);

//Serial.print("Delay 4 amount, blue pot, MUX 16 Y6 - ");  Serial.println(pot);                        // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-
*/
//_________________________________________________________________________________________________________________________________
digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW); // POT 15  logic Y2 on 14
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_14);// / 66.2) - 0.30;              // Orange           LFO frequency
  pot = ((potLog * (potLog + 1)) >> 10) / 68.22;  // LOG correction

//  if (pot < 0.0) pot = 0.0;
//  if (pot > 15.0) pot = 15.0;
  if (LFO_type == WAVEFORM_SAMPLE_HOLD) pot = pot * 8.0;
  LFO.frequency(pot);
//Serial.println(pot);                    // Reads on pot 15  Needs calibration

  MIDI.read();  //**************************

//_________________________________________________________________________________________________________________________________
/*
digitalWrite(S0, LOW);   digitalWrite(S1, HIGH);  digitalWrite(S2, LOW); // POT  logic Y2 on 15
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_15);                            // Pot             Noise level master
  pot = ((potLog * (potLog + 1)) >> 10) / 2046.0;  // LOG correction
  osc_mixA_01.gain(3, pot);  osc_mixA_02.gain(3, pot);  osc_mixA_03.gain(3, pot);  osc_mixA_04.gain(3, pot);
  osc_mixA_05.gain(3, pot);  osc_mixA_06.gain(3, pot);  osc_mixA_07.gain(3, pot);  osc_mixA_08.gain(3, pot);
//Serial.print("White noise level, pot, MUX 14 Y6 - ");  Serial.println(pot);    //  Reads GOOD
//  &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-
*/
digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, HIGH); // POT 22  logic Y6 on 14
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_14);                            // Pot                    Noise level
  pot = ((potLog * (potLog + 1)) >> 10) / 4092.0;  // LOG correction
  osc_mixA_01.gain(3, pot);  osc_mixA_02.gain(3, pot);  osc_mixA_03.gain(3, pot);  osc_mixA_04.gain(3, pot);
  osc_mixA_05.gain(3, pot);  osc_mixA_06.gain(3, pot);  osc_mixA_07.gain(3, pot);  osc_mixA_08.gain(3, pot);
//  osc_mixA_01.gain(3, pot);  osc_mixA_02.gain(3, pot);  osc_mixA_03.gain(3, pot);  osc_mixA_04.gain(3, pot);
//  osc_mixA_05.gain(3, pot);  osc_mixA_06.gain(3, pot);  osc_mixA_07.gain(3, pot);  osc_mixA_08.gain(3, pot);
//Serial.print("White noise level, pot, MUX 14 Y6 - ");  Serial.println(pot);    //  Reads GOOD   Dodgy wire connection
//  &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, HIGH);  digitalWrite(S1, HIGH);  digitalWrite(S2, HIGH); // POT 22  logic Y7 on 14
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_14);                            // Pot           White Pink noise pan
  pot = ((potLog * (potLog + 1)) >> 10) / 2046.0;  // LOG correction
  noise_mix.gain(0, pot);  noise_mix.gain(1, 1.0 - pot);
//Serial.print("Pink noise level, pot, MUX 14 Y7 - ");  Serial.println(pot);    //  Reads GOOD
//  &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _________________
digitalWrite(S0, LOW);  digitalWrite(S1, LOW);  digitalWrite(S2, HIGH); // TRIMPOT 22  logic Y4 on 14
  for (int i=0; i <= 4; i++) pot = ((float)analogRead(muxPot_14) / 0.2000) - 98.0;             // Trimpot 1       White noise attack
  if (pot < 0.0) pot = 0.0;
  if (pot > 5000.0) pot = 5000.0;
  noise_env_01.attack(pot);  noise_env_02.attack(pot);  noise_env_03.attack(pot);  noise_env_04.attack(pot);
  noise_env_05.attack(pot);  noise_env_06.attack(pot);  noise_env_07.attack(pot);  noise_env_08.attack(pot);
//Serial.print("Trimpot level, trimpot 1, MUX 14 Y4 - ");  Serial.println(pot);  //  [GOOD]

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);  digitalWrite(S2, HIGH); // TRIMPOT 23  logic Y5 on 14
  for (int i=0; i <= 4; i++) pot = ((float)analogRead(muxPot_14) / 0.0490) - 855.0;            // Trimpot 2        White noise decay
  if (pot < 0.0) pot = 0.0;
  if (pot > 20000.0) pot = 20000.0;
  noise_env_01.decay(pot);  noise_env_02.decay(pot);  noise_env_03.decay(pot);  noise_env_04.decay(pot);
  noise_env_05.decay(pot);  noise_env_06.decay(pot);  noise_env_07.decay(pot);  noise_env_08.decay(pot);
//Serial.print("Trimpot level, trimpot 23, MUX 14 Y5 - ");  Serial.println(pot);  //  [GOOD]

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
if (pitchBend == 1.0)  {
digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);  digitalWrite(S2, HIGH);  // POT 10  logic Y5 on 12 ?-?-?
  for (int i=0; i <= 4; i++){ keyShift1 = (float)analogRead(muxPot_18); }                      // SW             Octave shift Osc 01
//Serial.print(keyShift1);
                                                                      // val  1/2  
if (keyShift1 < 105) keyShift1 = -36; else                            // 11   105
if ((keyShift1 > 104) && (keyShift1 < 273))  keyShift1 = -24; else    // 199  273
if ((keyShift1 > 272) && (keyShift1 < 474))  keyShift1 = -12; else    // 347  473.5
if ((keyShift1 > 473) && (keyShift1 < 687))  keyShift1 = 0; else      // 600  686.5
if ((keyShift1 > 686) && (keyShift1 < 826))  keyShift1 = 12; else     // 773  825.5
if ((keyShift1 > 825) && (keyShift1 < 951))  keyShift1 = 24; else     // 878  950.5
if (keyShift1 > 950)  keyShift1 = 36;                                 // 1023

if (keyShift1 != oldKeyShift1) {
  wave_1_01.frequency(noteFreq[nP1 + keyShift1]);
  wave_1_02.frequency(noteFreq[nP2 + keyShift1]);
  wave_1_03.frequency(noteFreq[nP3 + keyShift1]);
  wave_1_04.frequency(noteFreq[nP4 + keyShift1]);
  wave_1_05.frequency(noteFreq[nP5 + keyShift1]);
  wave_1_06.frequency(noteFreq[nP6 + keyShift1]);
  wave_1_07.frequency(noteFreq[nP7 + keyShift1]);
  wave_1_08.frequency(noteFreq[nP8 + keyShift1]);

if (dataDisplay < 3) {Serial.print("Octave shift on OSC 1 = ");  Serial.println(keyShift1);}
oldKeyShift1 = keyShift1;
}
//Serial.print("  Octave shift OSC 1 - ");  Serial.println(keyShift1);                    // Reads GOOD
}

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
if (pitchBend == 1.0)  {
digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, HIGH);  // POT 11  logic Y6 on 18
  for (int i=0; i <= 4; i++){ keyShift2 = (float)analogRead(muxPot_18); }                      // SW             Octave shift Osc 02
// Serial.print(keyShift2);
// Serial.println();
                                                                      // val  1/2
if (keyShift2 < 105) keyShift2 = -36; else                            // 12
if ((keyShift2 > 104) && (keyShift2 < 273))  keyShift2 = -24; else    // 197
if ((keyShift2 > 272) && (keyShift2 < 474))  keyShift2 = -12; else    // 343
if ((keyShift2 > 473) && (keyShift2 < 687))  keyShift2 = 0; else      // 600
if ((keyShift2 > 686) && (keyShift2 < 826))  keyShift2 = 12; else     // 773
if ((keyShift2 > 825) && (keyShift2 < 951))  keyShift2 = 24; else     // 878
if (keyShift2 > 950)  keyShift2 = 36;                                 // 1021

if (keyShift2 != oldKeyShift2) {
  wave_2_01.frequency(noteFreq[nP1 + keyShift2]);
  wave_2_02.frequency(noteFreq[nP2 + keyShift2]);
  wave_2_03.frequency(noteFreq[nP3 + keyShift2]);
  wave_2_04.frequency(noteFreq[nP4 + keyShift2]);
  wave_2_05.frequency(noteFreq[nP5 + keyShift2]);
  wave_2_06.frequency(noteFreq[nP6 + keyShift2]);
  wave_2_07.frequency(noteFreq[nP7 + keyShift2]);
  wave_2_08.frequency(noteFreq[nP8 + keyShift2]);

if (dataDisplay < 3) Serial.print("Octave shift on OSC 2 = ");  Serial.println(keyShift2);
oldKeyShift2 = keyShift2;
}
// Serial.print("  Octave shift OSC 2 - ");  Serial.println(keyShift2);                    // Reads GOOD
}

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
if (pitchBend == 1.0)  {
digitalWrite(S0, HIGH);  digitalWrite(S1, HIGH);  digitalWrite(S2, HIGH); // POT 12  logic Y7 on 18
  for (int i=0; i <= 4; i++){ keyShift3 = (float)analogRead(muxPot_18); }                      // SW             Octave shift Osc 03
//Serial.println(keyShift3);                    // Reads on pot D8

if (keyShift3 < 105) keyShift3 = -36; else                            // 12
if ((keyShift3 > 104) && (keyShift3 < 273))  keyShift3 = -24; else    // 200
if ((keyShift3 > 272) && (keyShift3 < 474))  keyShift3 = -12; else    // 347
if ((keyShift3 > 473) && (keyShift3 < 687))  keyShift3 = 0; else      // 610
if ((keyShift3 > 686) && (keyShift3 < 826))  keyShift3 = 12; else     // 775
if ((keyShift3 > 825) && (keyShift3 < 951))  keyShift3 = 24; else     // 885
if (keyShift3 > 950)  keyShift3 = 36;                                 // 1023

if (keyShift3 != oldKeyShift3) {
  wave_3_01.frequency(noteFreq[nP1 + keyShift3]);
  wave_3_02.frequency(noteFreq[nP2 + keyShift3]);
  wave_3_03.frequency(noteFreq[nP3 + keyShift3]);
  wave_3_04.frequency(noteFreq[nP4 + keyShift3]);
  wave_3_05.frequency(noteFreq[nP5 + keyShift3]);
  wave_3_06.frequency(noteFreq[nP6 + keyShift3]);
  wave_3_07.frequency(noteFreq[nP7 + keyShift3]);
  wave_3_08.frequency(noteFreq[nP8 + keyShift3]);

if (dataDisplay < 3) Serial.print("Octave shift on OSC 3 = ");  Serial.println(keyShift3);
oldKeyShift3 = keyShift3;
}
//Serial.println(keyShift3);  // [GOOD]
}

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
// OSC fine ON 12 Y0
if (pitchBend == 1.0)  {
digitalWrite(S0, LOW);  digitalWrite(S1, LOW);  digitalWrite(S2, LOW);  // POT 13  logic Y0 on 12

  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_12);                            // Grey 1              Finetune OSC 1
  fineTune = ((potLog * (potLog + 1)) >> 10) / 1023.0;  // LOG correction
  
//  fineTune_1 = 1.0 + (fineTune / 38.0);
  fineTune_1 = 1.0 + (fineTune / 19.0);
//  fineTune_1 = 1.0 + (fineTune / 9.5);

  if (fineTune > 0.0) {
  wave_1_01.frequency(noteFreq[nP1 + keyShift1] * fineTune_1);
  wave_1_02.frequency(noteFreq[nP2 + keyShift1] * fineTune_1);
  wave_1_03.frequency(noteFreq[nP3 + keyShift1] * fineTune_1);
  wave_1_04.frequency(noteFreq[nP4 + keyShift1] * fineTune_1);
  wave_1_05.frequency(noteFreq[nP5 + keyShift1] * fineTune_1);
  wave_1_06.frequency(noteFreq[nP6 + keyShift1] * fineTune_1);
  wave_1_07.frequency(noteFreq[nP7 + keyShift1] * fineTune_1);
  wave_1_08.frequency(noteFreq[nP8 + keyShift1] * fineTune_1);
  }
}
//Serial.print("Fine Tune, pot 21, MUX C Y4 - ");         Serial.print("OSC 1 = ");  Serial.print(fineTune_1);
//Serial.print("  OSC 3 = ");  Serial.print(fineTune_2);  Serial.print("  POT = ");  Serial.println(fineTune);  // [GOOD]

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

if (pitchBend == 1.0)  {
digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);  digitalWrite(S2, LOW); // POT 14  logic Y1 on 12
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_12);                            // Grey 2              Finetune OSC 2
  fineTune = ((potLog * (potLog + 1)) >> 10) / 1023.0;  // LOG correction

//  if (fineTune < 0) fineTune = 0.0;
//  if (fineTune > 1.0) fineTune = 1.0;
//  Serial.println(fineTune);                    // Reads GOOD

//  fineTune_2 = 1.0 - (fineTune / 33.0);
  fineTune_2 = 1.0 - (fineTune / 16.5);
//  fineTune_1 = 1.0 + (fineTune / 10.0);

  if (fineTune > 0.0) {
  wave_2_01.frequency(noteFreq[nP1 + keyShift2] * fineTune_2);
  wave_2_02.frequency(noteFreq[nP2 + keyShift2] * fineTune_2);
  wave_2_03.frequency(noteFreq[nP3 + keyShift2] * fineTune_2);
  wave_2_04.frequency(noteFreq[nP4 + keyShift2] * fineTune_2);
  wave_2_05.frequency(noteFreq[nP5 + keyShift2] * fineTune_2);
  wave_2_06.frequency(noteFreq[nP6 + keyShift2] * fineTune_2);
  wave_2_07.frequency(noteFreq[nP7 + keyShift2] * fineTune_2);
  wave_2_08.frequency(noteFreq[nP8 + keyShift2] * fineTune_2);
  }
}
//Serial.print("Fine Tune, pot 14, MUX B Y5 - ");         Serial.print("OSC 1 = ");  Serial.print(fineTune_1);
//Serial.print("  OSC 2 = ");  Serial.print(fineTune_2);  Serial.print("  POT = ");  Serial.println(fineTune);  // [GOOD]

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

// ====================================================================================================== Wave type selection start
/*
byte oldVCO1;
byte oldVCO2;
byte oldVCO3;
byte oldLFO;
WAVEFORM_ARBITRARY
WAVEFORM_SAMPLE_HOLD
*/

digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW); // Pot 7  logic Y2 on 19
  for (int i=0; i <= 4; i++) pot = (float)analogRead(muxPot_19);                               // SW                   Wave on OSC 1
//Serial.println(pot);                    // Reads GOOD
  
if ((pot < 120) && (VCO1 != 0))  {                                      // 12
    wave_1_type = WAVEFORM_SAMPLE_HOLD;
    if (dataDisplay < 3) Serial.println("OSC 1 Control waveform: 0 - Sample and hold");
    VCO1 = 0;
    }
      else if ((pot > 119) && (pot < 380) && (VCO1 != 1))  {            // 227
      wave_1_type = WAVEFORM_SINE;
      if (dataDisplay < 3) Serial.println("OSC 1 Control waveform: 1 - Sine");
      VCO1 = 1;
      }
        else if ((pot > 379) && (pot < 626) && (VCO1 != 2))  {          // 531
        wave_1_type = WAVEFORM_TRIANGLE;
        if (dataDisplay < 3) Serial.println("OSC 1 Control waveform: 2 - Triangle");
        VCO1 = 2;
        }
          else if ((pot > 625) && (pot < 798) && (VCO1 != 3))  {        // 720
          wave_1_type = WAVEFORM_SAWTOOTH;
          if (dataDisplay < 3) Serial.println("OSC 1 Control waveform: 3 - Sawtooth");
          VCO1 = 3;
          }
            else if ((pot > 797) && (pot < 950) && (VCO1 != 4))  {      // 875
            wave_1_type = WAVEFORM_SQUARE;
            if (dataDisplay < 3) Serial.println("OSC 1 Control waveform: 4 - Square");
            VCO1 = 4;
            }
              else if (pot > 949 && (VCO1 != 5))  {                     // 1023
              wave_1_type = WAVEFORM_PULSE;
              if (dataDisplay < 3) Serial.println("OSC 1 Control waveform: 5 - Pulse");
              VCO1 = 5;
              }

    if (VCO1 != oldVCO1)  {
    wave_1_01.begin(wave_1_type);  wave_1_02.begin(wave_1_type);  wave_1_03.begin(wave_1_type);  wave_1_04.begin(wave_1_type);
    wave_1_05.begin(wave_1_type);  wave_1_06.begin(wave_1_type);  wave_1_07.begin(wave_1_type);  wave_1_08.begin(wave_1_type);
    wave_1_01.phase(0.0);  wave_1_02.phase(0.0);  wave_1_03.phase(0.0);  wave_1_04.phase(0.0);
    wave_1_05.phase(0.0);  wave_1_06.phase(0.0);  wave_1_07.phase(0.0);  wave_1_08.phase(0.0);
    sinefmPhase();
    oldVCO1 = VCO1;
    }

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, HIGH);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW);// Pot 8   logic Y3 on 19
  for (int i=0; i <= 4; i++) pot = (float)analogRead(muxPot_19);                               // SW                   Wave on OSC 2
//Serial.println(pot);                    // Reads GOOD

if ((pot < 120) && (VCO2 != 0))  {                                        // 12
    wave_2_type = WAVEFORM_SAMPLE_HOLD;
    if (dataDisplay < 3) Serial.println("OSC 2 Control waveform: 0 - Sample and hold");
    VCO2 = 0;
    }
      else if ((pot > 119) && (pot < 380) && (VCO2 != 1))  {              // 227
      wave_2_type = WAVEFORM_SINE;
      if (dataDisplay < 3) Serial.println("OSC 2 Control waveform: 1 - Sine");
      VCO2 = 1;
      }
        else if ((pot > 379) && (pot < 626) && (VCO2 != 2))  {            // 530
        wave_2_type = WAVEFORM_TRIANGLE;
        if (dataDisplay < 3) Serial.println("OSC 2 Control waveform: 2 - Triangle");
        VCO2 = 2;
        }
          else if ((pot > 625) && (pot < 798) && (VCO2 != 3))  {          // 720
          wave_2_type = WAVEFORM_SAWTOOTH_REVERSE;
          if (dataDisplay < 3) Serial.println("OSC 2 Control waveform: 3 - Sawtooth reverse");
          VCO2 = 3;
          }
            else if ((pot > 797) && (pot < 950) && (VCO2 != 4))  {        // 880
            wave_2_type = WAVEFORM_SQUARE;
            if (dataDisplay < 3) Serial.println("OSC 2 Control waveform: 4 - Square");
            VCO2 = 4;
            }
              else if (pot > 949 && (VCO2 != 5))  {                       // 1023
              wave_2_type = WAVEFORM_PULSE;
              if (dataDisplay < 3) Serial.println("OSC 2 Control waveform: 5 - Pulse");
              VCO2 = 5;
              }

    if (VCO2 != oldVCO2)  {
    wave_2_01.begin(wave_2_type);  wave_2_02.begin(wave_2_type);  wave_2_03.begin(wave_2_type);  wave_2_04.begin(wave_2_type);
    wave_2_05.begin(wave_2_type);  wave_2_06.begin(wave_2_type);  wave_2_07.begin(wave_2_type);  wave_2_08.begin(wave_2_type);
    wave_2_01.phase(0.0);  wave_2_02.phase(0.0);  wave_2_03.phase(0.0);  wave_2_04.phase(0.0);
    wave_2_05.phase(0.0);  wave_2_06.phase(0.0);  wave_2_07.phase(0.0);  wave_2_08.phase(0.0);
    sinefmPhase();
    oldVCO2 = VCO2;
    }

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, LOW);  digitalWrite(S1, LOW);  digitalWrite(S2, HIGH);   // Pot 9  logic Y4 on 18
  for (int i=0; i <= 4; i++) pot = (float)analogRead(muxPot_18);                               // SW                   Wave on OSC 3
//Serial.println(pot);                    // Reads GOOD

if ((pot < 120) && (VCO3 != 0))  {
    wave_3_type = WAVEFORM_ARBITRARY;
    if (dataDisplay < 3) Serial.println("OSC 3 Control waveform: 0 - Arbitrary");
    VCO3 = 0;
    }
      else if ((pot > 119) && (pot < 380) && (VCO3 != 1))  {
      wave_3_type = WAVEFORM_SINE;
      if (dataDisplay < 3) Serial.println("OSC 3 Control waveform: 1 - Sine");
      VCO3 = 1;
      }
        else if ((pot > 379) && (pot < 626) && (VCO3 != 2))  {
        wave_3_type = WAVEFORM_TRIANGLE;
        if (dataDisplay < 3) Serial.println("OSC 3 Control waveform: 2 - Triangle");
        VCO3 = 2;
        }
          else if ((pot > 625) && (pot < 798) && (VCO3 != 3))  {
          wave_3_type = WAVEFORM_SAWTOOTH;
          if (dataDisplay < 3) Serial.println("OSC 3 Control waveform: 3 - Sawtooth");
          VCO3 = 3;
          }
            else if ((pot > 797) && (pot < 950) && (VCO3 != 4))  {
            wave_3_type = WAVEFORM_SQUARE;
            if (dataDisplay < 3) Serial.println("OSC 3 Control waveform: 4 - Square");
            VCO3 = 4;
            }
              else if (pot > 949 && (VCO3 != 5))  {
              wave_3_type = WAVEFORM_PULSE;
              if (dataDisplay < 3) Serial.println("OSC 3 Control waveform: 5 - Pulse");
              VCO3 = 5;
              }

    if (VCO3 != oldVCO3)  {
    wave_3_01.begin(wave_3_type);  wave_3_02.begin(wave_3_type);  wave_3_03.begin(wave_3_type);  wave_3_04.begin(wave_3_type);
    wave_3_05.begin(wave_3_type);  wave_3_06.begin(wave_3_type);  wave_3_07.begin(wave_3_type);  wave_3_08.begin(wave_3_type);
    wave_3_01.phase(0.0);  wave_3_02.phase(0.0);  wave_3_03.phase(0.0);  wave_3_04.phase(0.0);
    wave_3_05.phase(0.0);  wave_3_06.phase(0.0);  wave_3_07.phase(0.0);  wave_3_08.phase(0.0);
    sinefmPhase();
    oldVCO3 = VCO3;
    }

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-


digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, HIGH); // Pot D7  logic Y6 on 13
  for (int i=0; i <= 4; i++) pot = (float)analogRead(muxPot_13);                               // SW                     Wave on LFO
//Serial.println(pot);                    // Reads GOOD

if ((pot < 118) && (LFO1 != 0))  {                                    //  12.00
    LFO_type = WAVEFORM_SAMPLE_HOLD;
    Serial.println("LFO Control waveform: 0 - Sample and hold");
    LFO1 = 0;
    }
      else if ((pot > 117) && (pot < 337) && (LFO1 != 1))  {          //  224.00
      LFO_type = WAVEFORM_SINE;
      if (dataDisplay < 3) Serial.println("LFO Control waveform: 1 - Sine");
      LFO1 = 1;
      }
        else if ((pot > 336) && (pot < 628) && (LFO1 != 2))  {        //  530.00
        LFO_type = WAVEFORM_TRIANGLE;
        if (dataDisplay < 3) Serial.println("LFO Control waveform: 2 - Triangle");
        LFO1 = 2;
        }
          else if ((pot > 627) && (pot < 805) && (LFO1 != 3))  {      //  725.00
          LFO_type = WAVEFORM_SAWTOOTH_REVERSE;
          if (dataDisplay < 3) Serial.println("LFO Control waveform: 3 - Sawtooth reverse");
          LFO1 = 3;
          }
            else if ((pot > 804) && (pot < 955) && (LFO1 != 4))  {    //  885.00
            LFO_type = WAVEFORM_SQUARE;
            if (dataDisplay < 3) Serial.println("LFO Control waveform: 4 - Square");
            LFO1 = 4;
            }
              else if (pot > 954 && (LFO1 != 5))  {                   //  1023.00
              LFO_type = WAVEFORM_PULSE;
              if (dataDisplay < 3) Serial.println("LFO Control waveform: 5 - Pulse");
              LFO1 = 5;
              }

    if (LFO1 != oldLFO)  {
    LFO.begin(LFO_type);
//    L_fSweepOSC.begin(LFO_type);
//    R_fSweepOSC.begin(LFO_type);
    oldLFO = LFO1;
    }

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

// ======================================================================================================== Wave type selection end

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, HIGH);  // POT 21  logic Y6 on 17
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_17);                           // Pot     Pulse width Osc 1+2+3 + LFO 
  pot = ((potLog * (potLog + 1)) >> 10) / 800.0;  // LOG correction

  if (pot < 0.01) pot = 0.01;
  if (pot > 1.0) pot = 1.0;
    wave_1_01.pulseWidth(pot);    wave_2_01.pulseWidth(pot);    wave_3_01.pulseWidth(pot);
    wave_1_02.pulseWidth(pot);    wave_2_02.pulseWidth(pot);    wave_3_02.pulseWidth(pot);
    wave_1_03.pulseWidth(pot);    wave_2_03.pulseWidth(pot);    wave_3_03.pulseWidth(pot);
    wave_1_04.pulseWidth(pot);    wave_2_04.pulseWidth(pot);    wave_3_04.pulseWidth(pot);
    wave_1_05.pulseWidth(pot);    wave_2_05.pulseWidth(pot);    wave_3_05.pulseWidth(pot);
    wave_1_06.pulseWidth(pot);    wave_2_06.pulseWidth(pot);    wave_3_06.pulseWidth(pot);
    wave_1_07.pulseWidth(pot);    wave_2_07.pulseWidth(pot);    wave_3_07.pulseWidth(pot);
    wave_1_08.pulseWidth(pot);    wave_2_08.pulseWidth(pot);    wave_3_08.pulseWidth(pot);
    LFO.pulseWidth(pot);
//Serial.println(pot);                    // Reads on ext pot  Needs calibration

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
// ============================================================================================= VOLUME ENVELOPE start
digitalWrite(S0, HIGH);  digitalWrite(S1, HIGH);  digitalWrite(S2, HIGH); // POT 4 logic Y7 on 19
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_19);                            // Blue 1            10s Attack level

  env_att = (((potLog * (potLog + 1)) >> 10) / 0.102);  // LOG correction
//  env_att = ((potLog * (potLog + 1)) / 104.65) - 8.0;  // LOG correction
 
  if (env_att < clickDelay) env_att = clickDelay;
  if (env_att > 10000.0) env_att = 10000.0;
    env_01.attack(env_att); env_02.attack(env_att); env_03.attack(env_att); env_04.attack(env_att);
    env_05.attack(env_att); env_06.attack(env_att); env_07.attack(env_att); env_08.attack(env_att);
//Serial.println(env_att);                    // Reads GOOD but faulty connection at pin block

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, LOW);  digitalWrite(S1, LOW);  digitalWrite(S2, LOW);  // POT 5 logic Y0 on 19
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_19);                           // Blue 2                5s Hold level
  env_hld = ((potLog * (potLog + 1)) / 209.35) - 2.0;  // LOG correction
  if (env_hld < 0.0) env_hld = 0.0;
  if (env_hld > 5000.0) env_hld = 5000.0;
    env_01.hold(env_hld); env_02.hold(env_hld); env_03.hold(env_hld); env_04.hold(env_hld);
    env_05.hold(env_hld); env_06.hold(env_hld); env_07.hold(env_hld); env_08.hold(env_hld);
//Serial.println(env_hld);                    // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, LOW);  digitalWrite(S1, LOW);  digitalWrite(S2, HIGH);   // POT 1 logic Y4 on 19
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_19);                            // Blue 3              5s Decay level
  env_dec = ((potLog * (potLog + 1)) / 209.35) - 2.0;  // LOG correction
  if (env_dec < 0.0) env_dec = 0.0;
  if (env_dec > 5000.0) env_dec = 5000.0;
    env_01.decay(env_dec); env_02.decay(env_dec); env_03.decay(env_dec); env_04.decay(env_dec);
    env_05.decay(env_dec); env_06.decay(env_dec); env_07.decay(env_dec); env_08.decay(env_dec);
//Serial.println(env_dec);                    // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);  digitalWrite(S2, HIGH);  // POT 2 logic Y5 on 19
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_19);                            // Blue 4           1.0 Sustain level
  env_sus = ((potLog * (potLog + 1)) >> 10) / 1023.0;  // LOG correction
//  if (env_sus < 0.0) env_sus = 0.0;
//  if (env_sus > 1.0) env_sus = 1.0;
    env_01.sustain(env_sus); env_02.sustain(env_sus); env_03.sustain(env_sus); env_04.sustain(env_sus);
    env_05.sustain(env_sus); env_06.sustain(env_sus); env_07.sustain(env_sus); env_08.sustain(env_sus);
//Serial.println(env_sus);                    // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, LOW);  digitalWrite(S1, LOW);  digitalWrite(S2, LOW); // POT D1  logic Y0 on 13
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_13);                            // Blue 5           10s Release level
  env_rel = ((potLog * (potLog + 1)) / 104.65) - 8.0;  // LOG correction
  if (env_rel < 0.0) env_rel = 0.0;
  if (env_rel > 10000.0) env_rel = 10000.0;
    env_01.release(env_rel); env_02.release(env_rel); env_03.release(env_rel); env_04.release(env_rel);
    env_05.release(env_rel); env_06.release(env_rel); env_07.release(env_rel); env_08.release(env_rel);
//Serial.println(env_rel);                    // Reads GOOD

// ============================================================================================================ VOLUME ENVELOPE end

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

// ============================================================================================= FILTER ENVELOPE start
digitalWrite(S0, HIGH);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW); // POT D4  logic Y3 on 13
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_13);                      

  pot = (((potLog * (potLog + 1)) >> 10) / 511.5) - 1.0;  // LOG correction

//pot = (pot * 2.0) - 1.0;
//  if (pot < -1.0) pot = -1.0;
//  if (pot > 1.0) pot = 1.0;
  filtDC.amplitude(pot);                                                                       // Green 2                 Filter mix
//Serial.println(pot);                    // Reads on pot D4

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);  digitalWrite(S2, LOW); // POT 6  logic Y1 on 19
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_19);                            // Red 1      10s Filter attack level

//  fenv_att = (((potLog * (potLog + 1)) >> 10) / 0.102) - 14.0;  // LOG correction
  fenv_att = ((potLog * (potLog + 1)) / 104.65) - 8.0;  // LOG correction

  if (fenv_att < 0.0) fenv_att = 0.0;
  if (fenv_att > 10000.0) fenv_att = 10000.0;
    filtEnv_01.attack(fenv_att); filtEnv_02.attack(fenv_att); filtEnv_03.attack(fenv_att); filtEnv_04.attack(fenv_att);
    filtEnv_05.attack(fenv_att); filtEnv_06.attack(fenv_att); filtEnv_07.attack(fenv_att); filtEnv_08.attack(fenv_att);
//Serial.println(fenv_att);                    // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);  digitalWrite(S2, HIGH);  // POT D6  logic Y5 on 13
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_13);                            // Red 2         5s Filter hold level

//  fenv_hld = (((potLog * (potLog + 1)) >> 10) / 0.2045) - 1.0;  // LOG correction
  fenv_hld = ((potLog * (potLog + 1)) / 209.35) - 2.0;  // LOG correction

  if (fenv_hld < 0.0) fenv_hld = 0.0;
  if (fenv_hld > 5000.0) fenv_hld = 5000.0;
    filtEnv_01.hold(fenv_hld); filtEnv_02.hold(fenv_hld); filtEnv_03.hold(fenv_hld); filtEnv_04.hold(fenv_hld);
    filtEnv_05.hold(fenv_hld); filtEnv_06.hold(fenv_hld); filtEnv_07.hold(fenv_hld); filtEnv_08.hold(fenv_hld);
//Serial.println(fenv_hld);                    // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, HIGH); // POT 3  logic Y6 on 19
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_19);                            // Red 3        5s Filter decay level

  fenv_dec = (((potLog * (potLog + 1)) >> 10) / 0.2045) - 1.0;  // LOG correction

  if (fenv_dec < 0.0) fenv_dec = 0.0;
  if (fenv_dec > 5000.0) fenv_dec = 5000.0;
    filtEnv_01.decay(fenv_dec); filtEnv_02.decay(fenv_dec); filtEnv_03.decay(fenv_dec); filtEnv_04.decay(fenv_dec);
    filtEnv_05.decay(fenv_dec); filtEnv_06.decay(fenv_dec); filtEnv_07.decay(fenv_dec); filtEnv_08.decay(fenv_dec);
//Serial.println(fenv_dec);                    // Reads GOOD
//Serial.println(potLog);                      // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, LOW);  digitalWrite(S1, LOW);  digitalWrite(S2, HIGH); // POT D5  logic Y4 on 13
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_13);                            // Red 4         Filter sustain level

  fenv_sus = (((potLog * (potLog + 1)) >> 10) / 1023.0);// - 1.0;  // LOG correction

//  if (fenv_sus < 0.0) fenv_sus = 0.0;
//  if (fenv_sus > 1.0) fenv_sus = 1.0;
    filtEnv_01.sustain(fenv_sus); filtEnv_02.sustain(fenv_sus); filtEnv_03.sustain(fenv_sus); filtEnv_04.sustain(fenv_sus);
    filtEnv_05.sustain(fenv_sus); filtEnv_06.sustain(fenv_sus); filtEnv_07.sustain(fenv_sus); filtEnv_08.sustain(fenv_sus);
//Serial.println(fenv_sus);                    // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW);  // POT D3  logic Y2 on 13
  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_13);                            // Red 5     10s Filter release level

//  fenv_rel = (((potLog * (potLog + 1)) >> 10) / 0.102) - 14.0;  // LOG correction
  fenv_rel = ((potLog * (potLog + 1)) / 104.65) - 8.0;  // LOG correction

  if (fenv_rel < 0.0) fenv_rel = 0.0;
  if (fenv_rel > 10000.0) fenv_rel = 10000.0;
    filtEnv_01.release(fenv_rel); filtEnv_02.release(fenv_rel); filtEnv_03.release(fenv_rel); filtEnv_04.release(fenv_rel);
    filtEnv_05.release(fenv_rel); filtEnv_06.release(fenv_rel); filtEnv_07.release(fenv_rel); filtEnv_08.release(fenv_rel);
//Serial.println(fenv_rel);                    // Reads GOOD

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
//digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW); // logic Y1 on 14                    0.8 - 5.0
//  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_14);// / 200.6) + 0.23;           // POT      Resonance to filter envelope
//  pot = (((potLog * (potLog + 1)) >> 10) / 203.0) + 0.6;  // LOG correction                                  Has an effect
//  if (pot < 0.8) pot = 0.8;
//  if (pot > 5.0) pot = 5.0;
//  filt_01.resonance(pot);  filt_02.resonance(pot);  filt_03.resonance(pot);  filt_04.resonance(pot);
//  filt_05.resonance(pot);  filt_06.resonance(pot);  filt_07.resonance(pot);  filt_08.resonance(pot);
//Serial.println(pot);

//digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW); // logic Y1 on 14                    0.0 - 7.0
//  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_14);                              // POT      Octave to filter envelope
//  pot = (((potLog * (potLog + 1)) >> 10) / 125.0) - 0.32;  // LOG correction                                 Has no useful effect 
//  if (pot < 0.0) pot = 0.0;
//  if (pot > 7.0) pot = 7.0;
//  filt_01.octaveControl(pot);  filt_02.octaveControl(pot);  filt_03.octaveControl(pot);  filt_04.octaveControl(pot);
//  filt_05.octaveControl(pot);  filt_06.octaveControl(pot);  filt_07.octaveControl(pot);  filt_08.octaveControl(pot);
//Serial.println(pot);

//digitalWrite(S0, LOW);  digitalWrite(S1, HIGH);  digitalWrite(S2, LOW); // logic Y1 on 14                    30.0 - 2000.0
//  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_14);// / 0.9900) - 27.0;           // POT     Frequency to filter envelope
//  pot = (((potLog * (potLog + 1)) >> 10) / 0.5);  // LOG correction                                          Moderate effect
//  if (pot < 30.0) pot = 30.0;
//  if (pot > 2000.0) pot = 2000.0;
//  filt_01.frequency(pot);  filt_02.frequency(pot);  filt_03.frequency(pot);  filt_04.frequency(pot);
//  filt_05.frequency(pot);  filt_06.frequency(pot);  filt_07.frequency(pot);  filt_08.frequency(pot);
//Serial.println(pot);

//  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
digitalWrite(S0, HIGH);  digitalWrite(S1, HIGH);  digitalWrite(S2, HIGH);// ROT SW D8  logic Y7 on 13
  for (int i=0; i <= 4; i++){ pot = (float)analogRead(muxPot_13); }                            // SW                     Filter type
//Serial.println(pot);                    // Reads GOOD

  if ((butt == 6) && (buttonTog == 0))  {
    buttonTog = 1;
    if (fltBypass == 0)  {
      filtMix_01.gain(0, 0.0);  filtMix_01.gain(1, 0.0);  filtMix_01.gain(2, 0.0);  filtMix_01.gain(3, 1.0);
      filtMix_02.gain(0, 0.0);  filtMix_02.gain(1, 0.0);  filtMix_02.gain(2, 0.0);  filtMix_02.gain(3, 1.0);
      filtMix_03.gain(0, 0.0);  filtMix_03.gain(1, 0.0);  filtMix_03.gain(2, 0.0);  filtMix_03.gain(3, 1.0);
      filtMix_04.gain(0, 0.0);  filtMix_04.gain(1, 0.0);  filtMix_04.gain(2, 0.0);  filtMix_04.gain(3, 1.0);
      filtMix_05.gain(0, 0.0);  filtMix_05.gain(1, 0.0);  filtMix_05.gain(2, 0.0);  filtMix_05.gain(3, 1.0);
      filtMix_06.gain(0, 0.0);  filtMix_06.gain(1, 0.0);  filtMix_06.gain(2, 0.0);  filtMix_06.gain(3, 1.0);
      filtMix_07.gain(0, 0.0);  filtMix_07.gain(1, 0.0);  filtMix_07.gain(2, 0.0);  filtMix_07.gain(3, 1.0);
      filtMix_08.gain(0, 0.0);  filtMix_08.gain(1, 0.0);  filtMix_08.gain(2, 0.0);  filtMix_08.gain(3, 1.0);
      if (dataDisplay < 3) Serial.println("Filter envelope is off");
      fltBypass = 1;
    }
    else
    {
      if (dataDisplay < 3) Serial.println("Filter envelope is on");
      fltBypass = 0;
      fltSwitch = 0;
    }
  }

    if (fltBypass == 0)  {
if ((pot < 104) && (fltSwitch != 1))  {                                                                        //   11.00
      filtMix_01.gain(0, 0.90);  filtMix_01.gain(1, 0.0);  filtMix_01.gain(2, 0.0);  filtMix_01.gain(3, 0.0);
      filtMix_02.gain(0, 0.90);  filtMix_02.gain(1, 0.0);  filtMix_02.gain(2, 0.0);  filtMix_02.gain(3, 0.0);
      filtMix_03.gain(0, 0.90);  filtMix_03.gain(1, 0.0);  filtMix_03.gain(2, 0.0);  filtMix_03.gain(3, 0.0);
      filtMix_04.gain(0, 0.90);  filtMix_04.gain(1, 0.0);  filtMix_04.gain(2, 0.0);  filtMix_04.gain(3, 0.0);
      filtMix_05.gain(0, 0.90);  filtMix_05.gain(1, 0.0);  filtMix_05.gain(2, 0.0);  filtMix_05.gain(3, 0.0);
      filtMix_06.gain(0, 0.90);  filtMix_06.gain(1, 0.0);  filtMix_06.gain(2, 0.0);  filtMix_06.gain(3, 0.0);
      filtMix_07.gain(0, 0.90);  filtMix_07.gain(1, 0.0);  filtMix_07.gain(2, 0.0);  filtMix_07.gain(3, 0.0);
      filtMix_08.gain(0, 0.90);  filtMix_08.gain(1, 0.0);  filtMix_08.gain(2, 0.0);  filtMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("1 - LOWPASS");
      fltSwitch = 1;
    }
    else
if ((pot > 103) && (pot < 271) && (fltSwitch != 2))  {                                                          //   196.00
      filtMix_01.gain(0, 0.45);  filtMix_01.gain(1, 0.45);  filtMix_01.gain(2, 0.0);  filtMix_01.gain(3, 0.0);
      filtMix_02.gain(0, 0.45);  filtMix_02.gain(1, 0.45);  filtMix_02.gain(2, 0.0);  filtMix_02.gain(3, 0.0);
      filtMix_03.gain(0, 0.45);  filtMix_03.gain(1, 0.45);  filtMix_03.gain(2, 0.0);  filtMix_03.gain(3, 0.0);
      filtMix_04.gain(0, 0.45);  filtMix_04.gain(1, 0.45);  filtMix_04.gain(2, 0.0);  filtMix_04.gain(3, 0.0);
      filtMix_05.gain(0, 0.45);  filtMix_05.gain(1, 0.45);  filtMix_05.gain(2, 0.0);  filtMix_05.gain(3, 0.0);
      filtMix_06.gain(0, 0.45);  filtMix_06.gain(1, 0.45);  filtMix_06.gain(2, 0.0);  filtMix_06.gain(3, 0.0);
      filtMix_07.gain(0, 0.45);  filtMix_07.gain(1, 0.45);  filtMix_07.gain(2, 0.0);  filtMix_07.gain(3, 0.0);
      filtMix_08.gain(0, 0.45);  filtMix_08.gain(1, 0.45);  filtMix_08.gain(2, 0.0);  filtMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("2 - LOWPASS + BANDPASS");
      fltSwitch = 2;
    }
    else
if ((pot > 270) && (pot < 477) && (fltSwitch != 3))  {                                                        //   345.00
      filtMix_01.gain(0, 0.45);  filtMix_01.gain(1, 0.0);  filtMix_01.gain(2, 0.45);  filtMix_01.gain(3, 0.0);
      filtMix_02.gain(0, 0.45);  filtMix_02.gain(1, 0.0);  filtMix_02.gain(2, 0.45);  filtMix_02.gain(3, 0.0);
      filtMix_03.gain(0, 0.45);  filtMix_03.gain(1, 0.0);  filtMix_03.gain(2, 0.45);  filtMix_03.gain(3, 0.0);
      filtMix_04.gain(0, 0.45);  filtMix_04.gain(1, 0.0);  filtMix_04.gain(2, 0.45);  filtMix_04.gain(3, 0.0);
      filtMix_05.gain(0, 0.45);  filtMix_05.gain(1, 0.0);  filtMix_05.gain(2, 0.45);  filtMix_05.gain(3, 0.0);
      filtMix_06.gain(0, 0.45);  filtMix_06.gain(1, 0.0);  filtMix_06.gain(2, 0.45);  filtMix_06.gain(3, 0.0);
      filtMix_07.gain(0, 0.45);  filtMix_07.gain(1, 0.0);  filtMix_07.gain(2, 0.45);  filtMix_07.gain(3, 0.0);
      filtMix_08.gain(0, 0.45);  filtMix_08.gain(1, 0.0);  filtMix_08.gain(2, 0.45);  filtMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("3 - LOWPASS + HIGHPASS");
      fltSwitch = 3;
    }
    else
if ((pot > 478) && (pot < 694) && (fltSwitch != 4))  {                                                        //  608.00
      filtMix_01.gain(0, 0.3);  filtMix_01.gain(1, 0.3);  filtMix_01.gain(2, 0.3);  filtMix_01.gain(3, 0.0);
      filtMix_02.gain(0, 0.3);  filtMix_02.gain(1, 0.3);  filtMix_02.gain(2, 0.3);  filtMix_02.gain(3, 0.0);
      filtMix_03.gain(0, 0.3);  filtMix_03.gain(1, 0.3);  filtMix_03.gain(2, 0.3);  filtMix_03.gain(3, 0.0);
      filtMix_04.gain(0, 0.3);  filtMix_04.gain(1, 0.3);  filtMix_04.gain(2, 0.3);  filtMix_04.gain(3, 0.0);
      filtMix_05.gain(0, 0.3);  filtMix_05.gain(1, 0.3);  filtMix_05.gain(2, 0.3);  filtMix_05.gain(3, 0.0);
      filtMix_06.gain(0, 0.3);  filtMix_06.gain(1, 0.3);  filtMix_06.gain(2, 0.3);  filtMix_06.gain(3, 0.0);
      filtMix_07.gain(0, 0.3);  filtMix_07.gain(1, 0.3);  filtMix_07.gain(2, 0.3);  filtMix_07.gain(3, 0.0);
      filtMix_08.gain(0, 0.3);  filtMix_08.gain(1, 0.3);  filtMix_08.gain(2, 0.3);  filtMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("4 - LOWPASS + BANDPASS + HIGHPASS");
      fltSwitch = 4;
    }
    else
if ((pot > 693) && (pot < 839) && (fltSwitch != 5))  {                                                        //  778.00
      filtMix_01.gain(0, 0.0);  filtMix_01.gain(1, 0.90);  filtMix_01.gain(2, 0.0);  filtMix_01.gain(3, 0.0);
      filtMix_02.gain(0, 0.0);  filtMix_02.gain(1, 0.90);  filtMix_02.gain(2, 0.0);  filtMix_02.gain(3, 0.0);
      filtMix_03.gain(0, 0.0);  filtMix_03.gain(1, 0.90);  filtMix_03.gain(2, 0.0);  filtMix_03.gain(3, 0.0);
      filtMix_04.gain(0, 0.0);  filtMix_04.gain(1, 0.90);  filtMix_04.gain(2, 0.0);  filtMix_04.gain(3, 0.0);
      filtMix_05.gain(0, 0.0);  filtMix_05.gain(1, 0.90);  filtMix_05.gain(2, 0.0);  filtMix_05.gain(3, 0.0);
      filtMix_06.gain(0, 0.0);  filtMix_06.gain(1, 0.90);  filtMix_06.gain(2, 0.0);  filtMix_06.gain(3, 0.0);
      filtMix_07.gain(0, 0.0);  filtMix_07.gain(1, 0.90);  filtMix_07.gain(2, 0.0);  filtMix_07.gain(3, 0.0);
      filtMix_08.gain(0, 0.0);  filtMix_08.gain(1, 0.90);  filtMix_08.gain(2, 0.0);  filtMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("5 - BANDPASS");
      fltSwitch = 5;
    }
    else
if ((pot > 838) && (pot < 961) && (fltSwitch != 6))  {                                                        //  898.00
      filtMix_01.gain(0, 0.0);  filtMix_01.gain(1, 0.45);  filtMix_01.gain(2, 0.45);  filtMix_01.gain(3, 0.0);
      filtMix_02.gain(0, 0.0);  filtMix_02.gain(1, 0.45);  filtMix_02.gain(2, 0.45);  filtMix_02.gain(3, 0.0);
      filtMix_03.gain(0, 0.0);  filtMix_03.gain(1, 0.45);  filtMix_03.gain(2, 0.45);  filtMix_03.gain(3, 0.0);
      filtMix_04.gain(0, 0.0);  filtMix_04.gain(1, 0.45);  filtMix_04.gain(2, 0.45);  filtMix_04.gain(3, 0.0);
      filtMix_05.gain(0, 0.0);  filtMix_05.gain(1, 0.45);  filtMix_05.gain(2, 0.45);  filtMix_05.gain(3, 0.0);
      filtMix_06.gain(0, 0.0);  filtMix_06.gain(1, 0.45);  filtMix_06.gain(2, 0.45);  filtMix_06.gain(3, 0.0);
      filtMix_07.gain(0, 0.0);  filtMix_07.gain(1, 0.45);  filtMix_07.gain(2, 0.45);  filtMix_07.gain(3, 0.0);
      filtMix_08.gain(0, 0.0);  filtMix_08.gain(1, 0.45);  filtMix_08.gain(2, 0.45);  filtMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("6 - BANDPASS + HIGHPASS");
      fltSwitch = 6;
    }
    else  {
if ((pot > 960) && (fltSwitch != 7))  {                                                                       //  1023.00
      filtMix_01.gain(0, 0.0);  filtMix_01.gain(1, 0.0);  filtMix_01.gain(2, 0.90);  filtMix_01.gain(3, 0.0);
      filtMix_02.gain(0, 0.0);  filtMix_02.gain(1, 0.0);  filtMix_02.gain(2, 0.90);  filtMix_02.gain(3, 0.0);
      filtMix_03.gain(0, 0.0);  filtMix_03.gain(1, 0.0);  filtMix_03.gain(2, 0.90);  filtMix_03.gain(3, 0.0);
      filtMix_04.gain(0, 0.0);  filtMix_04.gain(1, 0.0);  filtMix_04.gain(2, 0.90);  filtMix_04.gain(3, 0.0);
      filtMix_05.gain(0, 0.0);  filtMix_05.gain(1, 0.0);  filtMix_05.gain(2, 0.90);  filtMix_05.gain(3, 0.0);
      filtMix_06.gain(0, 0.0);  filtMix_06.gain(1, 0.0);  filtMix_06.gain(2, 0.90);  filtMix_06.gain(3, 0.0);
      filtMix_07.gain(0, 0.0);  filtMix_07.gain(1, 0.0);  filtMix_07.gain(2, 0.90);  filtMix_07.gain(3, 0.0);
      filtMix_08.gain(0, 0.0);  filtMix_08.gain(1, 0.0);  filtMix_08.gain(2, 0.90);  filtMix_08.gain(3, 0.0);
      if (dataDisplay < 3) Serial.println("7 - HIGHPASS");
      fltSwitch = 7;
    }
  }
  }

  MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-
// =============================================================================================== FILTER ENVELOPE end

//_________________________________________________________________________________________________________________________________
  if ((butt == 8) && (buttonTog == 0))  {                                                      // Button 8           Velocity toggle
    buttonTog = 1;
    if (velBypass == 0)  {
      velBypass = 1;
      if (dataDisplay < 3) Serial.println("Velocity control is off and set at fixed level");
    }
    else  {
      velBypass = 0;
      if (dataDisplay < 3) Serial.println("Velocity control from keyboard is on");
    }
  }

 MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
  if ((butt == 4) && (buttonTog == 0))  {                                                      // Button 4                 MONO/POLY
    buttonTog = 1;
    if (monoPoly == 0)  {
      monoPoly = 1;
      if (dataDisplay < 3) Serial.println("Polyphonic");
    }
    else  {
      monoPoly = 0;
      if (dataDisplay < 3) Serial.println("Monophonic");
    }
  }

 MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

//_________________________________________________________________________________________________________________________________
  if ((butt == 9) && (buttonTog == 0))  {                                                      // Button 9                   Display
    buttonTog = 1;
    if (dataDisplay == 4) Serial.println("0 - Button controls only");
    if (dataDisplay == 0) Serial.println("1 - MIDI data");
    if (dataDisplay == 1) Serial.println("2 - CPU loads and Memory");
    if (dataDisplay == 2) Serial.println("3 - Button pin test data");
    if (dataDisplay == 3) {  Serial.println("4 - Timing of loop");  oldTicker = micros();  }
    dataDisplay = dataDisplay + 1;      if (dataDisplay == 5) dataDisplay = 0;
  }

 MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-

// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv FLANGE CONTROL start
  // If the passthru button is pushed
  // turn the flange effect on
  // filter index and then switch the effect to passthru

  if ((butt == 7) && (flangeTog == 0) && (buttonTog == 0))  {                                  // Button 7             Flange toggle
    buttonTog = 1;
    L_flange.voices(s_idx_mod,s_depth_mod,(s_freq_mod * 1.1));
    R_flange.voices(s_idx_mod,s_depth_mod,s_freq_mod);
if (dataDisplay < 3) {
    Serial.println("Flange effect on");
    Serial.print("s_idx   = ");   Serial.println(s_idx_mod);
    Serial.print("s_depth = "); Serial.println(s_depth_mod);
    Serial.print("s_freq  = ");  Serial.println(s_freq_mod);
}
    flangeTog = 1;
  }
  else
  if ((butt == 7) && (flangeTog == 1) && (buttonTog == 0))  {
    buttonTog = 1;
    L_flange.voices(FLANGE_DELAY_PASSTHRU,0,0);
    R_flange.voices(FLANGE_DELAY_PASSTHRU,0,0);
if (dataDisplay < 3) {
    Serial.println("Flange effect off");
    Serial.println("");
}
    flangeTog = 0;
  }

  MIDI.read();  //**************************

if (flangeTog == 1) {
    if (s_depth_mod != old_s_depth) {
    L_flange.voices(s_idx_mod,s_depth_mod,(s_freq_mod * 1.1));
    R_flange.voices(s_idx_mod,s_depth_mod,(s_freq_mod * 0.9));
    old_s_depth = s_depth_mod;
    }

  MIDI.read();  //**************************

    if (s_freq_mod != old_s_freq) {
    L_flange.voices(s_idx_mod,s_depth_mod,(s_freq_mod * 1.1));
    R_flange.voices(s_idx_mod,s_depth_mod,(s_freq_mod * 0.9));
    old_s_freq = s_freq_mod;
    }

  MIDI.read();  //**************************

//_________________________________________________________________________________________________________________________________
//  DISPLAY DURATION FOR LOOP COMPLETION 
if (dataDisplay == 4)  {
//Ticker = millis();
Ticker = micros();
difTicker = Ticker - oldTicker;
Serial.print(" Loop microSec - ");  Serial.print(difTicker);
if (maxMicro <= difTicker) maxMicro = difTicker;
Serial.print(" Max - ");  Serial.print(maxMicro);

Serial.print("   milliSec - ");  Serial.print(difTicker / 1000);
if (maxMilli <= difTicker / 1000) maxMilli = difTicker / 1000;
Serial.print(" Max - ");  Serial.print(maxMilli);

Serial.print("   Seconds - ");  Serial.print(difTicker / 1000000);
if (maxSecond <= difTicker / 1000000) maxSecond = difTicker / 1000000;
Serial.print(" Max - ");  Serial.print(maxSecond);

Serial.print("      Time since boot - ");  Serial.println(Ticker);
oldTicker = Ticker;

 MIDI.read();  // <-<-<-<-<-<-<-<-<-<-<-<-<-
}
}
//_________________________________________________________________________________________________________________________________
//_________________________________________________________________________________________________________________________________
//digitalWrite(S0, HIGH);  digitalWrite(S1, LOW);  digitalWrite(S2, HIGH); // POT  logic Y5 on 15 LOG POT TEST
//  for (int i=0; i <= 4; i++) potLog = (float)analogRead(muxPot_15);

//  clickDelay = ((potLog * (potLog + 1)) >> 10);// / 5.11;  // LOG correction
 
//    env_01.delay(clickDelay); env_02.delay(clickDelay); env_03.delay(clickDelay); env_04.delay(clickDelay);
//    env_05.delay(clickDelay); env_06.delay(clickDelay); env_07.delay(clickDelay); env_08.delay(clickDelay);



//Serial.print("Test pot, MUX 15 Y5 - ");  Serial.print(clickDelay);  Serial.print("   pot - ");  Serial.println(potLog);                        // Reads GOOD

}

//_________________________________________________________________________________________________________________________________
//_________________________________________________________________________________________________________________________________
//void testLogPot()  {                                                                    // LOG POT Test call
//digitalWrite(S0, HIGH);  digitalWrite(S1, HIGH);  digitalWrite(S2, HIGH); // POT D4  logic Y7 on 14 LOG POT TEST
//  for (int i=0; i <= 4; i++) pot = ((float)analogRead(muxPot_14) / 990.0) - 0.02;

//Serial.print("Test LOG pot 14, MUX C Y7 - ");  Serial.println(pot);                        // Reads GOOD
//}

/*
TO DO LIST
Add control button hardware for Pitch bend PBOct variable toggling between 1 and 2 octave bends
 */
 
Last edited:
Update with more info

First off the Midi library I am using is version 3.2 and not 2.4 as I said before (is there even a 2.4 out there?).

Also, my apologies for putting up the current full code listing but simpler versions haven't had the same patterns of problems. It seems that as soon as I put the noise modules in here the issues trebled. It reminds me of memory leak effects from back in the days of 386DX computers, DOS and Pascal or assembly coding. Then again it is the nostalgia for that kind of environment that got me into these Arduino and Teensy things in the first place.

A few updated details.

On the "white noise", "pink noise", "Sine_FM", "PWM" and Multiply objects playing up to 4 to 5 notes simultaneously works nicely as expected. Any more than this however first results in an intermittent response in that it will then only respond to every second note played. Play enough notes at the same time and often the object will become completely silent until reboot.

Tried to test all failures so as to describe them in better detail this morning.
PWM plays up to and including 5 notes and fails until reboot on 6 or more
Sine_FM goes to 4 notes and fails with more.
Multiply plays 3, does nothing more until 6 and then goes into failure state.
Noise plays 5 and fails at 6.
There are two failure states. First is when the notes randomize, no consistent failure pattern from test to test. The second is a full fail at around 7 to 8 notes when the object goes silent.

The 3 "main oscillators" using the core waveform object work correctly in all situations however even though these are triggered within the same routines.

Another issue seems to be in play in the noise objects. When notes are played with noise mixed in the noise will scale up gradually about half an octave. (It's actually a pretty cool effect but it would be nice to be able to control, choose or expand on it.) I haven't spent much time checking this one out but it is dependent on the state of the noise envelope object and the ramping goes at different rates on the pink and white noise objects. I will look into the conditions effecting this more when I get a chance and come straight back here and vent (or pass on how to use this interesting phenomenon if I master it). EDIT: It IS dependent on the envelope I have used for the noise objects and it effects the noise and anything I send that noise into (PWM, Sine_FM etc.). They all ramp in frequency together on the attack of the envelope Knowing this I may be able to use it.

The audio card failure I mentioned has turned out not to be a hardware failure. It happened again so I swapped the original, newer audio card back into the system and the issue went away again for the time being.

At this rate I may have to give up on the noise source all together. It seems to have introduced a lot of new odd problems. Except of course for the note failure problem on the PWM and SineFM. They have been there for a while and I put them off thinking they would just take an hour or two of sorting out a coding mistake or two. Famous last words I guess.
 
Last edited:
Have you tried printing the max memory and CPU usage info?

With so many objects and nearly 300 audio connections between them, it’s possible you’re simply running out of resources.
 
Have you tried printing the max memory and CPU usage info?

With so many objects and nearly 300 audio connections between them, it’s possible you’re simply running out of resources.

Hey Paul, hows the marathon treating you? Hope you are getting some holiday time.

Yep. I put that in the cluster of info at the top of the code...

CPU consumption sits roughly at a stable 50% or less in this setup.
Audio MEMORY peaks at 192, idles at 168
...derived from the simple code at the top of the main program loop.

Compiles to 10% program storage space
Compiles to 66% dynamic memory
...derived of course from the compile in the Arduino IDE

I suppose that the next thing to try would be temporarily commenting out as many objects as I can to pull back some resources and try that one out. It would be a shame if that were the issue. I had only just begun.

Is it possible to fairly easily daisy chain two or three Teensys together on the I2C with the audio output on the final one? I know there are clock issues but maybe there is something I am missing. I would have thought that sending from one Teensy to another would make it possible to sync it with the sound output clocks. I thought of doing this when I tried memory on the audio board and lost a huge amount of clock to processing delay on it (it lived most of the time at 95%CPU when it wasn't crashing). I figured that since I was just using it for a reverb effect for now I could live with the software version of the delay. I was thinking that I could put all multi channel generation on one Teensy, mix it and send the audio to another for common processing and possibly a third Teensy for more. A soon as I looked into it it seemed not viable. Tried using two audio cards with a line out to line in chain but sound quality suffered with the conversions.
 
Last edited:
Just noting: "The IDE is currently version 1.8.1. on my system.", but not catching a note on TeensyDuino version?

There may be fixes made if not using the latest builds of TD 1.40 - also updating to IDE 1.8.5 would be the easiest to test and fix against as well.
 
Just noting: "The IDE is currently version 1.8.1. on my system.", but not catching a note on TeensyDuino version?

There may be fixes made if not using the latest builds of TD 1.40 - also updating to IDE 1.8.5 would be the easiest to test and fix against as well.

It would be the previous version of TeensyDuino before the recently released (1 before 1.40 at the moment) and the latest Audio library downloaded as a zip from Github. I've been updating the lib as soon as it comes out rather than full IDEs to keep track of the bug fix listing. I'll update this weekend.
 
Is it possible to fairly easily daisy chain two or three Teensys together on the I2C with the audio output on the final one?
That would need to be over I2S, not I2C. I’m not much of an audio guy, but find the idea interesting from a EE and programming view.

I’m thinking the last Teensy in the chain (the one with Audio Shield) would provide master timing. It’s I2S interface would be in master mode -- the Audio Shield needs to be a slave and requires an MCLK input. The master Teensy would back-propagate RX_BCLK and RX_FS to the slave Teensys’ BCLK and FS inputs. I2S data would flow forward through slave chain to master.

All slave Teensys would be frequency locked to the masters Teensy. At least on average, not sure if jitter or latency would be a problem.
 
Last edited:
Yes, to chain them together one would need to be in I2S master mode and the others in I2S slave mode. I2S slave does not need MCLK, so you only need to connect BCLK, LRCLK and data.

On the resource usage, you said "sits roughly at a stable 50% or less in this setup". That sounds like you're printing the live reading.

The library also tracks the max and gives you a function to reset it. If you're occasionally going over 100% CPU usage, the Arduino sketch may not be able to detect it, since another run happens immediately due to the pending software interrupt. Try printing the max as tracked by the library, rather than visually looking at what the instantaneous does. The library provide worst-case max tracking for exactly this reason.

https://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html
 
It's also quite possible there's an unknown bug lurking somewhere in one of those many objects, perhaps something that only happens when you combine and use so many at once? If the max CPU and memory really are staying under 100 and the number of blocks you allocated, maybe try to come up with a version I can run here without extra hardware beyond the audio shield. There's not much I can do if I can't reproduce the problem here.
 
Yes, to chain them together one would need to be in I2S master mode and the others in I2S slave mode. I2S slave does not need MCLK, so you only need to connect BCLK, LRCLK and data.

On the resource usage, you said "sits roughly at a stable 50% or less in this setup". That sounds like you're printing the live reading.

The library also tracks the max and gives you a function to reset it. If you're occasionally going over 100% CPU usage, the Arduino sketch may not be able to detect it, since another run happens immediately due to the pending software interrupt. Try printing the max as tracked by the library, rather than visually looking at what the instantaneous does. The library provide worst-case max tracking for exactly this reason.

https://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html

I gotta get less sloppy with my postings here. Yeah, I should have said that the peak was around 50%. It was Idling at about 48%. There is about three obvious and simple lines of code at the top of the loop section of code about half way down the listing that I'm pulling those figures from. They have stood up pretty well up until now. A previous version of this system would crash at exactly 100% which gave me faith in the code pulling this check. It isn't like the good old days of DOS on a 386DX when you could build a pretty decent TSR and check the memory map of anything you were running. Most of what is going on in these things is pretty much faith and hope. I wish I had the time I had back then to really hack these things.
 
It's also quite possible there's an unknown bug lurking somewhere in one of those many objects, perhaps something that only happens when you combine and use so many at once? If the max CPU and memory really are staying under 100 and the number of blocks you allocated, maybe try to come up with a version I can run here without extra hardware beyond the audio shield. There's not much I can do if I can't reproduce the problem here.

OK, it was an informative weekend. On the suggestion of Defragster I did an overdue reinstall of the Arduino IDE to version 1.8.5 (from 1.8.1) and put in your latest Teensyduino 1.4. The results were quite an improvement. With a default compile (Faster I think) the volume levels have now stabilized, the Sine_FM is now playing all of the notes with a predictable response from a noise source. (Although it seems to be injecting the noise also on other source settings where it should be getting the signal from the waveform objects alone.) The PWM plays all of the notes but with a noise source it still ramps up in pitch when fed from the noise through an envelope. With attack set to 0 it changes the pitch of the PWM up about a fifth with no ramping but I will look at that harder later. The multiply object still does an intermittent dance with the notes depending now on how the detune is set or sometimes the octave position. The mixer objects inputMix_01 to inputMix_08 an the line-in still don't work at all. (Line in works perfectly with the Tutorial examples.)

Next compile I did with the IDE set to "Fastest + pure code". Now the multiply object works correctly but the amplitude envelope has a very minor bug. If I run a sequencer and feed in a multitracked piece into it the envelope doesn't completely turn off the notes an they play on even after the end of the piece on until reboot. When it is in this state the CPU usage shoots up to 98%.

It all looked to me originally like a good old compiler memory mapping issue and now I am pretty much convinced especially considering the range of problems that it seems to effect. I seem to have reached the code memory limit before the mapping issues kick in and the consistent ways the different compile settings effect the performance all over the beast seem to confirm it (to my dusty and rusty programmers memory anyway).

Hopefully someone out there will think my code has enough in it to try it out for themselves (It's not a bad beginners source IMHO) and might report back if they are getting similar problems.

As far as the number of connections are concerned the problems with the FM and PWM objects have been there for some time before the beast evolved into the fat one it is.

BTW, what is the LTO in the Optimize menu?
 
Nice the update to newest helped - usually it doesn't backslide - when it does it takes somebody running it to notice and point it out. I'm on Windows and do an unzip not install - so I run the newest in parallel to try it leaving the old one undisturbed in case I need to revert while it gets repaired - or to compare against.

...
BTW, what is the LTO in the Optimize menu?

LTO is Link Time Optimization:

Link-time optimization is a type of program optimization performed by a compiler to a program at link time. Link time optimization is relevant in programming languages that compile programs on a file-by-file basis, and then link those files together (such as C and Fortran), rather than all at once (such as Java's "Just in time" (JIT) compilation[citation needed]).
Once all files have been compiled separately into object files, traditionally, a compiler links (merges) the object files into a single file, the executable. However, in the case of the GCC compiler, for example, with Link Time Optimization (LTO) enabled, GCC is able to dump its internal representation (GIMPLE) to disk, so that all the different compilation units that will go to make up a single executable can be optimized as a single module. This expands the scope of inter-procedural optimizations to encompass the whole program (or, rather, everything that is visible at link time). With link-time optimization, the compiler can apply various forms of interprocedural optimization to the whole program, allowing for deeper analysis, more optimization, and ultimately better program performance.

Net effect - it can be really cool - when it doesn't screw something up - if it makes any difference at all.
 
what do you mean??

About LTO? In the Arduino IDE with Teensyduino "Tools" menu under the "Optimize" branch where you can set the compilation options (for what I assume is the compression level of the uploaded code for memory conservation) there are options that I haven't seen before like "Fast", "Fast LTO", "Faster" or "Faster LTO". I was just wondering in passing what LTO referred to.
 
Nice the update to newest helped - usually it doesn't backslide - when it does it takes somebody running it to notice and point it out. I'm on Windows and do an unzip not install - so I run the newest in parallel to try it leaving the old one undisturbed in case I need to revert while it gets repaired - or to compare against.
I wouldn't even have thought of that almost one step upgrade without you hitting me over the head with the obvious. Thanks much for that. It hasn't solved the problem completely but it has at least eased my decaying mind that it isn't necessarily something that I have missed in my coding. I can now stop wasting time going around in circles and get back to other bits of development while looking for new clues.
I have been treating the upgrades the same way as you keeping the last best and complete Arduino install (for my needs) and running parallel installs from the zips while checking for bug fixes and upgrading the Audio lib as soon as it comes. I just hadn't done it for a couple of months on anything but the audio lib. It's still a weird result though. The core problem is kind of still there and has just started to have different random tiny problems in different parts of the system.
The strangest one to me is the failure of one entire bank of mixers. (Designated "inputMix_01", "..02" etc.) I can see one more object being a problem. I can see 1, 2 or 3 in that set failing but just that one on every key channel no matter how I link it up? That's odd. It's a bit of a shame too because I was going to be relying on quite a few of them in the next development stage using them as virtual patch leads between virtual modules controlled by a touch screen graphic. I might have to go back to square one and re-think.

Last night I figured what I would do is go through my code and hard fix all the values, eliminating the external wiring in a setting arrangement that would produce the same failure states without having to build the entire beast. At least then I could have uploaded it to you guys and you could have just run it on a Teensy and audio card combo without having to waste time building the whole thing. One problem though. Every time I changed the code even a little to eliminate a pot the symptom would change to a different settings arrangement in pretty unpredictable ways. It was like trying to heard fifty cats hoping that just one would go through the gate with the rottweiler in it. I'll just have to polish my descriptive skills.

BTW, thanks for the LTO enlightenment.
 
Last edited:
That would need to be over I2S, not I2C. I’m not much of an audio guy, but find the idea interesting from a EE and programming view.

I’m thinking the last Teensy in the chain (the one with Audio Shield) would provide master timing. It’s I2S interface would be in master mode -- the Audio Shield needs to be a slave and requires an MCLK input. The master Teensy would back-propagate RX_BCLK and RX_FS to the slave Teensys’ BCLK and FS inputs. I2S data would flow forward through slave chain to master.

All slave Teensys would be frequency locked to the masters Teensy. At least on average, not sure if jitter or latency would be a problem.

I gotta admit I'm not even a tech trained guy (which explains why I should be watched and corrected).
 
The best cat I ever had was discovered by a rotteiller - a cute kitten abandoned on the edge of the road.

From reading your summary it sounds like it could be:
> memory issue in the core sketch : arrays - overrun or other abuse.
> that the one more object is causing havoc in part of the audio library, because of a bug there

What does it do when compiled 'DEBUG' - that fattens code and minimizes re-org. Won't fix anything - but may change behavior for worse - or better enough to see the direction of the error.

Did a quick scan - a few arrays that seems to be used within bounds as far as I went. Way too many multiplies . . . but I didn't see any pointer use?

How much of the code can be NOP's away and still see the odd behavior? Any frills related to the pot system - rather than set them as fixed - just remove that code to just the base function?

Perhaps add some run time 'ASSERTS' - where some expected value or data can be expected - just wrote this and it seems to function as follows:
Code:
#define rt_ASSERT( X,Y )    ( test_ASSERT( X,__LINE__, Y ) )
void test_ASSERT( uint32_t xx, uint32_t aline, const char *sz ) {
  if (!xx)
  {
    Serial.print( "\n ASSERT Line#:" );
    Serial.print( aline );
    Serial.println( sz );
    delay( 300 );
  }
}

void setup() {
  // put your setup code here, to run once:
  rt_ASSERT( 1, "NO ASSERT" );
  rt_ASSERT( sizeof(bool) == sizeof(int) , "  no bull : ASSERT" );
  rt_ASSERT( 0 , "  ASSERT" );
  rt_ASSERT( !1 , "  I should !not be here" );
  rt_ASSERT( !0 , "  I should not be here" );

}

void loop() {
  // put your main code here, to run repeatedly:
  rt_ASSERT( millis() % 1000 , "  another second!" );
}
 
The best cat I ever had was discovered by a rotteiller - a cute kitten abandoned on the edge of the road.

From reading your summary it sounds like it could be:
> memory issue in the core sketch : arrays - overrun or other abuse.
> that the one more object is causing havoc in part of the audio library, because of a bug there

What does it do when compiled 'DEBUG' - that fattens code and minimizes re-org. Won't fix anything - but may change behavior for worse - or better enough to see the direction of the error.

Did a quick scan - a few arrays that seems to be used within bounds as far as I went. Way too many multiplies . . . but I didn't see any pointer use?

How much of the code can be NOP's away and still see the odd behavior? Any frills related to the pot system - rather than set them as fixed - just remove that code to just the base function?

Perhaps add some run time 'ASSERTS' - where some expected value or data can be expected - just wrote this and it seems to function as follows:
Code:
#define rt_ASSERT( X,Y )    ( test_ASSERT( X,__LINE__, Y ) )
void test_ASSERT( uint32_t xx, uint32_t aline, const char *sz ) {
  if (!xx)
  {
    Serial.print( "\n ASSERT Line#:" );
    Serial.print( aline );
    Serial.println( sz );
    delay( 300 );
  }
}

void setup() {
  // put your setup code here, to run once:
  rt_ASSERT( 1, "NO ASSERT" );
  rt_ASSERT( sizeof(bool) == sizeof(int) , "  no bull : ASSERT" );
  rt_ASSERT( 0 , "  ASSERT" );
  rt_ASSERT( !1 , "  I should !not be here" );
  rt_ASSERT( !0 , "  I should not be here" );

}

void loop() {
  // put your main code here, to run repeatedly:
  rt_ASSERT( millis() % 1000 , "  another second!" );
}

OK. Did a compile this morning in Debug mode and most problems went away except for the failing mixer set (with only a brief assessment) and the lack of signal from the line-in. The discrepancies in the multiply objects seem to have cleared up in this mode very well so that everything that is still giving a workable response is doing it as should be expected. Makes me wonder. Is there any sort of significant penalty in compiling to debug in this system? Does the lack of optimization cost clock cycles for example? If it is only a memory resource issue I doubt that I will need it with the 3.6. I have no doubt that that I will run out of clock long before I fill the program space.

I found it a little strange though that with a compile optimization set to "Fastest + pure code" it was using 13% of program space but in debug it went back to 10%. Just tells me I have to spend some time doing some homework on that part of the system really. I've pretty much just take the Arduino compile for granted up until now.
 
Interesting debug is smaller. Ideally it runs slower not having the compiler 'help' improve things. It doesn't 'add' any debug tidbits - just doesn't overtly shuffle the code expecting it to run more efficiently in any way. As noted - that is not a fix - unless it proved to be a compiler error as it interpreted the code for the purposes of optimization - in which case it should run perfectly, and it does not.

Can't say that pinpoints anything - just that a problem is there and something is trashing something. That behavior may or may not tell you generally where it is failing. It does give you a place to focus - improve, examine, remove or minimize those affected 'failing mixer set'.

If you examined all that code for errors and saw nothing - or pulled it all out - and the problem goes away there and in other compile options that was the 'straw' that broke the camel's back (or just the part that got trashed first) - if not then look at what happened next.

Look at suspect 'failing mixer set' as best you can see them, anything feeding into or out of the 'failing mixer set' - Use the ASSERT() type code to test things you expect/know to be true - especially if they are passed off or used later in the process. If you catch anything too small, too big, or having an unexpected value - you should be able to catch and address that with the ASSERT. If the asserts drive you crazy and the one you want flies by you can add a 3rd PARAM to pass through and have it HALT rather than delay when it gets hit. Or make other changes to the assert code. A failed assert() is either a warning or error about your assumptions.

The code was large and used a lot of stuff - you'll need to narrow it down if not fix it by some process. If you can reduce the complexity for review or running by others - or point to a specific problem area in underlying PJRC code others would be more able to focus time to help.

<edit>: the 'multiply objects' improving may be worth a second look too. They may have been failing and trashing themselves - now they are only trashing the 'mixer set'
 
Last edited:
If you ever do create a program the demonstrates the mixer issue, I would really like to look into it. The mixer it fairly simple code. I really don’t understand how it could have those sorts of issues.

The debug option is actually -Og to gcc. It’s a relatively new gcc feature, where most optimization is still done, but certain optimizations which would interfere with debug are disabled. Turns out it often works out almost as well as the fastest. You can usually expect fastest, which is -O3 to gcc, to produce larger code, because it turns on optimizations for speed which are normally not considered due to larger code size.
 
Status
Not open for further replies.
Back
Top