aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lfoFreqArray.h97
-rw-r--r--multiFilter.h97
-rw-r--r--squelette_synth_midi.ino103
3 files changed, 267 insertions, 30 deletions
diff --git a/lfoFreqArray.h b/lfoFreqArray.h
new file mode 100644
index 0000000..fa3bab3
--- /dev/null
+++ b/lfoFreqArray.h
@@ -0,0 +1,97 @@
+
+#if ARDUINO >= 100
+# include "Arduino.h"
+#else
+# include "WProgram.h"
+#endif
+#include <avr/pgmspace.h>
+// La grosse ligne incomprehensible est un macro utilisé par GCC pour mettre la variable dans
+// la memoire flash du microcontroleur.
+const float __attribute__ ((section(".progmem.data"))) LFO_ARRAY[] = {
+
+ 0.1, 0.15843137254901962, 0.2168627450980392, 0.2752941176470588,
+ 0.33372549019607844, 0.3921568627450981, 0.4505882352941176,
+ 0.5090196078431373, 0.5674509803921569, 0.6258823529411764,
+ 0.6843137254901961, 0.7427450980392157, 0.8011764705882353,
+ 0.8596078431372549, 0.9180392156862746, 0.9764705882352941,
+ 1.0349019607843137, 1.0933333333333335, 1.151764705882353,
+ 1.2101960784313728, 1.2686274509803923, 1.3270588235294118,
+ 1.3854901960784316, 1.4439215686274511, 1.5023529411764707,
+ 1.5607843137254904, 1.61921568627451, 1.6776470588235295,
+ 1.7360784313725492, 1.7945098039215688, 1.8529411764705883,
+ 1.911372549019608, 1.9698039215686276, 2.028235294117647,
+ 2.086666666666667, 2.1450980392156866, 2.203529411764706,
+ 2.2619607843137257, 2.3203921568627455, 2.378823529411765,
+ 2.4372549019607845, 2.4956862745098043, 2.5541176470588236,
+ 2.6125490196078434, 2.670980392156863, 2.7294117647058824,
+ 2.787843137254902, 2.846274509803922, 2.9047058823529412,
+ 2.963137254901961, 3.0215686274509808, 3.08, 3.13843137254902,
+ 3.1968627450980396, 3.255294117647059, 3.3137254901960786,
+ 3.3721568627450984, 3.4305882352941177, 3.4890196078431375,
+ 3.5474509803921572, 3.6058823529411765, 3.6643137254901963,
+ 3.722745098039216, 3.7811764705882354, 3.839607843137255,
+ 3.898039215686275, 3.956470588235294, 4.0149019607843135,
+ 4.073333333333333, 4.131764705882353, 4.190196078431373,
+ 4.248627450980392, 4.307058823529411, 4.365490196078431,
+ 4.423921568627451, 4.482352941176471, 4.54078431372549,
+ 4.599215686274509, 4.657647058823529, 4.716078431372549,
+ 4.7745098039215685, 4.832941176470588, 4.891372549019608,
+ 4.949803921568627, 5.008235294117647, 5.066666666666666,
+ 5.125098039215686, 5.183529411764706, 5.241960784313726,
+ 5.300392156862745, 5.358823529411764, 5.417254901960784,
+ 5.475686274509804, 5.534117647058824, 5.592549019607843,
+ 5.650980392156862, 5.709411764705882, 5.767843137254902,
+ 5.8262745098039215, 5.884705882352941, 5.943137254901961,
+ 6.00156862745098, 6.06, 6.118431372549019, 6.176862745098039,
+ 6.235294117647059, 6.293725490196079, 6.3521568627450975,
+ 6.410588235294117, 6.469019607843137, 6.527450980392157,
+ 6.5858823529411765, 6.644313725490196, 6.702745098039215,
+ 6.761176470588235, 6.819607843137255, 6.878039215686274,
+ 6.936470588235294, 6.994901960784314, 7.053333333333333,
+ 7.1117647058823525, 7.170196078431372, 7.228627450980392,
+ 7.287058823529412, 7.345490196078432, 7.40392156862745,
+ 7.46235294117647, 7.52078431372549, 7.57921568627451,
+ 7.6376470588235295, 7.696078431372549, 7.754509803921569,
+ 7.812941176470588, 7.871372549019608, 7.929803921568627,
+ 7.988235294117647, 8.046666666666667, 8.105098039215687,
+ 8.163529411764706, 8.221960784313726, 8.280392156862746,
+ 8.338823529411764, 8.397254901960784, 8.455686274509803,
+ 8.514117647058823, 8.572549019607843, 8.630980392156863,
+ 8.689411764705882, 8.747843137254902, 8.806274509803922,
+ 8.864705882352942, 8.923137254901961, 8.981568627450981, 9.04,
+ 9.098431372549019, 9.156862745098039, 9.215294117647058,
+ 9.273725490196078, 9.332156862745098, 9.390588235294118,
+ 9.449019607843137, 9.507450980392157, 9.565882352941177,
+ 9.624313725490197, 9.682745098039216, 9.741176470588234,
+ 9.799607843137254, 9.858039215686274, 9.916470588235294,
+ 9.974901960784313, 10.033333333333333, 10.091764705882353,
+ 10.150196078431373, 10.208627450980392, 10.267058823529412,
+ 10.325490196078432, 10.383921568627452, 10.44235294117647,
+ 10.50078431372549, 10.55921568627451, 10.617647058823529,
+ 10.676078431372549, 10.734509803921569, 10.792941176470588,
+ 10.851372549019608, 10.909803921568628, 10.968235294117648,
+ 11.026666666666667, 11.085098039215687, 11.143529411764705,
+ 11.201960784313725, 11.260392156862745, 11.318823529411764,
+ 11.377254901960784, 11.435686274509804, 11.494117647058824,
+ 11.552549019607843, 11.610980392156863, 11.669411764705883,
+ 11.727843137254903, 11.786274509803922, 11.844705882352942,
+ 11.90313725490196, 11.96156862745098, 12.02, 12.07843137254902,
+ 12.136862745098039, 12.195294117647059, 12.253725490196079,
+ 12.312156862745098, 12.370588235294118, 12.429019607843138,
+ 12.487450980392158, 12.545882352941177, 12.604313725490195,
+ 12.662745098039215, 12.721176470588235, 12.779607843137255,
+ 12.838039215686274, 12.896470588235294, 12.954901960784314,
+ 13.013333333333334, 13.071764705882353, 13.130196078431373,
+ 13.188627450980393, 13.247058823529413, 13.30549019607843,
+ 13.36392156862745, 13.42235294117647, 13.48078431372549,
+ 13.53921568627451, 13.59764705882353, 13.65607843137255,
+ 13.714509803921569, 13.772941176470589, 13.831372549019608,
+ 13.889803921568628, 13.948235294117648, 14.006666666666666,
+ 14.065098039215686, 14.123529411764705, 14.181960784313725,
+ 14.240392156862745, 14.298823529411765, 14.357254901960784,
+ 14.415686274509804, 14.474117647058824, 14.532549019607844,
+ 14.590980392156863, 14.649411764705883, 14.707843137254901,
+ 14.766274509803921, 14.82470588235294, 14.88313725490196,
+ 14.94156862745098, 15.0
+};
+
diff --git a/multiFilter.h b/multiFilter.h
new file mode 100644
index 0000000..1b65fe0
--- /dev/null
+++ b/multiFilter.h
@@ -0,0 +1,97 @@
+#ifndef MultiFilter_H
+# define MultiFilter_H
+# include <StateVariable.h>
+# include <LowPassFilter.h>
+
+class Multifilter {
+ private:
+ int filterSelection;
+ int freq;
+ int res;
+ LowPassFilter lpf;
+ StateVariable <NOTCH> nf;
+ StateVariable <HIGHPASS> hpf;
+ StateVariable <BANDPASS> bpf;
+
+ public:
+
+ Multifilter(int type){
+ filterSelection = type;
+ }
+
+ /**
+ * 0: Lowpass 1: Highpass, 2 : Bandpass, 3: Notch, 4 : Allpass.
+ */
+ int changeFilter(int selection) {
+ if (filterSelection != selection){
+ filterSelection = selection;
+ setResonance(res);
+ setCutoffFreq(freq);
+ }
+ }
+
+ int setResonance(int resonance) {
+ res = resonance;
+ switch (filterSelection) {
+ case 0:
+ lpf.setResonance(resonance);
+ break;
+ case 1:
+ // Oh non, c'est trop louuurd.
+ //hpf.setResonance(map(resonance, 180, 1, 0, 255));
+ // Approximation d'un mappage de valeurs de 0 à 255 vers 20 à 147.
+ hpf.setResonance(180 - (resonance>>1) -33);
+ break;
+ case 2:
+ bpf.setResonance(180 - (resonance>>1) -33);
+ break;
+ case 3:
+ nf.setResonance(180 - (resonance>>1) -33);
+ break;
+ }
+ }
+
+ int setCutoffFreq(int cutoff) {
+ freq = cutoff;
+ switch (filterSelection) {
+ case 0:
+ lpf.setCutoffFreq(cutoff);
+ break;
+ case 1:
+ // Approximation de mappage de valeurs de 0 à 255 vers 20 à 4100.
+ hpf.setCentreFreq((cutoff<<4)+20);
+ break;
+ case 2:
+
+ bpf.setCentreFreq((cutoff<<4)+20);
+ break;
+ case 3:
+
+ nf.setCentreFreq((cutoff<<4)+20);
+ break;
+ }
+ }
+
+ int next(int signal) {
+ switch (filterSelection) {
+ case 0:
+ return lpf.next(signal);
+
+ case 1:
+ return hpf.next(signal);
+
+ case 2:
+ return bpf.next(signal);
+
+ case 3:
+ return nf.next(signal);
+
+ case 4:
+ return signal;
+
+ }
+ }
+
+};
+#endif
+
diff --git a/squelette_synth_midi.ino b/squelette_synth_midi.ino
index 6e5edf2..ea272d4 100644
--- a/squelette_synth_midi.ino
+++ b/squelette_synth_midi.ino
@@ -8,7 +8,8 @@
#include <ADSR.h>
#include <LowPassFilter.h>
#include "pitchbendArray.h"
-
+#include "multiFilter.h"
+#include "lfoFreqArray.h"
#define CONTROL_RATE 256
@@ -17,15 +18,23 @@ int tableChange = 0;
Oscil <SAW256_NUM_CELLS, AUDIO_RATE> ncoOne(SAW256_DATA),
ncoTwo(SAW256_DATA), ncoThree(SAW256_DATA);
-Oscil <SIN256_NUM_CELLS, CONTROL_RATE> lfo(SIN256_DATA);
-ADSR <CONTROL_RATE> adsr;
-int noteOnn = 1;
+
+Oscil <SIN256_NUM_CELLS, CONTROL_RATE> lfoOne(SIN256_DATA),
+lfoTwo(SIN256_DATA);
+
+ADSR <CONTROL_RATE> adsr_envelope;
+ADSR <CONTROL_RATE> adsr_filter;
+
+
float lastFreq = 0;
-int noteOnBuffer[4];
+int noteBuffer[4];
int bufferIndex = 0;
float pbAmount = 0.0;
float lastMidiNote = 0.0;
LowPassFilter lpf;
+int lastLfoValues[2];
+Multifilter mf(0);
+bool lfoEffect[2][5]; //0:oscil1, 1:oscil2, 2:oscil3, 3:envelope, 4:detune
void handlePitchBend(byte channel, byte lsb, byte msb) {
@@ -42,10 +51,10 @@ void handleNoteOn(byte channel, byte note, byte velocity) {
}
for(int i = 3; i > 0; i--) {
- noteOnBuffer[i] = noteOnBuffer[i - 1];
+ noteBuffer[i] = noteBuffer[i - 1];
}
- noteOnBuffer[0] = note;
+ noteBuffer[0] = note;
jouerNote((float)note);
}
@@ -54,27 +63,29 @@ void jouerNote(float note) {
lastFreq = Q16n16_to_float(Q16n16_mtof(float_to_Q16n16(totalNote)));
ncoOne.setFreq(lastFreq);
lastMidiNote = note;
- adsr.noteOn();
+ adsr_filter.noteOn();
+ adsr_envelope.noteOn();
}
void handleNoteOff(byte channel, byte note, byte velocity) {
int i = 0;
- while(i < 3 && noteOnBuffer[i] != note) {
+ while(i < 3 && noteBuffer[i] != note) {
i++;
}
while(i < 3) {
- noteOnBuffer[i] = noteOnBuffer[i + 1];
+ noteBuffer[i] = noteBuffer[i + 1];
i += 1;
}
if(i < 4) {
- noteOnBuffer[3] = -1;
+ noteBuffer[3] = -1;
}
- if(noteOnBuffer[0] != -1) {
- jouerNote((float)noteOnBuffer[0]);
+ if(noteBuffer[0] != -1) {
+ jouerNote((float)noteBuffer[0]);
} else {
- noteOnn = 0;
- adsr.noteOff();
+
+ adsr_filter.noteOff();
+ adsr_envelope.noteOff();
}
}
@@ -85,31 +96,63 @@ void setup() {
ncoOne.setFreq(400);
startMozzi(CONTROL_RATE);
MIDI.begin();
- lfo.setFreq(1);
+ lfoOne.setFreq(1);
for(int i = 0; i < 3; i++) {
- noteOnBuffer[i] = -1;
+ noteBuffer[i] = -1;
}
- adsr.setADLevels(255, 210);
- adsr.setTimes(188, 345, 65000, 345);
- adsr.setSustainLevel(255);
- lpf.setResonance(156);
-
+ adsr_envelope.setADLevels(255, 210);
+ adsr_envelope.setTimes(188, 345, 65000, 345);
+ adsr_envelope.setSustainLevel(255);
+ mf.setResonance(156);
+ lastLfoValues[0] = 0;
+ lastLfoValues[1] = 0;
}
-int lfoNext = 0;
+int lastFilter = 0;
void updateControl() {
- lfoNext = lfo.next();
- ncoTwo.setFreq(lastFreq + (lfoNext * 0.02f));
- //version tarrée à virgule fixe.
- //ncoThree.setFreq((float)(((Q15n0_to_Q15n16((mozziAnalogRead(5)-512))*(float_to_Q15n16(0.004))>>23)*float_to_Q15n16(lastFreq))>>23));
+ lastLfoValues[0] = lfoOne.next();
+ lastLfoValues[1] = lfoTwo.next();
+ // Oscillator detune.
+ //
+ int filterReading = mozziAnalogRead(0)>>8;
+ if (lastFilter != filterReading ) {
+ mf.changeFilter(filterReading);
+ lastFilter = filterReading;
+ }
+
MIDI.read();
- adsr.update();
- lpf.setCutoffFreq(255 * adsr.next() >> 8);
+ adsr_envelope.update();
+ mf.setCutoffFreq(255 * adsr_envelope.next() >> 8);
}
int updateAudio() {
//adsr.next();
- return (int) (adsr.next()*(lpf.next((ncoOne.next() + ncoTwo.next() + ncoThree.next()) >> 2))) >> 2;
+
+ /**
+ int osc1 = ncoOne.next();
+ int osc2 = ncoTwo.next();
+ int osc3 = ncoThree.next();
+ */
+ /** for(int i=0;i<2;i++) {
+ if(lfoEffect[i][0] {
+ osc1 = osc1*lastLfoValues[i];
+ }
+ if(lfoEffect[i][1] {
+ osc2 = osc2*lastLfoValues[i];
+ }
+ if(lfoEffect[i][2] {
+ osc3 = osc3*lastLfoValues[i];
+ }
+ if(lfoEffect[i][3] {
+ //envelope
+ }
+ if(lfoEffect[i][4] {
+ //detune
+ }
+ } */
+
+
+ return (int) (adsr_envelope.next()*(mf.next((ncoOne.next() + ncoTwo.next() + ncoThree.next()) >> 2))) >> 2;
}
void loop() {