Compare commits

...

7 Commits
master ... dev

2 changed files with 86 additions and 34 deletions

116
FM/FM.ino
View File

@ -13,16 +13,8 @@ MIDI_CREATE_DEFAULT_INSTANCE();
#define MIDI_CHANNEL 3 #define MIDI_CHANNEL 3
bool gate = 0; bool gate = 0;
byte noteBuffer[8];
// desired carrier frequency max and min, for AutoMap byte bufferIndex = 0;
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 // desired intensity max and min, for AutoMap, note they're inverted for reverse dynamics
const int MIN_INTENSITY = 700; const int MIN_INTENSITY = 700;
@ -32,7 +24,12 @@ const int MAX_INTENSITY = 10;
const int MIN_MOD_SPEED = 10000; const int MIN_MOD_SPEED = 10000;
const int MAX_MOD_SPEED = 1; const int MAX_MOD_SPEED = 1;
AutoMap kMapCarrierFreq(0,1023,MIN_CARRIER_FREQ,MAX_CARRIER_FREQ); const int MIN = 10;
const int MAX = 1;
const int MIN_2 = 1;
const int MAX_2 = 15;
AutoMap kMapIntensity(0,1023,MIN_INTENSITY,MAX_INTENSITY); AutoMap kMapIntensity(0,1023,MIN_INTENSITY,MAX_INTENSITY);
AutoMap kMapModSpeed(0,1023,MIN_MOD_SPEED,MAX_MOD_SPEED); AutoMap kMapModSpeed(0,1023,MIN_MOD_SPEED,MAX_MOD_SPEED);
AutoMap mapThis(0,1023,MIN,MAX); AutoMap mapThis(0,1023,MIN,MAX);
@ -55,33 +52,69 @@ long fm_intensity; // carries control info from updateControl to updateAudio
float smoothness = 0.95f; float smoothness = 0.95f;
Smooth <long> aSmoothIntensity(smoothness); Smooth <long> aSmoothIntensity(smoothness);
int carrier_freq = 440; int carrier_freq;
void noteOn(byte channel, byte note, byte velocity) { void noteOn(byte channel, byte note, byte velocity) {
if (channel == MIDI_CHANNEL) { if (channel == MIDI_CHANNEL) {
carrier_freq = mtof((int) note);
gate = 1; gate = 1;
updateBuffer(note, gate);
//playNote(); // this is called from within buffer update
} }
} }
void noteOff(byte channel, byte note, byte velocity) { void noteOff(byte channel, byte note, byte velocity) {
if (channel == MIDI_CHANNEL) { if (channel == MIDI_CHANNEL) {
gate = 0; updateBuffer(note, 0);
} }
} }
void updateBuffer(byte bNote, bool bGate) {
if (bGate == 1) {
noteBuffer[bufferIndex] = bNote;
playNote();
bufferIndex++;
}
if (bGate == 0) { // && bufferIndex != 0
for (int i = 0; i <= bufferIndex; i++) {
if (noteBuffer[i] == bNote) {
// Removing the note from the array and shifting everything to close the gap
for (int n = i; n <= bufferIndex; n++) {
noteBuffer[n] = noteBuffer[n + 1]; // what happens if it's the last note in buffer?
}
bufferIndex--;
if (i == bufferIndex && i != 0) {
bufferIndex--; //we need to play the notefrom previous cell of buffer write index, that's where -- and ++ come from
gate = 1;
playNote();
bufferIndex++;
} else if (i == bufferIndex && i == 0) {
gate = 0;
}
}
}
}
}
void playNote() {
byte note = noteBuffer[bufferIndex];
carrier_freq = mtof((int) note);
}
void setup(){ void setup(){
pinMode(LED_BUILTIN_TX,INPUT); //switch rx and tx leds of, so they don't blink on midi // switch rx and tx leds of, so they don't blink on midi
pinMode(LED_BUILTIN_TX,INPUT);
pinMode(LED_BUILTIN_RX,INPUT); pinMode(LED_BUILTIN_RX,INPUT);
startMozzi(); startMozzi();
//MIDI DIN
MIDI.setHandleNoteOn(noteOn); MIDI.setHandleNoteOn(noteOn);
MIDI.setHandleNoteOff(noteOff); MIDI.setHandleNoteOff(noteOff);
MIDI.begin(MIDI_CHANNEL); MIDI.begin(MIDI_CHANNEL);
} }
void updateControl(){ void updateControl(){
//MIDI USB
midiEventPacket_t rx; midiEventPacket_t rx;
do { do {
rx = MidiUSB.read(); rx = MidiUSB.read();
@ -91,12 +124,14 @@ void updateControl(){
noteOff(rx.byte1 - 127, rx.byte2, rx.byte3); noteOff(rx.byte1 - 127, rx.byte2, rx.byte3);
} }
} while (rx.header != 0); } while (rx.header != 0);
int freqVal = mozziAnalogRead(CONTROLL3); // value is 0-1023 //Knob 3
int FRQ = mapThis(freqVal); int freqVal = mozziAnalogRead(CONTROLL3); // value is 0-1023
int FRQ = mapThis(freqVal);
int knob2 = mozziAnalogRead(CONTROLL4); // value is 0-1023
int knob2Val = mapThis(knob2); //Knob 4
int knob4 = mozziAnalogRead(CONTROLL4); // value is 0-1023
int knob4calibrated = mapThis(knob4);
//calculate the modulation frequency to stay in ratio //calculate the modulation frequency to stay in ratio
int mod_freq = carrier_freq * mod_ratio * FRQ; int mod_freq = carrier_freq * mod_ratio * FRQ;
@ -104,32 +139,47 @@ void updateControl(){
// set the FM oscillator frequencies // set the FM oscillator frequencies
aCarrier.setFreq(carrier_freq); aCarrier.setFreq(carrier_freq);
aModulator.setFreq(mod_freq); aModulator.setFreq(mod_freq);
// read the light dependent resistor on the width Analog input pin //Knob 1
int Knob1value= mozziAnalogRead(CONTROLL1); // value is 0-1023 int Knob1value= mozziAnalogRead(CONTROLL1); // value is 0-1023
int Knob1calibrated = kMapIntensity(Knob1value); int Knob1calibrated = kMapIntensity(Knob1value);
// calculate the fm_intensity // calculate the fm_intensity
fm_intensity = ((long)Knob1calibrated * knob2Val * (kIntensityMod.next()+128))>>8; // shift back to range after 8 bit multiply fm_intensity = ((long)Knob1calibrated * knob4calibrated * (kIntensityMod.next()+128))>>8; // shift back to range after 8 bit multiply
// read the light dependent resistor on the speed Analog input pin // Knob 2
int Knob2value= mozziAnalogRead(CONTROLL2); // value is 0-1023 int Knob2value= mozziAnalogRead(CONTROLL2); // value is 0-1023
// use a float here for low frequencies // use a float here for low frequencies
float mod_speed = (float)kMapModSpeed(Knob2value)/1000; float mod_speed = (float)kMapModSpeed(Knob2value)/1000;
kIntensityMod.setFreq(mod_speed); kIntensityMod.setFreq(mod_speed);
// Debugging
/*
Serial.print("Buffer Index: ");
Serial.print(bufferIndex);
Serial.print(" | Knob1: "); //3rd on the pannel, connected to A0
Serial.print(Knob1calibrated);
Serial.print(" | Knob2: "); //2nd on the pannel, conntcted to A1
Serial.print(Knob2value);
Serial.print(" | Knob3: "); //1st on the pannel, connected to A2, unstable around 0
Serial.print(FRQ);
Serial.print(" | Knob4: "); //4th on the pannel, A3
Serial.print(knob4calibrated);
Serial.println();
*/
// MIDI DIN
MIDI.read(); MIDI.read();
} }
int updateAudio(){ AudioOutput_t updateAudio(){
long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next(); long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next();
if (gate == 1) { if (gate == 1) {
return aCarrier.phMod(modulation);//(int)(envelope.next() * aCarrier.phMod(modulation))>>8; return aCarrier.phMod(modulation);//(int)(envelope.next() * aCarrier.phMod(modulation))>>8;

View File

@ -4,4 +4,6 @@ DIY Arduino-based synth built with [Mozzi library](https://sensorium.github.io/M
## ToDo: ## ToDo:
- Add note buffer - Add note buffer
- Tune the values and remap the knobs - Tune the values, remap the knobs, clean up the code
- Update readme
- Add schematics and documentations