name(String/symbol) as argument in SynthDef

Hey,

I wrote a function, to send envelope data from a SynthDef (over the server) to a visual program via OSC. I use the SendReply function. But for the osc address I want the SynthDev to have an argument that I can set with an unique name, when creating the Synth.

But when I create a SynthDef and I want to add an argument to set an unique name for the Synth to be transmitted to the sendSignal function, I have a problem:

When adding an Object as an argument

SynthDef.new(\mySynthDef, {

arg myName='name‘;

myName.postln;

….

})

The argument value is:

an OutputProxy

When adding the arg as a String

myName=„name“

it says

ERROR: Primitive ‘_ArrayAdd’ failed.

Wrong type.

I have the feeling, I’m missing some basic knowledge there, but can’t figure out what.
The whole code looks like this right now:

(
var oscDest = NetAddr(“127.0.0.1”, 5001);

// example target address - insert your target host & port here

//Send OSC Function:

var sendSignal = {
arg address = ‘/test’, signal = [20,30], refreshRate = 60;
“signalSender on Work”.postln;
address.postln;
// osc listener for sendReply
OSCdef(\listener, {|msg|
var data = msg[3…];
data.postln;
oscDest.sendMsg(address, data[0]);
}, address);
//create sendreply
SendReply.kr(Impulse.kr(refreshRate), address, signal, -1);
address;
};
a = sendSignal;

//Kick-Drum:

SynthDef.new(\kick, {
arg freqA=1000, freqB=50, freqC=10, freqDur1=0.01, freqDur2=0.2, freqC1=1, freqC2=(-1),
att=0.01, rel=1, c1=1, c2=(-12), amp=0.3, pan=0, out=0, name2=“bla”;
var sig, env, freqSweep, myName="/test";
freqSweep = Env([freqA, freqB, freqC], [freqDur1, freqDur2],[freqC1, freqC2]).ar;
env = Env([0, 1, 0], [att, rel], [c1, c2]).kr(doneAction: 2);
//oscSending Section
//oscAddress = ‘/test’;
name2.asString.postln;
myName = “/” +name2.asString;
myName = myName.replace(" ", “”);//remove empty spaces
a.value(myName, env);
sig = SinOsc.ar(freqSweep, pi/2);
sig = sig * env;
sig = Pan2.ar(sig, pan, amp);
Out.ar(out, sig);
}).add;

//Pattern:

Pdef(\kickPattern,
Pbind(
\instrument, \kick,
\dur, 2 * Pseq([1, 0.25, 0.75], inf),
\amp, 0.8,
\freqA, 700,
\att, 0.035,
)
).play;

)

SynthDef arguments aren’t really arguments, and you can’t use them with arbitrary datatypes.

Even if you could define a SynthDef argument default as a string, you wouldn’t be able to send it directly in OSC (because the server doesn’t understand strings as control values – only names).

There should be a way to hack it by sending ASCII codes as numbers, with a zero to terminate the string. But I’m not at my computer now so I can’t work it out at the moment.

Or, mass-produce a different SynthDef name for each outgoing OSC string.

hjh

Actually, there’s an obscure feature by which you can send “special” strings as control values, e.g. “c7” will set (actually map) the value by reading from control bus 7 and likewise with the “a” prefix for audio busses. I’ve used that here. But other than that, there’s indeed no support for any other fancy expressions as values in the server protocol.

This feature is documented in the server reference:

floating point and integer arguments are interpreted as control value. a symbol argument consisting of the letter ‘c’ or ‘a’ (for control or audio) followed by the bus’s index.

Alas that’s not presently possible. You’ll have make make due with concatenating the synth name and its (node) id. It’s somewhat worse for groups as those only have an id, so it’s even less suggestive what they do. There was a discussion here (more like a feature request) on naming groups.

Sorta works using an array of controls, but it’s pretty ugly

SynthDef(\testName, { |out = 0, freq = 440, amp = 0.1, name = #[0, 0, 0, 0], gate = 1| Out(out, 0); }).add

a = Synth(\testName, [\name, "foo".ascii] )

a.getn(\name, 4, { arg value; ("name is now:" + value).postln; });

a.getn(\name, 4, { arg value; ("name is now:" + value.collect({|x| x.asInteger.asAscii}).inject("", _++_)).postln; });

There’s surely a more compact way to store those chars as floats, but in pinch…