diff options
| author | Guillaume Riou <guiloua2@hotmail.com> | 2014-05-05 14:23:03 -0400 |
|---|---|---|
| committer | Guillaume Riou <guiloua2@hotmail.com> | 2014-05-05 14:23:03 -0400 |
| commit | 301ec25ed8dc6b627930a3842c4e94c4788b0dda (patch) | |
| tree | b104cc665f1c8de713b473f60091c64fff1c758b | |
| parent | 7ad727874e5dde9968b9d29a1a138e35af691b4f (diff) | |
Adds a multifilter class that is a wrapper around the 4 possible filters that
are included in mozzi. The control changes takes values from 0 to 255
and are internally converted to values the fancier filters (hpf,nf,bpf)
can use.
| -rw-r--r-- | lfoFreqArray.h | 97 | ||||
| -rw-r--r-- | multiFilter.h | 97 | ||||
| -rw-r--r-- | squelette_synth_midi.ino | 103 |
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() { |
