Go Down

Topic: MIDI Polyphony (Read 397 times) previous topic - next topic

CDAfonso

Hello!

I'm running this project that reads data from Piezo's and send over MIDI USB (MocoLufa) the signals of 3 notes (36,38,46 - Kick, Snare, HiHat).

Its works but when i press two or three piezos at the same time it only sends one note at time.

It would be nice to get some delay between instructions (150ms), but everytime i use delay instruction, the piezos doensn't respond well.


Can you help me?


This is my code:

Quote
#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>

#define CHANNEL 1
#define DEBOUNCE 30



const int sensKC=0;
const int sensSN=1;
const int sensHH=2;

MIDI_CREATE_DEFAULT_INSTANCE();


int thKC = 300;
int thSN = 400;
int thHH = 400;


void setup() {
 Serial.begin(31250); 
  MIDI.begin();

}

void playKC(){
       MIDI.sendNoteOn(36, 127, CHANNEL);
       MIDI.sendNoteOff(36, 0, CHANNEL);

}

void playSN(){
       MIDI.sendNoteOn(38, 127, CHANNEL);
       MIDI.sendNoteOff(38, 0, CHANNEL);

}

void playHH(){
       MIDI.sendNoteOn(46, 127, CHANNEL);
       MIDI.sendNoteOff(46, 0, CHANNEL);

}

void playKCSN() {
       MIDI.sendNoteOn(36, 127, CHANNEL);
       MIDI.sendNoteOn(38, 127, CHANNEL);
       MIDI.sendNoteOff(36, 0, CHANNEL);
       MIDI.sendNoteOff(38, 0, CHANNEL);
}


void loop() {

 
  int valKC= analogRead(sensKC);
  int valSN= analogRead(sensSN);
  int valHH= analogRead(sensHH);

//KC
if ((valKC >= thKC) && (valSN < thSN) && (valHH < thHH)) {
       playKC(); 
       delay(150);
   
}


//SN   
if ((valSN >= thSN) && (valKC < thKC) && (valHH < thHH)) {
       playSN();
       
}

//HH
if ((valHH >= thHH) && (valKC < thKC) && (valSN < thSN)) {
       playHH();
     

}


}

DVDdoug

Quote
Its works but when i press two or three piezos at the same time it only sends one note at time.

It would be nice to get some delay between instructions (150ms), but everytime i use delay instruction, the piezos doensn't respond well.
Of course, if you delay after reading the 1st one you have to wait 150ms before you can read the next one.

delay() is kind-of rare in real world programs because program execution pauses and the processor can't "do anything" during the delay time.  

Look at the Blink Without Delay Example and try to understand how it works.   Then look at Demonstration code for several things at the same time.      Note that you can have multiple-simultaneous timers with different previous  variables and multiple interval  variables, but of course there is only one current time.

CDAfonso

Thanks DVDdoug, I understand now.
I was using delay to handle with unwanted retrigging.

Do you have any suggestions to get the multi-note working?

slipstick

Code: [Select]
if ((valKC >= thKC) && (valSN < thSN) && (valHH < thHH)) {
This and the other if statements are checking that only one piezo was hit. Presumably you need in each case to take out the checks that the other two are below the threshold.

Steve

MarkT

#4
Nov 04, 2018, 03:13 pm Last Edit: Nov 04, 2018, 03:13 pm by MarkT
Whenever you send a start-note message for one of the sensors, record the value of millis() in a
variable specific to that sensor, and record in a boolean that that note is active.

In loop() always check for every sensor if it is active, and if so has time progressed 150ms since
its time variable was set?  If so send the note off message and reset the boolean.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

CDAfonso

Thank you!!! With millis() i managed to get it working.

God bless you all!

Go Up