diff --git a/Input.h b/Input.h new file mode 100644 index 0000000..5268513 --- /dev/null +++ b/Input.h @@ -0,0 +1,88 @@ +#ifndef Input_h +#define Input_h + +/* + * Input + */ +class Input{ + + private: + byte analogInput; + byte midiChannel; + byte midiControl; + byte value; + + public: + Input(); + Input(byte analogInput); + Input(byte midiChannel, byte midiControl); + Input(byte analogInput, byte midiChannel, byte midiControl); + byte getAnalogInput(); + byte getMidiChannel(); + byte getMidiControl(); + byte getValue(); + void setValue(byte value); + void handleMidi(byte channel, byte control, byte value); + void handleAnalog(); +}; + +/** + * Constructor + */ +inline Input::Input(){ +} + +inline Input::Input(byte analogInput){ + this->analogInput = analogInput; +} + +inline Input::Input(byte midiChannel, byte midiControl){ + this->analogInput = 255; + this->midiChannel = midiChannel; + this->midiControl = midiControl; +} + +inline Input::Input(byte analogInput, byte midiChannel, byte midiControl){ + this->analogInput = analogInput; + this->midiChannel = midiChannel; + this->midiControl = midiControl; +} + +inline byte Input::getAnalogInput(){ + return this->analogInput; +} + +inline byte Input::getMidiChannel(){ + return this->midiChannel; +} + +inline byte Input::getMidiControl(){ + return this->midiControl; +} + +inline byte Input::getValue(){ + return this->value; +} + +inline void Input::setValue(byte value){ + this->value = value; +} + +inline void Input::handleMidi(byte channel, byte control, byte value){ + if(channel == this->midiChannel && control == this->midiControl){ + byte byteValue = map(value, 0, 127, 0, 255); + this->value = byteValue; + } +} + +inline void Input::handleAnalog(){ + if(this->analogInput < 255){ + byte value = map(analogRead(this->analogInput), 0, 1023, 0, 255); + + if(this->value != value){ + this->value = value; + } + } +} + +#endif diff --git a/README.md b/README.md index c76350a..432ed4b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # SimpleSynth SimpleSynth is a Teensy based synth with the main objective to keep it simple. +NOTE: I have stopped maintaining this repo in favor of [Synth](https://github.com/ghostintranslation/synth). + ## Features * FM, AM and Ring synthesis with 1 carier and 1 modulator diff --git a/SimpleSynth.ino b/SimpleSynth.ino index 57e1c4e..8cd6b23 100644 --- a/SimpleSynth.ino +++ b/SimpleSynth.ino @@ -12,6 +12,7 @@ https://github.com/ghostintranslation #include MIDI_CREATE_DEFAULT_INSTANCE(); // MIDI library init +#include "Input.h" #include "Synth.h" int ledPin = 13; @@ -20,7 +21,17 @@ bool controllerIsLaunchpad = true; const int interval_time = 50; elapsedMillis clock_count; -Synth synth(A0, A1, A2, A3, A4, A5, A6, A7, A8); +Input synthInput(1, 0); +Input modeInput(A1, 0, 1); +Input parameterInput(A2, 0, 2); +Input modulatorFrequencyInput(A5, 0, 5); +Input modulatorAmplitudeInput(A4, 0, 4); +Input mixInput(A3, 0, 3); +Input attackInput(A8, 0, 8); +Input decayInput(A6, 0, 6); +Input releaseInput(A7, 1, 7); + +Synth synth(&synthInput, &modeInput, ¶meterInput, &modulatorFrequencyInput, &modulatorAmplitudeInput, &mixInput, &attackInput, &decayInput, &releaseInput); // AudioOutputI2S i2s2; AudioConnection patchCord1(*synth.getOutput(), 0, i2s2, 0); @@ -41,10 +52,12 @@ void setup() { MIDI.setHandleNoteOn(onNoteOn); MIDI.setHandleNoteOff(onNoteOff); + MIDI.setHandleControlChange(onControlChange); MIDI.begin(MIDI_CHANNEL_OMNI); usbMIDI.setHandleNoteOn(onNoteOn); usbMIDI.setHandleNoteOff(onNoteOff); + usbMIDI.setHandleControlChange(onControlChange); usbMIDI.setHandleStop(onStop); usbMIDI.setHandleSystemReset(onStop); @@ -130,13 +143,23 @@ void onStop() { } -void myControlChange(byte channel, byte control, byte value){ - Serial.print("myControlChange "); +void onControlChange(byte channel, byte control, byte value){ + Serial.print("onControlChange "); Serial.print(channel); Serial.print(" "); Serial.print(control); Serial.print(" "); - Serial.print(value); + Serial.println(value); + + synthInput.handleMidi(channel, control, value); + modeInput.handleMidi(channel, control, value); + parameterInput.handleMidi(channel, control, value); + modulatorFrequencyInput.handleMidi(channel, control, value); + modulatorAmplitudeInput.handleMidi(channel, control, value); + mixInput.handleMidi(channel, control, value); + attackInput.handleMidi(channel, control, value); + decayInput.handleMidi(channel, control, value); + releaseInput.handleMidi(channel, control, value); } diff --git a/Synth.h b/Synth.h index 6bcf7a6..b39d93c 100644 --- a/Synth.h +++ b/Synth.h @@ -3,6 +3,7 @@ #include +#include "Input.h" #include "Voice.h" @@ -33,14 +34,15 @@ class Synth{ unsigned int release; int modulatorFrequency; float modulatorAmplitude; - byte synthPin; - byte modePin; - byte parameterPin; - byte modulatorFrequencyPin; - byte modulatorAmplitudePin; - byte attackPin; - byte decayPin; - byte releasePin; + + Input *synthInput; + Input *modeInput; + Input *parameterInput; + Input *modulatorFrequencyInput; + Input *modulatorAmplitudeInput; + Input *attackInput; + Input *decayInput; + Input *releaseInput; AudioConnection* patchCords[voiceCount/4 + voiceCount]; AudioMixer4 *mixers[voiceCount/2]; @@ -48,7 +50,7 @@ class Synth{ public: Synth(); - Synth(byte synthPin, byte modePin, byte parameterPin, byte modulatorFrequencyPin, byte modulatorAmplitudePin, byte mixPin, byte attackPin, byte decayPin, byte releasePin); + Synth(Input *synthInput, Input *modeInput, Input *parameterInput, Input *modulatorFrequencyInput, Input *modulatorAmplitudeInput, Input *mixPin, Input *attackInput, Input *decayInput, Input *releaseInput); void noteOn(byte midiNote); void noteOff(byte midiNote); @@ -94,15 +96,15 @@ inline Synth::Synth(){ /** * Constructor that sets the potentiometer pins */ -inline Synth::Synth(byte synthPin, byte modePin, byte parameterPin, byte modulatorFrequencyPin, byte modulatorAmplitudePin, byte mixPin, byte attackPin, byte decayPin, byte releasePin): Synth(){ - this->synthPin = synthPin; - this->modePin = modePin; - this->parameterPin = parameterPin; - this->modulatorFrequencyPin = modulatorFrequencyPin; - this->modulatorAmplitudePin = modulatorAmplitudePin; - this->attackPin = attackPin; - this->decayPin = decayPin; - this->releasePin = releasePin; +inline Synth::Synth(Input *synthInput, Input *modeInput, Input *parameterInput, Input *modulatorFrequencyInput, Input *modulatorAmplitudeInput, Input *mixPin, Input *attackInput, Input *decayInput, Input *releaseInput): Synth(){ + this->synthInput = synthInput; + this->modeInput = modeInput; + this->parameterInput = parameterInput; + this->modulatorFrequencyInput = modulatorFrequencyInput; + this->modulatorAmplitudeInput = modulatorAmplitudeInput; + this->attackInput = attackInput; + this->decayInput = decayInput; + this->releaseInput = releaseInput; } @@ -205,7 +207,9 @@ inline AudioMixer4 * Synth::getOutput(){ inline void Synth::update(){ // Synthesis - byte synthesis = (byte)map(analogRead(this->synthPin), 0, 1023, 0, 4); + this->synthInput->handleAnalog(); + + byte synthesis = (byte)map(this->synthInput->getValue(), 0, 255, 0, 4); if(this->synthesis != synthesis){ this->synthesis = synthesis; for (int i = 0; i < voiceCount ; i++) { @@ -214,7 +218,9 @@ inline void Synth::update(){ } // Mode - byte mode = (byte)map(analogRead(this->modePin), 0, 1023, 0, 2); + this->modeInput->handleAnalog(); + + byte mode = (byte)map(this->modeInput->getValue(), 0, 255, 0, 2); if(this->mode != mode){ this->mode = mode; @@ -244,7 +250,9 @@ inline void Synth::update(){ } // Parameter - int parameter = analogRead(this->parameterPin); + this->parameterInput->handleAnalog(); + + int parameter = this->parameterInput->getValue(); if(this->parameter != parameter){ this->parameter = parameter; switch(modes(this->mode)){ @@ -284,8 +292,10 @@ inline void Synth::update(){ // Attack + this->attackInput->handleAnalog(); + // TODO This should send a standardized value from 0 to 1023 - int attack = map(analogRead(this->attackPin), 0, 1023, 0, 2000); + int attack = map(this->attackInput->getValue(), 0, 255, 0, 2000); if(this->attack != attack){ this->attack = attack; for (int i = 0; i < voiceCount ; i++) { @@ -294,8 +304,10 @@ inline void Synth::update(){ } // Decay + this->decayInput->handleAnalog(); + // TODO This should send a standardized value from 0 to 1023 - int decay = map(analogRead(this->decayPin), 0, 1023, 0, 2000); + int decay = map(this->decayInput->getValue(), 0, 255, 0, 2000); if(this->decay != decay){ this->decay = decay; for (int i = 0; i < voiceCount ; i++) { @@ -304,8 +316,11 @@ inline void Synth::update(){ } // Release + this->releaseInput->handleAnalog(); + // TODO This should send a standardized value from 0 to 1023 - int release = map(analogRead(this->releasePin), 0, 1023, 0, 2000); + int release = map(this->releaseInput->getValue(), 0, 255, 0, 2000); + if(this->release != release){ this->release = release; for (int i = 0; i < voiceCount ; i++) { @@ -314,8 +329,10 @@ inline void Synth::update(){ } // Modulator frequency + this->modulatorFrequencyInput->handleAnalog(); + // TODO This should send a standardized value from 0 to 1023 - int modulatorFrequency = map(analogRead(this->modulatorFrequencyPin), 0, 1023, 1, 50); + int modulatorFrequency = map(this->modulatorFrequencyInput->getValue(), 0, 255, 1, 50); if(this->modulatorFrequency != modulatorFrequency){ this->modulatorFrequency = modulatorFrequency; for (int i = 0; i < voiceCount ; i++) { @@ -324,8 +341,10 @@ inline void Synth::update(){ } // Modulator amplitude + this->modulatorAmplitudeInput->handleAnalog(); + // TODO This should send a standardized value from 0 to 1023 - float modulatorAmplitude = (float)analogRead(this->modulatorAmplitudePin)/(float)4096; + float modulatorAmplitude = (float)map((float)this->modulatorAmplitudeInput->getValue(), 0, 255, 0, 1); if(this->modulatorAmplitude != modulatorAmplitude){ this->modulatorAmplitude = modulatorAmplitude; for (int i = 0; i < voiceCount ; i++) {