Support for non-USB MIDI ports (Ex: virtual, network, etc )

Hi! I’m working on a simple tool to make my nanoKONTROL2 to behave as a sequencer. The program I’m using use RtMidi C++ lib to read from a device and create another virtual port ( this is the project GitHub - patriciogonzalezvivo/MidiGyver and this is the particular script for it I’m working on https://github.com/patriciogonzalezvivo/MidiGyver/blob/master/examples/sequencer.yaml ). It works well on any other Linux/MacOS/Windows computer including other Raspberry Pi distributions but in Norns I’m getting the following error:

$ midigyver sequencer.yaml
MidiInAlsa::openPort: ALSA error making port connection.
terminate called after throwing an instance of 'RtMidiError'
what():  MidiInAlsa::openPort: ALSA error making port connection.
[1]    11292 abort      midigyver sequencer.yaml

Any one have an idea what this means? what’s the nature of the ALSA error.

Thanks in advance

2 Likes

my guess is that ALSA doesn’t allow multiple connections to the same port, and matron is already holding onto it.

Do you know if there is a way to prevent matron to load/listen to particular devices?

not really. you would have to edit the source:

first, determine that my hypothesis is correct by halting the matron process and trying your process again.

You were right! If I stop matron it works!

Unfortunately then I can’t load matron back again. So I would probably have to modify it and recompile it.

why not?

matron is controlled by a systemd service. the service confiuration is specified here:

and it is installed to /etc/systemd/system/norns-matron.service. as you can see, all this does is wrap the matron process in our websocket stdio wrapper tool so that it can be controlled remotely by the web IDE.

you could edit the systemd scripts to start up your tool before starting matron. (there is also norns.target for example, that could be the best place.) then matron will probably throw the same ALSA error when it tries to grab the device, but it might not be a real problem. to avoid that error, yes you would have to edit matron source to ignore the device.

for development purposes, it can sometimes be more convenient to use the scripts ~/norns/start.sh and ~/norns/stop.sh, which do the same tasks as the systemd services.

Hi! Thanks so much for your patience. In a very hacky way I’m ignoring my midi device…

void handle_device(struct udev_device *dev) {
    const char *action = udev_device_get_action(dev);
    const char *node = udev_device_get_devnode(dev);
    const char *subsys = udev_device_get_subsystem(dev);

    const char *name = get_device_name(dev);
    printf(" --> handle_device( %s )\n", name);
    if (strcmp(name,"nanoKONTROL2") == 0)
        return;

    if (action == NULL) {
        // scan
        if (node != NULL) {
            device_t t = check_dev_type(dev);

            if (t >= 0 && t < DEV_TYPE_COUNT) {
                dev_list_add(t, node, get_device_name(dev));
            }
        }
    } else {
...

Then loading my program. It creates a virtual midi port ,(midigyver / sequencer ) which I can’t see on the norns.
I tried restarting norns using:

sudo systemctl stop norns-matron 
sudo systemctl start norns-matron 

but I get the same result. The virtual device is not visible for norns but still visible by ALSA

$ aconnect -i -o -l 
    client 0: 'System' [type=kernel]
        0 'Timer           '
        1 'Announce        '
    client 14: 'Midi Through' [type=kernel]
        0 'Midi Through Port-0'
    client 20: 'nanoKONTROL2' [type=kernel,card=1]
        0 'nanoKONTROL2 MIDI 1'
            Connecting To: 129:0
            Connected From: 130:0[real:0]
    client 128: 'midigyver' [type=user,pid=17264]
        0 'sequencer       '
    client 129: 'midigyver' [type=user,pid=17264]
        0 'nanoKONTROL2*   '
            Connected From: 20:0
    client 130: 'midigyver' [type=user,pid=17264]
        0 'nanoKONTROL2*   '
            Connecting To: 20:0[real:0]

Any suggestion or hint why norns is not aware of it?

Thanks!

Oh I see there is a longer conversation regarding non-usb midi devices here maybe I could re use @TheTechnobear diff https://github.com/monome/norns/pull/532

oh, i see. so this is really a separate issue: you want norns to see the virtual midi device you created, but ignore the physical port

yes, the norns device detection system is just designed to watch the USB device tree and assign appropriate handlers.

my point in the linked issue was that one probably would not want to support non-USB devices by hacking the device discovery mechanisms. technobear’s example was GPIO midi, and yours is virtual midi. in both cases, you don’t need discovery because the first case is hardwired and the second is a kown path to a device that you just created.

but whatever

if you do want to use that diff, you would want to look carefully at what happens downstream from handle_device and probably make some changes so that it is correctly ignoring non-midi, non-hid, non-serial hardware and TTY devices. i think once you do that, better solutions will occur to you anyway.

Yeah… you are right that diff is not really good for me because my port is virtual. Any plan to add ALSA midi devices? or MIDI over BlueTooth?

it’s sort of an edge case but if you are willing to help implement it, it should not be too hard.

here are two use cases not currently addressed:

  • running norns stack on non-norns hardware where midi devices can be GPIO and not just USB. (technobear’s case)
  • running non-norns software alongside norns software with virtual midi ports (your case)

both could probably be handled by same solution: more flexible device scanning logic, and the ability to explicitly open a device connection by path without waiting for it to be detected and auto-populated.

MIDI over bluetooth: no. norns hardware doesn’t have bluetooth, and supporting it requires complex weird stuff on embedded linux, which we are not gonna get into for an nonstandard use case.

Interesting! Researching how it would look like for my case (because seams RtMidi or a similar library is not an option for matron) I step upon this implementation of aconnect here

But later I saw this,


do you think it would work to use this kernel modules to trick matron that the virtual devices are “real” once ??

I guess I’m going to give it a change…

i’m sorry if i was unclear.

i believe that the problem is not that matron “can’t see” virtual devices from ALSA, but that it is not looking for them because it is explicitly first looking for USB devices, then getting ALSA device handles from them. you could indeed try technobear’s diff to see whether this affects your situation. you may get some garbage downstream after that, and you will additionally have to tell matron device discovery to ignore the physical port.

as a test, i’d try just inverting the logic so that matron device disccovery scans everything that isn’t a USB device.

we could of course use something like RtMidi library, but it would not really solve your use case - you would then be left with the problem of two ALSA clients (via rtmidi) fighting for the same device.

so either way, we need more flexible and configurable logic around device discovery for various “nonstandard” use cases. this actually extends beyond MIDI, there are also issues like distinguishing between ACM devices that expect different protocols (e.g. crow and trellis-based DIY grid controllers) -

so the solution currently in the pipeline is to add a layer of scripting and rich configuration to the device acquisition. this is planned for norns 3.0 (or maybe 3.x) which has been in development for a while now and does not have a planned release date (situation of the world has not made it easy.)

if you can hack a behavior that works for you, it would be great to see it so that we can support that in the next version of the system.

1 Like

Oh… I see… I have done that before, seams to try to open every single file in the /dev folder but never steps into something I can recognize like the virtual port. That’s where I got the assumption that by using this way matron can’t see the virtual device and maybe by loading that kernel module it will. As a context the virtual device appears on aconnect -o but not on amidi -l.

Do you know if virtual devices have a specific “subsystem” like usb in this line

...
if (udev_device_get_parent_with_subsystem_devtype(dev, "usb", NULL)) {  
...

Sorry for all this questions and thanks again for your patience. I really would love to contribute, I’m really new to such a low level of linux audio APIs

ok, gotcha, thanks… so yeah, 'm sorry, i just don’t know the answer, not having spent a lot of time with MIDI on linux myself. (IOW i cant say off hand whether/where virtual devices appear in /dev… i just assumed that they did, somehow.)

(to make the context clear, i did write the initial implementation of device management - quick and stupid, only for monome grids and HID - but others have had their hand in since then to add the basic USB-MIDI support that we have, and to incrementally address some widening use cases. since releasing the shield, use cases have widened further and thats why we are wanting to re-architect the whole thing.)

no time like the present to get your hands dirty with the APIs! no-one is born an expert

I’d argue that it’s a worthwhile add for norns shield users - so not entirely non-standard. Also Bluetooth can be easily added to stock norns with a USB dongle.

FWIW - BTMidi is not that hard to get working (generally) and just requires a recompile of the Bluez sources - which could get wrapped into a kernel update for shield.

Now - once the connection is there, we run into the same issues being discussed in this thread. In this case - getting the device code to look at the bluetooth subsystem.

I’ve tried this but crashed and I don’t know enough to debug further in that situation.

@patriciogv I’ve done some hacking on the device_monitor code (mostly check_dev_type to get clone devices recognized) and played a bit with BT Midi, so I might be useful as a tester

( I would need to dig back in on the BT midi stuff to get a testing situation working again - it’s been many months since I looked at that)

2 Likes

i’ve used bluez on raspbi quite a bit incuding for pisound (with their rolled in support.) ive done lighting control and beacon-based systems on pi, some simple and some pushing the envelope; in every case it made the project a lot harder to maintain and a lot harder to support for end users. (because there are many things that an go wrong.) i want to spent all my limited norns time making the core features more robust, improving documentation, all of that - not adding new features that implicitly reqiure lots of work from other people to maintain.

i’m saying it’s a considerable add to the system complexity. differnet dongles are differently reliable, in fact reliability is all over the place even if it’s working perfectly and supported as a primary use case. (bluez is full of bugs (?) and kernel compatibility issues.) realistically, i’m not gonna maintain this and neither will brian and it would seem irresponsible for me to pretend otherwise.

I wasn’t aware that there are reliability issues.

I’ve only tinkered with it and it seemed fine to me, but totally understand if it’s not something you want to touch.

yeah - sorry not meaning to be defensive. just - it’s not that we haven’t considered it. i’m sure we could make someting that works great 90% of the time. but we already have to handle support cases for things in norns that work great 99% of the time, and these are things that the core devs actually use every day.

in s nutshell, bluetooth is just complicated and will always have a packet-loss / bandwidth tradeoff (physics) and its really freaking hard to guarantee any kind of latency target or a smooth experience with pairing (unless you are Apple and can QA everything in sight… and even then.)

and finallly, bluetooth just needs other system services to be running all the time and blasting RF into a system thats already susceptible to noise and pushing the envelope of compute resources. in my “turnkey” audio Pi projects i have tried to use e.g. pisounds out-of-box bluetooth support and ended up having to disable all that stuff (eg., the bluez services in patchbox OS) to make other aspects of the system reliable (e.g., buffer underruns in audio), falling back on wifi hotspots with TCP sockets.

if i’m gonna put the time into some kind of wireless midi protocol, it would be over TCP and aimed at integrating with hosts like ableton without requiring dongles. because we are already running network services all the time.

5 Likes

finally (sorry) i will say that handling other device subsystems is on the radar and will be supported eventually in a way that i think wil make everyone very happy. this will include bluetooth devices if someone is willing to take on the support and maintenance burden of bluez and kernel changes across all devices. but TLDR is yea, i don’t really want to touch that it feels like a “life is too short” thing.

2 Likes