2020-10-08 20:20:01 +00:00
|
|
|
#include <MozziGuts.h>
|
2020-12-27 23:09:38 +00:00
|
|
|
#include <mozzi_midi.h>
|
2020-10-08 20:20:01 +00:00
|
|
|
#include <Oscil.h> // oscillator
|
|
|
|
#include <tables/cos2048_int8.h> // table for Oscils to play
|
|
|
|
#include <Smooth.h>
|
|
|
|
#include <AutoMap.h> // maps unpredictable inputs to a range
|
|
|
|
#include <MIDIUSB.h>
|
2020-10-22 21:35:32 +00:00
|
|
|
#include <MIDI.h>
|
|
|
|
|
|
|
|
MIDI_CREATE_DEFAULT_INSTANCE();
|
2020-10-08 20:20:01 +00:00
|
|
|
|
|
|
|
#define CONTROL_RATE 64
|
2020-12-27 23:09:38 +00:00
|
|
|
#define MIDI_CHANNEL 3
|
2020-10-08 20:20:01 +00:00
|
|
|
|
|
|
|
bool gate = 0;
|
|
|
|
|
|
|
|
// desired carrier frequency max and min, for AutoMap
|
|
|
|
const int MIN_CARRIER_FREQ = 22;
|
|
|
|
const int MAX_CARRIER_FREQ = 440;
|
|
|
|
|
2020-12-14 23:09:50 +00:00
|
|
|
const int MIN = 10;
|
|
|
|
const int MAX = 1;
|
2020-10-08 20:20:01 +00:00
|
|
|
|
|
|
|
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<COS2048_NUM_CELLS, AUDIO_RATE> aCarrier(COS2048_DATA);
|
|
|
|
Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aModulator(COS2048_DATA);
|
|
|
|
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> 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 <long> aSmoothIntensity(smoothness);
|
|
|
|
|
|
|
|
int carrier_freq = 440;
|
|
|
|
|
|
|
|
void noteOn(byte channel, byte note, byte velocity) {
|
2021-02-27 00:57:20 +00:00
|
|
|
if (channel == MIDI_CHANNEL) {
|
2020-12-27 23:09:38 +00:00
|
|
|
carrier_freq = mtof((int) note);
|
|
|
|
gate = 1;
|
|
|
|
}
|
2020-10-08 20:20:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void noteOff(byte channel, byte note, byte velocity) {
|
2021-02-27 00:57:20 +00:00
|
|
|
if (channel == MIDI_CHANNEL) {
|
2020-12-27 23:09:38 +00:00
|
|
|
gate = 0;
|
|
|
|
}
|
2020-10-08 20:20:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2020-10-22 21:35:32 +00:00
|
|
|
|
|
|
|
startMozzi();
|
|
|
|
|
|
|
|
MIDI.setHandleNoteOn(noteOn);
|
|
|
|
MIDI.setHandleNoteOff(noteOff);
|
2021-02-27 00:57:20 +00:00
|
|
|
MIDI.begin(MIDI_CHANNEL);
|
2020-10-08 20:20:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void updateControl(){
|
|
|
|
midiEventPacket_t rx;
|
|
|
|
do {
|
|
|
|
rx = MidiUSB.read();
|
|
|
|
if (rx.header == 0x09) {
|
2021-02-27 00:57:20 +00:00
|
|
|
noteOn(rx.byte1 - 143, rx.byte2, rx.byte3); //need to figure out what's with this 143 and 127 on noteoff
|
2020-10-08 20:20:01 +00:00
|
|
|
} else if (rx.header == 0x08) {
|
2021-02-27 00:57:20 +00:00
|
|
|
noteOff(rx.byte1 - 127, rx.byte2, rx.byte3);
|
2020-10-08 20:20:01 +00:00
|
|
|
}
|
|
|
|
} 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
|
2021-02-27 00:57:20 +00:00
|
|
|
int Knob1value= mozziAnalogRead(CONTROLL1); // value is 0-1023
|
2020-10-08 20:20:01 +00:00
|
|
|
|
|
|
|
|
2021-02-27 00:57:20 +00:00
|
|
|
int Knob1calibrated = kMapIntensity(Knob1value);
|
2020-10-08 20:20:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
// calculate the fm_intensity
|
2021-02-27 00:57:20 +00:00
|
|
|
fm_intensity = ((long)Knob1calibrated * knob2Val * (kIntensityMod.next()+128))>>8; // shift back to range after 8 bit multiply
|
2020-10-08 20:20:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
// read the light dependent resistor on the speed Analog input pin
|
2021-02-27 00:57:20 +00:00
|
|
|
int Knob2value= mozziAnalogRead(CONTROLL2); // value is 0-1023
|
2020-10-08 20:20:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
// use a float here for low frequencies
|
2021-02-27 00:57:20 +00:00
|
|
|
float mod_speed = (float)kMapModSpeed(Knob2value)/1000;
|
2020-10-08 20:20:01 +00:00
|
|
|
|
|
|
|
kIntensityMod.setFreq(mod_speed);
|
2020-10-22 21:35:32 +00:00
|
|
|
|
|
|
|
MIDI.read();
|
2020-10-08 20:20:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|