Perhaps people are actually making music and not spending time just writing new programming libraries (ahem).
Now that’s a good thing…
Yep, discovering attached and detached devices appears to work fine. Thanks for confirming this.
From reading the contents of the Post Window I’m quite sure you also have MonoM - another SuperCollider library - installed. It also outputs discovered (attached) devices. MonoM does not seem to report detached devices. These sections are from MonoM:
Device connect on port:[port]
[id]
[type]
Wow, 10 seconds is a long time. Do you get the same delay in other programs - ie, do you use Max/MSP? Can you confirm whether the MonoM section (above) was printed at the same as the SerialOSCClient section for attached devices, which looks like this:
A SerialOSC Device was attached:
SerialOSCGrid([type], [id], [port])
For arcs SerialOSCEnc() is posted.
If they are posted the same time it could mean the delay you refer to is induced by serialoscd and not SuperCollider or SerialOSCClient.
This might be a good time to describe some differences between MonoM (which I haven’t used that much) and SerialOSCClient. Code wise MonoM it’s way more lean than SerialOSCClient. That - I believe, correct me on this if I’m wrong - is due to MonoM only handling binding of devices to SuperCollider and output of led messages. For incoming events (key presses, encoder deltas, etc) it relies on OSCdef or OSCFunc usage. I also believe you need to bind devices explicitly by useDevice and usePort. Don’t get me wrong, this is fine and it’s a lean and mean little class which I stole some ideas from.
SerialOSCClient does autodiscovery of devices (attached and detached), maintains a list of current devices in SerialOSCClient.devices and uses that list to route incoming events (key presses, encoder deltas, etc) to SerialOSC device specific *def and *Func objects (GridKeydef/Func for incoming key presses, EncDeltadef/Func for encoder deltas, etc).
From a simple step-sequencer:
GridKeydef.press(\edit_pattern, { |x, y| ~toggle_trig.(y, x) });
As with SuperCollider OSCdef/OSCFunc classes, you can filter each def you create by different properties such as x, y, state and device (for GridKeydef). If you provide no filtering, all events will pass through.
So, in the simple case of having one device or one of each type of device - one grid and one arc is often the case for me - you can just whack some *defs out and don’t care at all about ids, ports, prefixes, device order, etc. I guess this is how the current Max/MSP serialosc stuff works, but I’m not sure.
Default grid and encoder devices are also set up automatically once attached so for prototyping (and real apps) you can code against a default grid if it’s available using a particular SuperCollider idiom:
SerialOSCGrid.default !? { |grid| grid.ledSet(0, 0, true) };
You can also listen to updates when new default grids or encoders are set to do something when a device is attached and set to default or a user explicitly change default device of a given type:
SerialOSCGrid.addDependant { |thechanged, what|
if (what == 'default') {
// send current grid led state as defined by app to update grid
};
};
So, for simple device configurations I hope “plug-in device and go” is within reach.
Of course there are trade offs and a lot of unimplemented features at this point. All devices just bind to prefix “/sclang” for instance, which probably breaks some basic ideas in how serialosc routing was supposed to work. But it works pretty well for me…
This is great feedback, thanks.
Different strokes for different folks… My code sections above may be hard to grok if you’re not into SuperCollider yet I include them if some other is interested. SerialOSCClient has 0% documentation right now.