-
Notifications
You must be signed in to change notification settings - Fork 39
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
Cheap MIDI interface fails with MIDINOTE operator #287
Comments
cool thanks for the data point. this is one of those things that is hard to test on enough devices. one thing that would help would be to see the raw MIDI bytes coming in from the controller. for example, the raw output of pd's though if i had to guess, i'd bet on a problem at the point of USB connection/handshake, not with parsing the midi stream itself. (that is, OS-level stuff, not app stuff.) if you do want to help debug on the aleph side:
|
here's the dump of from the pd [midiin]
Turns out the cheap Chinese keyboard has correctly implemented the MIDI note off spec. It's sending a first byte value of 0x80 for noteoff messages, rather than 0x90 with a velocity of 0. I can probably fix this myself but I'm not too familiar with where in the codebase I'd find functions touching this data. |
IIRC a note-on with velocity 0 should be treated like a note off in addition to a note-off with any velocity (release velocity). I vaguely recall handling this in the monome module firmware but I don't remember the state of the aleph firmware (off to go look). |
bees midi note operator does indeed handle 0x8 noteoff nybbles, if that's what you are implying. that code is here: I am now doubling my bet on an issue with handshaking / connection. my suggestion of printing in the connection event handler is the next diagnostic step. |
Agreed regarding |
if bees doesn't get a connection event then we have to look at the UHI code. which is hairy. I can't guess off the top of my head why UHI stack wouldn't be recognizing the device class, but the triage would be straightforward (albeit requiring the hardware) if bees gets a connection event but notein op isn't getting anything, then I dunno. most recent midi input packet is just in a static global (sorry) that any op can access. so if a controller is sending a lot of weird extra packets it could get fubard, but that doesn't seem to be the case here. (unless! unless pd is filtering out packets that it doesn't think are standard midi... but nah, i doubt it) |
yeah i mean... its not actually the first time I've made a midi input :) |
it is however the first time tried to make a usb midi host :D |
apologies if I implied the midi implementation wasn't to spec. It was my confusion. More noob questions, how do I "copy debug version to sdcard and flash it with the bootloader"? |
Okay, so here's what I got. Snarky debugging comments in output are my own. Controller that works outputs
Controller that doesn't work outputs
Both seem to enter the block in |
It's probably also worth noting that the OLED screen becomes 100% white for about one cycle when I plug in the broken controller. |
more interesting debugging output. Moving the volume fader on the keyboard spam outputs this debugging message to the console, produces an all white OLED screen.
|
ok, so i haven't looked at this stuff in a while, but there's nothing in there that actually looks wrong. (which just means the debug print statements that happen to be in there are not pointing at the exact problem - to be expected.) usb is complicated. its normal for a device to supply multiple interfaces - in fact for audio/midi devices it's required. the [0x1 , 0x1] interface that we're skipping is the "audio control" interface (audio devices have to supply it, and midi devices are subclasses of audio devices, but they generally don't have a meaningful use for the AC interface.) midi devices also have to supply a "midi streaming" interface, which must include "bulk data transfer" or "interrupt" endpoints, and most in addition have "isochronous" endpoints for hosts that can support the necessary bandwidth. we're polling the device, so we want to the use bulk/interrupt async methods. anyways: theory 2): we are making some kind of bad assumption in @ngwese - didn't you do a lot of midi cleanup for libavr32 at some point? can we ditch all this horrible old code? if i have time this weekend i'll go through the code in more detail and try to pinpoint some other things to look at. if you really want to get into this stuff you could also try using here's a good page of reference material, in addition to the official usb class specs: btw: "event queue full" and screen glitches are common sights in aleph debugging sessions if there is tons of serial output being printed, because this in itself can make it hard for the processor to keep up with incoming realtime events. |
apologies for the candor, but a quicker path to victory (and to save dev
energy for more fun things) might be to get a different cheap midi
interface that is known to work.
it's a rabbit hole to fix midi inplementations for every interface on the
market.
…On Sat, Nov 4, 2017 at 4:27 PM ezra buchla ***@***.***> wrote:
ok, so i haven't looked at this stuff in a while, but there's nothing in
there that actually looks wrong. (which just means the debug print
statements that happen to in there are not pointing at the exact problem -
to be expected.)
usb is complicated. its normal for a device to supply multiple interfaces
- in fact for audio/midi devices it's *required*. the [0x1 , 0x1]
interface that we're skipping is the "audio control" interface. midi
devices also have to supply a "bulk data transfer" or "interrupt"
interface, and most in addition have a "streaming" or "isochronous"
interface for hosts that can support the necessary badnwidth.
here's a good page of reference material, in addition to the official usb
class specs:
http://www.beyondlogic.org/usbnutshell/usb5.shtml#InterfaceDescriptors
anyways:
** theory 1):** for some reason we're mistakenly using the isochronous
interface for this device, when we should be using the bulk/interrupt
interface. an endless number of packets are available every single time we
poll the device.
*theory 2):* we are making some kind of bad assumption in
midi.c:midi_parse() - which is not about parsing note messages &c, but
about watching incoming packets for status/data and signalling events when
completed packet comes in. obviously it's a pretty crude system; i had a
lot of functionality to implement, midi wasn't actually top priority, and
just did what i could to get it working with limited test coverage for
different devices.
@ngwese <https://github.com/ngwese> - didn't you do a lot of midi cleanup
for libavr32 at some point?
if i have time this weekend i'll go through the code in more detail and
try to pinpoint some other things to look at.
if you really want to get into this stuff you could also try using usbmon
or wireshark to get raw usb packets from the device on linux, see how the
OS deals with handshaking for this keyboard.
"event queue full" and screen glitches are common sights in debugging
sessions if there is tons of serial output being printed, because this in
itself can make it hard for the processor to keep up with incoming realtime
events.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#287 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAPEcBN1Tbnqx8Qo3R_WyD2PIBHgwTvMks5szMilgaJpZM4QRynN>
.
|
to be clear, i absolutely agree. i doubt i'll actually be able to put any more time into this. on linux, for example, broad support for usb midi- and hid-class devices, has been an incremental project spanning many many years and involving many many people. if OP wants to use this as an opportunity to get hands dirty with the guts of USB interfaces and endpoints, while making midi support in aleph/libavr32 more robust, i'm all for it. but this is not really something that blindly debugging by email is going to help with. |
@tehn I already have a MIDI interface that works. It's cool, I'm interested in this kind of hardware debugging. Thanks for the tips! |
I have USB protocol dumps from wireshark and the midi_parse() function is fully commented with debug output. I also have a keyboard that works, as a reference. I'll see how far I can get with this. @catfact wanna come to Noisebridge for a debugging session? :) |
@catfact regarding cleanup of the midi bits in libavr32 - yes I did end up modifying a bunch of stuff. After reading the USB MIDI spec I came to the conclusion that the aleph code was trying to handle cases which only occurred when interacting w/ a real MIDI DIN jack. USB MIDI is more constrained w.r.t. how messages are formatted in USB frames so I removed a bunch of code. IIRC the aleph MIDI code could fail in certain cases if USB frames got dropped or sysex came through. The simplified code in libavr32 basically shunts the incoming packets into the event queue: ...compared to the aleph avr32 code which does much more: I haven't back ported any of the libavr32 MIDI changes to the aleph code base but according to this post the changes apparently work fine on the aleph as well: |
I should add that various MIDI devices such as a ROLI block and Linnstrument were generating MIDI streams which would overwhelm and/or lockup the earthsea/ansible (aka libavr32) code. Recent firmware for ROLI block does seem to fix the problems I was running into last year. I mention this in support of @tehn's comment earlier. I've come to realize how variable USB MIDI devices are and how complex USB is. Without a ton of devices on hand to test it is really difficult to make things bullet proof. |
Yup, my public dev branch is now using libavr32 & this is the firmware I'm running whilst working on fmsynth module. Haven't observed any unexpected regressions so far... |
@lazzarello I've overhauled aleph's midi support in an effort to get things working properly with all my midi gear - would you be able to help me test that branch with your midi hardware? https://github.com/boqs/aleph/tree/midi_common So far things are working right with EMU midi1x1Tab (input/output) & a YouRock midi guitar 🤘 According to my observations the midi output support on monome/dev is simply buggy, and furthermore I claim that the changes on this branch fix the bugs! But should warn you before enlisting help there's a decent probability I'm barking up the wrong tree... |
Branch built, firmware loaded and default waves scene loads as expected. Heading into the studio to try out the MIDI controller. |
Confirmed MIDI works with the midi_common branch on my Aleph. Closing. |
I was going through the MIDI tutorial and plugged in a Midiplus AKM320. No note on messages were recognized. Then I swapped the controller out for a M-Audio Keystation 61es. Note on messages controlled the sound.
I checked the midiplus on my laptop in PD and indeed, noteon data is recieved via the [notein] object.
Not sure how to debug this problem in the Aleph MIDI implementation.
The text was updated successfully, but these errors were encountered: