I'm having a hard time extracting midi messages from a JavaScript byte stream right now.
I am reading data from a device using the Serial Web API (yes, I know the Web Midi API exists, but this does not work in that case and I do not want to use it)
This code shows how I access the byte stream.
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 115200 });
while (port.readable) {
const reader = port.readable.getReader();
while (true) {
const { value, done } = await reader.read();
// the Uint8Array
console.log(value);
}
}
After connection, data is sent constantly. But I want to have only the MIDI data (Currently I do this by checking the ByteLength
)
An example of a MIDI Uint8Array
looks like this: [1, 15, 48, 48, 51, 52, 99, 102, 97, 49, 55, 102, 55, 102, 48, 48, 48, 48, 48, 48, 48, 48, 23, 2, 48, 53, 48, 101, 48, 51, 48, 102, 48, 50, 51, 102, 3, 2, 48, 48, 48, 101, 48, 51, 98, 48, 50, 102, 50, 56, 3, 4, 52, 55, 10]
transforming it to ASCII -> \x01\x0F0034cfa17f7f00000000\x17\x02050e030f023f\x03\x02000e03b02f28\x03\x0447\n
The following characters looked striking \x01, \x0F, \x17, \x02, \x03, \x04
. I then searched for it and found out that these are non-printable characters (https://condor.depaul.edu/sjost/lsp121/documents/ascii-npr.htm)
So I splitted the String with bytes.split(/\W+/).filter(Boolean)
and now I have every single part of it. 0034cfa17f7f00000000
, 050e030f023f
, 000e03b02f28
and 47
.
This part 000e03b02f28 is the MIDI-Message
- channel: 03
- command: b0
- don't know: 2f
- value: 28
I don't know what 000e is.
But this way seems very strange to me and is probably not the right one.
I tried reading code from libraries like mido
(https://github.com/mido/mido) because it worked with it right away, but I only got conditionally smarter.
So my question. How can I identify a midi message as such from a byte stream and print it out as a readable String? Thanks for any help!