Is there a way to send a signal to "All" MIDI notes?

Status
Not open for further replies.

sargentpilcher

Well-known member
I'm working on some code using the Teensy where I am using MIDI on and off messages to control the on and off of each RGB LED on some LED strips. I occasionally run into a problem where a light doesn't get the message, and if it doesn't receive a "light off" message, then it will stay on indefinitely until it gets triggered again and has an oppurtunity to rereceive the MIDI off message that is supposed to go with every note. I am looking to create a sort of a "Panic" button that will turn off all of the lights for as long as I have it pressed. Maybe even like a "mute" button.

So is there a way to do this easily? I have my code listed below, and I'm wondering if it's possible to specifiy "All MIDI channels" instead of "Channel 3" or "All MIDI notes" instead of "Note 60". The only way I could think of to write the code would be to write 16 lines of code to send it across all channels, and to write 128 lines of code to go across all MIDI notes, and multiply all of that by 6 for my 6 LED strips, but there HAS to be a better way! I've consulted this https://www.pjrc.com/teensy/td_midi.html but I could not find my answer there.

Code:
 #include <Adafruit_DotStar.h> 
#define NUMPIXELS 240 //Dotstar pixels
#define DATAPIN    36
#define CLOCKPIN   35

byte colorMatrix[16*42][3] ; // 2D matrix to hold velocity readings - index is for light number 
unsigned int light; // light is cacluatated by multiplying zero-indexed channel ID * 42 lights per channel + integer trunc of note/3

Adafruit_DotStar  strip1 = Adafruit_DotStar(NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BRG); // initialize pixel object

void setup(){
  usbMIDI.setHandleNoteOn(OnNoteOn);
    usbMIDI.setHandleNoteOff(OnNoteOff);
  strip1.begin();
  strip1.show(); // Initialize all pixels to 'off'
}



void OnNoteOn(byte channel, byte note, byte velocity){
  light = (channel*42)-(42) + note/3; // calculate which light the message is for
  // note%3 returns an index for the three RGB positions 0,1,2 based on the remainder when the note is divided by three!
  colorMatrix[light][note%3] = velocity*2; // read the velocity and scale to 8-bit from 7 and write to matrix
  // could make set pixel conditional to blue updates (if (note%3 = 2)...) if you make sure all three are sent in order when a light's values are changed
  // this wouild prevent updates before all values are available to avoid incorrect colors being displayed wiht R and G valeues being sent
  strip1.setPixelColor(light,colorMatrix[light][0],colorMatrix[light][1],colorMatrix[light][2]);
}

void OnNoteOff(byte channel, byte note, byte velocity){
  light = (channel*42)-(42) + note/3; // calculate which light the message is for
  // note%3 returns an index for the three RGB positions 0,1,2 based on the remainder when the note is divided by three!
  colorMatrix[light][note%3] = 0; // read the velocity and scale to 8-bit from 7 and write to matrix
  // could make set pixel conditional to blue updates (if (note%3 = 2)...) if you make sure all three are sent in order when a light's values are changed
  // this wouild prevent updates before all values are available to avoid incorrect colors being displayed wiht R and G valeues being sent
  strip1.setPixelColor(light,colorMatrix[light][0],colorMatrix[light][1],colorMatrix[light][2]);
}




void loop() {
  while (usbMIDI.read()) {
    // keep reading until all incoming messages read
  }
  strip1.show();
}
 
As explained in that table, it is just a specific Control Change message. The table shows that you send a Control Change message to a channel with the second byte set to 123 (decimal) and the third byte set to zero.

Pete
 
Thanks so much for the help! I'll try it out now

Edit:

I couldn't get it working. I can only theorize, and I am a noob, so I'm probably doing something wrong. I put it into the code like this

Code:
void myPitchChange(byte channel, int pitch){
  usbMIDI.sendControlChange(123,0,channel);
}

My thinking was that anytime I move the pitch bend knob, that it would shut off the lights. This was not the case though, and I'm wondering if it could be because of a lack of understanding of the message? That is, would Teensy be smart enough to know that that particular control change means "All MIDI notes off"? And if Teensy WAS smart enough to know that, would I have to make a different call other than for the Teensy to send the MIDI signal? It's like this weird loop where the Teensy is sending a MIDI signal to Ableton live (Computer software), and the Teensy code is written in a way that it only responds to received messages from Ableton. So Ableton gets the message "All MIDI notes off" and is essentially wondering "What do you want me to do with this?".

I need a way for Ableton itself to be able to send a note off signal, or an "All MIDI notes off" signal if I'm to approach it like how I have my code (To be a receiver of instructions, and not a sender of instructions.). I need to find a way for ableton to send a message to the Teensy, and for the Teensy to know what to do with those instructions. This would require either 1) A method of having Ableton send the "All notes off message" and maybe/maybe not rewrite the code to fit this new function. Or 2) Find a method from within Teensy itself to perform the desired function off of the press of a button.

Would I be able to do something along the lines of "Channel 0-15" to represent all channels? Or "Note 0-127" to represent all note values?
 
Last edited:
Status
Not open for further replies.
Back
Top