Syncing LEDs with a MIDI Instrument being Looped

I am working on an LED system that responds to MIDI from my electric drum kit. I’ve been trying to get the LEDs to sync with a drum pattern being repeated by a Boss RC-505 looper. Each drum note corresponds to sections of a DotStar LED strip that will be placed underneath the drum heads. My goal is to create a sort of “ghost drummer” effect from the lights following along to the audio.

To do this, I am needing to basically create a simple MIDI looper with my Arduino UNO. This is due to the RC-505 only recording and playing back audio, not MIDI. The looper communicates with my arduino using control changes each time I hit my footpedal to record into the RC-505. In other words, the arduino is receiving two MIDI lines. One for the drum notes and the other for the looper control changes.

To paraphrase how I am coding this, the program operates in either a record or playback state while receiving MIDI from the drums. When the record command comes from the RC-505, incoming note and velocity bytes are stored in an array and the moment in time is stored. When the playback command is received, the array is fed to the LEDs in the correctly timed out sequence.

There are three issues I am encountering with the looping playback:

  1. Playing too quickly causes the playback to halt until it starts the loop over.
  2. Playing two or more drums at once only displays one at a time.
  3. The storage space of the UNO is a major limiting factor.

I am certain that issues 1 and 2 have to do with my approach to this problem. I am using the MIDI library to handle the incoming MIDI from the drums and getting near perfect response from the LEDs. The looping playback likely has no way of being used by the MIDI library with bytes coming from a stored array rather than a serial port. This means the exact timing of the LEDs to the MIDI is up to my subpar coding skills.

Sorry about the wall of text, I want to share as much of my thought process for this project as I can. Here is a Youtube video I uploaded to better illustrate what is happening:

My .ino file is attached since the code is pretty lengthy. There is also a picture of my circuit and the schematic I followed for each MIDI input.

I’m at the end of my rope trying to get the looping to work with this method. I know that there’s got to be a better way to accomplish my goal. Any ideas would be greatly appreciated! Thank you.

LED_Drums.ino (4.87 KB)

My .ino file is attached since the code is pretty lengthy.

No it isn't. It would have perfectly well been posted correctly in code tags.
In fact the problem is that your code is too short, meaning that there is a lot more to the problem than you have addressed.

I think the use of software serial might be an issue along with your method of recording and playing back the MIDI in the buffer.

The received MIDI should be stored in the buffer along with the time it arrived derived from the millis() function. At the start of the recording you take a reading of the current system time using millis() and when you have finished inputting the data into the buffer you again take a reading of the current time. So your program can determine the length of the recording.

Then you need to add this length time to the arrival time of all the notes in the buffer. This gives you a system time when that note needs to be played. Then you go through the buffer one at a time and do not play anything out until the stored time matches the system time. Then "play" that note and add the length of recording time to the time component so you know when to play the note next time through the loop. When you come to a buffer entry with the time component of zero then you know that is the end of the buffer and you should loop round again.

  1. Playing two or more drums at once only displays one at a time.

Yes that is how your code is written, when even a new note is played you look to turn off the LEDs from the previous ones. As this is percussion then you don't normally have a note off MIDI message, so again when you light a section of LEDs record the time you did it and only turn them off when a fixed time has expired.

Your code is quite hard to read due to the use of cryptic variable names. This is a compiled language so the variable name has no effect on anything other than your ability to read it clearly. Variable names like tIterMax or a function name of rel, might be easy enough for you to remember now but in six months time you will wonder what on earth it means.

A MIDI looper is one of the projects in my book:- Arduino Music & Audio Projects and is at the end of chapter 4. Listing 4-10 is the actual code that can be down loaded from that link. It is not as complex as your requirements but it shows you the basics of what I have outlined above.