Why does the third example generate an error? What is the difference between putting the function in its own variable vs. the event namespace variable?
These two are passing a function into SynthDef.new.
This one is passing the result of the function, but not the function itself.
If you change it to read SynthDef(\test, a[\function]); then it should work. .xxx and [\xxx] are not interchangeable even though many examples use them as such.
Thank you. Is this documented somewhere? It was not particularly obvious although it makes sense now.
I guess [\xxx] is like at and .xxx is like a method call.
This is where its implemented - don’t think its documented.
In Smalltalks you can look at the message (bit after the full-stop) and redirect it if the underlying class doesn’t understand it using the doesNotUnderstand method.
If the Environment item is a function, it is evaluated as if it were a method definition. The first argument passed into the function is the Environment that holds the function; arguments to the method call follow as the second, third etc. arguments passed into the function.
e.printMe("Oh hai wrldz");
// same as
e['printMe'].value(e, "Oh hai wrldz");
I want to compose SynthDefs out of functions, in the way you might use a templating engine. In the example below, I am defining a “footer” called outs which takes an audio rate signal which I would like to define once and re-use.
I am reading the Environment docs but I’m having trouble wrapping my head around the scopes. The code below generates an error.
~test = ();
~test.outs = { arg sig; Out.ar(\out.kr(0), sig * \gate.kr(0) ) };
~test.signalPath = { var sig = SinOsc.ar; ~test[\outs].valueEnvir };
~test.signalPath.play;
// ERROR: Message 'addKr' not understood.
I also tried some variants using ~test.make and ~test.use.
Any suggestions here?
What about this case? Below is a class method which will iterate through a directory, call the .load method on the file and try and create a synthDef from it.
// The compiler provides a shortcut syntax where ~ is a placeholder for currentEnvironment.
// This makes the expression ~myvariable; equivalent to currentEnvironment.at(\myvariable); and the expression ~myvariable = 888; equivalent to currentEnvironment.put(\myvariable, 888);
a = 'foo';
~a = 'bar';
currentEnvironment[\a] // bar
topEnvironment[\a] // bar
What is the Environment of a? Does a have an environment? Is there a method to discern it?
That should be a[\outs].value(sig), no fullstop between a and [.
Assuming that is ‘a’ without a tilde then there is no environment, this is stored in the Interpreter class.
If however, you declare ‘a’ like this … var a … then a exists in the local scope (surrounding curly braces) and will be destroyed when the code leaves the scope and there are no other references to the variable. If you want to use ‘a’ outside of the scope just return it or append it to something.
You could try it by yourself – what do you see if you remove the “at” operation? (What is the value of currentEnvironment? Of topEnvironment?)
Why are there two names? Because currentEnvironment may change but topEnvironment doesn’t. But the fact that currentEnvironment can change means that ~a is not truly global. It acts like it’s global in most usages but if you push or use a different environment, then you have a different ~a. So “global” is not quite the right concept here.
I feel like I abandoned this question either because I didn’t ask the right question, make my use case clear enough or understand the answers. Anyway, here is the working code that I eventually figured out, for posterity’s sake:
This let me make the classvar globalContext an Environment and then set (for example) globalContext.numChans. Then, in the context of the synthDef, I’ll do things like: