diff options
| author | Guillaume Riou <guiloua2@hotmail.com> | 2014-04-14 17:27:42 -0400 |
|---|---|---|
| committer | Guillaume Riou <guiloua2@hotmail.com> | 2014-04-14 17:27:42 -0400 |
| commit | 7ad727874e5dde9968b9d29a1a138e35af691b4f (patch) | |
| tree | b24a28de4601359586318389acb26b14f5fef7f1 | |
| parent | a3a7abadc5289008c618a01810770c71b11f8c0d (diff) | |
Adds support for pitch bend.
| -rw-r--r-- | pitchbendArray.h | 30 | ||||
| -rw-r--r-- | squelette_synth_midi.ino | 151 |
2 files changed, 116 insertions, 65 deletions
diff --git a/pitchbendArray.h b/pitchbendArray.h new file mode 100644 index 0000000..d0ef6ae --- /dev/null +++ b/pitchbendArray.h @@ -0,0 +1,30 @@ + +#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"))) PB_ARRAY[] = { + + -1.0, -0.984375, -0.96875, -0.953125, -0.9375, -0.921875, -0.90625, -0.890625, + -0.875, -0.859375, -0.84375, -0.828125, -0.8125, -0.796875, -0.78125, -0.765625, + -0.75, -0.734375, -0.71875, -0.703125, -0.6875, -0.671875, -0.65625, -0.640625, + -0.625, -0.609375, -0.59375, -0.578125, -0.5625, -0.546875, -0.53125, -0.515625, + -0.5, -0.484375, -0.46875, -0.453125, -0.4375, -0.421875, -0.40625, -0.390625, + -0.375, -0.359375, -0.34375, -0.328125, -0.3125, -0.296875, -0.28125, -0.265625, + -0.25, -0.234375, -0.21875, -0.203125, -0.1875, -0.171875, -0.15625, -0.140625, + -0.125, -0.109375, -0.09375, -0.078125, -0.0625, -0.046875, -0.03125, -0.015625, + 0.0, 0.015625, 0.03125, 0.046875, 0.0625, 0.078125, 0.09375, 0.109375, 0.125, + 0.140625, 0.15625, 0.171875, 0.1875, 0.203125, 0.21875, 0.234375, 0.25, 0.265625, + 0.28125, 0.296875, 0.3125, 0.328125, 0.34375, 0.359375, 0.375, 0.390625, 0.40625, + 0.421875, 0.4375, 0.453125, 0.46875, 0.484375, 0.5, 0.515625, 0.53125, 0.546875, + 0.5625, 0.578125, 0.59375, 0.609375, 0.625, 0.640625, 0.65625, 0.671875, 0.6875, + 0.703125, 0.71875, 0.734375, 0.75, 0.765625, 0.78125, 0.796875, 0.8125, 0.828125, + 0.84375, 0.859375, 0.875, 0.890625, 0.90625, 0.921875, 0.9375, 0.953125, 0.97275, + 1.0 + +}; + diff --git a/squelette_synth_midi.ino b/squelette_synth_midi.ino index 963101a..6e5edf2 100644 --- a/squelette_synth_midi.ino +++ b/squelette_synth_midi.ino @@ -7,91 +7,112 @@ #include <tables/sin256_int8.h> #include <ADSR.h> #include <LowPassFilter.h> +#include "pitchbendArray.h" + #define CONTROL_RATE 256 -int tableChange =0; -Oscil <SAW256_NUM_CELLS, AUDIO_RATE> nco(SAW256_DATA), nco_det(SAW256_DATA); + +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; -float lastFreq = 0.0; +float lastFreq = 0; int noteOnBuffer[4]; int bufferIndex = 0; +float pbAmount = 0.0; +float lastMidiNote = 0.0; LowPassFilter lpf; -void handleNoteOn(byte channel, byte note, byte velocity){ - //If velocity is 0, the noteOn message is equivalent to a noteOff message. - if(velocity == 0){ - handleNoteOff(channel,note,velocity); - return; - } - - for(int i = 3; i> 0 ; i --){ - noteOnBuffer[i] = noteOnBuffer[i-1]; - } - - noteOnBuffer[0] = note; - jouerNote(note); +void handlePitchBend(byte channel, byte lsb, byte msb) { + + pbAmount = pgm_read_float_near(PB_ARRAY+msb); + jouerNote(lastMidiNote); +} + +void handleNoteOn(byte channel, byte note, byte velocity) { + //If velocity is 0, the noteOn message is equivalent to a noteOff message. + if(velocity == 0) { + handleNoteOff(channel, note, velocity); + + return; + } + + for(int i = 3; i > 0; i--) { + noteOnBuffer[i] = noteOnBuffer[i - 1]; + } + + noteOnBuffer[0] = note; + jouerNote((float)note); } -void jouerNote(byte note){ - noteOnn = 1; - lastFreq = mtof(note); - nco.setFreq(lastFreq); - - adsr.noteOn(); +void jouerNote(float note) { + float totalNote = note + pbAmount; + lastFreq = Q16n16_to_float(Q16n16_mtof(float_to_Q16n16(totalNote))); + ncoOne.setFreq(lastFreq); + lastMidiNote = note; + adsr.noteOn(); } -void handleNoteOff(byte channel, byte note, byte velocity){ - int i =0; - while(i<3 && noteOnBuffer[i] != note){ - i ++; - } - while(i < 3){ - noteOnBuffer[i] = noteOnBuffer[i+1]; - i+=1; - } - if(i < 4){ - noteOnBuffer[3] = -1; - } - if(noteOnBuffer[0] != -1){ - jouerNote(noteOnBuffer[0]); - }else{ - noteOnn = 0; - adsr.noteOff(); - } +void handleNoteOff(byte channel, byte note, byte velocity) { + int i = 0; + + while(i < 3 && noteOnBuffer[i] != note) { + i++; + } + while(i < 3) { + noteOnBuffer[i] = noteOnBuffer[i + 1]; + i += 1; + } + if(i < 4) { + noteOnBuffer[3] = -1; + } + if(noteOnBuffer[0] != -1) { + jouerNote((float)noteOnBuffer[0]); + } else { + noteOnn = 0; + adsr.noteOff(); + } } -void setup(){ - MIDI.setHandleNoteOn(handleNoteOn); - MIDI.setHandleNoteOff(handleNoteOff); - nco.setFreq(400); - startMozzi(CONTROL_RATE); - MIDI.begin(); - lfo.setFreq(1); - for(int i = 0; i<3; i++){ - noteOnBuffer[i] = -1; - } - adsr.setADLevels(255,210); - adsr.setTimes(188,345,65000,345); - adsr.setSustainLevel(255); - lpf.setResonance(156); +void setup() { + MIDI.setHandleNoteOn(handleNoteOn); + MIDI.setHandleNoteOff(handleNoteOff); + MIDI.setHandlePitchBend(handlePitchBend); + ncoOne.setFreq(400); + startMozzi(CONTROL_RATE); + MIDI.begin(); + lfo.setFreq(1); + for(int i = 0; i < 3; i++) { + noteOnBuffer[i] = -1; + } + adsr.setADLevels(255, 210); + adsr.setTimes(188, 345, 65000, 345); + adsr.setSustainLevel(255); + lpf.setResonance(156); + } -void updateControl(){ - int lfoNext = lfo.next(); - nco_det.setFreq(lastFreq+(lfoNext*0.02f)); - MIDI.read(); - adsr.update(); - lpf.setCutoffFreq(255*adsr.next()>>8); +int lfoNext = 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)); + MIDI.read(); + adsr.update(); + lpf.setCutoffFreq(255 * adsr.next() >> 8); } -int updateAudio(){ - //adsr.next(); - return (int)(adsr.next()*(lpf.next((nco.next()+nco_det.next())>>2)))>>4; +int updateAudio() { + //adsr.next(); + return (int) (adsr.next()*(lpf.next((ncoOne.next() + ncoTwo.next() + ncoThree.next()) >> 2))) >> 2; } -void loop(){ - audioHook(); +void loop() { + audioHook(); } + |
