Compare commits
7 Commits
Author | SHA1 | Date |
---|---|---|
Oleksiy | 5bbaf130cd | |
Oleksiy | 383cae76d7 | |
Oleksiy | 0015cc0418 | |
Oleksiy | 16c22072a1 | |
Oleksiy | 032d9f3e1a | |
Oleksiy | b0025406ac | |
Oleksiy | 15e543a2e1 |
116
FM/FM.ino
116
FM/FM.ino
|
@ -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;
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue