2

I am trying to change the volume using Line.kr but I get this error: ERROR: can't set a control to a UGen

Here is the code:

a = {arg freq=440, vol=0; SinOsc.ar(freq)*vol}.play
a.set(\vol,Line.kr(0,1.0,3))

Any ideas?

Yiannis K
  • 21
  • 2

2 Answers2

2

This is actually such a basic issue/topic that a more elaborate answer is perhaps warranted. Basically, if you need/want "total flexibility" in what that \vol envelope is, you have to read it from a (server-side) bus or use one of the many client-side wrapper tricks that hide that (bus) plumbing under some syntactic sugar. A typical example of the latter would be JITLib. An example using the latter:

a = Ndef(\a, {arg freq=440, vol=0; SinOsc.ar(freq)*vol}).play;
a.set(\vol, Ndef(\v, { Line.kr(0,1.0,3) }))

If you now do a.edit you'll see somthing like

enter image description here

Without using that JITLib sugar, you'd have allocate and map a bus yourself, such as in:

a = {arg freq=440, vol=0; SinOsc.ar(freq)*vol}.play;
b = Bus.control(s, 1); // "s" is the default-bound server variable
a.map(\vol, b);
c = { Out.kr(b, Line.kr(0,1.0,3);) }.play;

With JITlib you can just set all over as it has "smarts" to detect the argument type, but with the basic SC you need to distinguish between mapping and setting... although you can also set something to a c-led bus-number string to achieve the same effect (map basically does that for you), i.e. the penultimate line above can be a.set(\vol, b.asMap); Just b.asMap evaluates to something like e.g. "c1", meaning control bus 1. (Audio busses use "a" prefixes instead, as you might expect.)


This bit may be somewhat more confusing, but keeping in mind that a and ~a are different types of variables (more or less function stack vs environment stack), the Ndef keys (first Ndef arguments) can be used "directly" in "shortcut" ~variables provided by the ProxySpace as in

p = ProxySpace.push(s);
~a = {arg freq=440, vol=0; SinOsc.ar(freq)*vol};
~a.play;  // play the NodeProxy, not the Function (Synth) directly
~a.set(\vol, ~v); // ~v is a NodeProxy.nil(localhost, nil) due to ProxySpace
~v = { Line.kr(0,1.0,3) };

Under the hood this last example practically auto-issues Ndefs, i.e the 2nd line does the same as Ndef(\a ..., so you don't have to type Ndefs explicitly anymore. The way this works is that ProxySpace replaces the currentEnvironment (where ~variables live) with one in which put, which is triggered by assignments to ~variables, is now creating or modifying Ndefs and at is accessing them, e.g. if you evaluate currentEnvironment now it shows something like

ProxySpace ( ~a - ar(1) ~v - kr(1) )

(To get back to your prior environment issue a p.pop now.)

Fizz
  • 4,782
  • 1
  • 24
  • 51
1

You can't use UGen to set some arg of a SynthDef, but you can set the arguments of Line.kr:

a = {arg freq=440, vol=0; SinOsc.ar(freq)*Line.kr(atk,sus,rel)}.play
a.set(\atk,0,\sus,1,\rel,0)

please note that with Line.kr you can't restart the envelope. For a more specific control please see the EnvGen UGen: http://doc.sccode.org/Classes/EnvGen.html

BROKENCODE
  • 85
  • 1
  • 10
  • 1
    In the first line, that needs to be `Line.kr(\atk.kr, \sus.kr, \rel.kr)` otherwise you're not making any controls (and you'll also get an error for undeclared variables in that example). You can (later) `set` controls that don't exist alas, it's just that nothing happens in that case. – Fizz Nov 30 '21 at 19:41
  • 2
    And the params for `Line` are really `(start, end, dur)`. – Fizz Nov 30 '21 at 19:47