Synthetech
Active member
Well after a few weeks of learning to program through trial and error and lots of research, I have a working MIDI controlled synthesizer
made with a Teensy 3.5 and the Audio Library.
I present the "Seenthysizer"!
(v1.0)
https://www.youtube.com/watch?v=fVdPEy9sTUk
It's a start.. most definately not finished!
I will post code after some cleaning up and sorting a few bugs.
If my 3.5 can do all this with only 13% of it's memory used so far, I can only imagine what else it can do when it is at say.. 50%!
/Blaine
EDIT 2-21-17
Here is a version of the code that seems to work well enough to share.
I have only used it on a Teensy 3.5. It may work fine on 3.2 or earlier, I am not certain since I don't have those boards to test it with.
If you have earlier boards than mine to try on, please post your results.
The controller (Ctrlr) software is found here-
https://drive.google.com/file/d/0B_IDH8cQH_eNSDhXUkxzcEJTZDQ/view?usp=sharing
FIRST load up the code and/or power up the Teensy with code already on it.
THEN open up the Ctrlr app so it can locate the Teensy MIDI interface.
If you ever restart the Teensy, you MUST RESTART THE CONTROLLER.. every time.
If you have sluggish controls, try closing the Ctrlr App, restart Teensy, open Ctrlr back up.
Here you go!
PS- There were some erroneous statements of the specs of 3.5 in my vid.. it's been a long few weeks! Corrections were made in the description and a mention of where to get the specs.
I simply just dont have time to redo the entire vid again.
made with a Teensy 3.5 and the Audio Library.
I present the "Seenthysizer"!
(v1.0)
https://www.youtube.com/watch?v=fVdPEy9sTUk
It's a start.. most definately not finished!
I will post code after some cleaning up and sorting a few bugs.
If my 3.5 can do all this with only 13% of it's memory used so far, I can only imagine what else it can do when it is at say.. 50%!
/Blaine
EDIT 2-21-17
Here is a version of the code that seems to work well enough to share.
I have only used it on a Teensy 3.5. It may work fine on 3.2 or earlier, I am not certain since I don't have those boards to test it with.
If you have earlier boards than mine to try on, please post your results.
The controller (Ctrlr) software is found here-
https://drive.google.com/file/d/0B_IDH8cQH_eNSDhXUkxzcEJTZDQ/view?usp=sharing
FIRST load up the code and/or power up the Teensy with code already on it.
THEN open up the Ctrlr app so it can locate the Teensy MIDI interface.
If you ever restart the Teensy, you MUST RESTART THE CONTROLLER.. every time.
If you have sluggish controls, try closing the Ctrlr App, restart Teensy, open Ctrlr back up.
Here you go!
HTML:
/*Project Seenthysizer v2.8
*a modified Teensy 3.2+ Audio Proect originally written by otemrellik
*this MIDI controlled version written by:
*Blaine Perkins
*
*Includes support for Teensy Audio Board, USB Audio and USB MIDI
*/
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce.h>
// GUItool: begin automatically generated code
AudioSynthWaveformDc lfoenvelope; //xy=1526.1395568847656,1195.7141723632812
AudioSynthWaveform lfo; //xy=1614.1395568847656,1401.7141723632812
AudioMixer4 mixer1; //xy=1657.1395568847656,1256.7141723632812
AudioAnalyzePeak peak1; //xy=1886.1395568847656,1119.7141723632812
AudioSynthWaveform voice8b; //xy=2122.1395568847656,2170.7141723632812
AudioSynthNoiseWhite voice8n; //xy=2122.1395568847656,2205.7141723632812
AudioSynthWaveform voice8a; //xy=2124.1395568847656,2132.7141723632812
AudioSynthWaveform voice4a; //xy=2143.1395568847656,1154.7141723632812
AudioSynthWaveform voice4b; //xy=2144.1395568847656,1192.7141723632812
AudioSynthNoiseWhite voice4n; //xy=2144.1395568847656,1227.7141723632812
AudioSynthWaveform voice5b; //xy=2145.1395568847656,1448.7141723632812
AudioSynthNoiseWhite voice5n; //xy=2145.1395568847656,1483.7141723632812
AudioSynthWaveform voice5a; //xy=2150.1395568847656,1405.7141723632812
AudioSynthWaveform voice7b; //xy=2154.1395568847656,1939.7141723632812
AudioSynthNoiseWhite voice7n; //xy=2154.1395568847656,1974.7141723632812
AudioSynthWaveform voice6b; //xy=2157.1395568847656,1702.7141723632812
AudioSynthNoiseWhite voice6n; //xy=2157.1395568847656,1737.7141723632812
AudioSynthWaveform voice6a; //xy=2159.1395568847656,1664.7141723632812
AudioSynthWaveform voice7a; //xy=2159.1395568847656,1896.7141723632812
AudioSynthWaveform voice3b; //xy=2165.1395568847656,944.7141723632812
AudioSynthNoiseWhite voice3n; //xy=2165.1395568847656,979.7141723632812
AudioSynthWaveform voice3a; //xy=2170.1395568847656,901.7141723632812
AudioSynthWaveform voice1b; //xy=2195.1395568847656,478.71417236328125
AudioSynthNoiseWhite voice1n; //xy=2198.1395568847656,522.7141723632812
AudioSynthWaveform voice2b; //xy=2198.1395568847656,712.7141723632812
AudioSynthNoiseWhite voice2n; //xy=2198.1395568847656,747.7141723632812
AudioSynthWaveform voice1a; //xy=2200.1395568847656,435.71417236328125
AudioSynthWaveform voice2a; //xy=2200.1395568847656,674.7141723632812
AudioSynthWaveformDc voice8filterenv; //xy=2250.1395568847656,2316.7141723632812
AudioSynthWaveformDc voice8env; //xy=2264.1395568847656,2255.7141723632812
AudioMixer4 voice8mix; //xy=2267.1395568847656,2190.7141723632812
AudioSynthWaveformDc voice4filterenv; //xy=2272.1395568847656,1338.7141723632812
AudioSynthWaveformDc voice5filterenv; //xy=2273.1395568847656,1594.7141723632812
AudioSynthWaveformDc voice7filterenv; //xy=2282.1395568847656,2085.7141723632812
AudioSynthWaveformDc voice4env; //xy=2286.1395568847656,1277.7141723632812
AudioSynthWaveformDc voice6filterenv; //xy=2285.1395568847656,1848.7141723632812
AudioSynthWaveformDc voice5env; //xy=2287.1395568847656,1533.7141723632812
AudioMixer4 voice4mix; //xy=2289.1395568847656,1212.7141723632812
AudioMixer4 voice5mix; //xy=2290.1395568847656,1468.7141723632812
AudioSynthWaveformDc voice3filterenv; //xy=2293.1395568847656,1090.7141723632812
AudioSynthWaveformDc voice7env; //xy=2296.1395568847656,2024.7141723632812
AudioSynthWaveformDc voice6env; //xy=2299.1395568847656,1787.7141723632812
AudioMixer4 voice7mix; //xy=2299.1395568847656,1959.7141723632812
AudioMixer4 voice6mix; //xy=2302.1395568847656,1722.7141723632812
AudioSynthWaveformDc voice3env; //xy=2307.1395568847656,1029.7141723632812
AudioMixer4 voice3mix; //xy=2310.1395568847656,964.7141723632812
AudioSynthWaveformDc voice1filterenv; //xy=2324.1395568847656,614.7141723632812
AudioSynthWaveformDc voice2filterenv; //xy=2326.1395568847656,858.7141723632812
AudioMixer4 voice1mix; //xy=2340.1395568847656,498.71417236328125
AudioSynthWaveformDc voice2env; //xy=2340.1395568847656,797.7141723632812
AudioSynthWaveformDc voice1env; //xy=2341.1395568847656,563.7141723632812
AudioMixer4 voice2mix; //xy=2343.1395568847656,732.7141723632812
AudioEffectMultiply voice8multiply; //xy=2431.1395568847656,2228.7141723632812
AudioMixer4 voice8filtermodmixer; //xy=2441.1395568847656,2344.7141723632812
AudioEffectMultiply voice4multiply; //xy=2453.1395568847656,1250.7141723632812
AudioEffectMultiply voice5multiply; //xy=2454.1395568847656,1506.7141723632812
AudioMixer4 voice4filtermodmixer; //xy=2463.1395568847656,1366.7141723632812
AudioEffectMultiply voice7multiply; //xy=2463.1395568847656,1997.7141723632812
AudioEffectMultiply voice6multiply; //xy=2466.1395568847656,1760.7141723632812
AudioMixer4 voice5filtermodmixer; //xy=2471.1395568847656,1616.7141723632812
AudioEffectMultiply voice3multiply; //xy=2474.1395568847656,1002.7141723632812
AudioMixer4 voice6filtermodmixer; //xy=2476.1395568847656,1876.7141723632812
AudioMixer4 voice7filtermodmixer; //xy=2480.1395568847656,2107.7141723632812
AudioMixer4 voice3filtermodmixer; //xy=2491.1395568847656,1112.7141723632812
AudioEffectMultiply voice1multiply; //xy=2504.1395568847656,536.7141723632812
AudioEffectMultiply voice2multiply; //xy=2507.1395568847656,770.7141723632812
AudioMixer4 voice2filtermodmixer; //xy=2517.1395568847656,886.7141723632812
AudioMixer4 voice1filtermodmixer; //xy=2521.1395568847656,646.7141723632812
AudioFilterStateVariable voice8filter; //xy=2614.1395568847656,2251.7141723632812
AudioFilterStateVariable voice5filter; //xy=2634.1395568847656,1550.7141723632812
AudioFilterStateVariable voice4filter; //xy=2636.1395568847656,1273.7141723632812
AudioFilterStateVariable voice7filter; //xy=2643.1395568847656,2041.7141723632812
AudioFilterStateVariable voice6filter; //xy=2649.1395568847656,1783.7141723632812
AudioFilterStateVariable voice3filter; //xy=2654.1395568847656,1046.7141723632812
AudioFilterStateVariable voice2filter; //xy=2690.1395568847656,793.7141723632812
AudioFilterStateVariable voice1filter; //xy=2707.1395568847656,588.7141723632812
AudioMixer4 last4premix; //xy=3114.1395568847656,1523.7141723632812
AudioMixer4 first4premix; //xy=3115.1395568847656,1439.7141723632812
AudioMixer4 mainOutMixer; //xy=3519.4252014160156,1509.5711517333984
AudioFilterStateVariable delayFilter; //xy=3564.1395568847656,1633.7141723632812
AudioEffectDelay delay1; //xy=3693.1395568847656,1828.7141723632812
AudioOutputUSB usb1; //xy=3860.2857666015625,1450.28564453125
AudioOutputI2S i2s1; //xy=3861.1395568847656,1514.7141723632812
AudioConnection patchCord1(lfoenvelope, 0, mixer1, 0);
AudioConnection patchCord2(lfo, 0, voice1filtermodmixer, 1);
AudioConnection patchCord3(lfo, 0, voice2filtermodmixer, 1);
AudioConnection patchCord4(lfo, 0, voice3filtermodmixer, 1);
AudioConnection patchCord5(lfo, 0, voice4filtermodmixer, 1);
AudioConnection patchCord6(lfo, 0, voice5filtermodmixer, 1);
AudioConnection patchCord7(lfo, 0, voice6filtermodmixer, 1);
AudioConnection patchCord8(lfo, 0, voice7filtermodmixer, 1);
AudioConnection patchCord9(lfo, 0, voice8filtermodmixer, 1);
AudioConnection patchCord10(lfo, 0, mixer1, 1);
AudioConnection patchCord11(mixer1, peak1);
AudioConnection patchCord12(voice8b, 0, voice8mix, 1);
AudioConnection patchCord13(voice8n, 0, voice8mix, 2);
AudioConnection patchCord14(voice8a, 0, voice8mix, 0);
AudioConnection patchCord15(voice4a, 0, voice4mix, 0);
AudioConnection patchCord16(voice4b, 0, voice4mix, 1);
AudioConnection patchCord17(voice4n, 0, voice4mix, 2);
AudioConnection patchCord18(voice5b, 0, voice5mix, 1);
AudioConnection patchCord19(voice5n, 0, voice5mix, 2);
AudioConnection patchCord20(voice5a, 0, voice5mix, 0);
AudioConnection patchCord21(voice7b, 0, voice7mix, 1);
AudioConnection patchCord22(voice7n, 0, voice7mix, 2);
AudioConnection patchCord23(voice6b, 0, voice6mix, 1);
AudioConnection patchCord24(voice6n, 0, voice6mix, 2);
AudioConnection patchCord25(voice6a, 0, voice6mix, 0);
AudioConnection patchCord26(voice7a, 0, voice7mix, 0);
AudioConnection patchCord27(voice3b, 0, voice3mix, 1);
AudioConnection patchCord28(voice3n, 0, voice3mix, 2);
AudioConnection patchCord29(voice3a, 0, voice3mix, 0);
AudioConnection patchCord30(voice1b, 0, voice1mix, 1);
AudioConnection patchCord31(voice1n, 0, voice1mix, 2);
AudioConnection patchCord32(voice2b, 0, voice2mix, 1);
AudioConnection patchCord33(voice2n, 0, voice2mix, 3);
AudioConnection patchCord34(voice1a, 0, voice1mix, 0);
AudioConnection patchCord35(voice2a, 0, voice2mix, 0);
AudioConnection patchCord36(voice8filterenv, 0, voice8filtermodmixer, 0);
AudioConnection patchCord37(voice8env, 0, voice8multiply, 1);
AudioConnection patchCord38(voice8mix, 0, voice8multiply, 0);
AudioConnection patchCord39(voice4filterenv, 0, voice4filtermodmixer, 0);
AudioConnection patchCord40(voice5filterenv, 0, voice5filtermodmixer, 0);
AudioConnection patchCord41(voice7filterenv, 0, voice7filtermodmixer, 0);
AudioConnection patchCord42(voice4env, 0, voice4multiply, 1);
AudioConnection patchCord43(voice6filterenv, 0, voice6filtermodmixer, 0);
AudioConnection patchCord44(voice5env, 0, voice5multiply, 1);
AudioConnection patchCord45(voice4mix, 0, voice4multiply, 0);
AudioConnection patchCord46(voice5mix, 0, voice5multiply, 0);
AudioConnection patchCord47(voice3filterenv, 0, voice3filtermodmixer, 0);
AudioConnection patchCord48(voice7env, 0, voice7multiply, 1);
AudioConnection patchCord49(voice6env, 0, voice6multiply, 1);
AudioConnection patchCord50(voice7mix, 0, voice7multiply, 0);
AudioConnection patchCord51(voice6mix, 0, voice6multiply, 0);
AudioConnection patchCord52(voice3env, 0, voice3multiply, 1);
AudioConnection patchCord53(voice3mix, 0, voice3multiply, 0);
AudioConnection patchCord54(voice1filterenv, 0, voice1filtermodmixer, 0);
AudioConnection patchCord55(voice2filterenv, 0, voice2filtermodmixer, 0);
AudioConnection patchCord56(voice1mix, 0, voice1multiply, 0);
AudioConnection patchCord57(voice2env, 0, voice2multiply, 1);
AudioConnection patchCord58(voice1env, 0, voice1multiply, 1);
AudioConnection patchCord59(voice2mix, 0, voice2multiply, 0);
AudioConnection patchCord60(voice8multiply, 0, voice8filter, 0);
AudioConnection patchCord61(voice8filtermodmixer, 0, voice8filter, 1);
AudioConnection patchCord62(voice4multiply, 0, voice4filter, 0);
AudioConnection patchCord63(voice5multiply, 0, voice5filter, 0);
AudioConnection patchCord64(voice4filtermodmixer, 0, voice4filter, 1);
AudioConnection patchCord65(voice7multiply, 0, voice7filter, 0);
AudioConnection patchCord66(voice6multiply, 0, voice6filter, 0);
AudioConnection patchCord67(voice5filtermodmixer, 0, voice5filter, 1);
AudioConnection patchCord68(voice3multiply, 0, voice3filter, 0);
AudioConnection patchCord69(voice6filtermodmixer, 0, voice6filter, 1);
AudioConnection patchCord70(voice7filtermodmixer, 0, voice7filter, 1);
AudioConnection patchCord71(voice3filtermodmixer, 0, voice3filter, 1);
AudioConnection patchCord72(voice1multiply, 0, voice1filter, 0);
AudioConnection patchCord73(voice2multiply, 0, voice2filter, 0);
AudioConnection patchCord74(voice2filtermodmixer, 0, voice2filter, 1);
AudioConnection patchCord75(voice1filtermodmixer, 0, voice1filter, 1);
AudioConnection patchCord76(voice8filter, 0, last4premix, 3);
AudioConnection patchCord77(voice5filter, 0, last4premix, 0);
AudioConnection patchCord78(voice4filter, 0, first4premix, 3);
AudioConnection patchCord79(voice7filter, 0, last4premix, 2);
AudioConnection patchCord80(voice6filter, 0, last4premix, 1);
AudioConnection patchCord81(voice3filter, 0, first4premix, 2);
AudioConnection patchCord82(voice2filter, 0, first4premix, 1);
AudioConnection patchCord83(voice1filter, 0, first4premix, 0);
AudioConnection patchCord84(last4premix, 0, mainOutMixer, 1);
AudioConnection patchCord85(first4premix, 0, mainOutMixer, 0);
AudioConnection patchCord86(mainOutMixer, 0, i2s1, 0);
AudioConnection patchCord87(mainOutMixer, 0, i2s1, 1);
AudioConnection patchCord88(mainOutMixer, delay1);
AudioConnection patchCord89(mainOutMixer, 0, usb1, 1);
AudioConnection patchCord90(mainOutMixer, 0, usb1, 0);
AudioConnection patchCord91(delayFilter, 0, mainOutMixer, 3);
AudioConnection patchCord92(delay1, 0, delayFilter, 0);
AudioControlSGTL5000 sgtl5000_1; //xy=3598.1395568847656,1283.7141723632812
// GUItool: end automatically generated code
Bounce button0 = Bounce(0, 15);
//a table to store CC values coming in from the usbMIDI interface
//later any value can be recalled for each parameter
float CCvalues[128];
float prevCCvalues[128];
// array for the notes to be assigned to one of eight voices
int voice[8];
int noteFreq[8];
//vars for the state machine cases
const int noteOnWait = 0;
const int ATTACK = 1;
const int ATTACKwait = 2;
const int DECAY = 3;
const int SUSTAIN = 4;
const int RELEASE1 = 5;
//beginning cases for each voice state machines
int state0a = noteOnWait;
int state0b = noteOnWait;
int state0c = noteOnWait;
int state0d = noteOnWait;
int state0e = noteOnWait;
int state0f = noteOnWait;
int state0g = noteOnWait;
int state0h = noteOnWait;
int state0i = noteOnWait;
int state0j = noteOnWait;
int state0k = noteOnWait;
int state0l = noteOnWait;
int state0m = noteOnWait;
int state0n = noteOnWait;
int state0o = noteOnWait;
int state0p = noteOnWait;
//ADSR timing elements
unsigned long int attackMillisA[8];
unsigned long int attackMillisF[8];
//used to track how many voices are active
//when limit is reached, msg prints Voice Limit Exceeded!
int noteCount = 0;
//some of this from previous code may not be in use
float tempPulseWidth;
float tempPeak;
float tempRMS;
//synth
float mainVolume;
//not used at this time
//int tempLineOutLevel;
float vcoOneLevel;
float vcoTwoLevel;
float deTune;
int waveShapeOneIndex;
int waveShapeTwoIndex;
int lfoWaveShapeIndex;
short waveShapes[4] = {
WAVEFORM_SINE,
WAVEFORM_SAWTOOTH,
WAVEFORM_SQUARE,
WAVEFORM_PULSE,
};
bool voiceBPulse;
float tempDetuneMod;
float deTuneLfo;
//LFO WaveShapes
short lfoWaveShapes[5] = {
WAVEFORM_SINE,
WAVEFORM_SAWTOOTH,
WAVEFORM_SAWTOOTH_REVERSE,
WAVEFORM_SQUARE,
WAVEFORM_SAMPLE_HOLD,
};
//ADSR
int attackTime;
int decayTime;
float sustainLevel;
int releaseTime;
//Filter ADSR
int attackTimeFilter;
int decayTimeFilter;
float sustainLevelFilter;
int releaseTimeFilter;
//LFO ADSR -- not used at this time
// int attackTimeLFO;
// int decayTimeLFO;
// float sustainLevelLFO;
// int releaseTimeLFO;
//MIDI routines
//triggered when usb port has data
void OnControlChange (byte Channel, byte control, byte value)
{
MIDIccData(control, value);
}
void OnNoteOn(byte channel, byte note, byte velocity)
{
MIDInoteOn(note, velocity);
}
void OnNoteOff(byte channel, byte note, byte velocity)
{
MIDInoteOff(note, velocity);
}
//function to allocate a new MIDI Note On to an available voice number
//scans for elements that are zero value. then assigns the note number to it
void MIDInoteOn(int note, int vel)
{
if (noteCount == 8) {
//Serial.println("Voice Limit Exceeded!");
//may use the noteCount to enable a "note stealing" routine later on
}
for (int i = 0; i < 8; i++) {
if (!voice[i]) {
voice[i] = note;
noteFreq[i] = voice[i];
Serial.print("New Note # ");
Serial.println(note);
//float freq = 440.0 * powf(2.0, (float)(note - 69) * 0.08333333);
//Serial.print("Frequency= ");
//Serial.println(freq);
//Serial.print("Velocity= ");
//Serial.println(vel);
Serial.print("Assigned to Voice # ");
Serial.println(i + 1);
Serial.println();
noteCount++;
if (voice[i]) {
return;
}
}
}
}
void MIDIccData(int CCnumber, float CCvalue)
{
//Serial.print("CC#= ");
//Serial.print(CCnumber);
//Serial.print(" Value= ");
//Serial.println(CCvalue);
//assign values to the CC lookup table
CCvalues[CCnumber] = {CCvalue};
}
//functin called when a Note Off msg is received. Will scan the voice array to locate
//the note to be shut off. Thus returning the element to zero value. which frees up that
//voice for use of a new note.
void MIDInoteOff(int note, int vel)
{
for (int i = 0; i < 8; i++) {
if (voice[i] == note) {
voice[i] = 0;
//Serial.print("-note off # ");
//Serial.println(note);
//Serial.print("Shut Off Voice # ");
//Serial.println(i + 1);
noteCount--;
if (noteCount < 0) {
noteCount = 0;
}
}
}
}
//an exponential formula mapping function
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void setup() {
AudioMemory(320);
Serial.begin(9600);
sgtl5000_1.enable();
sgtl5000_1.volume(.7);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn) ;
usbMIDI.setHandleControlChange(OnControlChange);
pinMode(0, INPUT_PULLUP);
//mix
first4premix.gain(0, .25);
first4premix.gain(1, .25);
first4premix.gain(2, .25);
first4premix.gain(3, .25);
last4premix.gain(0, .25);
last4premix.gain(1, .25);
last4premix.gain(2, .25);
last4premix.gain(3, .25);
//initiate values to CCvalues array for the default patch
CCvalues[7] = 127;
CCvalues[32] = 15;
CCvalues[33] = 8;
CCvalues[34] = 127;
CCvalues[35] = 106;
CCvalues[36] = 63;
CCvalues[40] = 32;
CCvalues[41] = 96;
CCvalues[42] = 81;
CCvalues[43] = 64;
CCvalues[44] = 16;
CCvalues[45] = 89;
CCvalues[46] = 52;
CCvalues[47] = 3;
CCvalues[49] = 127;
CCvalues[50] = 72;
CCvalues[71] = 100;
CCvalues[74] = 37;
CCvalues[94] = 70;
// initialize the oscillators
//Voice 1
voice1a.begin(.3, 440, WAVEFORM_SQUARE);
voice1b.begin(.3, 440, WAVEFORM_SAWTOOTH);
//Voice 2
voice2a.begin(.3, 440, WAVEFORM_SQUARE);
voice2b.begin(.3, 440, WAVEFORM_SAWTOOTH);
//Voice 3
voice3a.begin(.3, 440, WAVEFORM_SQUARE);
voice3b.begin(.3, 440, WAVEFORM_SAWTOOTH);
//Voice 4
voice4a.begin(.3, 440, WAVEFORM_SQUARE);
voice4b.begin(.3, 440, WAVEFORM_SAWTOOTH);
//Voice 5
voice5a.begin(.3, 440, WAVEFORM_SQUARE);
voice5b.begin(.3, 440, WAVEFORM_SAWTOOTH);
//Voice 6
voice6a.begin(.3, 440, WAVEFORM_SQUARE);
voice6b.begin(.3, 440, WAVEFORM_SAWTOOTH);
//Voice 7
voice7a.begin(.3, 440, WAVEFORM_SQUARE);
voice7b.begin(.3, 440, WAVEFORM_SAWTOOTH);
//Voice 8
voice8a.begin(.3, 440, WAVEFORM_SQUARE);
voice8b.begin(.3, 440, WAVEFORM_SAWTOOTH);
delayFilter.frequency(3000);
delayFilter.resonance(1);
delay1.delay(0, 0);
mainOutMixer.gain(3, 0);
//LFO
lfo.begin(1, 3, WAVEFORM_SINE);
lfo.frequency(0);
voice1filtermodmixer.gain(1, 0);
voice2filtermodmixer.gain(1, 0);
voice3filtermodmixer.gain(1, 0);
voice4filtermodmixer.gain(1, 0);
voice5filtermodmixer.gain(1, 0);
voice6filtermodmixer.gain(1, 0);
voice7filtermodmixer.gain(1, 0);
voice8filtermodmixer.gain(1, 0);
deTune = 1;
mainOutMixer.gain(0, .5);
mainOutMixer.gain(1, .5);
//lfoenvelope.amplitude(1);
voiceBPulse = false;
}
void loop() {
usbMIDI.read();
button0.update();
//prints the values set in the CC lookup table
if (button0.fallingEdge()) {
for (int i = 0; i < 128; i++) {
if (CCvalues[i]) {
Serial.print("CC:");
Serial.print(i);
Serial.print(" is Value:");
Serial.print(CCvalues[i]);
Serial.println();
}
}
}
//Volume
mainVolume = CCvalues[7];
mainVolume = mainVolume / 127;
sgtl5000_1.volume(mainVolume);
//not used at this time
//tempLineOutLevel = CCvalues[7];
//tempLineOutLevel = map(tempLineOutLevel, 0, 127, 31, 13);
//sgtl5000_1.lineOutLevel(tempLineOutLevel);
//start of voice service for loop
//notes set to frequencies
for (int i = 0; i < 8; i++) {
if (i == 0) {
voice1a.frequency(440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333));
voice1b.frequency((440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333))* deTune);
}
if (i == 1) {
voice2a.frequency(440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333));
voice2b.frequency((440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333))* deTune);
}
if (i == 2) {
voice3a.frequency(440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333));
voice3b.frequency((440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333))* deTune);
}
if (i == 3) {
voice4a.frequency(440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333));
voice4b.frequency((440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333))* deTune);
}
if (i == 4) {
voice5a.frequency(440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333));
voice5b.frequency((440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333))* deTune);
}
if (i == 5) {
voice6a.frequency(440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333));
voice6b.frequency((440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333))* deTune);
}
if (i == 6) {
voice7a.frequency(440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333));
voice7b.frequency((440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333))* deTune);
}
if (i == 7) {
voice8a.frequency(440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333));
voice8b.frequency((440.0 * powf(2.0, (float)(noteFreq [i] - 69) * 0.08333333))* deTune);
}
//sevice envelopes for voices
if (i == 0) {
switch (state0a) {
//service the Amp ADSR
case noteOnWait:
if (voice[i]) {
state0a = ATTACK;
}
break;
case ATTACK:
attackMillisA[i] = millis();
voice1env.amplitude(1, attackTime);
state0a = ATTACKwait;
if (!voice[i]) {
state0a = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisA[i] > attackTime) {
state0a = DECAY;
}
if (!voice[i]) {
state0a = RELEASE1;
}
break;
case DECAY:
voice1env.amplitude(sustainLevel, decayTime);
state0a = SUSTAIN;
if (!voice[i]) {
state0a = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0a = RELEASE1;
}
break;
case RELEASE1:
voice1env.amplitude(0, releaseTime);
state0a = noteOnWait;
break;
}
// service the Filter ADSR
switch (state0b) {
case noteOnWait:
if (voice[i]) {
state0b = ATTACK;
}
break;
case ATTACK:
attackMillisF[i] = millis();
voice1filterenv.amplitude(1, attackTimeFilter);
state0b = ATTACKwait;
if (!voice[i]) {
state0b = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisF[i] > attackTimeFilter) {
state0b = DECAY;
}
if (!voice[i]) {
state0b = RELEASE1;
}
break;
case DECAY:
voice1filterenv.amplitude(sustainLevelFilter, decayTimeFilter);
state0b = SUSTAIN;
if (!voice[i]) {
state0b = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0b = RELEASE1;
}
break;
case RELEASE1:
voice1filterenv.amplitude(0, releaseTimeFilter);
state0b = noteOnWait;
break;
}
}
if (i == 1) {
switch (state0c) {
//service the Amp ADSR
case noteOnWait:
if (voice[i]) {
state0c = ATTACK;
}
break;
case ATTACK:
attackMillisA[i] = millis();
voice2env.amplitude(1, attackTime);
state0c = ATTACKwait;
if (!voice[i]) {
state0c = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisA[i] > attackTime) {
state0c = DECAY;
}
if (!voice[i]) {
state0c = RELEASE1;
}
break;
case DECAY:
voice2env.amplitude(sustainLevel, decayTime);
state0c = SUSTAIN;
if (!voice[i]) {
state0c = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0c = RELEASE1;
}
break;
case RELEASE1:
voice2env.amplitude(0, releaseTime);
state0c = noteOnWait;
break;
}
// service the Filter ADSR
switch (state0d) {
case noteOnWait:
if (voice[i]) {
state0d = ATTACK;
}
break;
case ATTACK:
attackMillisF[i] = millis();
voice2filterenv.amplitude(1, attackTimeFilter);
state0d = ATTACKwait;
if (!voice[i]) {
state0d = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisF[i] > attackTimeFilter) {
state0d = DECAY;
}
if (!voice[i]) {
state0d = RELEASE1;
}
break;
case DECAY:
voice2filterenv.amplitude(sustainLevelFilter, decayTimeFilter);
state0d = SUSTAIN;
if (!voice[i]) {
state0d = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0d = RELEASE1;
}
break;
case RELEASE1:
voice2filterenv.amplitude(0, releaseTimeFilter);
state0d = noteOnWait;
break;
}
}
if (i == 2) {
switch (state0e) {
//service the Amp ADSR
case noteOnWait:
if (voice[i]) {
state0e = ATTACK;
}
break;
case ATTACK:
attackMillisA[i] = millis();
voice3env.amplitude(1, attackTime);
state0e = ATTACKwait;
if (!voice[i]) {
state0e = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisA[i] > attackTime) {
state0e = DECAY;
}
if (!voice[i]) {
state0e = RELEASE1;
}
break;
case DECAY:
voice3env.amplitude(sustainLevel, decayTime);
state0e = SUSTAIN;
if (!voice[i]) {
state0e = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0e = RELEASE1;
}
break;
case RELEASE1:
voice3env.amplitude(0, releaseTime);
state0e = noteOnWait;
break;
}
// service the Filter ADSR
switch (state0f) {
case noteOnWait:
if (voice[i]) {
state0f = ATTACK;
}
break;
case ATTACK:
attackMillisF[i] = millis();
voice3filterenv.amplitude(1, attackTimeFilter);
state0f = ATTACKwait;
if (!voice[i]) {
state0f = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisF[i] > attackTimeFilter) {
state0f = DECAY;
}
if (!voice[i]) {
state0f = RELEASE1;
}
break;
case DECAY:
voice3filterenv.amplitude(sustainLevelFilter, decayTimeFilter);
state0f = SUSTAIN;
if (!voice[i]) {
state0f = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0f = RELEASE1;
}
break;
case RELEASE1:
voice3filterenv.amplitude(0, releaseTimeFilter);
state0f = noteOnWait;
break;
}
}
if (i == 3) {
switch (state0g) {
//service the Amp ADSR
case noteOnWait:
if (voice[i]) {
state0g = ATTACK;
}
break;
case ATTACK:
attackMillisA[i] = millis();
voice4env.amplitude(1, attackTime);
state0g = ATTACKwait;
if (!voice[i]) {
state0g = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisA[i] > attackTime) {
state0g = DECAY;
}
if (!voice[i]) {
state0g = RELEASE1;
}
break;
case DECAY:
voice4env.amplitude(sustainLevel, decayTime);
state0g = SUSTAIN;
if (!voice[i]) {
state0g = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0g = RELEASE1;
}
break;
case RELEASE1:
voice4env.amplitude(0, releaseTime);
state0g = noteOnWait;
break;
}
// service the Filter ADSR
switch (state0h) {
case noteOnWait:
if (voice[i]) {
state0h = ATTACK;
}
break;
case ATTACK:
attackMillisF[i] = millis();
voice4filterenv.amplitude(1, attackTimeFilter);
state0h = ATTACKwait;
if (!voice[i]) {
state0h = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisF[i] > attackTimeFilter) {
state0h = DECAY;
}
if (!voice[i]) {
state0h = RELEASE1;
}
break;
case DECAY:
voice4filterenv.amplitude(sustainLevelFilter, decayTimeFilter);
state0h = SUSTAIN;
if (!voice[i]) {
state0h = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0h = RELEASE1;
}
break;
case RELEASE1:
voice4filterenv.amplitude(0, releaseTimeFilter);
state0h = noteOnWait;
break;
}
}
if (i == 4) {
switch (state0i) {
//service the Amp ADSR
case noteOnWait:
if (voice[i]) {
state0i = ATTACK;
}
break;
case ATTACK:
attackMillisA[i] = millis();
voice5env.amplitude(1, attackTime);
state0i = ATTACKwait;
if (!voice[i]) {
state0i = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisA[i] > attackTime) {
state0i = DECAY;
}
if (!voice[i]) {
state0i = RELEASE1;
}
break;
case DECAY:
voice5env.amplitude(sustainLevel, decayTime);
state0i = SUSTAIN;
if (!voice[i]) {
state0i = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0i = RELEASE1;
}
break;
case RELEASE1:
voice5env.amplitude(0, releaseTime);
state0i = noteOnWait;
break;
}
// service the Filter ADSR
switch (state0j) {
case noteOnWait:
if (voice[i]) {
state0j = ATTACK;
}
break;
case ATTACK:
attackMillisF[i] = millis();
voice5filterenv.amplitude(1, attackTimeFilter);
state0j = ATTACKwait;
if (!voice[i]) {
state0j = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisF[i] > attackTimeFilter) {
state0j = DECAY;
}
if (!voice[i]) {
state0j = RELEASE1;
}
break;
case DECAY:
voice5filterenv.amplitude(sustainLevelFilter, decayTimeFilter);
state0j = SUSTAIN;
if (!voice[i]) {
state0j = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0j = RELEASE1;
}
break;
case RELEASE1:
voice5filterenv.amplitude(0, releaseTimeFilter);
state0j = noteOnWait;
break;
}
}
if (i == 5) {
switch (state0k) {
//service the Amp ADSR
case noteOnWait:
if (voice[i]) {
state0k = ATTACK;
}
break;
case ATTACK:
attackMillisA[i] = millis();
voice6env.amplitude(1, attackTime);
state0k = ATTACKwait;
if (!voice[i]) {
state0k = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisA[i] > attackTime) {
state0k = DECAY;
}
if (!voice[i]) {
state0k = RELEASE1;
}
break;
case DECAY:
voice6env.amplitude(sustainLevel, decayTime);
state0k = SUSTAIN;
if (!voice[i]) {
state0k = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0k = RELEASE1;
}
break;
case RELEASE1:
voice6env.amplitude(0, releaseTime);
state0k = noteOnWait;
break;
}
// service the Filter ADSR
switch (state0l) {
case noteOnWait:
if (voice[i]) {
state0l = ATTACK;
}
break;
case ATTACK:
attackMillisF[i] = millis();
voice6filterenv.amplitude(1, attackTimeFilter);
state0l = ATTACKwait;
if (!voice[i]) {
state0l = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisF[i] > attackTimeFilter) {
state0l = DECAY;
}
if (!voice[i]) {
state0l = RELEASE1;
}
break;
case DECAY:
voice6filterenv.amplitude(sustainLevelFilter, decayTimeFilter);
state0l = SUSTAIN;
if (!voice[i]) {
state0l = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0l = RELEASE1;
}
break;
case RELEASE1:
voice6filterenv.amplitude(0, releaseTimeFilter);
state0l = noteOnWait;
break;
}
}
if (i == 6) {
switch (state0m) {
//service the Amp ADSR
case noteOnWait:
if (voice[i]) {
state0m = ATTACK;
}
break;
case ATTACK:
attackMillisA[i] = millis();
voice7env.amplitude(1, attackTime);
state0m = ATTACKwait;
if (!voice[i]) {
state0m = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisA[i] > attackTime) {
state0m = DECAY;
}
if (!voice[i]) {
state0m = RELEASE1;
}
break;
case DECAY:
voice7env.amplitude(sustainLevel, decayTime);
state0m = SUSTAIN;
if (!voice[i]) {
state0m = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0m = RELEASE1;
}
break;
case RELEASE1:
voice7env.amplitude(0, releaseTime);
state0m = noteOnWait;
break;
}
// service the Filter ADSR
switch (state0n) {
case noteOnWait:
if (voice[i]) {
state0n = ATTACK;
}
break;
case ATTACK:
attackMillisF[i] = millis();
voice7filterenv.amplitude(1, attackTimeFilter);
state0n = ATTACKwait;
if (!voice[i]) {
state0n = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisF[i] > attackTimeFilter) {
state0n = DECAY;
}
if (!voice[i]) {
state0n = RELEASE1;
}
break;
case DECAY:
voice7filterenv.amplitude(sustainLevelFilter, decayTimeFilter);
state0n = SUSTAIN;
if (!voice[i]) {
state0n = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0n = RELEASE1;
}
break;
case RELEASE1:
voice7filterenv.amplitude(0, releaseTimeFilter);
state0n = noteOnWait;
break;
}
}
if (i == 7) {
switch (state0o) {
//service the Amp ADSR
case noteOnWait:
if (voice[i]) {
state0o = ATTACK;
}
break;
case ATTACK:
attackMillisA[i] = millis();
voice8env.amplitude(1, attackTime);
state0o = ATTACKwait;
if (!voice[i]) {
state0o = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisA[i] > attackTime) {
state0o = DECAY;
}
if (!voice[i]) {
state0o = RELEASE1;
}
break;
case DECAY:
voice8env.amplitude(sustainLevel, decayTime);
state0o = SUSTAIN;
if (!voice[i]) {
state0o = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0o = RELEASE1;
}
break;
case RELEASE1:
voice8env.amplitude(0, releaseTime);
state0o = noteOnWait;
break;
}
// service the Filter ADSR
switch (state0p) {
case noteOnWait:
if (voice[i]) {
state0p = ATTACK;
}
break;
case ATTACK:
attackMillisF[i] = millis();
voice8filterenv.amplitude(1, attackTimeFilter);
state0p = ATTACKwait;
if (!voice[i]) {
state0p = RELEASE1;
}
break;
case ATTACKwait:
if (millis() - attackMillisF[i] > attackTimeFilter) {
state0p = DECAY;
}
if (!voice[i]) {
state0p = RELEASE1;
}
break;
case DECAY:
voice8filterenv.amplitude(sustainLevelFilter, decayTimeFilter);
state0p = SUSTAIN;
if (!voice[i]) {
state0p = RELEASE1;
}
break;
case SUSTAIN:
if (!voice[i]) {
state0p = RELEASE1;
}
break;
case RELEASE1:
voice8filterenv.amplitude(0, releaseTimeFilter);
state0p = noteOnWait;
break;
}
}
}
//end of voice service for loop
//assign CC Values to Parameters
if (CCvalues[40] != prevCCvalues[40]) {
waveShapeOneIndex = CCvalues[40] / 31;
if (waveShapeOneIndex < 4) {
voice1a.begin(waveShapes[waveShapeOneIndex]);
voice2a.begin(waveShapes[waveShapeOneIndex]);
voice3a.begin(waveShapes[waveShapeOneIndex]);
voice4a.begin(waveShapes[waveShapeOneIndex]);
voice5a.begin(waveShapes[waveShapeOneIndex]);
voice6a.begin(waveShapes[waveShapeOneIndex]);
voice7a.begin(waveShapes[waveShapeOneIndex]);
voice8a.begin(waveShapes[waveShapeOneIndex]);
prevCCvalues[40] = CCvalues[40];
}
}
//vcoMixBalance
if (CCvalues[36] != prevCCvalues[36]) {
vcoOneLevel = (CCvalues[36]) / 127;
vcoTwoLevel = 1 - (CCvalues[36]) / 127;
voice1mix.gain(1, vcoOneLevel);
voice1mix.gain(0, vcoTwoLevel);
voice2mix.gain(1, vcoOneLevel);
voice2mix.gain(0, vcoTwoLevel);
voice3mix.gain(1, vcoOneLevel);
voice3mix.gain(0, vcoTwoLevel);
voice4mix.gain(1, vcoOneLevel);
voice4mix.gain(0, vcoTwoLevel);
voice5mix.gain(1, vcoOneLevel);
voice5mix.gain(0, vcoTwoLevel);
voice6mix.gain(1, vcoOneLevel);
voice6mix.gain(0, vcoTwoLevel);
voice7mix.gain(1, vcoOneLevel);
voice7mix.gain(0, vcoTwoLevel);
voice8mix.gain(1, vcoOneLevel);
voice8mix.gain(0, vcoTwoLevel);
prevCCvalues[36] = CCvalues[36];
}
if (CCvalues[41] != prevCCvalues[41]) {
waveShapeTwoIndex = CCvalues[41] / 31;
if (waveShapeTwoIndex < 4) {
if (waveShapeTwoIndex == 3) {
voiceBPulse = true;
} else {
voiceBPulse = false;
}
voice1b.begin(waveShapes[waveShapeTwoIndex]);
voice2b.begin(waveShapes[waveShapeTwoIndex]);
voice3b.begin(waveShapes[waveShapeTwoIndex]);
voice4b.begin(waveShapes[waveShapeTwoIndex]);
voice5b.begin(waveShapes[waveShapeTwoIndex]);
voice6b.begin(waveShapes[waveShapeTwoIndex]);
voice7b.begin(waveShapes[waveShapeTwoIndex]);
voice8b.begin(waveShapes[waveShapeTwoIndex]);
prevCCvalues[41] = CCvalues[41];
}
}
if (CCvalues[94] != prevCCvalues[94]) {
deTune = CCvalues[94];
deTune = mapfloat(deTune, 0, 127, .875, 1.125);
prevCCvalues[94] = CCvalues[94];
}
//LFO
if (CCvalues[47] != prevCCvalues[47]) {
lfo.frequency(CCvalues[47] / 13);
prevCCvalues[47] = CCvalues[47];
}
if (CCvalues[46] != prevCCvalues[46]) {
lfoWaveShapeIndex = CCvalues[46] / 25.4;
if (lfoWaveShapeIndex < 5) {
lfo.begin(lfoWaveShapes[lfoWaveShapeIndex]);
//Serial.println(lfoWaveShapeIndex);
prevCCvalues[46] = CCvalues[46];
}
}
//noise
if (CCvalues[48] != prevCCvalues[48]) {
voice1n.amplitude(CCvalues[48] / 384.8);
voice2n.amplitude(CCvalues[48] / 384.8);
voice3n.amplitude(CCvalues[48] / 384.8);
voice4n.amplitude(CCvalues[48] / 384.8);
voice5n.amplitude(CCvalues[48] / 384.8);
voice6n.amplitude(CCvalues[48] / 384.8);
voice7n.amplitude(CCvalues[48] / 384.8);
voice8n.amplitude(CCvalues[48] / 384.8);
prevCCvalues[48] = CCvalues[48];
}
//Filter
if (CCvalues[74] != prevCCvalues[74]) {
voice1filter.frequency(CCvalues[74] * 9.33);
voice2filter.frequency(CCvalues[74] * 9.33);
voice3filter.frequency(CCvalues[74] * 9.33);
voice4filter.frequency(CCvalues[74] * 9.33);
voice5filter.frequency(CCvalues[74] * 9.33);
voice6filter.frequency(CCvalues[74] * 9.33);
voice7filter.frequency(CCvalues[74] * 9.33);
voice8filter.frequency(CCvalues[74] * 9.33);
prevCCvalues[74] = CCvalues[74];
}
//resonance
if (CCvalues[71] != prevCCvalues[71]) {
if (CCvalues[71] < 5) {
CCvalues[71] = 5;
}
voice1filter.resonance((CCvalues[71] / 25.4) + .9);
voice2filter.resonance((CCvalues[71] / 25.4) + .9);
voice3filter.resonance((CCvalues[71] / 25.4) + .9);
voice4filter.resonance((CCvalues[71] / 25.4) + .9);
voice5filter.resonance((CCvalues[71] / 25.4) + .9);
voice6filter.resonance((CCvalues[71] / 25.4) + .9);
voice7filter.resonance((CCvalues[71] / 25.4) + .9);
voice8filter.resonance((CCvalues[71] / 25.4) + .9);
prevCCvalues[71] = CCvalues[71];
}
//filter octaveControl
voice1filter.octaveControl(3.5);
voice2filter.octaveControl(3.5);
voice3filter.octaveControl(3.5);
voice4filter.octaveControl(3.5);
voice5filter.octaveControl(3.5);
voice6filter.octaveControl(3.5);
voice7filter.octaveControl(3.5);
voice8filter.octaveControl(3.5);
//lfoModulation Depth
if (CCvalues[2] != prevCCvalues[2]) {
voice1filtermodmixer.gain(1, CCvalues[2] / 127);
voice2filtermodmixer.gain(1, CCvalues[2] / 127);
voice3filtermodmixer.gain(1, CCvalues[2] / 127);
voice4filtermodmixer.gain(1, CCvalues[2] / 127);
voice5filtermodmixer.gain(1, CCvalues[2] / 127);
voice6filtermodmixer.gain(1, CCvalues[2] / 127);
voice7filtermodmixer.gain(1, CCvalues[2] / 127);
voice8filtermodmixer.gain(1, CCvalues[2] / 127);
prevCCvalues[2] = CCvalues[2];
}
//envelope mod depth
if (CCvalues[49] != prevCCvalues[49]) {
voice1filtermodmixer.gain(0, CCvalues[49] / 127);
voice2filtermodmixer.gain(0, CCvalues[49] / 127);
voice3filtermodmixer.gain(0, CCvalues[49] / 127);
voice4filtermodmixer.gain(0, CCvalues[49] / 127);
voice5filtermodmixer.gain(0, CCvalues[49] / 127);
voice6filtermodmixer.gain(0, CCvalues[49] / 127);
voice7filtermodmixer.gain(0, CCvalues[49] / 127);
voice8filtermodmixer.gain(0, CCvalues[49] / 127);
prevCCvalues[49] = CCvalues[49];
}
//Delay
//time
if (CCvalues[88] != prevCCvalues[88]) {
delay1.delay(0, (CCvalues[88] * 8.05) / 2.4);
prevCCvalues[88] = CCvalues[88];
}
//feedback
if (CCvalues[89] != prevCCvalues[89]) {
mainOutMixer.gain(3, CCvalues[89] / 127);
prevCCvalues[89] = CCvalues[89];
}
//pulseWidth
if (CCvalues[50] != prevCCvalues[50]) {
tempPulseWidth = 1 - (CCvalues[50] / 127);
tempDetuneMod = CCvalues[50] / 254;
prevCCvalues[50] = CCvalues[50];
}
//attack Filter
if (CCvalues[42] != prevCCvalues[42]) {
attackTimeFilter = (CCvalues[42] * 12.05) * 2;
prevCCvalues[42] = CCvalues[42];
}
//attack Amp
if (CCvalues[32] != prevCCvalues[32]) {
attackTime = (CCvalues[32] * 8.05) * 2;
prevCCvalues[32] = CCvalues[32];
}
//decay Filter
if (CCvalues[43] != prevCCvalues[43]) {
decayTimeFilter = CCvalues[43] * 12.05;
prevCCvalues[43] = CCvalues[43];
}
//decay Amp
if (CCvalues[33] != prevCCvalues[33]) {
decayTime = CCvalues[33] * 8.05;
prevCCvalues[33] = CCvalues[33];
}
//sustain Filter
if (CCvalues[44] != prevCCvalues[44]) {
sustainLevelFilter = CCvalues[44] * 4.05;
sustainLevelFilter = mapfloat(sustainLevelFilter, 0, 127, -1, 1);
prevCCvalues[44] = CCvalues[44];
}
//sustain Amp
if (CCvalues[34] != prevCCvalues[34]) {
sustainLevel = CCvalues[34] / 127;
prevCCvalues[34] = CCvalues[34];
}
//release Filter
if (CCvalues[45] != prevCCvalues[45]) {
releaseTimeFilter = (CCvalues[45] * 8.05) * 2;
prevCCvalues[45] = CCvalues[45];
}
//Release Amp
if (CCvalues[35] != prevCCvalues[35]) {
releaseTime = (CCvalues[35] * 8.05) * 2;
prevCCvalues[35] = CCvalues[35];
}
//LFO Peak
if (peak1.available()) {
tempPeak = peak1.read();
}
voice1a.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice2a.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice3a.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice4a.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice5a.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice6a.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice7a.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice8a.pulseWidth((tempPeak / 2) + tempPulseWidth);
if (voiceBPulse) {
voice1b.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice2b.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice3b.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice4b.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice5b.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice6b.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice7b.pulseWidth((tempPeak / 2) + tempPulseWidth);
voice8b.pulseWidth((tempPeak / 2) + tempPulseWidth);
} else {
deTuneLfo = ((tempPeak) * tempDetuneMod + 1);
//Serial.println(deTuneLfo);
}
//end loop
}
PS- There were some erroneous statements of the specs of 3.5 in my vid.. it's been a long few weeks! Corrections were made in the description and a mention of where to get the specs.
I simply just dont have time to redo the entire vid again.
Last edited: