1 // this is probably not working anymore. see NetAddr.sc instead for the newer way.
4 // Open Sound Control support
7 classvar <>sc; // this contains the "/sc" default behaviour for all input ports.
9 // a not-very-secure password for access to the compiler
10 // setting password to a Symbol opens SC to potential hacking
13 var <name, <>children, <>function, <>value, <port;
15 *new { arg name, function, children, value;
16 ^super.newCopyArgs(name, children, function ? { arg node, x; x }, value);
18 *tree { arg children, argName, argValue;
19 children = children.collect({ arg subtree;
20 var name, thing, value;
21 #name, thing, value = subtree;
23 this.tree(thing, name, value);
25 OSCNode(name, thing, nil, value);
28 ^OSCNode(argName, nil, children, argValue);
31 if (children.isNil, { children = Array.new(4) });
32 children = children.add(child);
35 if (children.notNil, { children.take(child); });
40 name_ { arg theName; name = theName.asSymbol; }
42 // these are for send and reply on the same machine.
43 send { arg oscAddress ... args;
45 ^this.primitiveFailed;
47 reply { arg oscAddress ... args;
49 ^this.primitiveFailed;
53 // Build the default behaviour for all input ports.
54 // You might want to comment some or all of this out for installations
55 // so you can't be hacked..
58 // Warning: the 'run' method makes SC vulnerable executing any
59 // code sent to it over the net. If you don't want to worry about it
60 // then never set the password and you'll be safe.
61 [\run, { arg node, msgPassword, string;
62 if (password.isKindOf(Symbol) and: { password === msgPassword },
64 string.interpret; // a powerful tool for both Good and Evil...
67 [\set, { arg node, varName, value; // set one of the variables a-z in the interpreter
68 thisProcess.interpreter.perform(varName.asSetter, value);
70 [\clearAll, { thisProcess.interpreter.clearAll; }],
71 [\executeFile, { arg node, pathname; thisProcess.interpreter.executeFile(pathname); }]
75 [\choose, { arg node, names; Library.prLibMenuChoose(names); }],
76 [\perform, { arg node, names, selector ... args;
78 obj = Library.at(names);
80 obj.performList(selector, args);
86 [\perform, { arg node, id, selector ... args;
88 obj = ObjectTable.at(id);
90 obj.performList(selector, args);
94 // a function cannot be sent via the OSC, so 'put' only works using
95 // inter-VM-messaging on the same machine.
96 [\put, { arg node, id, function; ObjectTable.put(id, function.value); }],
98 [\remove, { arg node, id; ObjectTable.remove(id); }]
101 [\play, { arg node, pathName, duration, loop=false;
102 SoundFile.play(pathName, duration: duration, loop: loop);
106 [\stop, { arg node, channel;
107 MixerPlayer.forInput(channel, { arg input;
108 input.killBox.value = 0;
109 input.killBox.doAction;
112 [\copy, { arg node, channel;
113 MixerPlayer.forInput(channel, { arg input;
114 input.copyBtn.doAction;
117 [\volume, { arg node, channel, volume = 0.0;
118 MixerPlayer.forInput(channel, { arg input;
119 input.volumeSlider.value = volume;
123 MixerPlayer.mixer.notNil.if({
124 MixerPlayer.mixer.close;
128 [\ping, { arg node; node.port.reply("/sc/postln", "I'm listening") }],
129 [\run, { thisProcess.run }],
130 [\stop, { Synth.stop }],
131 [\post, { arg node ... args; args.do({ arg item; item.post; " ".post; }); "\n".post; }],
132 [\postln, { arg node ... args; args.do({ arg item; item.postln; });}]
137 call { arg rcvPort ... args;
139 value = function.valueArray(this, args);
144 ////////////////////////////
149 classvar <openPorts; // keep track of all open ports
150 var <portID, udpPort, <>oscNode;
153 if (openPorts.notNil, {
154 openPorts.copy.do({ arg port; port.close; });
158 openPorts.remove(this);
165 ^this.primitiveFailed;
168 if (openPorts.isNil, { openPorts = Array.new(4); });
169 openPorts = openPorts.add(this);
173 OSCInPort : OSCPort {
174 // UDP port for incoming OSC messages
176 *new { arg portID, oscNode;
177 ^super.new.init(portID, oscNode)
179 reply { arg oscAddress ... args;
181 ^this.primitiveFailed;
185 init { arg argPortID, argOSCNode;
187 oscNode = argOSCNode;
193 ^this.primitiveFailed;
198 OSCOutPort : OSCPort {
199 // UDP port for outgoing OSC messages
202 *new { arg portID, hostname, oscNode;
203 ^super.new.init(portID, hostname, oscNode)
206 send { arg oscAddress ... args;
208 ^this.primitiveFailed;
210 sendNoTags { arg oscAddress ... args;
211 _OSCOutPort_SendNoTags
212 ^this.primitiveFailed;
214 sendRaw { arg rawArray;
216 ^this.primitiveFailed;
219 sendArray { arg array;
220 this.performList(\send, array);
224 init { arg argPortID, argHostname, argOSCNode;
226 hostname = argHostname;
227 oscNode = argOSCNode;
233 ^this.primitiveFailed;