MIDIIn.connect arguments?

I’ve been using MIDIIn.connectAll in Linux for such a long time that I forget what arguments to pass to MIDIIn.connect.

This method is, inexplicably, undocumented.

I’m debugging something else in my libraries, I don’t have time to do a hundred tests. Does anyone know? (Could that person write documentation for it?)

hjh

~connect =
{
	MIDIIn.connect
	(
		inport:
		(
			~inport =
			(
				MIDIClient.sources.indexOf
				(
					MIDIIn.findPort
					(
						deviceName:
						(
							MIDIClient.sources.last.device
						),
						portName:
						(
							MIDIClient.sources.last.name
						)
					)
				)
			)
		),
		device:
		(
			~src_uid =
			(
				uid
				(
					MIDIClient.sources.at(~inport)
				)
			)
		)
	)
}

I second the proposal to clarify this method in the documentation… however, I believe throwing in something like this as an example in the MIDIIn help source would be a bit of an overkill, and nowhere near typical sc-help source style… perhaps it could be included in Using MIDI, under MIDIIn… or as it’s own section in Using MIDI… something like “connecting individual MIDI sources”

Also, there may need to be included with this example, an emphasis on the possibility of having to run MIDIIn.disconnect, using the same arguments… especially in the case that one is re-evaluating code that runs MIDIClient.init, MIDIIn.connect… in this case, MIDIClient was already initialized, and calling .init is not the same as calling .restart, or calling .disposeClient.init, and sometimes what happens is, the port is already occupied, even though the arguments remain the same, and nothing extraneous has been connected/disconnected, and with nothing else having been added to the MIDIClient.sources list…

A safer version version of this example would look more like:

MIDIIn.disconnect(~inport = <>, ~src_uid = <>).connect(~inport, ~src_uid)

…however, I think we would all agree, the possible necessity of needing to disconnect prior to calling connect, only deserves to be given a quick mention in the accompanying example ‘clear English’ text, and shouldn’t be included in the initial MIDIIn.connect individual source code example… it would be (however slightly) too much of an overkill, or a little too much information upfront… especially for someone who is still new to these concepts.

Ok, thanks.

I thought that’s what I did – MIDIIn.connect(index, uid) – but it threw some error so I thought maybe I had the wrong idea… then found there wasn’t an easy way to look it up (which is… like… you can’t use MIDI input at all without connecting something – it’s not exactly an obscure method).

In the end I found that you can’t debug SC MIDI output by self-connecting and tracing messages… I had to use Pd to print the MIDI note messages :laughing:

hjh

I’ve recently come across a bug in MIDI (might be macOS only) and when debugging I tried to use MIDIIn.connect instead of connectAll. I think that running MIDIIn.connect on the already connected port results in doubling messages in the responders… And thus MIDIIn.connectAll is the method to use, since it disconnects everything first.
I agree that this should be better documented. Also, on Linux you also need to connect MIDIOut, right? It would be great to have these work the same on all platforms…

I added this as an issue: ‘MIDIIn.connect requires further documentation’

Uhm… I can’t produce the doubling of messages I thought I experienced with MIDIIn.connect. So maybe that’s not an issue…?

…which MIDI controller constantly outputs notes, as you put it?

…which MIDI controller constantly outputs notes, as you put it?

I’m working with Genki Wave, once connected it’s streaming control and bend messages continuously.

Interesting… I’ve never seen these before.

In the future, I believe MIDIIn.connectAll and MIDIIn.disconnectAll will simply perform MIDIClient.respectivePorts.do{ |x, in| MIDIIn.*nect(in, x )}

I think we can all agree how important it is, to keep the experience and functionality of SC’s MIDI interface as clear and smooth as possible, just as I think we can all commend the devs for understanding that until the absolute perfection of this particular class/feature takes an urgent level of precedence (all respect and gratitude to our dev team) … until then, connectAll has always kept everyone satisfied, and worked well enough for eighty to ninety percent of everyone’s needs… what with all the complications between operating systems, as well as different in-case uses, desires, necessities, etc… they’ve boiled down MIDI (all platforms) into mostly only two methods: connectAll (in) & newByName (out).

And so, I believe the issue you’re trying to shed light upon is:

sclang crashes when the call to disconnect conflicts with any immediate or nearly simultaneous incoming messages…

Such situations must be somewhat rare, however, not quite so unusual when one is calling disconnect, hitting cmd+enter upon wearing a ring-shaped instrument capable of sending 6 or more classes of messages!

Whether for as needed use only, or, as a safety precaution implemented into everyone class files, I believe that perhaps one solution would be:

MIDIdef.freeAll

~connected_port.latency.wait

MIDIIn.disconnectAll

s.latency.wait // extra safe

and finally,

MIDIClient.disposeClient (might be all that’s really necessary)

…before updating the client list.

Perhaps MIDIIn needs a ‘clearAllResponseDefs’, or even an ‘ignoreAllPreviouslyScheduledTasksInstantiatedFromMIDIResponseDefinitions’… internal use function or something, or perhaps a ‘quit’ and ‘hardQuit’ version of the SC-MIDI, just like our CmdPeriod and server-quit functionality.

Just my thoughts… I know without having to over-explain everything, even while our heads are scratching, the devs know what to do, what they’re doing, etc… big thanks to all the devs here, god-speed to all the developers working hard on SC.

And thanks for your input regarding the G-wave rings… if they become rage, hopefully SC can beat the clock for achieving full support for such a unique & idiosyncratic interface, before a sort of tipping point is reached… as well as for any other electronic instrument that could potentially become a sensation.

FWIW I’m unable to reproduce this crash in Linux (even with a MIDI clock patch in Pure Data, where I set the tempo to 200 bpm = 60000/24 / 200 = 12.5 ms between clock ticks).

So… are you seeing this in Mac, Windows or both?

I think this would be irrelevant to the crash. The MIDI messages go from the OS MIDI subsystem into SC’s backend function to handle incoming MIDI, which then calls MIDIIn handlers, and these finally dispatch to MIDIFunc / MIDIdef. A crash is almost certainly in the backend, long before reaching the responsedefs (hence removing responsedefs would do nothing to prevent the crash).

hjh

I tested the issue on macOS only.

I think this would be irrelevant to the crash. The MIDI messages go from the OS MIDI subsystem into SC’s backend function to handle incoming MIDI, which then calls MIDIIn handlers, and these finally dispatch to MIDIFunc / MIDIdef. A crash is almost certainly in the backend, long before reaching the responsedefs (hence removing responsedefs would do nothing to prevent the crash).

I agree, this seems to be triggered on the disconnectAll step if the timing of messages is “right”.

Thanks guys.

I was just about to suggest it was a complication in the long chain of OS → MIDI → SC → OS → MIDI, etc… and then I realized, I was simply reiterating what everyone had already said… and so exuse me for my ignorance.

I’m re-posting Marcin’s issue here

Maybe someone else can shed some more light on the subject… however… I think it’s a long road to fully synchronous message relaying across all networks and interfaces… unless we make an OS purely out of the desire (need) for precise time-based scheduling for all (parallel, multiple) threads, musical sequencing, etc.