#include #include #include // oscillator #include // table for Oscils to play #include #include // maps unpredictable inputs to a range #include #include MIDI_CREATE_DEFAULT_INSTANCE(); #define CONTROL_RATE 64 #define MIDI_CHANNEL 3 bool gate = 0; // desired carrier frequency max and min, for AutoMap const int MIN_CARRIER_FREQ = 22; const int MAX_CARRIER_FREQ = 440; const int MIN = 10; const int MAX = 1; const int MIN_2 = 1; const int MAX_2 = 15; // desired intensity max and min, for AutoMap, note they're inverted for reverse dynamics const int MIN_INTENSITY = 700; const int MAX_INTENSITY = 10; // desired mod speed max and min, for AutoMap, note they're inverted for reverse dynamics const int MIN_MOD_SPEED = 10000; const int MAX_MOD_SPEED = 1; AutoMap kMapCarrierFreq(0,1023,MIN_CARRIER_FREQ,MAX_CARRIER_FREQ); AutoMap kMapIntensity(0,1023,MIN_INTENSITY,MAX_INTENSITY); AutoMap kMapModSpeed(0,1023,MIN_MOD_SPEED,MAX_MOD_SPEED); AutoMap mapThis(0,1023,MIN,MAX); AutoMap mapThisToo(0,1023,MIN_2,MAX_2); //Mapping the knob pins const int CONTROLL1 = 0; const int CONTROLL2 = 1; const int CONTROLL3 = 2; const int CONTROLL4 = 3; Oscil aCarrier(COS2048_DATA); Oscil aModulator(COS2048_DATA); Oscil kIntensityMod(COS2048_DATA); int mod_ratio = 5; // brightness (harmonics) long fm_intensity; // carries control info from updateControl to updateAudio // smoothing for intensity to remove clicks on transitions float smoothness = 0.95f; Smooth aSmoothIntensity(smoothness); int carrier_freq = 440; void noteOn(byte channel, byte note, byte velocity) { if (channel == MIDI_CHANNEL) { carrier_freq = mtof((int) note); gate = 1; } } void noteOff(byte channel, byte note, byte velocity) { if (channel == MIDI_CHANNEL) { gate = 0; } } 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); startMozzi(); MIDI.setHandleNoteOn(noteOn); MIDI.setHandleNoteOff(noteOff); MIDI.begin(MIDI_CHANNEL); } void updateControl(){ midiEventPacket_t rx; do { rx = MidiUSB.read(); if (rx.header == 0x09) { noteOn(rx.byte1 - 143, rx.byte2, rx.byte3); //need to figure out what's with this 143 and 127 on noteoff } else if (rx.header == 0x08) { noteOff(rx.byte1 - 127, rx.byte2, rx.byte3); } } while (rx.header != 0); int freqVal = mozziAnalogRead(CONTROLL3); // value is 0-1023 int FRQ = mapThis(freqVal); int knob2 = mozziAnalogRead(CONTROLL4); // value is 0-1023 int knob2Val = mapThis(knob2); //calculate the modulation frequency to stay in ratio int mod_freq = carrier_freq * mod_ratio * FRQ; // set the FM oscillator frequencies aCarrier.setFreq(carrier_freq); aModulator.setFreq(mod_freq); // read the light dependent resistor on the width Analog input pin int Knob1value= mozziAnalogRead(CONTROLL1); // value is 0-1023 int Knob1calibrated = kMapIntensity(Knob1value); // calculate the fm_intensity fm_intensity = ((long)Knob1calibrated * knob2Val * (kIntensityMod.next()+128))>>8; // shift back to range after 8 bit multiply // read the light dependent resistor on the speed Analog input pin int Knob2value= mozziAnalogRead(CONTROLL2); // value is 0-1023 // use a float here for low frequencies float mod_speed = (float)kMapModSpeed(Knob2value)/1000; kIntensityMod.setFreq(mod_speed); MIDI.read(); } int updateAudio(){ long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next(); if (gate == 1) { return aCarrier.phMod(modulation);//(int)(envelope.next() * aCarrier.phMod(modulation))>>8; } } void loop(){ audioHook(); }