OSCMapper: A high level library for OSC controllers

OSC Mapper

A high level library to interact with SuperCollider via an OSC controller.

I found myself writing way too many OSCdefs in a project and decided to wrap common OSC routing functionality in a library.

The basic idea is to attach a Class which handles the incoming data to an address. This data can be a float, a button, a 2 dim XY … I tried to cover everything that gets used in TouchOSC and beyond that.
Declaring a layout of address: Class mapping can be done via

  • Using a pre-defined layout - useful for quick interaction
  • Writing the layout by oneself - useful for custom controllers and bigger works
  • Learning an OSC controller: A good way to start the addresses to Class mapping

The layout of a controller can be changed on the fly and also allows to

  • Use the values in sclang [e.g. patterns, callbacks] and on server [via Ndef/Bus]
  • Add a callback when new values are received
  • Modify the range of the input data via a function (e.g. linlin, …)
  • Access and modify the controller in def style
  • Allow to access multiple elements, e.g. on a XY graph we can access both components via .x and .y

If you have any feedback, comments, improvements or found a bug please write it here or on GitHub :slight_smile:

Have fun!

Quickstart

Installation

// install the quark
Quarks.install("https://github.com/capital-G/OSCMapper.git");
// restart the interpreter so the new classes are available
thisProcess.recompile;
// open documention
HelpBrowser.openHelpFor("Classes/OSCMapper");

Creating a layout

You can either define the layout manually

(
o = OSCMapper(\myLayout, (
    '/1/fader1': OSCMapperFader(
        altName: \fader1,
        defaultValue: 0.5,
        transformer: linlin(_, 0.0, 1.0, 0.5, 10.0),
        callback: {|v| ["received a value", v].postln;},
        lag: 0.5,
    ),
    '/1/xy1': OSCMapperXY(
        altName: \touchPanel
    ),
));

or use a preset like Mix 2 from TouchOSC like

o = OSCMapper.mix2(\myLayout);

or learn a custom controller on the fly

OSCMapper.learn;
// move controls
o = OSCMapper.finishLearn(\myLayout);

Using the controller within SuperCollider

As Ndef

// the osc mapper we created earlier can also be accessed in def style
o = OSCMapper(\myLayout);

Ndef(\mySine, {SinOsc.ar!2 * o['/1/fader1'].asNdef}).play;

Ndef(\mySine).clear(2);

As bus

// use the default synth
s = Synth(\default);
s.map(\amp, o['/1/fader1'].asBus);
s.free;

In a pattern via Pdefn

(
p = Pbind(
    \instrument, \default,
    \dur, 0.5,
    \degree, Pxrand((0..10), inf),
    \amp, o['/1/fader1'].asPdefn,
).play;
)

p.stop;

As raw value access

o['/1/fader1'].value;

Add a callback on change

o['/1/fader1'].callback = {|v| "value is now %".format(v).postln};
// and free the callback
o['/1/fader1'].callback = {};
7 Likes