Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simultaneous MIDI BLE notes not played. #2

Open
JerryH31 opened this issue Apr 11, 2020 · 9 comments
Open

Simultaneous MIDI BLE notes not played. #2

JerryH31 opened this issue Apr 11, 2020 · 9 comments
Labels
enhancement New feature or request

Comments

@JerryH31
Copy link

When a MIDI file contains simultaneous notes (like a chord), only one of the notes is played. I suspect this has something to do with MIDI 'running status' not being implemented in the BLE MIDI Library.

Note that the circuitpython MIDI library (MIDI over USB) handles simultaneous notes correctly.

I've attached a test file that plays 4 G chords:
G chord test (short).zip

@tannewt
Copy link
Member

tannewt commented Apr 13, 2020

I agree this is a running status issue. It's non-trivial to support because the BLE MIDI spec doesn't allow running status to run across packets.

Screen Shot 2020-04-13 at 4 17 40 PM

It should be doable but isn't a high priority for me.

@JerryH31
Copy link
Author

Oh, I didn't realize it was difficult to implement this. Maybe referencing the Arduino Bluefruit MIDI implementation might provide some insight:
https://learn.adafruit.com/web-ble-midi/ble-midi
I know firsthand that the Arduino Bluefruit MIDI implementation works well--no MIDI notes are dropped. I wish I could help, but this is way beyond my skill level.

@tannewt
Copy link
Member

tannewt commented Apr 14, 2020

The Arduino implementation doesn't merge midi messages into a single packet so I'm not sure why it works there. Maybe because it always inserts timestamps? Here is what I was looking at for the Arduino implementation: https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/master/libraries/Bluefruit52Lib/src/services/BLEMidi.cpp

I'm going to reopen in case someone else wants to fix it.

@tannewt tannewt reopened this Apr 14, 2020
@kattni kattni added the enhancement New feature or request label May 4, 2020
@JerryH31
Copy link
Author

Just wondering if anyone has an interest in fixing this issue. My project is stalled without the ability of this code to handle MIDI 'Running Status' messages. I wish I could work on the code myself, but it is beyond my abilities. ...I'm certainly willing to test and provide feedback!

@AllTheProjects
Copy link

This is a major roadblock for me as well. My project is dead in the water.

@ladyada
Copy link
Member

ladyada commented Jun 5, 2022

best bet is to send individual note on/off's for now

@AllTheProjects
Copy link

AllTheProjects commented Jun 6, 2022

best bet is to send individual note on/off's for now

Wish I could. It was supposed to read MIDI notes out of the Synesthesia Game piano app. I am unable to change the way the app sends out MIDI. I sold the BLE 33 Nano board and am going with MIDI USB via an Arduino Micro board instead.

@tekktrik tekktrik linked a pull request Aug 23, 2022 that will close this issue
@tekktrik tekktrik removed a link to a pull request Aug 23, 2022
@JerryH31
Copy link
Author

I'm still hoping someone might fix this issue. I don't have control over the source MIDI material. My MIDI source uses running status messages.

@keithngroover
Copy link

keithngroover commented Mar 29, 2023

I found a way to send multiple messages in one packet, but it feels like a hack to me.

First off, this code on the adafruit site straight up doesn't work:

# Send 2 events AT+BLEMIDITX=90-3C-7F-A0-3C-7F OK

The problem is that synths expect a timestamp in between each event. So what I did was fake a timestamp by putting an EE in there, like this:

AT+BLEMIDITX=90-3C-7F-EE-A0-3C-7F

I have a MIDI controller that needs to stop and start multiple notes simultaneously, so I wrote up this monstrosity:

//turning off old notes
ble.print("AT+BLEMIDITX=");
ble.print((128 + MIDIchannel), HEX);
ble.print("-");
lastNote = constrain(lastNote, 0, 127);
if (lastNote <=15)
{
  ble.print("0");
  ble.print(lastNote, HEX);
}
else
{
 ble.print(lastNote, HEX);
}
ble.print("-00-EE-"); //fake timestamp
ble.print((128 + MIDIchannel), HEX);
ble.print("-");
if ((lastNote + 7) <=15)
{
  ble.print("0");
  ble.print((lastNote + 7), HEX);
}
else
{
  ble.print((lastNote + 7), HEX);}
}
ble.println("-00");
 //end of first packet

Whenever print formats HEX, it doesn't always print two digits, which is why there's that if (lastNote <=15) stuff in there.

It's ugly, but it works. If there's a better and fast way to do this, I'd love to see it.

What would be ideal would be if it could be structured something like this:

blemidi.send(noteOn, firstNoteName, firstNoteVelocity, noteOn, secondNoteName, secondNoteVelocity, noteOn, thirdNoteName, thirdNoteVelocity, noteOn, fourthNoteName, fourthNoteVelocity);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants