//Hardware Definitions #define Knob1 A6 //Intensity #define Knob2 A4 //Modulation Frequency #define Knob3 A2 //Harmonics #define Knob4 A0 #define KnobA A5 #define KnobDR A3 #define KnobS A1 #define CVIn A7 #define GateIn 10 #define EnvSwitch 11 #define DroneSwitch 12 #define LED 5 // smoothing for intensity to remove clicks on transitions float smoothness = 0.95f; Smooth aSmoothIntensity(smoothness); int carrierFreq = 440; int mod_ratio = 5; // brightness (harmonics) long fm_intensity; // carries control info from updateControl to updateAudio void MIDINoteOn(byte channel, byte note, byte velocity) { carrierFreq = mtof((int) note); envelope.noteOn(); MIDINotePlaying = true; digitalWrite(LED, LOW); } void MIDINoteOff(byte channel, byte note, byte velocity) { envelope.noteOff(); //MIDINotePlaying = false; digitalWrite(LED, HIGH); } void setup(){ //pinMode(LED_BUILTIN_TX,INPUT); //switch rx and tx leds of, so they don't blink on midi //pinMode(LED_BUILTIN_RX,INPUT); pinMode(LED, OUTPUT); pinMode(GateIn, INPUT_PULLUP); pinMode(EnvSwitch, INPUT_PULLUP); pinMode(DroneSwitch, INPUT_PULLUP); MIDI.setHandleNoteOn(MIDINoteOn); MIDI.setHandleNoteOff(MIDINoteOff); MIDI.begin(MIDI_CHANNEL); startMozzi(); digitalWrite(LED, HIGH); } void updateControl(){ //Get Control Values int CVInVal = mozziAnalogRead(CVIn); int knob1Val = mozziAnalogRead(Knob1); int knob2Val = mozziAnalogRead(Knob2); int knob3Val = mozziAnalogRead(Knob3); int knob4Val = mozziAnalogRead(Knob4); int knobAVal = mozziAnalogRead(KnobA); int knobDRVal = mozziAnalogRead(KnobDR); int knobSVal = mozziAnalogRead(KnobS); bool droneSwitchVal = digitalRead(DroneSwitch); bool envSwitchVal = digitalRead(EnvSwitch); bool gateInVal = !digitalRead(GateIn); //Remap the Values if (!MIDINotePlaying) { carrierFreq = kMapCarrierFreq(CVInVal); //Pitch if (gateInVal && !gateIsHigh) { gateIsHigh = true; envelope.noteOn(); } else if (!gateInVal && gateIsHigh) { gateIsHigh = false; envelope.noteOff(); } } else if (MIDINotePlaying && !envelope.playing()) { // MIDINotePlaying = false; } int intensity = kMapIntensity(knob1Val); float modSpeed = (float)kMapModSpeed(knob2Val)/1000; //float for lower frequencies int harmonics = kMapHarmonics(knob3Val); int knob4Map = 1;//mapThisToo(knob4Val); //Update Envelope Settings int attackTime = kMapAttack(knobAVal); int decayReleaseTime = kMapDecayRelease(knobDRVal); int sustainLevel = kMapSustain(knobSVal); envelope.setDecayLevel(sustainLevel); //Should be enough //envelope.setSustainLevel(sustainLevel); //but with this, just in case envelope.setTimes(attackTime, decayReleaseTime, 30000, decayReleaseTime); //30000 is so the note will sustain 30 seconds unless a noteOff comes //envelope.setDecayLevel(100); //envelope.setSustainLevel(100); //envelope.setTimes(150, 300, 10000, 300); //10000 is so the note will sustain 10 seconds unless a noteOff comes //calculate the modulation frequency to stay in ratio int modFreq = carrierFreq * mod_ratio * harmonics; // set the FM oscillator frequencies aCarrier.setFreq(carrierFreq); aModulator.setFreq(modFreq); // calculate the fm_intensity fm_intensity = ((long)intensity * knob4Map * (kIntensityMod.next()+128))>>8; // shift back to range after 8 bit multiply kIntensityMod.setFreq(modSpeed); MIDI.read(); digitalWrite(LED, !gateInVal); envelope.update(); if(!droneSwitchVal) { gain = envelope.next(); } else { gain = 255; } } AudioOutput updateAudio(){ long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next(); return MonoOutput::from16Bit((int) gain * aCarrier.phMod(modulation)); } void loop(){ audioHook(); }