#include #include // oscillator #include // table for Oscils to play #include #include // maps unpredictable inputs to a range #include #include #include #include #define N_PAD 5 //Pad order 4, 0, 3, 2, 1 const int tone_piano[N_PAD] = { 1000, 60, 440, 220, 150 }; // for triggering the envelope EventDelay noteDelay; ADSR envelope; boolean note_is_on = true; // desired carrier frequency max and min, for AutoMap const int MIN_CARRIER_FREQ = 22; const int MAX_CARRIER_FREQ = 880; const int MIN = 1; const int MAX = 10; // desired intensity max and min, for AutoMap, note they're inverted for reverse dynamics const int MIN_INTENSITY = 1000; const int MAX_INTENSITY = 2; // desired mod speed max and min, for AutoMap, note they're inverted for reverse dynamics const int MIN_MOD_SPEED = 100000; 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); const int KNOB_PIN = 3; // set the input for the knob to analog pin 8 const int LDR1_PIN = 4; // set the analog input for fm_intensity to pin 9 const int LDR2_PIN = 5; // set the analog input for mod rate to pin 10 const int LDR3_PIN = 6; // multiplicator pin set to 11 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); void setup() { //Serial.begin(9600); // for Teensy 3.1, beware printout can cause glitches SerialUSB.begin(115200); // set up the Serial output so we can look at the piezo values // set up the Serial output so we can look at the light level randSeed(); noteDelay.set(10); startMozzi(); // :)) Wire.begin(1); Wire.onReceive(receiveEvent); } unsigned int duration, attack, decay, sustain, release_ms; //different parts of an ADSR envelope void updateControl() { if (noteDelay.ready()) { byte attack_level = rand(128) + 127; byte decay_level = rand(255); //random new adsr time parameter value in milliseconds unsigned int new_value = rand(300) + 100; //choose one adsr parameters randomly and set new value envelope.setADLevels(attack_level, decay_level); switch (rand(4)) { case 0: attack = new_value; // new_value; break; case 1: decay = new_value; // new_value; break; case 2: sustain = new_value; // new_value; break; case 3: release_ms = new_value; // new_value; break; } envelope.setTimes(attack, decay, sustain, release_ms); //Set Random note value /*byte midi_note = rand(107) + 20; aOscil.setFreq((int)mtof(midi_note));*/ noteDelay.start(attack + decay + sustain + release_ms); } int freqVal = mozziAnalogRead(LDR3_PIN); // value is 0-1023 int FRQ = mapThis(freqVal); // read the knob int knob_value = mozziAnalogRead(KNOB_PIN); // value is 0-1023 // map the knob to carrier frequency int carrier_freq = kMapCarrierFreq(knob_value); //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 Pot on the width Analog input pin int LDR1_value = mozziAnalogRead(LDR1_PIN); // value is 0-1023 int LDR1_calibrated = kMapIntensity(LDR1_value); // calculate the fm_intensity fm_intensity = ((long)LDR1_calibrated * (kIntensityMod.next() + 128)) >> 8; // shift back to range after 8 bit multiply // read the Pot on the speed Analog input pin int LDR2_value = mozziAnalogRead(LDR2_PIN); // value is 0-1023 // use a float here for low frequencies float mod_speed = (float)kMapModSpeed(LDR2_value) / 1000; kIntensityMod.setFreq(mod_speed); } AudioOutput_t updateAudio() { envelope.update(); long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next(); return MonoOutput::from16Bit((int)(envelope.next() * aCarrier.phMod(modulation))); //return MonoOutput::from16Bit((int)(envelope.next() * aOscil.next())); } void receiveEvent(int x) { int y = sustain; while (Wire.available()) { int c = Wire.read(); if (c < 6 && c >= 0) { aCarrier.setFreq(tone_piano[c]); envelope.noteOn(); sustain = 1000000; } else if (c == 6) { sustain = y; envelope.noteOff(); } /*else if (c > 1023 && c < 2048){ attack = map(c, 1024, 2047, 30, 2000); Wire.write("1024"); } else if (c > 2047 && c < 3072){ release_ms = map(c, 2048, 3071, 30, 2000); Wire.write(release_ms); }*/ } } void loop() { audioHook(); }