Looks good It’d be great to have a single utility that’d do everything.
It looks like it’s not far off - essentially it’d just need to support the automatic connection between hardware and software ports, if there’s a rule asking for it in the rules file.
What do you have in mind for the disallow rules? I think they’re mostly useful in case of having the wildcard rules which connect hw and sw together, to block certain unwanted connections.
With those 2 things sorted out, I think this could be merged into a single utility package.
direct sample, port, sample, specific, synth, synthesizer
I’m not sure if those type flags are really used all that much, other than the client and first port set. I’m planning on seeing what all my gear and software does to see what might be useful.
For disallow, I’m thinking of explicit negative rules:
The question is should the rules be evaluated in the order in the file (so you could have exceptions to negative rules with positive ones that follow) - or is it easier to just sort all the negative rules to the end. I’m leaning “file order”…
One last thing, I don’t yet implement the logic that wild cards connect the first port with the appropriate direction capability. I need to check if that is important for SuperCollider or Pd… but Imagine all HW ports are already bidirectional.
Ok, sounds good. I also don’t think the Port Type gets much use out there. It seems the only useful distinction are the hw and sw port types.
As for the rule order, it might make sense to do file order, but it might also lead to user mistakes where you could place a specific disallow rule somewhere, and then further down, add a rule that allows connection to any hardware port.
The approach in amidiauto was to evaluate the strength of rules that apply to whether the connection between 2 particular ports should be made. The strength depends on how explicit the rule is, so [hw] <-> [sw] rule would be considered a weak one, while OP-1 <-> [sw] would be stronger and OP-1 <-> Pisound would be the strongest one.
In addition to amidiauto rules logic, file order could be used so that the last rule would override the rule, in case a conflicting one is specified. Example:
OP-1 <-> [hw]
...
OP-1 <-x-> [hw] # This rule would override the one above
Using <-x-> (and related) and <-> (and related) would allow to get rid of [allow] and [disallow] sections altogether in the rules file.
There can definitely be one directional hardware ports.
My survey of everything I could get my hands on turned up this:
The only port properties that are set with any consistency are application and hardware.
The property software is only set by the kernel on the through port.
My inclination would be to say a port is [hw] if has the port type hardware, and [sw] if it has application. This would nicely exclude the system ports, and the kernel through port from a generic [hw] <-> [sw] rule.
There are some ports I’m just not clear about:
Touchosc seems to have different clients? There is a client touchosc that declares its port as hardware, so that one would do the right thing. There is another set of clients RtMidiIn and RtMidiOut - not sure what these are. Also, the second client has one bizarre port name!
I don’t understand what the client and port pisound-ctl is for.
Painoteq doesn’t make its ports subscribable… so it can’t be “helped” by either amidiminder or amidiauto. Sigh.
There seems to be several conflicting approaches to MIDI port handling by applications:
Some create ports and let the user connect externally to the application. Like Pd
Some let the user pick a MIDI port from within the application only. Ex.: Pianoteq. Then the app’s decision of what is an acceptable port limits you: I can’t pick the output of my looper application to go into Pianoteq! Moddep does something similar… but via the indirection of Jack’s re-exported ALSA Seq ports… it is even harder to get some software port into it!
Some create matching, separate in & out ports for each other port in the system - like SuperCollider.
I’m going to have to add the logic of defaulting to the first port of the appropriate direction when the port isn’t specified… Need to brood a bit on this one…
The RtMidiIn and RtMidiOut ports get created by rtmidi library that touchosc2midi uses. The touchosc ports are actually created using amidithru program to solve the port naming and port type for touchosc and possibly other ports which should fall in the ‘hardware’ group. I’ve looked into modifying touchosc2midi to avoid that, but the MIDI library it uses does not give enough control over the name or port type.
pisound-ctl is for the Pisound App, it should also be considered a hardware port. It’s hosted by osc2midi
The PDs use of MIDI ports seem to be the right way for software on Linux to do it.
The Pianoteq actually mimics how the ports work on other major platforms, but as far as I can remember, it has a setting which makes it act like PD does, where you can hook up the connections yourself.
Does SuperCollider really make a new port for each other port? Sounds very inefficient Does it make the connections automatically too? I was looking into its MIDI use, I noticed it had many ports, but I didn’t think it depended on the count of other ports in the system.
Installing the debian package file will set up a service to run by default, and start it immediately. The service will read a rules file placed in /etc/amidiminder.rules. If you edit that file, restart the service:
sudo systemctl restart amidiminder
It is recommended that you disable the amidiauto service if you have it, as this package contains all of that functionality, and more… and they’ll probably fight if both running.
The system is pretty verbose at the moment, see the logs with
.hw <---> .app
# Interconnect all hardware and application ports.
# For simple set ups, this is often all you need.
# Comment this out if you need to be more explicit about what is connected
# to what.
RtMidiIn Client <-x- *
RtMidiOut Client -x-> *
# Don't auto connect anything to these ports. They are generic client
# names used by various applications, and could mean anything.
That should be equivalent to the logic that amidiauto was using.
That’s great! We’ll look into moving to amidiminder.
I assume it still supports specifying the port number, in case a device has multiple available? It’s not mentioned in the latest information and it’d be great to explicitly mention it and the syntax in the readme/help for the program, currently it’s only visible in an example.
Btw, does it update the rules file as you make connections manually using aconnect, or does it store that state somewhere else?
It does support both port numbers and port names. But yes, I need to work on the README / help / man page.
Currently it only stores observed rules in memory, not on disk. If you restart it, however, it’ll “reobserve” them, since it does a scan at start up. Nonetheless, perhaps it should store them so that such things survive restart.
Things I think it needs before a 1.0 release:
reload signal (SIGHUP) support (& service file support)
watching the rules file and auto-reloading when written
writing out observed rules, and possibly reloading at start (somewhere in /var/run)
man page / readme / help – or all three…
Anything else?
I’m very curious to see how well this works for other people in practice. I look forward to feedback.
That’d be great - then you rarely would even have to manually edit the rules file, as you could rely on tools like aconnectgui to specify direct connections yourself, and rely on them. I guess you’d have to be careful to let the user override connections that are not initially allowed by the rules file.
Reinstalled everything (one should mention that ‘make’ can take minutes to finish
Summary: Restarted amidiminder and checked status: All ports are added but not connected by the rules.
(The journalctl is to long for a post and besides I find it kind of embarrassing to paste it here)
Just to be clear: If you are going to have the system service run amidiminder (rather than start it by hand all the time), then the rules you want to edit are in /etc/amidiminder.rules.
Looking at the output:
These rules look wrong. The format for a connection end point is device:port, so I think the rules you want are:
Notice that you can abbreviate the device names. Also, USB MIDI devices under linux don’t get useful names¹. So you can just use port numbers (which start at 0):
Yes…yes…after days…Devices are connected and survived disconnect and restart!!
Big Thx for your help!!
Many things to do on my Zero/W: Speeding up the patching (why can´t it start that quick like the MIDIHUB does?), setting a temporary hot spot connection, and of course supporting the amidiminder project!
Midihub runs a dedicated OS for this, while Raspberry Pi Zero runs a full generic OS which takes some time to boot before it’s ready to route USB MIDI.
Finally I had some time to test amidiminder. It works great with MidiHub and my multi-device setup.
Thank you for all the time and effort you put into it.
I struggled a little with two topics:
The inital standard rule (.hw <—> .app) was much too ‘aggressive’ for my setup. Suddenly everthing was connected to everything. A hint/warning in the ‘Install’ chapter of the very good readme would be nice.
A ‘rules generator’ would be nice for larger setups.
amidiminder -p | grep ‘connection’
does half of the trick and lists all active connections in almost the right syntax. However (being a linux noob) I was not able to pipe it into a file. So some cut, paste&edit was left to do. Maybe a modified -p routine can generate a .rules file out of the currently active connections.