aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pitchbendArray.h30
-rw-r--r--squelette_synth_midi.ino151
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();
}
+