Check when MIDI connections are ready

Hi,

I was wondering if there is a way to check when the MIDI ports/connections are ready for use.
I’m on Linux and have a script that connects to a specific MIDI port and sends some messages to it.
I have an init function that looks something like this (in pseudo code):

connectMidiIn;
connectMidiOut;
startRoutineThatSendsCcMsg;

when I check the msg leaving SC (I’m using Protokol) I see that some are missing. I implemented a counter in the CC msg I’m sending to easily check that (ie CC with value = (value + 1) % 128).
I thought I could use Condition to check when to start sending messages but, I can’t find anything in MIDIClient, MIDIIn anmd MIDIOut that tells me when the ports are actually ready (i.e. something like an isReadyToUse method).

Cheers,
Mario

1 Like

atm I’m using an arbitrarily wait but, that is just not ideal.

I have to admit that the situation is not completely clear from this description.

MIDIClient.init blocks the interpreter until it’s finished, so it shouldn’t need an additional wait.

Connecting a MIDIOut to a port should be instantaneous. As a test, I set up a simple patch in Pd “[ctlin 1] → [print]” and, in SC, ran this:

// reboot interpreter (to clear the old MIDIClient)
// then...

(
MIDIClient.init;

d = MIDIClient.destinations.detectIndex { |endpt| endpt.device.containsi("pure") };

m = MIDIOut(0).connect(d).latency_(0);

fork {
	10.do { |i|
		m.control(0, 1, i);
		0.01.wait;
	};
}
)

No dropped messages. Same if I put everything inside fork.

If you’re finding, then, that you connect the MIDIOut but the device isn’t ready, I think the problem is outside of SC.

I can imagine a couple of possibilities. One is that the connect command takes a little time (asynchronously) in your system, but doesn’t take that time in my Linux system. That sounds weird. The other is that maybe there’s just something funky about that device’s driver.

What I don’t see at this time is a clear approach to find out when the connection is up. If it’s the ALSA MIDI connection that’s taking extra time, then you would have to poll ALSA MIDI for that information. If it’s something specific to a device or driver, then I really couldn’t guess without knowing more.

There seems to be an assumption here that SC naturally, obviously should be able to check this. I don’t think that’s the case. ALSA MIDI connect should be very, very fast (instantaneous).

hjh

If you’re finding, then, that you connect the MIDIOut but the device isn’t ready, I think the problem is outside of SC.

In my scenario, I’m connecting to a hardware MIDI controller, not sure if that makes any difference (I suppose it does though). But, the fact that the problem lives (or not) outside SC doesn’t make any difference from a user perspective. The issue could be overcome having something in place that lets you check the status of the connections (see the isPortOpen method in RtMidi for example).
BTW I’m on Linux too (Ubuntu Studio), but I haven’t checked the scenario you describes (MIDI from SC to other software). I’ll try to give that a try later on, good shout.

In this case, however, it does make a difference.

MIDIOut in Linux does one of two things.

If you use the uid argument to MIDIOut.new, then outgoing messages are tagged with the UID, and the ALSA MIDI system delivers the packet directly to that device. Note that this isn’t a connection to the device. I believe that, in Windows and Mac, connecting a MIDIOut port to a device issues an OS call to make the connection, but in Linux for this case, there is no system function being invoked. It’s only that the MIDIOut instance remembers the UID and uses it when sending. So there is no connection action to complete – hence, nothing to watch.

If you use the .connect method, then a call is issued to tell the ALSA MIDI layer to connect the SC output port to the device. In this case, though, it’s wrong to think of “SC connecting to the device.” SC only sends the messages out through the MIDIClient source labeled “SuperCollider.” After that, sclang’s responsibility is over and it’s up to ALSA to send the message to the right place.

What puzzles me about your scenario is: you plug in the MIDI device, and ALSA should open the driver. This might take a little time, but you haven’t run SC yet. Then you init the MIDIClient, and it finds the sources/destinations. I can’t imagine why the device would be ready, then not ready, then ready again, in this sequence. I also can’t imagine why the connection would be made late (since it’s a trivially fast operation). (However… I could imagine a badly written MIDI device driver reporting to the OS that it’s ready when it isn’t ready.)

I have no idea how to check the status of a MIDI driver in Linux.

hjh

I think you’re missing my point. You are right about the 2 MIDI workflows, I’m aware of them, but again, from a user perspective it’s irrelevant if what I’m witnessing lives within SC or not.
I’m not trying to say it’s SC responsibility, I wouldn’t even know at this point in time (again, I’ll try few more things later on and report back here).

What puzzles me about your scenario is: you plug in the MIDI device, and ALSA should open the driver. This might take a little time, but you haven’t run SC yet. Then you init the MIDIClient, and it finds the sources/destinations. I can’t imagine why the device would be ready, then not ready, then ready again, in this sequence.

I perfectly agree with you, in fact I was surprised when I saw the results I saw.

(However… I could imagine a badly written MIDI device driver reporting to the OS that it’s ready when it isn’t ready.)

I used the same device with other DSLs (e.g. ChucK) and didn’t have the same results.
Also, once the device was plugged in, I didn’t disconnect it anymore.
Again, I’ll run few more tests asap.

OK, it turns out I’m an idiot! (what a surprise)
The issue is neither with SC nor the hardware, but with Protokol (MIDI Monitor), or to be more precise with me!
Since I didn’t check the size of its parameter keep log lines, that was set to 250, and so even if I was clearing the console every time I launched the script, I have been sending more than 250 msg to the MIDI controller and so the first got deleted to make space to the last ones!
Double-checked with a bigger buffer and it’s all good!
Sorry for the noise :smiley: