10 -Keyword Assignment, MouseX.kr and MouseY.kr, Linear and Exponential values 

Keyword Assignment 

In the examples above we included most of the arguments for each message. Objects and messages are setup with defaults when no value is given in the argument list. The default value for add is 0, or no change, so in the previous examples it was left off. Below there are no arguments for the SinOsc, but it still works. It uses default values of 440, 0, 1, and 0 for freq, phase, mul, and add. 

10.1. Defaults 

{SinOsc.ar}.play

You might have also noticed that we entered a 0 for the phase argument even though the default value for phase is 0. This is because the arguments have to be entered in the correct order. Phase is the second argument and mul is the third. We had to enter the 0 as a sort of place marker so that the mul would be in the correct position. 

This becomes a problem if there are 10 arguments and you want to change only the sixth value. You would have to enter 1-5 just so the sixth argument is in the correct position. This is not only cumbersome, but prone to error. 

The solution is keyword assignment. Using keywords you can specify the name of the argument you are changing followed a colon and the value. The documentation for SinOsc.ar shows the following: SinOsc.ar(freq, phase, mul, add). The keywords are freq, phase,  mul,  and add. Using keywords not only allows you to enter a single argument out of order,  but to mix the order of the arguments. Here are several versions of the SinOsc example written using keywords. All of them have precisely the same meaning. 

10.2. keywords, indents 

{SinOsc.ar(freq: 440, phase: 0, mul: 0.4, add: 0)}.play;

{SinOsc.ar(phase: 0, freq: 440, add: 0, mul: 0.4)}.play;

{SinOsc.ar(freq: 440, mul: 0.4)}.play;

(
{
	SinOsc.ar(
		freq: SinOsc.ar(
			freq: 15,
			add: 500,
			mul: 20
		),
		add: 0,
		mul: 0.4,
		phase: 0
	)
}.play
)

Another good reason for using keywords is documentation. In the first examples it may have been hard to see what each of the numbers in the argument list meant. But in the later examples it is clear what the freq and mul arguments are. 

I've also spread the last example out. White space (tabs, spaces, returns, etc) is ignored in code. Use of white space changes a little with each author, but a common practice is to indent sections to indicate which level of enclosures they belong to. In the example above the object function braces are flush left. It is the only item on that level because everything else is enclosed in the braces. I begin a new line for the first SinOsc, and new level of indentation because it is contained in the function. The freq, phase, mul, and add are also all on the same level of indentation to show they all belong to the argument list for the first SinOsc. For the second (which is a nested Ugen for the freq of the outer SinOsc) I start another level. This is where com-] and com-[ come in handy. They increase the level of indentation to the left or right. You can select several lines and increase their indentation at once. 

MouseX.kr and MouseY.kr 

In the examples above we changed each value, then ran the code, then changed the value and ran the example again. You may have wished you could attach some type of knob to the patch so that you could try a range of values at once. This is what MouseX.kr and MouseY.kr will do. They link mouse movement and position to values that can be used in the patch. The first three arguments are: minval, maxval, warp. 

These ugens can replace any static value with a range of values that change in real time in relation to the position of the mouse on the screen. As an illustration, try the first patch reproduced below with a MouseX in place of the first argument for LFNoise0. 

10.3. MouseX (LFNoise0, SinOsc, mul) 

{SinOsc.ar(LFNoise0.ar(MouseX.kr(1, 50), 500, 600), mul: 0.5)}.play;

Much easier than changing, trying, changing, trying, etc. 

In the example below MouseY (Y axis is top to bottom) is used to control amplitude. The minval is 0.9 and maxval is 0.0. These may seem backwards, but the minimum position for the mouse is actually the top of the screen, the maximum is the bottom. The next example adds a MouseX to control frequency. The minimum value is A 220 and the maximum is two octaves higher,  or 880. Since the motion of the mouse spans two octaves you might be able to play a tune with this patch. 

10.4. MouseY controlling amp and freq 

{SinOsc.ar(440, mul: MouseY.kr(0.9, 0))}.play;

{SinOsc.ar(MouseX.kr(220, 880), mul: 0.3)}.play;

The reason it is difficult to pick out a melody is that the warp is set to linear (the default). A linear warp means the numeric values change with the same proportion as the motion and position of the mouse. But the increase of frequency over successive octaves is not linear, but exponential. The amount of change between one of the low octaves (such as 110 to 220) is smaller (110) in comparison to a higher octave (1760 to 3520; a change of 1760). With a linear warp and a range of 220 to 880 the middle of the screen will be 550. But if we want the screen to visually represent a musical scale the middle should be 440, the left half for pitches between 220 and 440 (a difference of 220) and the right half should be 440 to 880 (a difference of 440). This can be corrected using the warp. The warp value is set using a symbol (a word in single quotes), either linear or exponential. You can also enter the number  0 for linear or 1 for exponential. Try playing a melody or major scale with the following adjustments. You will notice the whole and half-steps seem to be the same distance. 

10.5. exponential change 

{SinOsc.ar(MouseX.kr(220, 880, 'exponential'), mul: 0.3)}.play;

As a general rule you will want to use exponential values when dealing with frequency. 

I introduce MouseX and Y as a tool for trying values in patches and experimenting in real time, but it is reminiscent of one of the earliest (and very successful) electronic instruments; the Theremin. The Theremin controlled pitch and amplitude by proximity of the performer's hand to an antenna and protruding loop. Performers "played" the Theremin by moving their hands closer or farther away from the antenna or loop. 

Use the components we have discussed to create a virtual Theremin where MouseY controls amplitude and MouseX controls frequency. To imitate that classic sci-fi sound you should try to play it with a heavy vibrato. 

Practice 

The patch below uses only two SinOsc and one LFNoise0, but can generate very rich sounds because of the way they are linked together (frequency modulation, covered later). 

There are four mouse controls and the arguments for the patch are taken from the mouse position. Notice that in one case the MouseX position represents values between 100 and 1000, while in the other it is 1 to 12. Use the mouse position to explore sounds. Try the four corners first, then some spots in the middle. 

Try changing the high and low ranges for the MouseX and MouseY. 

10.6. Practice sci-fi computer (MouseX and Y) 

(
{
	SinOsc.ar(
		freq: SinOsc.ar(
			freq: MouseX.kr(100, 1000),
			mul: MouseY.kr(100, 1000), 
			add: LFNoise0.kr(
				freq: MouseX.kr(1, 12),
				mul: MouseY.kr(30, 1000),
				add: 600
			)
		), 
	mul: 0.6
	)
}.play
)

10. Exercises 

10.1. Rewrite this example so that each argument list has its own level of indentation. 

{RLPF.ar(LFSaw.ar([8, 12], 0, 0.2), LFNoise1.ar([2, 3].choose, 1500, 1600), 0.05)}.play 

10.2. Using the help files if necessary, insert a MouseX.kr and MouseY.kr to control 
frequency and pulse width (kwidth) of this patch: 

{Pulse.ar(300, 0.2, 0.5)}.play