Monday, May 24, 2010

Numbers and Math

In the previous post, we talked a bit about Integers, which, remember are whole numbers, like -1, 0, 1, 2. And we learned about the do message.

What are some things you might want to do to a number? Add, subtract, multiply, divide, modulus.

Remember algebra where a*b + c*d = (a * b) + (c * d). And remember how that one cheap calculator just did what you punched in, in the order you punched it in, without respecting order of operations? SuperCollider is like that cheap calculator. Mathematical expressions are evaluated left to right. Addition and subtraction have the same precedence as multiplication and division. That means that if you want to do things in some order, you've got to use parenthesis.

Parentheses are evaluated innermost to outermost:
(a + (b * (c + d)))
( 2 + (4 * (3 + 2))) = (2 + (4 *(5))) = (2 + (20)) = 22

What about order of operations within longer lines of code? If we have func.value(3+4), it evaluates 3+ 4 to 7 before calling the function. We can put anything we want inside those parentheses and it will evaluate what's inside until it gets to the outermost parenthesis and then it will call the function.

One math operation that you might not have seen before is modulus. It means "remainder" and it's represented by a '%'.
10 % 3 = 1
26 % 9 = 8

Ok, so the output of a modulus between two integers is an integer, by definition. And if you add or subtract two integers, you get an integer. As you do if you multiply two integers. But what is the result of division?
3 / 2 = 1.5

1.5 is not an integer. It's a type of number called a Floating point, or in SuperCollider, a Float. A float is a fraction. 1.1, 2.5, -0.2, 5.0 are all Floats. They also can add subtract, etc.

You can do more with numbers than simple math and do loops. There are many interesting and useful messages one can pass to Integer. It has a help file worth reading. So type in the word Integer, starting with a capital-I and press apple-d to look at the help file. The top of that help file says:

superclass: SimpleNumber

superclass is a vocabulary word. It refers to a concept called inheritance. What this superclass designation means is that Integer is a SimpleNumber. When you define classes (recall that a class is the definition for an object), you can define subclasses of any class. A subclass is a special type of the original class. It inherits all the properties of its superclass. So the subclass is the child and the superclass is the parent. We'll come back to this. But what it means for us is that Integer is a SimpleNumber. Which means it understands all the messages that you can pass to a SimpleNumber. So to find out about what these inherited messages are, we should highlight "SimpleNumber" and hit apple-d Float and Integer both inherit from SimpleNumber, so take a look at that help file. Looking at help files and trying stuff out will get you learning the language faster than anything else. They might not make a lot of sense right now, but if you keep looking, you'll get context and be able to figure them out in the future.

We have one more example that hopefully ties all of this together. Remember our SynthDef from posts past? Here's an updated version of it.

(

 SynthDef.new("example2", {arg freq = 440, amp = 0.2;
  Out.ar(0, SinOsc.ar(freq, mul: amp));
 }).load(s);
 
)

We’ve added a field called amp, which indicates the amplitude or volume at which the sound should play. In SuperCollider, amplitudes louder than 1 will peak when you listen to them. Therefore output amplitudes should be between 0, which is silent, and 1, which is as loud as possible.

Now, lets’ write some code to play N overtones of 100Hz. We need to make sure that our overall amplitude doesn’t exceed 1, or else we’ll get peaking. So, we will divide 1 by the number of overtones into 1 to get the amp value to send to each synth.


(
 var func;
 
 func = { arg repeats = 4;
  repeats.do({ arg index;

    Synth.new("example2", [\freq, (index + 1) * 100,
        \amp, 1 / repeats]);
   });
 };
 func.value;
)

Let's hear what happens when we play this. All the sounds play at once! This is because the loop goes through as fast as it can. We'll cover timing issues very soon.

Summary

  • Whole numbers are Integers
  • Real numbers are Floats
  • You can indicate order of operations with parenthesis
  • Math operations are evaluated innermost to outermost parenthesis and left to right
  • Modulus (%) means remainder
  • Subclasses inherit the properties of their superclasses - an Integer is a SimpleNumber
  • Output amplitudes should be between 0 and 1.

Problems

  1. Translate the following algebraic expressions into proper supercollider syntax, using parenthesis where needed. Try to make your answers human-readable.
    1. 3 + 5 * 4
    2. 7 * 2 + 1
    3. 6 * (4 + 2)
    4. 2 * 3 + 4 * 5 + 7 / 2 + 1
  2. Get yourself familiar with modulus by working out these problems by hand.
    1. 5 % 4
    2. 163 % 9
    3. 20 % 5
    4. 17 % 6
    5. 23 % 2
    6. 3 % 5
  3. Write a function to print out the first n multiples of 10, starting from 0. Pass the number of multiples into the function as an argument. Set the default number to 7.

  4. Write a function that takes three arguments, numberOfOvertones, pitch and amp. It should play the number of overtones above pitch specified by the argument numberOfOvertones. The amplitude of the overtones should be half the amplitude of the fundamentals and the total amplitude for the fundamental plus the overtones should be amp.

  5. rand is a message that you can send to numbers. y.rand returns a number between 0 and y. Humans are generally able to hear frequencies between 20Hz and 20000Hz (the freq argument for oscillator UGens is in Hz). Write a function that calls your previous function. You want to play n random pitches and the first m overtones of those pitches. Make sure that the random pitches are all in the audible range. Pass the number of random pitches and the number of overtones into your new function as arguments. Set the default number of random pitches to 2 and the default number of overtones to 3. Make certain that your total amplitude will not peak. Finally, give the arguments descriptive names.

    1. Can you figure out a way to make sure that all your pitches, including overtones, are in the audible range?

No comments: