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)

1 Like

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.

4 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

I can’t seem to find very many details on this, but this reference says the following:

In Debian those devices are available in /dev/snd/ as well, and they also are internally linked with the old OSS device locations: /dev/midiXX.

So…assuming the virtual device shows up in /dev/snd/, then you should be able to output udev_device_get_subsystem(dev) for your virtual device to see what subsystem it’s on?

Hi! Spend the day researching and so far this is what I understood (please @zebra @okyeron feel free to deny/expand/correct/edit/confirm) :

  • Matron listen only to udev devices/events and from them they derive RAW MIDI ports
  • This represent the lower level of the ALSA stack and consist on hardware only ports it’s eventually what amidi -l list as input.
  • It’s possible to open virtual raw MIDI ports by using a kernel module and then connect any other port (virtual / real or even from Bluetooth - I think - to them) by doing:
    sudo modprobe snd_virmidi
    aconnect -lio
    aconnect [your desired midi source port] [virtual port]
    aconnect [virtual port] [your desired midi destination port]
  • BUT this still will not be recognize by matron because only listen to udev events.

Seams like a path forward to give matron more MIDI flexibility is to drop detection through udev and use ALSA MIDI Seq (sequencer) layer. This is build on top of the RAW and is designed to incorporate “real” and also virtual ports. This will allow both use virtual ports that applications open and/or bluetooth support (for those that are willing to recompile bluez in the RPi).

@zebra here you can find the code for aconnect.c and notice that it doesn’t use udev and snd_rawmidi_ api but snd_seq_ api. We could reuse part of this code to detect MIDI devices this way.

Dropping the udev/rawmidi in favor of snd_seq_ is not a minor change, and make me question.

  1. Why udev/rawmidi was use in the first place?
  2. What are the cascade of issues you for see this will bring?
  3. @zebra How do you feel about this? How much support you are willing to give to this transition?

In a personal note, I probably will keep hitting on it for a while and try to hack my way through it. My position is very comfortable because I don’t have to maintain and support a product tide to different hardware on an ever changing sea of drivers upgrades etc. So I’m not expecting much. BUT if this route is something you and the project seams interesting, I’m excited to team up and tackle it.

All the best,

Patricio

2 Likes

probably no good reason beyond expedience. the device monitoring stuff used udev because initially we just wanted to talk to usb-serial devices and HID. rawmidi required the least deviation from that pattern. (if i recall correctly)

using seq has been explored, mostly not by me but by @artfwo

i honestly don’t have a strong opinion. anyone is welcome to put the work in to make a robust solution that plays well with the existing ecosystem. if you want to do that i would be delighted. (but i will probably not be in a position to test MIDI stuff)

i don’t see a cascade of issues from setting up a clean and separate system for MIDI outside of monitoring USB device tree. but like you said, it’s not a quick hack to do that.

Thanks @zebra for the reference to those threads. Seams this have been a hot topic for a while.
I think I found a possible solution that doesn’t involve minimal full change. The plan involve loading the raw virtual Midi devices at the begining on main.c before dev_monitor_int() get excecute, this will not produce collisions with it because device_monitor.c only look for virtual devices (only ‘usb’). Once the virtual midi device is up we can use aconnect to redirect other ports to it. So far what I have done is:

  1. I took some code from amidi.c and put it on device_list.c to look up for ALSA raw virtual MIDI devices here is a commit

  2. in the raspberry pi I add the VirMidi module file so it get’s load on the kernel at boot time:

echo snd_virmidi >> /etc/modules
  1. recompile matron with my chances and reboot
  2. Sucess! Virtual Raw Midi divices are recognice

Now I’m trying to see how aconnecting things to it goes. I will report back.

@zebra is this PR material?

1 Like

yeah, feel free to open a PR whenever you feel it’s in a good, shareable state. that’s the best way to get more visibility from dev stakeholders!

i remembered that we were initially talking about using sequencer because we could not figure out how to get all ports for all devices using rawmidi, but forgot that @license i think got a fix in for that issue (https://github.com/monome/norns/commit/5cfbc5a638f9166aa3f2a43cf4c845bfc3865972)

so i think the non-usb case is the only remaining issue.

1 Like

Follow up:

  • did the steps from my previous post, which makes matron to see the virtual ports
  • run midigyver with a simple script that generate a constant pulse of note_on in a virtual midi port (not raw but in seq) in key 29 at 100 velocity. Here this yaml script that selt it up
out:
    -   midi://tempo

pulse:
    -   name: main_loop
        bpm: 60
        shape: |
            function() {
                return { 
                    'tempo': [[29, 100]]
                };
            }
  • then I connect the tempo virtual seq port to one of the raw virtual port 1
aconnect 128:0 20:0
  • In Norns I use the script MIDI-MONITOR and I receive the key event!! YAY! but only one! after that there is no more key events coming in… and I can’t replicate the experiment except if I restart the device. Any idea what could be happening?

Sorry, I dunno.

I don’t even know if the midi test script is supposed to append each received noteon, or if it is just collapsing repeated identical messages or something. @okyeron would know since it’s his script. I would just check with some print statements

The midi monitor script should display every event (appending). But yeah - some print statements might be helpful.

Checking matron after things “freeze” might also be good. (Maybe it crashes?)

Or… seeing if you can run other scripts

The script doesn’t crash… actually I just discover that if I send through a different channel or a different type of msg get’s logged… but If I just change the key or value it doesn’t.

1 Like