Hello.
I’m trying to set oscillator signal into “arg” parameter in SynthDef.
But this code output some error…
Anyone can help?
s.boot;
(
SynthDef(\test, {
arg freq = 440;
var out = {SinOsc.ar(freq!2)};
Out.ar(0, out);
}).add;
)
x = Synth(\test);
x.set(\freq, SinOsc.ar(440)); // error!
x.free;
console:
CALL STACK:
Exception:reportError
arg this = <instance of Error>
Nil:handleError
arg this = nil
arg error = <instance of Error>
Thread:handleError
arg this = <instance of Thread>
arg error = <instance of Error>
Object:throw
arg this = <instance of Error>
UGen:asControlInput
arg this = <instance of SinOsc>
Object:asOSCArgEmbeddedArray
arg this = <instance of SinOsc>
arg array = [*1]
< FunctionDef in Method SequenceableCollection:asOSCArgArray >
arg e = <instance of SinOsc>
ArrayedCollection:do
arg this = [*2]
arg function = <instance of Function>
var i = 1
SequenceableCollection:asOSCArgArray
arg this = [*2]
var array = [*1]
Node:set
arg this = <instance of Synth>
arg args = [*2]
Interpreter:interpretPrintCmdLine
arg this = <instance of Interpreter>
var res = nil
var func = <instance of Function>
var code = "x.set(\freq, SinOsc.ar(440));"
var doc = nil
var ideClass = <instance of Meta_ScIDE>
Process:interpretPrintCmdLine
arg this = <instance of Main>
^^ The preceding error dump is for ERROR: can't set a control to a UGen
@Geoffroy I am new to the language and still getting my head around ugens and and how they are instantiated. I have some questions about your solution. See comments below. There are two things I am confused about, the use of map and setting the control bus as an argument instead of directly in the UGen.
// This is rewritten how I am used to writting sc. It works.
SynthDef(\test, {
arg freq = 440, out = 0;
Out.ar(out, SinOsc.ar(freq ! 2));
}).add;
SynthDef(\modulator, {
arg freq = 1, out = 0;
Out.kr(out, SinOsc.kr(freq).range(440,600));
}).add;
~bus = Bus.control(s,1);
~testSynth = Synth(\test);
~modulatorSynth = Synth(\modulator, [\out, ~bus]);
~testSynth.map(\freq, ~bus);
// Now, there are a couple of things here that seem odd to me. The use
// of `map` and having to set `out` to bus as an argument after the
// synth is instantiated.
// First, if `~bus` is a global variable, why can't it be used in the
// `SynthDef` directly? This does not work. I am sure there is a good
// reason, I would just like to know why.
SynthDef(\test, {
arg freq = 440, out = 0;
Out.ar(out, SinOsc.ar(freq ! 2));
}).add;
SynthDef(\modulator, {
arg freq = 1;
Out.kr(~bus, SinOsc.kr(freq).range(440,600));
}).add;
~bus = Bus.control(s,1);
~testSynth = Synth(\test);
~modulatorSynth = Synth(\modulator);
~testSynth.map(\freq, ~bus);
// Second, the use of `map` over `set`. If I look up the help for map
// I see several help files. I assume this is the map for `NodeEvent`,
// but it's unclear why `set` doesn't work here. `set` is doing
// something, I'm not sure what...
SynthDef(\test, {
arg freq = 440, out = 0;
Out.ar(out, SinOsc.ar(freq ! 2));
}).add;
SynthDef(\modulator, {
arg freq = 1, out = 0;
Out.kr(out, SinOsc.kr(freq).range(440,600));
}).add;
~bus = Bus.control(s,1);
~testSynth = Synth(\test);
~modulatorSynth = Synth(\modulator, [\out, ~bus]);
~testSynth.set(\freq, ~bus);
// First, if ~bus is a global variable, why can’t it be used in the
// SynthDef directly? This does not work. I am sure there is a good
// reason, I would just like to know why.
Basically, when you create a SynthDef, the value of the variables are evaluated (i.e. “freezed”) when you evaluate the SynthDef, and the synth definition is sent to the server.
In your code, ~bus does not exist when you instantiate the SynthDef, hence the error.
// Second, the use of map over set. If I look up the help for map
// I see several help files. I assume this is the map for NodeEvent,
// but it’s unclear why set doesn’t work here. set is doing
// something, I’m not sure what…
If you “set” the value of a Synth parameter, it sets a fixed value to the parameter.
If you “map” a Synth parameter to a bus, SuperCollider will know to get the value in the bus at each processing block to update the Synth parameter.
Sooo, kinda offtopic, but, since we’re talking about control signals and busses, is there a way to .map a param of a synth instanciated by a pbind to a control bus??
Sorry to necropost, but I came across this thread yesterday, and it answered a question I’ve been wondering about for years! I’ve got this working using the Ndef / JIT lib method, but I want to use a whole bunch of these, and I’m finding myself writing a lot of repetitive code and copy/pasting, so I’m wondering if there’s a way to do this with iteration. The way I’m doing this now looks like this (wherein ~timer is a TempoClock):
ERROR: Message '++' not understood.
Perhaps you misspelled '+', or meant to call '++' on another receiver?
RECEIVER:
Integer 0
ARGS:
Integer -2134076441
PATH: /Users/spencerkingmangraham/Desktop/sc docs/superLeid.scd
CALL STACK:
DoesNotUnderstandError:reportError
arg this = <instance of DoesNotUnderstandError>
Nil:handleError
arg this = nil
arg error = <instance of DoesNotUnderstandError>
Thread:handleError
arg this = <instance of Thread>
arg error = <instance of DoesNotUnderstandError>
Object:throw
arg this = <instance of DoesNotUnderstandError>
Object:doesNotUnderstand
arg this = 0
arg selector = '++'
arg args = [*1]
NodeProxy:generateUniqueName
arg this = <instance of Ndef>
var uniqueName = -2134076441
Object:buildForProxy
arg this = <instance of Function>
arg proxy = <instance of Ndef>
arg channelOffset = 0
var channelConstraint = nil
var rateConstraint = 'scalar'
var argNames = nil
SynthDefControl:build
arg this = <instance of SynthDefControl>
arg proxy = <instance of Ndef>
arg orderIndex = 0
var ok = nil
var rate = nil
var numChannels = nil
var outerDefControl = nil
var outerBuildProxy = nil
var controlNames = nil
NodeProxy:put
arg this = <instance of Ndef>
arg index = nil
arg obj = <instance of Function>
arg channelOffset = 0
arg extraArgs = nil
arg now = true
var container = <instance of SynthDefControl>
var bundle = <instance of MixedBundle>
var oldBus = nil
NodeProxy:source_
arg this = <instance of Ndef>
arg obj = <instance of Function>
Meta_Ndef:new
arg this = <instance of Meta_Ndef>
arg key = 0
arg object = <instance of Function>
var res = <instance of Ndef>
var server = <instance of Server>
var dict = <instance of ProxySpace>
Integer:do
arg this = 8
arg function = <instance of Function>
var i = 0
Interpreter:interpretPrintCmdLine
arg this = <instance of Interpreter>
var res = nil
var func = <instance of Function>
var code = "8.do({
arg i;
Ndef(i, {
..."
var doc = nil
var ideClass = <instance of Meta_ScIDE>
Process:interpretPrintCmdLine
arg this = <instance of Main>
^^ ERROR: Message '++' not understood.
Perhaps you misspelled '+', or meant to call '++' on another receiver?
RECEIVER: 0
Any ideas as to how to go about creating Ndefs with iteration? It seems like there must be a way, but I can’t seem to find it.
yes! This is working. I didn’t know about .asSymbol, and that was definitely the missing ingredient. Thanks so much! Here’s the working version of what I was trying to do above:
works!
//modulators
48.do({
arg i;
if(
i < 9,
{
Ndef(i.asSymbol, {
SinOsc.kr(~timer.beatDur/rrand(2,16)).range(-1,1)
})
}
);
if(
(i > 8) && (i < 17),
{
Ndef(i.asSymbol, {
SinOsc.kr(~timer.beatDur/rrand(2,512)).range(500,15000)
})
}
);
if(
(i > 16) && (i < 25),
{
Ndef(i.asSymbol, {
SinOsc.kr(~timer.beatDur/rrand(2,512)).range(0,1)
})
}
);
if(
i > 24,
{
Ndef(i.asSymbol, {
SinOsc.kr(~timer.beatDur/rrand(2,512)).range(0.3,0.5)
})
}
)
});