postln('Loading custom functions.'); /* * JACK specific helper functions * TODO: move to Quark */ // disconnect a port ~jackDisconnectPort = { arg source, sourceChannel, destination, destinationChannel; ("jack_disconnect "++source++":"++sourceChannel++" "++destination++":"++destinationChannel).unixCmd({ arg exitCode; if(exitCode != 0, { postln("Disconnecting "++source++":"++sourceChannel++" from "++destination++":"++destinationChannel++" was unsuccessful!"); }); }); }; // connect a port ~jackConnectPort = { arg source, sourceChannel, destination, destinationChannel; ("jack_connect "++source++":"++sourceChannel++" "++destination++":"++destinationChannel).unixCmd({ arg exitCode; if(exitCode != 0, { postln("Connecting "++source++":"++sourceChannel++" from "++destination++":"++destinationChannel++" was unsuccessful!"); }); }); }; // returns the amount of ports of a given client ~jackClientPorts = { arg clientName; ("jack_lsp "++clientName++"| wc -l").unixCmdGetStdOut.asInt; }; /* * SuperCollider specific helper functions * */ // adds one or more channels to Server.local.options.num{In,Out}putBusChannels // makes the tuple available in ~additionalChannels Dictionairy ~addAdditionalChannels = { arg type, name, channels; if( name.isKindOf(Symbol) && channels.isArray, { switch (type, \input, { ~additionalChannels.at(\inputs).add(name -> channels); postln("Added additional input channels for '"++name++"': "++channels.asString); Server.local.options.numInputBusChannels = Server.local.options.numInputBusChannels + channels.size; postln("Setting numInputBusChannels to "++Server.local.options.numInputBusChannels); }, \output, { ~additionalChannels.at(\outputs).add(name -> channels); postln("Added additional output channels for '"++name++"': "++channels.asString); Server.local.options.numOutputBusChannels = Server.local.options.numOutputBusChannels + channels.size; postln("Setting numOutputBusChannels to "++Server.local.options.numOutputBusChannels); }, { postln("Expecting \input or \output as type, got "++type.asString); }); },{ postln('Expecting type Symbol for name and type Array for channels.'); }); }; /* * SSR specific helper functions * TODO: move to Quark */ // sets up the necessary OSC connection for an existing local or remote SSR // instance, subscribes to it and returns the NetAddr associated with it ~ssrSetupOSC = { arg host="localhost", port=50001; var ssr; // set ssr of the client instance ssr = NetAddr(host, port); // answer /poll messages with an /alive answer OSCdef( \pollreply, { arg msg, time, addr, recvPort; ~ssr.sendMsg("/alive"); }, '/poll', ssr ); // subscribe to server with MessageLevel::SERVER ssr.sendMsg("/subscribe", $T, 2); ssr; }; // clears the SSR scene, unsubscribes from the instance and removes alive // answers OSCdef ~ssrDismantleOSC = { arg ssr; if (ssr.isKindOf(NetAddr), { // remove all sources ssr.sendMsg("/scene/clear"); // unsubscribe from server ssr.sendMsg("/subscribe", $F); // disable alive answers OSCdef(\alive).disable; }); }; // adds a source to an SSR instance ~ssrAddSource = { arg ssr, name, model = "point", port, x = 0.0, y = 0.0, orientation = 0.0, gain = 0.0, movability = $F, orientationMovability = $F, mute = $F; if (ssr.isKindOf(NetAddr), { if (name.isString, { if (model.isString, { if (port.isString, { ssr.sendMsg("/source/new", name, model, port, x, y, orientation, gain, movability, orientationMovability, mute) },{ error("The port argument is not of type String: "++port.class); }); },{ error("The model argument is not of type String: "++model.class); }); },{ error("The name argument is not of type String: "++name.class); }); },{ error("The ssr argument is not of type NetAddr: "++ssr.class); }); };