Hardware finished, softare running ok with some things to fix, like init values.

pull/1/head
Pierre-Loup Martin 4 years ago
parent 0a38957623
commit 6f573d753b
  1. 8
      README.MD
  2. 379
      minimoog_mega_1/minimoog_mega_1.ino
  3. 25
      minimoog_mega_2/minimoog_mega_2.ino
  4. 88
      minimoog_teensy/audio_setup.h
  5. 262
      minimoog_teensy/minimoog_teensy.ino
  6. 9
      misc/lateral panel pinout.txt
  7. 606
      panels/svg/minimoog - panneau lateral.svg

@ -0,0 +1,8 @@
# TeensyMoog
## What is it ?
_Teensymoog_ is a synth, inspired by the legendary minimoog.
It aims at looking and functionning as close as possible of the orinal, but using digital tools, namely Teensy and Arduino boards.
It uses three boards, one Teensy 4.0 that handles the heavy computing (sound generation), and two Arduino Mega (chinese copies in a small form factor), that are used as "port expander", which read keys, switches and potentiometers and send their value on change to the Teensy.

@ -36,17 +36,17 @@
* glide pot A2 CC 5 * glide pot A2 CC 5
* pitchbend wheel pot A3 pitchbend change * pitchbend wheel pot A3 pitchbend change
* modulation wheel pot A4 CC 1 * modulation wheel pot A4 CC 1
* modulation mix 1 switch 2 CC 117 * modulation mix 1 switch 3 CC 117
* modulation mix 2 switch 3 CC 118 * modulation mix 2 switch 2 CC 118
* osc modulation switch 4 CC 115 * osc modulation switch 4 CC 115
* glide switch 5 CC 65 * glide switch 5 CC 65
* LFO waveform switch 6 CC 119 * LFO waveform switch 6 CC 119
* Oscillators * Oscillators
* osc 1 range switch A5 CC 102 * osc 1 range switch A5 CC 102
* osc 1 waveform switch A6 CC 103 * osc 1 waveform switch A8 CC 103
* osc 2 range switch A7 CC 104 * osc 2 range switch A6 CC 104
* osc 2 waveform switch A8 CC 105 * osc 2 waveform switch A9 CC 105
* osc 3 range switch A9 CC 106 * osc 3 range switch A7 CC 106
* osc 3 waveform switch A10 CC 107 * osc 3 waveform switch A10 CC 107
* osc 3 control switch 7 CC 108 * osc 3 control switch 7 CC 108
* Mixer * Mixer
@ -54,31 +54,39 @@
* osc 2 mix pot A12 CC 86 * osc 2 mix pot A12 CC 86
* osc 3 mix pot A13 CC 87 * osc 3 mix pot A13 CC 87
* noise mix pot A14 CC 88 * noise mix pot A14 CC 88
* external mix pot A15 CC 89 * feedback mix pot A15 CC 89
* osc 1 switch 8 Directly added to mix * osc 1 switch 8 Directly added to mix
* osc 2 switch 9 ditto * osc 2 switch 9 ditto
* osc 3 switch 10 ditto * osc 3 switch 10 ditto
* noise switch 11 ditto * noise switch 11 ditto
* external switch 12 ditto * feedback switch 12 ditto
* noise color switch 13 CC 114 * noise color switch 17 CC 114 // led on 13 lowers tension
* Other * Other
* function switch 14 CC 113 * function switch 14 CC 113
* transpose + switch 52 CC 112 * transpose + switch 15 CC 112
* transpose - switch 53 CC 112 * transpose - switch 16 CC 112
* Communication * Communication
* TX1 to mega 2 18 * TX1 to teensy 18
* RX1 from mega 2 19 * RX1 from teensy 19
*/ */
// includes // includes
#include "MIDI.h" #include "MIDI.h"
#include "PushButton.h" #include "PushButton.h"
#include "ExpFilter.h"
#include "defs.h"
// Constants // Constants
const uint8_t NUM_KEYS = 30; const uint8_t NUM_KEYS = 30;
const uint8_t MIDI_OFFSET = 23; // to be modified const uint8_t MIDI_OFFSET = 47; // to be maybe modified
// Digital pin definition
const uint8_t NUM_SWITCHES = 15;
const uint8_t NUM_POTS = 16;
const uint8_t NUM_SELECTORS = 6;
const uint8_t POT_FILTER_COEF = 15;
// Digital pin definition
const uint8_t KEYS[NUM_KEYS] = { const uint8_t KEYS[NUM_KEYS] = {
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
@ -86,25 +94,27 @@ const uint8_t KEYS[NUM_KEYS] = {
}; };
PushButton keys[NUM_KEYS]; PushButton keys[NUM_KEYS];
/*
const uint8_t PIN_MOD_MIX_1 = 2; const uint8_t PIN_MOD_MIX_1 = 2;
const uint8_t PIN_MOD_MIX_2 = 3; const uint8_t PIN_MOD_MIX_2 = 3;
const uint8_t PIN_OSC_MOD = 4; const uint8_t PIN_OSC_MOD = 4;
const uint8_t PIN_GLIDE = 5; const uint8_t PIN_GLIDE = 5;
const uint8_t PIN_DECAY = 6; const uint8_t PIN_LFO_WAVEFORM = 6;
const uint8_t PIN_LFO_WAVEFORM = 7; const uint8_t PIN_OSC3_CTRL = 7;
const uint8_t PIN_MIX_OSC_1 = 9; const uint8_t PIN_MIX_OSC_1 = 8;
const uint8_t PIN_MIX_OSC_2 = 10; const uint8_t PIN_MIX_OSC_2 = 9;
const uint8_t PIN_MIX_OSC_3 = 11; const uint8_t PIN_MIX_OSC_3 = 10;
const uint8_t PIN_MIX_OSC_NOISE = 12; const uint8_t PIN_MIX_OSC_NOISE = 11;
const uint8_t PIN_MIX_OSC_EXT = 13; const uint8_t PIN_MIX_OSC_EXT = 12;
const uint8_t PIN_MIX_OSC_NOISE_COLOR = 14; const uint8_t PIN_MIX_OSC_NOISE_COLOR = 13;
const uint8_t PIN_FUNCTION = 14;
const uint8_t PIN_TRANSPOSE_PLUS = 52; const uint8_t PIN_TRANSPOSE_PLUS = 52;
const uint8_t PIN_TRANSPOSE_MINUS = 53; const uint8_t PIN_TRANSPOSE_MINUS = 53;
*/
// Analog pin definition // Analog pin definition
/*
const uint8_t APIN_LFO_RATE = A0; const uint8_t APIN_LFO_RATE = A0;
const uint8_t APIN_MOD_MIX = A1; const uint8_t APIN_MOD_MIX = A1;
const uint8_t APIN_GLIDE = A2; const uint8_t APIN_GLIDE = A2;
@ -123,49 +133,27 @@ const uint8_t APIN_MIX_OSC_2 = A12;
const uint8_t APIN_MIX_OSC_3 = A13; const uint8_t APIN_MIX_OSC_3 = A13;
const uint8_t APIN_MIX_NOISE = A14; const uint8_t APIN_MIX_NOISE = A14;
const uint8_t APIN_MIX_EXT = A15; const uint8_t APIN_MIX_EXT = A15;
*/
const uint8_t APIN[NUM_POTS] = {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15};
// Vars // Vars
uint16_t potState[NUM_POTS];
const uint8_t PIN[NUM_SWITCHES] = {3, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 14, 15, 16};
PushButton switches[NUM_SWITCHES];
ExpFilter pots[NUM_POTS];
uint8_t selectors[NUM_SELECTORS];
// Keyboard // Keyboard
bool keyState[NUM_KEYS] = {}; bool keyState[NUM_KEYS];
// Modulation
uint16_t lfoRate = 0;
uint16_t modMix = 0;
uint16_t glide = 0;
uint16_t pitchWheel = 0;
uint16_t modWheel = 0;
bool modMix1 = 0;
bool modMix2 = 0;
bool oscMod = 0;
bool glideEn = 0;
bool decayEn = 0;
bool lfoWaveform = 0;
// Oscillators
uint8_t osc1Range = 0;
uint8_t osc1Waveform = 0;
uint8_t osc2Range = 0;
uint8_t osc2Waveform = 0;
uint8_t osc3Range = 0;
uint8_t osc3Waveform = 0;
bool osc3Control = 0;
// Mixer // Mixer
uint16_t osc1Mix = 0; uint16_t mix[5];
uint16_t osc2Mix = 0; bool mixSw[5];
uint16_t osc3Mix = 0;
uint16_t feedbackMix = 0;
uint16_t noiseMix = 0;
bool osc1MixSw = 0;
bool osc2MixSw = 0;
bool osc3MixSw = 0;
bool feedbackMixSw = 0;
bool noiseMixSw = 0;
// Miscellaneous
bool function = 0;
// Misc
uint8_t defaultVelocity = 96; uint8_t defaultVelocity = 96;
bool update = 0; bool update = 0;
@ -176,46 +164,62 @@ struct midiSettings : public midi::DefaultSettings{
}; };
// The one we use on synth // The one we use on synth
//MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial1, midi1, midiSettings); MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial1, midi1, midiSettings);
// For debug purposes // For debug purposes
MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial, midi1, midiSettings); //MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial, midi1, midiSettings);
void setup(){ void setup(){
// initialisation // initialisation
// Serial is for debug
//Serial.begin(115200);
midi1.setHandleControlChange(handleControlChange); midi1.setHandleControlChange(handleControlChange);
midi1.begin(1); midi1.begin(1);
// Serial 1 is for sending and receiving messages to and from Teensy midi1.turnThruOff();
// Serial1.begin(115200);
// Serial 2 is for sending and receiving messages to and from Mega 2
// Serial2.begin(115200);
// keys
/*
for(uint8_t i = 0; i < NUM_KEYS; ++i){
keyState[i] = 0;
pinMode(KEYS[i], INPUT_PULLUP);
}
*/
// Key initialisation
for(uint8_t i = 0; i < NUM_KEYS; ++i){ for(uint8_t i = 0; i < NUM_KEYS; ++i){
keys[i].begin(KEYS[i], INPUT_PULLUP); keys[i].begin(KEYS[i], INPUT_PULLUP);
keys[i].setDebounceDelay(1); keys[i].setDebounceDelay(12);
} }
// Switches initialisation
for(uint8_t i = 0; i < NUM_SWITCHES; ++i){
switches[i].begin(PIN[i], INPUT_PULLUP);
switches[i].setDebounceDelay(1);
}
// potentiometers initialisation
for (uint8_t i = 0; i < NUM_POTS; ++i){
pots[i].begin(analogRead(APIN[i]));
pots[i].setCoef(POT_FILTER_COEF);
}
} }
void loop(){ void loop(){
midi1.read(); midi1.read();
updateKeys(); updateKeys();
updateControls();
updateSwitches(); updateSwitches();
updateControls();
update = 0; update = 0;
} }
void sendLongControlChange(uint8_t controlChange, uint16_t value, uint8_t channel = 1){
uint8_t valueHigh = value >> 7;
uint8_t valueLow = value & 0x7F;
midi1.sendControlChange(controlChange, valueHigh, channel);
midi1.sendControlChange(controlChange + 32, valueLow, channel);
}
void updateMix(uint8_t ch, bool fromSw = 0){
uint16_t value = 0;
if(mixSw[ch]){
value = mix[ch];
}
if(value || fromSw) sendLongControlChange(CC_OSC1_MIX + ch, value, 1);
}
void updateKeys(){ void updateKeys(){
// reading keys // reading keys
for(uint8_t i = 0; i < NUM_KEYS; ++i){ for(uint8_t i = 0; i < NUM_KEYS; ++i){
@ -248,13 +252,228 @@ void updateKeys(){
} }
void updateControls(){ void updateSwitches(){
for(uint8_t i = 0; i < NUM_SWITCHES; ++i){
uint8_t change = 0;
switches[i].update();
if(switches[i].justPressed()){
change = 127;
} else if(switches[i].justReleased()){
change = 0;
} else if(update){
change = (uint8_t)switches[i].isPressed();
change *= 127;
} else {
// If no change, skip midi update.
continue;
}
int8_t controlChange = -1;
switch(i){
case 0:
// pin 2
controlChange = CC_MOD_MIX_1;
break;
case 1:
// pin 3
controlChange = CC_MOD_MIX_2;
break;
case 2:
// pin 4
controlChange = CC_OSC_MOD;
break;
case 3:
// pin 5
controlChange = CC_PORTAMENTO_ON_OFF;
break;
case 4:
// pin 6
controlChange = CC_LFO_SHAPE;
break;
case 5:
// pin 7
controlChange = CC_OSC3_CTRL;
break;
case 6:
// pin 8
mixSw[0] = (bool)change;
updateMix(0, 1);
continue;
case 7:
// pin 9
mixSw[1] = (bool)change;
updateMix(1, 1);
continue;
case 8:
// pin 10
mixSw[2] = (bool)change;
updateMix(2, 1);
continue;
case 9:
// pin 11
mixSw[3] = (bool)change;
updateMix(3, 1);
continue;
case 10:
// pin 12
mixSw[4] = (bool)change;
updateMix(4, 1);
continue;
case 11:
// pin 13
controlChange = CC_NOISE_COLOR;
break;
case 12:
// pin 14
controlChange = CC_FUNCTION;
break;
case 13:
// pin 15
controlChange = CC_TRANSPOSE;
if(change == 0) continue;
change = 127;
break;
case 14:
// pin 16
controlChange = CC_TRANSPOSE;
if(change == 127) continue;
change = 0;
break;
default:
continue;
}
midi1.sendControlChange(controlChange, change, 1);
}
} }
void updateSwitches(){ void updateControls(){
for(uint8_t i = 0; i < NUM_POTS; ++i){
uint16_t value = 0;
value = pots[i].filter(analogRead(APIN[i]));
if((value != potState[i]) || update){
potState[i] = value;
} else {
// If not change, skip midi update
continue;
}
int8_t controlChange = -1;
switch(i){
case 0:
controlChange = CC_LFO_RATE;
break;
case 1:
controlChange = CC_MODULATION_MIX;
break;
case 2:
controlChange = CC_PORTAMENTO_TIME;
break;
case 3:
midi1.sendPitchBend((int16_t)value - 512, 1);
continue;
case 4:
controlChange = CC_MOD_WHEEL;
break;
case 5:
// rotary selector : value must be divided by ~170
controlChange = CC_OSC1_RANGE;
value /= 170;
value = 5 - value;
// We have to check if the value after dividing is different from the previous one !
if(value == selectors[0]){
continue;
} else {
selectors[0] = value;
}
break;
case 6:
controlChange = CC_OSC2_RANGE;
value /= 170;
value = 5 - value;
if(value == selectors[1]){
continue;
} else {
selectors[1] = value;
}
break;
case 7:
controlChange = CC_OSC3_RANGE;
value /= 170;
value = 5 - value;
if(value == selectors[2]){
continue;
} else {
selectors[2] = value;
}
break;
case 8:
controlChange = CC_OSC1_WAVEFORM;
value /= 170;
if(value == selectors[3]){
continue;
} else {
selectors[3] = value;
}
break;
case 9:
controlChange = CC_OSC2_WAVEFORM;
value /= 170;
if(value == selectors[4]){
continue;
} else {
selectors[4] = value;
}
break;
case 10:
controlChange = CC_OSC3_WAVEFORM;
value /= 170;
if(value == selectors[5]){
continue;
} else {
selectors[5] = value;
}
break;
case 11:
// mix is to be sent only if switch is on.
// controlChange = CC_OSC1_MIX;
mix[0] = value;
updateMix(0);
continue;
case 12:
// controlChange = CC_OSC2_MIX;
mix[1] = value;
updateMix(1);
continue;
case 13:
// controlChange = CC_OSC3_MIX;
mix[2] = value;
updateMix(2);
continue;
case 14:
// controlChange = CC_NOISE_MIX;
mix[3] = value;
updateMix(3);
continue;
case 15:
// controlChange = CC_FEEDBACK_MIX;
mix[4] = value;
updateMix(4);
continue;
default:
continue;
}
if( controlChange < 32){
sendLongControlChange(controlChange, value, 1);
} else {
midi1.sendControlChange(controlChange, value, 1);
}
}
} }
void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){

@ -52,8 +52,6 @@
* Communication * Communication
* TX1 to teensy 18 * TX1 to teensy 18
* RX1 from teensy 19 * RX1 from teensy 19
* TX2 to mega 1 16
* RX2 from mega 1 17
*/ */
// includes // includes
@ -68,12 +66,16 @@ const uint8_t NUM_SWITCHES = 3;
const uint8_t NUM_POTS = 15; const uint8_t NUM_POTS = 15;
const uint8_t POT_FILTER_COEF = 10; const uint8_t POT_FILTER_COEF = 10;
// Note : pins are defined via tables, to improve code efficiency.
// Digital pin definition // Digital pin definition
const uint8_t PIN_FILTER_MOD = 2; const uint8_t PIN_FILTER_MOD = 2;
/*
const uint8_t PIN_KEYBOARD_CTRL_1 = 3; const uint8_t PIN_KEYBOARD_CTRL_1 = 3;
const uint8_t PIN_KEYBOARD_CTRL_2 = 4; const uint8_t PIN_KEYBOARD_CTRL_2 = 4;
*/
// Analog pin definition // Analog pin definition
/*
const uint8_t APIN_GLOBAL_TUNE = A0; const uint8_t APIN_GLOBAL_TUNE = A0;
const uint8_t APIN_OSC2_TUNE = A1; const uint8_t APIN_OSC2_TUNE = A1;
const uint8_t APIN_OSC3_TUNE = A2; const uint8_t APIN_OSC3_TUNE = A2;
@ -89,11 +91,12 @@ const uint8_t APIN_ATTACK = A11;
const uint8_t APIN_DECAY = A12; const uint8_t APIN_DECAY = A12;
const uint8_t APIN_SUSTAIN = A13; const uint8_t APIN_SUSTAIN = A13;
const uint8_t APIN_RELEASE = A14; const uint8_t APIN_RELEASE = A14;
*/
const uint8_t apin[NUM_POTS] = {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14}; const uint8_t APIN[NUM_POTS] = {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14};
// Variables // Variables
uint16_t potState[NUM_POTS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint16_t potState[NUM_POTS];
PushButton switches[NUM_SWITCHES]; PushButton switches[NUM_SWITCHES];
ExpFilter pots[NUM_POTS]; ExpFilter pots[NUM_POTS];
@ -118,7 +121,7 @@ void setup(){
} }
for (uint8_t i = 0; i < NUM_POTS; ++i){ for (uint8_t i = 0; i < NUM_POTS; ++i){
pots[i].begin(analogRead(apin[i])); pots[i].begin(analogRead(APIN[i]));
pots[i].setCoef(POT_FILTER_COEF); pots[i].setCoef(POT_FILTER_COEF);
} }
@ -139,7 +142,7 @@ void updateControls(){
for(uint8_t i = 0; i < NUM_POTS; ++i){ for(uint8_t i = 0; i < NUM_POTS; ++i){
uint16_t value = 0; uint16_t value = 0;
value = pots[i].filter(analogRead(apin[i])); value = pots[i].filter(analogRead(APIN[i]));
if((value != potState[i]) || update){ if((value != potState[i]) || update){
potState[i] = value; potState[i] = value;
} else { } else {
@ -147,7 +150,7 @@ void updateControls(){
continue; continue;
} }
uint8_t controlChange = 0; int8_t controlChange = -1;
switch(i){ switch(i){
case 0: case 0:
@ -157,6 +160,9 @@ void updateControls(){
controlChange = CC_OSC2_TUNE; controlChange = CC_OSC2_TUNE;
break; break;
case 2: case 2:
// This one has a problem : sends CC10 (instead of CC13) then CC45 as should be.
// or maybe pure data has a bug that shifts bits.
// It seems it's a bug of pure data : 13 are replaced by 10 also for values...
controlChange = CC_OSC3_TUNE; controlChange = CC_OSC3_TUNE;
break; break;
case 3: case 3:
@ -199,6 +205,7 @@ void updateControls(){
continue; continue;
} }
uint8_t valueHigh = value >> 7; uint8_t valueHigh = value >> 7;
uint8_t valueLow = value & 0x7F; uint8_t valueLow = value & 0x7F;
midi1.sendControlChange(controlChange, valueHigh, 1); midi1.sendControlChange(controlChange, valueHigh, 1);
@ -223,7 +230,7 @@ void updateSwitches(){
continue; continue;
} }
uint8_t controlChange = 0; int8_t controlChange = -1;
switch(i){ switch(i){
case 0: case 0:

@ -5,53 +5,53 @@
#include <SerialFlash.h> #include <SerialFlash.h>
// GUItool: begin automatically generated code // GUItool: begin automatically generated code
AudioSynthWaveformDc dcFilterEnvelope; //xy=169.76666259765625,540.0000305175781 AudioSynthWaveformDc dcFilterEnvelope; //xy=169,540
AudioSynthWaveformDc dcOscTune; //xy=228.76666259765625,149 AudioSynthWaveformDc dcOscTune; //xy=228,149
AudioSynthWaveformDc dcKeyTrack; //xy=231.76666259765625,113 AudioSynthWaveformDc dcKeyTrack; //xy=231,113
AudioSynthWaveformDc dcPitchBend; //xy=234.7666778564453,184.00001525878906 AudioSynthWaveformDc dcPitchBend; //xy=234,184
AudioSynthWaveformDc dcFilter; //xy=336.76666259765625,595.0000305175781 AudioSynthWaveformDc dcFilter; //xy=336,595
AudioSynthNoisePink pinkNoise; //xy=358.76666259765625,320 AudioSynthNoisePink pinkNoise; //xy=358,320
AudioSynthNoiseWhite whiteNoise; //xy=361.76666259765625,284 AudioSynthWaveformDc dcLfoFreq; //xy=360,369
AudioSynthWaveformDc dcLfoFreq; //xy=365.76666259765625,376 AudioSynthNoiseWhite whiteNoise; //xy=361,284
AudioEffectEnvelope filterEnvelope; //xy=367.76666259765625,540.0000305175781 AudioEffectEnvelope filterEnvelope; //xy=367,540
AudioSynthWaveformDc dcFilterKeyTrack; //xy=369.76666259765625,629.0000305175781 AudioSynthWaveformDc dcFilterKeyTrack; //xy=369,629
AudioAmplifier ampPitchBend; //xy=407.7666778564453,184.00001525878906 AudioAmplifier ampPitchBend; //xy=407,184
AudioMixer4 noiseMixer; //xy=544.7666625976562,317 AudioMixer4 noiseMixer; //xy=544,317
AudioSynthWaveformModulated lfoWaveform; //xy=548.7666625976562,374 AudioSynthWaveformModulated lfoWaveform; //xy=549,369
AudioAmplifier ampOsc3Mod; //xy=549.7666625976562,437 AudioAmplifier ampOsc3Mod; //xy=549,437
AudioAmplifier ampModEg; //xy=559.7666625976562,475 AudioAmplifier ampModEg; //xy=559,475
AudioMixer4 mainTuneMixer; //xy=631.7666625976562,133 AudioMixer4 mainTuneMixer; //xy=631,133
AudioMixer4 modMix2; //xy=755.7666015625,470 AudioMixer4 modMix2; //xy=755,470
AudioMixer4 modMix1; //xy=756.7666015625,399 AudioMixer4 modMix1; //xy=756,399
AudioSynthWaveformDc dcOsc3; //xy=758.7667541503906,193.00001525878906 AudioSynthWaveformDc dcOsc3; //xy=758,193
AudioMixer4 osc3ControlMixer; //xy=933.7667236328125,199 AudioMixer4 osc3ControlMixer; //xy=933,199
AudioMixer4 modMixer; //xy=945.7666015625,448 AudioMixer4 modMixer; //xy=945,448
AudioSynthWaveformDc dcOsc2Tune; //xy=1105.566650390625,155.56666564941406 AudioSynthWaveformDc dcOsc2Tune; //xy=1105,155
AudioSynthWaveformDc dcOsc3Tune; //xy=1106.36669921875,221.56666564941406 AudioSynthWaveformDc dcOsc3Tune; //xy=1106,221
AudioAmplifier ampModWheel; //xy=1159.7666015625,448 AudioAmplifier ampModWheel; //xy=1159,448
AudioMixer4 osc3TuneMixer; //xy=1289.36669921875,217.56666564941406 AudioMixer4 osc3TuneMixer; //xy=1289,217
AudioMixer4 osc2TuneMixer; //xy=1290.566650390625,153.56666564941406 AudioMixer4 osc2TuneMixer; //xy=1290,153
AudioSynthWaveformDc dcPulse; //xy=1306.566665649414,65.56666564941406 AudioSynthWaveformDc dcPulse; //xy=1306,65
AudioSynthWaveformModulated osc1Waveform; //xy=1523.7666015625,114 AudioSynthWaveformModulated osc1Waveform; //xy=1523,114
AudioSynthWaveformModulated osc2Waveform; //xy=1524.7666015625,151 AudioSynthWaveformModulated osc2Waveform; //xy=1524,151
AudioSynthWaveformModulated osc3Waveform; //xy=1524.7666015625,188 AudioSynthWaveformModulated osc3Waveform; //xy=1524,188
AudioMixer4 oscMixer; //xy=1710.7666015625,157 AudioMixer4 oscMixer; //xy=1710,157
AudioMixer4 globalMixer; //xy=1919.7666015625,204 AudioMixer4 globalMixer; //xy=1919,204
AudioAmplifier ampPreFilter; //xy=2083.7666015625,203 AudioAmplifier ampPreFilter; //xy=2083,203
AudioMixer4 filterMixer; //xy=2101.7666625976562,446 AudioMixer4 filterMixer; //xy=2101,446
AudioFilterStateVariable vcf; //xy=2270.7666625976562,440 AudioFilterStateVariable vcf; //xy=2270,440
AudioMixer4 bandMixer; //xy=2441.566665649414,435.56666564941406 AudioMixer4 bandMixer; //xy=2441,435
AudioEffectEnvelope mainEnvelope; //xy=2620.7664794921875,436 AudioEffectEnvelope mainEnvelope; //xy=2620,436
AudioEffectBitcrusher bitCrushOutput; //xy=2856.5662841796875,433.566650390625 AudioEffectBitcrusher bitCrushOutput; //xy=2856,433
AudioOutputI2S i2s; //xy=3046.7659912109375,435 AudioOutputI2S i2s; //xy=3046,435
AudioConnection patchCord1(dcFilterEnvelope, filterEnvelope); AudioConnection patchCord1(dcFilterEnvelope, filterEnvelope);
AudioConnection patchCord2(dcOscTune, 0, mainTuneMixer, 1); AudioConnection patchCord2(dcOscTune, 0, mainTuneMixer, 1);
AudioConnection patchCord3(dcKeyTrack, 0, mainTuneMixer, 0); AudioConnection patchCord3(dcKeyTrack, 0, mainTuneMixer, 0);
AudioConnection patchCord4(dcPitchBend, ampPitchBend); AudioConnection patchCord4(dcPitchBend, ampPitchBend);
AudioConnection patchCord5(dcFilter, 0, filterMixer, 2); AudioConnection patchCord5(dcFilter, 0, filterMixer, 2);
AudioConnection patchCord6(pinkNoise, 0, noiseMixer, 1); AudioConnection patchCord6(pinkNoise, 0, noiseMixer, 1);
AudioConnection patchCord7(whiteNoise, 0, noiseMixer, 0); AudioConnection patchCord7(dcLfoFreq, 0, lfoWaveform, 0);
AudioConnection patchCord8(dcLfoFreq, 0, lfoWaveform, 0); AudioConnection patchCord8(whiteNoise, 0, noiseMixer, 0);
AudioConnection patchCord9(filterEnvelope, 0, filterMixer, 1); AudioConnection patchCord9(filterEnvelope, 0, filterMixer, 1);
AudioConnection patchCord10(filterEnvelope, ampModEg); AudioConnection patchCord10(filterEnvelope, ampModEg);
AudioConnection patchCord11(dcFilterKeyTrack, 0, filterMixer, 3); AudioConnection patchCord11(dcFilterKeyTrack, 0, filterMixer, 3);
@ -87,10 +87,10 @@ AudioConnection patchCord40(globalMixer, ampPreFilter);
AudioConnection patchCord41(ampPreFilter, 0, vcf, 0); AudioConnection patchCord41(ampPreFilter, 0, vcf, 0);
AudioConnection patchCord42(filterMixer, 0, vcf, 1); AudioConnection patchCord42(filterMixer, 0, vcf, 1);
AudioConnection patchCord43(vcf, 0, bandMixer, 0); AudioConnection patchCord43(vcf, 0, bandMixer, 0);
AudioConnection patchCord44(vcf, 2, bandMixer, 1); AudioConnection patchCord44(vcf, 1, bandMixer, 1);
AudioConnection patchCord45(bandMixer, mainEnvelope); AudioConnection patchCord45(bandMixer, mainEnvelope);
AudioConnection patchCord46(mainEnvelope, 0, globalMixer, 1); AudioConnection patchCord46(mainEnvelope, bitCrushOutput);
AudioConnection patchCord47(mainEnvelope, bitCrushOutput); AudioConnection patchCord47(mainEnvelope, 0, globalMixer, 1);
AudioConnection patchCord48(bitCrushOutput, 0, i2s, 0); AudioConnection patchCord48(bitCrushOutput, 0, i2s, 0);
AudioConnection patchCord49(bitCrushOutput, 0, i2s, 1); AudioConnection patchCord49(bitCrushOutput, 0, i2s, 1);
// GUItool: end automatically generated code // GUItool: end automatically generated code

@ -24,6 +24,24 @@
* All user inputs are handled and send to the teensy board using midi commands * All user inputs are handled and send to the teensy board using midi commands
*/ */
/*
* Pinout
*
* RX from mega 1 (through tension divider) 0
* TX to mega 1 (serial 1) 1
* mega 1 reset 2
*
* RX from mega 2 (through tension divider) 16
* TX to mega 2 (serial 4) 17
* mega 2 reset 18
*
* I2S OUT1A 7
* I2S LRCLK1 20
* I2S BCLK1 21
*
* D+ & D- are also used to break the USB port to the rear panel
*/
#include <Audio.h> #include <Audio.h>
#include <Wire.h> #include <Wire.h>
#include <SPI.h> #include <SPI.h>
@ -33,7 +51,7 @@
#include "audio_setup.h" #include "audio_setup.h"
#include "defs.h" #include "defs.h"
//#include "MIDI.h" #include "MIDI.h"
// constants // constants
const uint8_t KEYTRACK_MAX = 10; const uint8_t KEYTRACK_MAX = 10;
@ -47,14 +65,28 @@ const float NOTE_RATIO = 1.0594630943593;
const float HALFTONE_TO_DC = (float)1 / (MAX_OCTAVE * 12); const float HALFTONE_TO_DC = (float)1 / (MAX_OCTAVE * 12);
const float FILTER_HALFTONE_TO_DC = (float)1 / (FILTER_MAX_OCTAVE * 12); const float FILTER_HALFTONE_TO_DC = (float)1 / (FILTER_MAX_OCTAVE * 12);
const float MAX_MIX = 0.8; const float MAX_MIX = 0.9;
const uint16_t RESO = 1024;
const uint16_t HALF_RESO = RESO / 2;
const int16_t PITCH_BEND_MIN = -168;
const int16_t PITCH_BEND_MAX = 134;
const int16_t PITCH_BEND_NEUTRAL = PITCH_BEND_MIN + (PITCH_BEND_MAX - PITCH_BEND_MIN) / 2;
const int16_t PITCH_BEND_COURSE = PITCH_BEND_MAX - PITCH_BEND_MIN;
const uint16_t MOD_WHEEL_MIN = 360;
const uint16_t MOD_WHEEL_MAX = 666;
const uint16_t MOD_WHEEL_NEUTRAL = MOD_WHEEL_MIN + (MOD_WHEEL_MAX - MOD_WHEEL_MIN) / 2;
const uint16_t MOD_WHEEL_COURSE = MOD_WHEEL_MAX - MOD_WHEEL_MIN;
const uint8_t MEGA1_RST = 2;
const uint8_t MEGA2_RST = 18;
// variables // variables
uint8_t midiChannel = 1; uint8_t midiChannel = 1;
int8_t transposeOffset = 5;
uint16_t glide = 0; uint16_t glide = 0;
bool glideEn = 0; bool glideEn = 0;
@ -80,6 +112,9 @@ uint8_t waveforms[6] = {WAVEFORM_SINE, WAVEFORM_TRIANGLE, WAVEFORM_SAWTOOTH,
uint8_t keyTrackIndex = 0; uint8_t keyTrackIndex = 0;
uint8_t keyTrack[KEYTRACK_MAX] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t keyTrack[KEYTRACK_MAX] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// double CC track
uint8_t ccTempValue[32];
enum keyMode_t{ enum keyMode_t{
KEY_FIRST = 0, KEY_FIRST = 0,
KEY_LAST, KEY_LAST,
@ -89,25 +124,49 @@ enum keyMode_t{
keyMode_t keyMode = KEY_LAST; keyMode_t keyMode = KEY_LAST;
struct midiSettings : public midi::DefaultSettings{
// static const bool UseRunningStatus = true;
static const long BaudRate = 115200;
};
//MIDI_CREATE_DEFAULT_INSTANCE(); // The one we use on synth
//MIDI_CREATE_INSTANCE(UsbTransport, sUsbTransport, usbMIDI); MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial1, midi1, midiSettings);
MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial4, midi2, midiSettings);
void setup() { void setup() {
// midi settings, start and callback usbMIDI.begin(1); usbMIDI.setHandleNoteOn(handleNoteOn) usbMIDI.setHandleNoteOff(handleNoteOff) usbMIDI.setHandlePitchBend(handlePitchBend) usbMIDI.setHandleControlChange(handleControlChange); // Mega resets
pinMode(MEGA1_RST, OUTPUT);
pinMode(MEGA2_RST, OUTPUT);
digitalWrite(MEGA1_RST, 0);
digitalWrite(MEGA2_RST, 0);
usbMIDI.setHandleNoteOn(handleNoteOn); // midi settings, start and callback
usbMIDI.setHandleNoteOff(handleNoteOff); midi1.begin(1);
usbMIDI.setHandlePitchChange(handlePitchBend); midi1.turnThruOff();
usbMIDI.setHandleControlChange(handleControlChange); midi1.setHandleNoteOn(handleNoteOn);
midi1.setHandleNoteOff(handleNoteOff);
midi1.setHandlePitchBend(handlePitchBend);
midi1.setHandleControlChange(handleControlChange);
Serial.begin(115200); midi2.begin(1);
// Serial.println("started..."); midi2.turnThruOff();
midi2.setHandleControlChange(handleControlChange);
/*
Serial.begin(115200);
Serial.println("started...");
*/
AudioMemory(200); AudioMemory(200);
digitalWrite(MEGA1_RST, 1);
digitalWrite(MEGA2_RST, 1);
delay(500);
midi1.sendControlChange(CC_ASK_FOR_DATA, 127, 1);
midi2.sendControlChange(CC_ASK_FOR_DATA, 127, 1);
// audio settings // audio settings
// dc // dc
dcKeyTrack.amplitude(0.0); dcKeyTrack.amplitude(0.0);
@ -122,11 +181,10 @@ void setup() {
dcOsc3Tune.amplitude(0.0); dcOsc3Tune.amplitude(0.0);
dcPulse.amplitude(-0.95); dcPulse.amplitude(-0.95);
// amp // amp
ampPitchBend.gain(3 * HALFTONE_TO_DC * 2); ampPitchBend.gain(3 * HALFTONE_TO_DC * 2);
ampModWheel.gain(0); ampModWheel.gain(0);
ampPreFilter.gain(0.7); ampPreFilter.gain(1.0);
ampModEg.gain(0.01); ampModEg.gain(0.01);
ampOsc3Mod.gain(1); ampOsc3Mod.gain(1);
@ -207,18 +265,22 @@ void setup() {
bitCrushOutput.bits(16); bitCrushOutput.bits(16);
bitCrushOutput.sampleRate(44100.0); bitCrushOutput.sampleRate(44100.0);
usbMIDI.sendControlChange(CC_ASK_FOR_DATA, 127, 1); delay(500);
midi1.sendControlChange(CC_ASK_FOR_DATA, 127, 1);
midi2.sendControlChange(CC_ASK_FOR_DATA, 127, 1);
} }
void loop() { void loop() {
usbMIDI.read(); midi1.read();
midi2.read();
} }
void noteOn(uint8_t note, uint8_t velocity, bool trigger = 1){ void noteOn(uint8_t note, uint8_t velocity, bool trigger = 1){
float duration = (float)glideEn * (float)glide * 30.0; float duration = (float)glideEn * (float)glide * 3.75;
float level = (float)note * HALFTONE_TO_DC; float level = ((float)note + 12 * transpose) * HALFTONE_TO_DC;
float filterLevel = (float)note * FILTER_HALFTONE_TO_DC; float filterLevel = ((float)note + 12 * transpose) * FILTER_HALFTONE_TO_DC;
AudioNoInterrupts(); AudioNoInterrupts();
dcKeyTrack.amplitude(level, duration); dcKeyTrack.amplitude(level, duration);
@ -265,6 +327,11 @@ int8_t keyTrackRemoveNote(uint8_t note){
} }
void handleNoteOn(uint8_t channel, uint8_t note, uint8_t velocity){ void handleNoteOn(uint8_t channel, uint8_t note, uint8_t velocity){
/*
Serial.print("note ");
Serial.print(note);
Serial.println(" on");
*/
switch(keyMode){ switch(keyMode){
// When KEY_FIRST, we play the note only if there is not one already playing // When KEY_FIRST, we play the note only if there is not one already playing
case KEY_FIRST: case KEY_FIRST:
@ -294,6 +361,11 @@ void handleNoteOn(uint8_t channel, uint8_t note, uint8_t velocity){
} }
void handleNoteOff(uint8_t channel, uint8_t note, uint8_t velocity){ void handleNoteOff(uint8_t channel, uint8_t note, uint8_t velocity){
/*
Serial.print("note ");
Serial.print(note);
Serial.println(" off");
*/
switch(keyMode){ switch(keyMode){
case KEY_FIRST: case KEY_FIRST:
/* if(keyTrackRemoveNote(note) == 0){ /* if(keyTrackRemoveNote(note) == 0){
@ -318,185 +390,228 @@ void handleNoteOff(uint8_t channel, uint8_t note, uint8_t velocity){
} }
void handlePitchBend(uint8_t channel, int16_t bend){ void handlePitchBend(uint8_t channel, int16_t bend){
dcPitchBend.amplitude(((float)bend - 64) / 128); dcPitchBend.amplitude(((float)bend - PITCH_BEND_NEUTRAL) / PITCH_BEND_COURSE);
// Pitch bend goes from -168 to 134.
// neutral at -11 from up, -24 from down. :/
/*
Serial.print("pitch bend :");
Serial.println(bend);
*/
} }
void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){
// Serial.println("control change"); /*
Serial.print("control change ");
Serial.println(command);
*/
uint16_t longValue = 0;
if(command < 32){
ccTempValue[command] = value;
/*
Serial.print("value : ");
Serial.print(value << 7);
Serial.print(" (sent : ");
Serial.print(value);
Serial.println(')');
*/
} else if(command < 64){
longValue = (uint16_t)ccTempValue[command - 32];
longValue <<= 7;
longValue += value;
/*
Serial.print("value : ");
Serial.print(longValue);
Serial.print(" (sent : ");
Serial.print(value);
Serial.println(')');
*/
} else {
/*
Serial.print("value : ");
Serial.println(value);
*/
}
switch(command){ switch(command){
case CC_MOD_WHEEL: // CC_1 case CC_MOD_WHEEL:
ampModWheel.gain((float)value / 12 / 127); // CC_1
break; break;
case CC_MODULATION_MIX: // CC_3 case CC_MODULATION_MIX:
AudioNoInterrupts(); // CC_3
modMixer.gain(0, (float)value / 127);
modMixer.gain(1, (127 - (float)value) / 127);
AudioInterrupts();
break; break;
case CC_PORTAMENTO_TIME: case CC_PORTAMENTO_TIME:
// CC_5 // CC_5
glide = value;
break; break;
case CC_OSC_TUNE: case CC_OSC_TUNE:
// CC_9 // CC_9
dcOscTune.amplitude(HALFTONE_TO_DC * 2 * ((float)value - 64) / 127);
break; break;
case CC_OSC2_TUNE: case CC_OSC2_TUNE:
// CC_12 // CC_12
dcOsc2Tune.amplitude(HALFTONE_TO_DC * 12 * 2 * ((float)value - 64) / 127);
break; break;
case CC_OSC3_TUNE: case CC_OSC3_TUNE:
// CC_13 // CC_13
dcOsc3Tune.amplitude(HALFTONE_TO_DC * 12 * 2 * ((float)value - 64) / 127);
break; break;
case CC_OSC1_MIX: case CC_OSC1_MIX:
// CC_14 // CC_14
oscMixer.gain(0, MAX_MIX * (float)value / 127);
break; break;
case CC_OSC2_MIX: case CC_OSC2_MIX:
// CC_15 // CC_15
oscMixer.gain(1, MAX_MIX * (float)value / 127);
break; break;
case CC_OSC3_MIX: case CC_OSC3_MIX:
// CC_16 // CC_16
oscMixer.gain(2, MAX_MIX * (float)value / 127);
break; break;
case CC_NOISE_MIX: case CC_NOISE_MIX:
// CC_17 // CC_17
oscMixer.gain(3, MAX_MIX * (float)value / 127);
break; break;
case CC_FEEDBACK_MIX: case CC_FEEDBACK_MIX:
// CC_18 // CC_18
globalMixer.gain(1, MAX_MIX * (float)value / 127);
break; break;
case CC_FILTER_BAND: case CC_FILTER_BAND:
// CC_19 // CC_19
AudioNoInterrupts();
bandMixer.gain(0, ((float)value - 127) / 127);
bandMixer.gain(1, (float)value / 127);
AudioInterrupts();
break; break;
case CC_FILTER_CUTOFF_FREQ: case CC_FILTER_CUTOFF_FREQ:
// CC_20 // CC_20
// vcf.frequency((float)value * 32); // vcf.frequency((float)value * 32);
dcFilter.amplitude(((float)value - 64) / 127);
break; break;
case CC_FILTER_EMPHASIS: case CC_FILTER_EMPHASIS:
// CC_21 // CC_21
vcf.resonance(0.7 + (float)value / 29.53);
break; break;
case CC_FILTER_CONTOUR: case CC_FILTER_CONTOUR:
// CC_22 // CC_22
filterMixer.gain(1, (float)value / 127); break;
case CC_FILTER_ATTACK: case CC_FILTER_ATTACK:
// CC_23 // CC_23
filterEnvelope.attack((float)value * 40);
break; break;
case CC_FILTER_DECAY: case CC_FILTER_DECAY:
// CC_24 // CC_24
filterDecay = value * 40;
AudioNoInterrupts();
filterEnvelope.decay(filterDecay);
if(decay) filterEnvelope.release(filterDecay);
AudioInterrupts();
break; break;
case CC_FILTER_SUSTAIN: case CC_FILTER_SUSTAIN:
// CC_25 // CC_25
filterEnvelope.sustain((float)value / 127);
break; break;
case CC_FILTER_RELEASE: case CC_FILTER_RELEASE:
// CC_26 // CC_26
filterEnvelope.release((float)value / 127);
break; break;
case CC_EG_ATTACK: case CC_EG_ATTACK:
// CC_27 // CC_27
mainEnvelope.attack((float)value * 40);
break; break;
case CC_EG_DECAY: case CC_EG_DECAY:
// CC_28 // CC_28
egDecay = value * 40;
AudioNoInterrupts();
mainEnvelope.decay(egDecay);
if(decay) mainEnvelope.release(egDecay);
AudioInterrupts();
break; break;
case CC_EG_SUSTAIN: case CC_EG_SUSTAIN:
// CC_29 // CC_29
mainEnvelope.sustain((float)value / 127);
break; break;
case CC_LFO_RATE: case CC_LFO_RATE:
// CC_31 // CC_31
dcLfoFreq.amplitude((float)value / 127);
break; break;
case CC_MOD_WHEEL_LSB: case CC_MOD_WHEEL_LSB:
// CC_33 // CC_33
ampModWheel.gain(((float)longValue - 1 - MOD_WHEEL_MIN) / 12 / MOD_WHEEL_COURSE);
// Mod wheel goes from 360 to 666.
/*
Serial.print("mod wheel : ");
Serial.println(longValue);
*/
break; break;
case CC_MODULATION_MIX_LSB: case CC_MODULATION_MIX_LSB:
// CC_35 // CC_35
AudioNoInterrupts();
modMixer.gain(0, (float)longValue / RESO);
modMixer.gain(1, (RESO - (float)longValue) / RESO);
AudioInterrupts();
break; break;
case CC_PORTAMENTO_TIME_LSB: case CC_PORTAMENTO_TIME_LSB:
// CC_37 // CC_37
glide = longValue;
break; break;
case CC_OSC_TUNE_LSB: case CC_OSC_TUNE_LSB:
// CC_41 // CC_41
dcOscTune.amplitude(HALFTONE_TO_DC * 2 * ((float)longValue - HALF_RESO) / RESO);
break; break;
case CC_OSC2_TUNE_LSB: case CC_OSC2_TUNE_LSB:
// CC_44 // CC_44
dcOsc2Tune.amplitude(HALFTONE_TO_DC * 12 * 2 * ((float)longValue - HALF_RESO) / RESO);
break; break;
case CC_OSC3_TUNE_LSB: case CC_OSC3_TUNE_LSB:
// CC_45 // CC_45
dcOsc3Tune.amplitude(HALFTONE_TO_DC * 12 * 2 * ((float)longValue - HALF_RESO) / RESO);
break; break;
case CC_OSC1_MIX_LSB: case CC_OSC1_MIX_LSB:
// CC_46 // CC_46
oscMixer.gain(0, MAX_MIX * (float)longValue / RESO);
break; break;
case CC_OSC2_MIX_LSB: case CC_OSC2_MIX_LSB:
// CC_47 // CC_47
oscMixer.gain(1, MAX_MIX * (float)longValue / RESO);
break; break;
case CC_OSC3_MIX_LSB: case CC_OSC3_MIX_LSB:
// CC_48 // CC_48
oscMixer.gain(2, MAX_MIX * (float)longValue / RESO);
break; break;
case CC_NOISE_MIX_LSB: case CC_NOISE_MIX_LSB:
// CC_49 // CC_49
oscMixer.gain(3, MAX_MIX * (float)longValue / RESO);
break; break;
case CC_FEEDBACK_MIX_LSB: case CC_FEEDBACK_MIX_LSB:
// CC_50 // CC_50
globalMixer.gain(1, MAX_MIX * (float)longValue / RESO);
break; break;
case CC_FILTER_BAND_LSB: case CC_FILTER_BAND_LSB:
// CC_51 // CC_51
AudioNoInterrupts();
bandMixer.gain(0, ((float)longValue - RESO) / RESO);
bandMixer.gain(1, (float)longValue / RESO);
AudioInterrupts();
break; break;
case CC_FILTER_CUTOFF_FREQ_LSB: case CC_FILTER_CUTOFF_FREQ_LSB:
// CC_52 // CC_52
dcFilter.amplitude(((float)longValue - HALF_RESO) / RESO);
break; break;
case CC_FILTER_EMPHASIS_LSB: case CC_FILTER_EMPHASIS_LSB:
// CC_53 // CC_53
vcf.resonance(0.7 + (float)longValue / 237.90);
break; break;
case CC_FILTER_CONTOUR_LSB: case CC_FILTER_CONTOUR_LSB:
// CC_54 // CC_54
filterMixer.gain(1, (float)longValue / RESO);
break; break;
case CC_FILTER_ATTACK_LSB: case CC_FILTER_ATTACK_LSB:
// CC_55 // CC_55
filterEnvelope.attack((float)longValue * 5.0);
break; break;
case CC_FILTER_DECAY_LSB: case CC_FILTER_DECAY_LSB:
// CC_56 // CC_56
filterEnvelope.decay((float)longValue * 5.0);
break; break;
case CC_FILTER_SUSTAIN_LSB: case CC_FILTER_SUSTAIN_LSB:
// CC_57 // CC_57
filterEnvelope.sustain((float)longValue / RESO);
break; break;
case CC_EG_ATTACK_LSB: case CC_FILTER_RELEASE_LSB:
// CC_58 // CC_58
filterEnvelope.release((float)longValue * 5.0);
break; break;
case CC_EG_DECAY_LSB: case CC_EG_ATTACK_LSB:
// CC_59 // CC_59
mainEnvelope.attack((float)longValue * 5.0);
break; break;
case CC_EG_SUSTAIN_LSB: case CC_EG_DECAY_LSB:
// CC_60 // CC_60
mainEnvelope.decay((float)longValue * 5.0);
break; break;
case CC_LFO_RATE_LSB: case CC_EG_SUSTAIN_LSB:
// CC_61
mainEnvelope.sustain((float)longValue / RESO);
break;
case CC_EG_RELEASE_LSB:
// CC_62 // CC_62
mainEnvelope.release((float)longValue * 5.0);
break;
case CC_LFO_RATE_LSB:
// CC_63
dcLfoFreq.amplitude((float)longValue / RESO);
break; break;
case CC_PORTAMENTO_ON_OFF: case CC_PORTAMENTO_ON_OFF:
// CC_65 // CC_65
if(value > 63){ if(value < 64){
glideEn = 1; glideEn = 1;
} else { } else {
glideEn = 0; glideEn = 0;
@ -608,6 +723,7 @@ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){
mainTuneMixer.gain(3, 0); mainTuneMixer.gain(3, 0);
} }
break; break;
/*
case CC_DECAY_SW: case CC_DECAY_SW:
// CC_116 // CC_116
AudioNoInterrupts(); AudioNoInterrupts();
@ -622,6 +738,7 @@ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){
} }
AudioInterrupts(); AudioInterrupts();
break; break;
*/
case CC_MOD_MIX_1: case CC_MOD_MIX_1:
// CC_117 // CC_117
AudioNoInterrupts(); AudioNoInterrupts();
@ -646,12 +763,21 @@ void handleControlChange(uint8_t channel, uint8_t command, uint8_t value){
} }
AudioInterrupts(); AudioInterrupts();
break; break;
/* case CC_LFO_SHAPE: // CC_119 case CC_LFO_SHAPE:
// CC_119
AudioNoInterrupts();
if(value > 63){ if(value > 63){
lfoWaveform.begin(WAVEFORM_TRIANGLE);
lfoWaveform.offset(0.0);
lfoWaveform.amplitude(1.0);
} else { } else {
lfoWaveform.begin(WAVEFORM_SQUARE);
lfoWaveform.offset(0.5);
lfoWaveform.amplitude(0.5);
} }
AudioInterrupts();
break; break;
*/ default: default:
break; break;
} }
} }

@ -0,0 +1,9 @@
0 GND
1 5V
2 pitch bend
3 mod wheel
4 LFO rate
5 glide
6 LFO shape
7 function
8 not used

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 58 KiB

Loading…
Cancel
Save