MIDIOut on Linux doesn't auto connect

I think this used to work automagically, but maybe i’m wrong. Doing

MIDIClient.init;
m = MIDIOut.newByName("mioXL", "mioXL MIDI 1");
m.noteOn(0, 60, 64);

now requires me to manually patch the MIDI bridge in Jack.
Is this how it’s supposed to be?

This code still works automagically for me:

(
if (MIDIClient.initialized.not) { MIDIClient.init; };
m = MIDIOut.newByName("INTEGRA-7", "INTEGRA-7 MIDI 1");
fork {
	m.noteOn(0, 60, 64);
	1.wait;
	m.noteOff(0, 60);
};
)

Hmm… maybe it’s something with Pipewire then. Or are you running that too?

No I’m not using Pipewire…

on linux, we have to declare how many virtual-port (in & out) SC make. So, if we want 2 In & 3 out :
MIDIClient.init(2,3)
m = MIDIOut(indexOfVirtualPort).connect(MIDIClient.destination index)
ex: m = MIDIOut(0).connect(1)

MIDIOut.newByName connect systematicaly on the virtual-port 0… this is not really usefull when using multiple midi port… i think…
Can you post the full msg_interpreter of MIDIClient please ? Your midi board seem to be very fat, i’m curious

There’s a bit of fine print in the MIDIOut helpfile (emphasis mine):

MIDIOut.newByName uses the uid argument, so we do not expect to see connections in any JACK or ALSA patchbays.

I realize now that this is worded slightly incorrectly (because I didn’t completely understand it when I wrote this). There’s no such thing as a “one-to-one connection.” I found this just now when I started looking for a way to “disconnect” a direct MIDIOut, and… there is no way.

Further, you can switch the uid of a MIDIOut object at any time, but this only changes the instance variable – there is no primitive to do anything under the hood to disconnect/reconnect. (If there were a concrete connection, it would be necessary have some code to reconnect.)

So then I looked at the source code. The uid is a parameter of the underlying ALSA MIDI sendMIDI() function (we don’t define it ourselves). So, guessing the behavior of this function from observation:

  • If uid is given, send MIDI only to that specific device, nowhere else. (AFAICS patchbay connections are always ignored in this case.)
  • If uid is 0 (not provided in SC), send MIDI through the source port, to any connected devices.

So in your case, there never was any “auto connect” – just that the MIDIOut should be sending individual messages to the specific uid device.

I’m not clear what you mean by this. Is it simply that you expected to see a connection and you don’t? Or are the messages not going through it all? (Or are you referring to an ALSA-JACK MIDI bridge such as a2jmidid?)

hjh

newByName doesn’t use virtual ports – see discussion above. When a MIDIOut specifies a valid uid, all connections from the virtual SC MIDI-out port are ignored. So it doesn’t matter how many newByName MIDIOuts exist with port 0 – each one will talk only to its specific target device.

hjh

Thanks for the very informative reply. Yes, sorry if i’m unclear. I find MIDI on Linux a bit confusing. It has always worked without further ado using newByName in the past. But since it suddenly didn’t work, i opened up the patchbay in Carla and noticed nothing was connected (and i guess this is expected since newByName connects directly to the port anyway). I could however make it work by patching the port showing up as SuperCollider:(capture_22) out0 to the port on my MIDI interface. I’m attaching a screenshot here to show what i did. If i understand this correctly, i shouldn’t have to do this using newByName? So maybe it’s actually a bug in PipeWire then.
MIDIIn works as expected btw.

I can’t quite see why newByName is failing in your case.

Is it specific to that device? That is, if you make a quick and dirty [notein] → [pack 0 0] → [print] patch in Pure Data, can you newByName to Pd’s MIDI port and see the messages printed over there? If yes, then it could be something about the device information being reported to SC. If no, then newByName is generally futzed.

What are the actual numbers in your MIDIOut object? m.dump. Does the UID match the output device’s real UID? (I can’t see why it wouldn’t but let’s not assume.) Maybe search by MIDIClient.destinations.detect { |d| d.uid == m.uid }.dump.

“It has always worked… But since it suddenly didn’t work” – did something change in the system around the same time that it stopped working?

I haven’t found any websites outlining Pipewire MIDI capabilities, hence, no evidence that Pipewire would be interfering with ALSA MIDI.

hjh

newByName to Pd works and the UID matches. I suspect it might have started when i installed pipewire some weeks ago actually. Haven’t used MIDI in a while. Maybe i’ll file an issue over at their Gitlab to investigate further.