Utterly confused with .ar after envelope

In the first example the env is set to ar. after the arguments ( which then scales a sinosc amp) , which works
In the second example the ar. is set before ( which doesn’t work )
The deeper I delve into it the more confusing it gets , and I don’t see any mention in the manual about this behaviour
The console says that envelope does not understand ar , so I assume in the first working example the array does understand ar
//some text//
//some text//
//some text//

In the Getting Started tutorial series, there is actually a section that explains a little bit about the most important fundamental concept in SC:

Now this next bit is a little bit tricky. In a given object, each message calls (calls means executes) a particular method. Different types of objects may have methods with the same name, and thus respond to the same message in different ways. Whoah, get that? Read it again slowly, as this is pretty important:

Different types of objects may have methods with the same name, and thus respond to the same message in different ways.

What’s this getting at?

Everything in SC is done by calling methods on objects. Everything. So, you have to understand method calls. There’s no way around it. Even 2 + 2 is a method call. Even control structures like if and while are method calls (with some magic in the backend to make them faster). Everything.

A method call has three parts:

  • A receiver. This is the object that will handle the method request.
  • A method selector. This is the name of the method to be called.
  • A list of arguments – the data in () parens. (This one is optional – there can be a method call with only a receiver and a selector.)
Env([0, 1, 0], [0.01, 0.25], [0, -5]).ar

What is the receiver? It’s Env([0, 1, 0], [0.01, 0.25], [0, -5]). This is an instance of the class Env.

What is the method selector? ar

So this means, somewhere in the system, there is an ar method defined for instances of Env. You can even look it up using ctrl-I, and you would eventually find:

	ar { arg doneAction = 0, gate = 1.0, timeScale = 1.0, levelScale = 1.0, levelBias = 0.0;
		^EnvGen.ar(this, gate, levelScale, levelBias, timeScale, doneAction)

So Env's answer to ar is to create an envelope generator.

OK, let’s flip it around as you had done:

Env.ar([0, 1, 0], [0.01, 0.25], [0, -5])

Same questions – what are the receiver and method selector? The method selector is still the same, ar. The receiver is different – it’s now the class Env rather than an instance of the class.

The fact that you are now calling ar on the class totally changes the picture. It’s not the same method.

In fact, there is no ar for class Env. So the method call is “not understood.” This is actually logical. Env(...).ar takes a concrete, already-defined envelope and produces an envelope player. Env.ar(... envelope parameters...) cannot skip over the concrete envelope definition and go directly to the player. It doesn’t make sense. There’s no way to create an envelope player when you don’t even have a defined envelope yet.

So the concepts that you need to go back and fill in are:

  • Method call: Receiver, selector, arguments.
  • The distinction between classes and object instances of those classes.


PS Would you mind posting code within:


… instead of screenshots? The screen picture requires other people to retype your code.


See also:



1 Like