FortySevenEffects / arduino_midi_library

MIDI for Arduino
MIT License
1.58k stars 254 forks source link

Peek MIDI buffer bytes available & flush MIDI buffer #78

Open nicolasdeory opened 7 years ago

nicolasdeory commented 7 years ago

Hi, I'm using FastLED and MIDI libraries to make a LED visualizer for my piano.

Problem is, when I play too many notes or I slowly press the sustain pedal (which I suppose will generate a lot of CC messages; one by one increments), Arduino bugs out and incorrectly lights several notes. If I keep playing, it only goes worse (up to a point).

Of course, I can turn off each light if I press each individual key (since they turn off on MIDI noteOff messages). However, I'm struggling to find what's wrong.

I thought about checking if the MIDI channel buffer exceeds a size, stop receiving incoming notes (AKA flush the buffer and start over), instead of running out of RAM (I suppose) and go crazy with the lights.

However, I don't know how to do any of these things. Can I check how many bytes there are left without doing MIDI.read() (thus consuming the byte)? And, how can I flush the buffer in case something goes wrong?

franky47 commented 7 years ago

The MIDI Library is just a wrapper around the Arduino serial libraries. So if you need to interact with the data stream (before actually letting the library interpret it as MIDI data), you can do that directly (eg: Serial.flush(), Serial.peek()).

dmadison commented 7 years ago

What LEDs are you using for the visualizer? If you're using a 3-wire chipset (e.g. NeoPixels / WS2812B) FastLED will disable interrupts and you'll lose serial data. See the FastLED documentation for more info. This has nothing to do with the MIDI library.

As an aside, Serial.flush() clears the outgoing buffer, not the incoming one (as of 1.0). I believe you'd need to run a loop until either available is 0 or read returns -1.

mrbjjackson commented 6 years ago

Hi there, I'm also having trouble integrating MIDI with FastLED on an Arduino.

I'm trying to control LEDStrips with MIDI controller values so I control some LEDs by pre-programming midi tracks in Ableton Live.

It works brilliantly for just one CC track but as I add more (to control hue, saturation etc), it's like the Arduino can't process them in time.

@dmadison it's interesting what you say about FastLED disabling interrupts. This sounds plausible but I'm pretty sure I have tried just lighting simple LEDs and controlling them with Arduino's output pins and the issue still arose (I'll double check this).

It seems to me that the Arduino can't read and process multiple simultaneous CC value changes. Could this be the case and can you think of a way around this? Many thanks, I'm new to the Arduino and I'm having a great time working with it.

franky47 commented 5 years ago

It can, but as everything is synchronous, you need to avoid blocking your event loop as much as possible (usual causes are explicit delay calls and debug printing to the serial monitor). If you feel some unresponsiveness, this would be the way to start.

@dmadison has a good point: if the incoming buffer gets full (because not regularly emptied by MIDI.read()), some data will be lost and subsequent messages will be read incorrectly.