SuperCollider peeps, let me know your views on this!
See below, my (alpha-stage) SerialOSCClient library for SuperCollider. It’s mostly been tested on Windows 10 using SuperCollider 3.6.6 but it should work on OSX (and I guess Linux). My aging Macbook unibody (2008) freaks out a bit when I tried this and hot swapped devices, no idea why but this appears to be serialoscd 1.2 related as it also occurs with frequent hot swapping of devices when SuperCollider is not running.
The library is contained in this file:
SerialOSCClient.sc (26.6 KB)
Installation: download and drop SerialOSCClient.sc into your SuperCollider Extensions folder and Recompile Class Library.
SerialOSCClient works a bit like MIDIClient. You init it and use *def classes (GridKeydef, EncDeltadef, etc) for listening to buttons and encoders. There is no need for OSCdef. For setting led / ring state each attached device gets a SerialOSCGrid or SerialOSCEnc instance with methods to facilitate this.
See below code for intro:
// First, plug in a grid device. Hot swapping is implemented and might work but is not well tested.
SerialOSCClient.init; // Initialize the SerialOSCClient.
// * Connected devices should get posted in the Post Window.
// * Note that SerialOSCClient initialization is performed asynchronously.
// Boot server
s.boot;
// Hello World - pressing the top-leftmost button auditions a sinewave.
GridKeydef.press(\playSine, { a = {SinOsc.ar}.play }, 0, 0);
GridKeydef.release(\stopSine, { a.release; a=nil }, 0, 0);
// Remove GridKeydefs using .free or by pressing Cmd-.
GridKeydef.press(\playSine).free;
GridKeydef.release(\stopSine).free;
// Now, setting leds... If everything works properly and you have a grid attached, a default SerialOSCGrid instance is defined
SerialOSCGrid.default;
// Use this instance to set leds
a=SerialOSCGrid.default;
a.ledSet(0, 0, true);
a.ledSet(0, 0, false);
// The !? idiom in SuperCollider (see help on !?) can be used to set leds of the default grid, but only if it is available (if SerialOSCGrid.default is not nil)
SerialOSCGrid.default !? { |grid| grid.ledSet(1, 2, true) };
(
// Scramble 8 random leds in a 8x8 matrix
SerialOSCGrid.default !? { |grid|
8 do: { grid.ledSet(8.rand, 8.rand, [true, false].choose) };
};
)
// Now, on handling multiple devices
// Info on what device triggered a GridKeydef is available in the function argument list.
GridKeydef(\debug, { |x, y, state, time, device| [x, y, state, time, device].debug });
// You can use a device as filter. See OSCdef help for how this works.
GridKeydef(\debug, { |x, y, state, time, device| [x, y, state, time, device].debug }, device: SerialOSCGrid.default);
// If several devices are attached you can retrieve SerialOSCGrid and SerialOSCEnc instances from SerialOSCClient.devices
SerialOSCClient.devices;
// Pick a device and set a led
a=SerialOSCClient.devices.first;
a.ledSet(1, 2, true); // this assumes first device in list is a grid (SerialOSCGrid)
Below, a monome and arc play together.
// Example, grid together with arc
(
var set_arc_led;
var scramble_8_grid_leds;
var b_spec = ControlSpec.new;
// Ensure server is running
s.serverRunning.not.if {
Error("Boot server stored in interpreter variable s.").throw
};
// Initialize client in order to use devices
SerialOSCClient.init;
// SynthDef to server
SynthDef(\test, { |freq, gate=1| Out.ar(0, ( SinOsc.ar(Lag.kr(freq)) * EnvGen.ar(Env.cutoff, gate) ) ! 2) }).add;
// Function to visualize a float value 0 - 1.0 on first encoder ring of default arc (if attached)
set_arc_led = { |value|
SerialOSCEnc.default !? { |enc|
enc.clearRings;
enc.ringSet(0, SerialOSCEnc.ledXSpec.map(value), 15);
};
};
// Function to scramble state for 8 random buttons in a 8x8 led matrix on the default grid (if attached)
scramble_8_grid_leds = {
SerialOSCGrid.default !? { |grid|
8 do: { grid.ledSet(8.rand, 8.rand, [true, false].choose) };
};
};
// Initial arc encoder setting
b = 0.5;
set_arc_led.(b);
// First Arc encoder control frequency of sinewave and scrambles 8 leds
EncDeltadef(\adjustFrequency, { |n, delta|
b = b_spec.constrain(b + (delta/1000));
a !? { a.set(\freq, \freq.asSpec.map(b)) };
set_arc_led.(b);
scramble_8_grid_leds.();
}, 0);
// Hitting any grid button auditions sinewave and scrambles 8 leds
GridKeydef.press(
\playSine,
{
a ?? {
a = Synth(\test, [\freq, \freq.asSpec.map(b)]);
scramble_8_grid_leds.();
};
}
);
// Releasing any grid button stops the sinewave
GridKeydef.release(\stopSine, { a.release; a = nil });
)
SerialOSCClient.sc (26.2 KB) (obsolete, use the one at the top of the post)