A Brief tutorial on keyboard5.py http://media.mit.edu/~nvawter/otherProduct/
Part II - The Magic of sin()
Take a peek at some images of sine waves here:
http://en.wikipedia.org/wiki/Image:Sine_cosine_plot.svg
http://4dw.net/triplel/sine%20wave4.jpg
As we learned in lecture, sinusoids, a.k.a. partials, sine waves, cosine, etc. are useful building blocks for synthesizing sound. They are useful, because you can construct any other sound out of them. But how, specifically, does the math behind the sin() function work?
v = Numeric.sin(t)
First, the Numeric.sin() function is exactly like the sin function you know from trigonometry. It accepts any number from negative infinity to positive infinity and returns values from -1 to 1. And here's the single most amazing fact about sin(): When you supply it with a steady stream of increasing numbers, it returns values that move back and forth between -1 and 1. This means you can use it as a sound source!
For example, if we wish to make a digital sinusoid with a frequency of 1000 Hz, we'll use the following set of statements:
freq = 1000.0
Fs=11025
for t in range(int(length)):
angle = t*freq/Fs*2*Numeric.pi
v[t] = Numeric.sin(angle)
What does that do? The line starting "v[t] =" will run a number of times. Each time it does, "t" will have a different value, and the sin() function will return a different number. We can make a little table of the first 13 steps:
t angle Numeric.sin(angle)
--- ----- ---------------
0 0.0 0.0
1 0.569 0.539
2 1.139 0.908
3 1.709 0.990
4 2.279 0.759
5 2.849 0.287
6 3.419 -0.274
7 3.989 -0.749
8 4.559 -0.988
9 5.129 -0.914
10 5.699 -0.551
11 6.268 -0.014
12 6.838 0.527
Focus on the third column. Notice how the value of the sine wave in the righthand column starts at 0, then goes up near 1 when t=3, then back down to -1 around t=8, then up to 0 again and past it? That is one complete oscillation, a.k.a. revolution, wavelength, or cycle. Astute observers will also notice that the value of the angle at one revolution is 2*π radians.
Notice how it took about 12 steps for the output of sin() to loop around once. We can change the numbers in the statement to make it loop faster or slower, creating a higher or lower frequency. To do that, simply change the value of of "freq" in the above code.
In Part III, we'll look at many more tricks with sinusoids.
A Closer Look
The above info is enough to be dangerous, but for those who want to get a little deeper, let's take a closer look:
v[t] = Numeric.sin(t*freq/Fs*2*Numeric.pi)
The arguments for sin() are in radians, so for sound work we need figure out how audible frequencies relate to radians. To perform the conversion:
Given
1 full revolution = 2π radians
Desired freq = 1000 Hz a.k.a. 1000 revolutions/sec
Number of samples per second = 11025 samples/sec
Numeric.pi = 6.28 - this is a constant
Calculations
Each second, we want 1000 revolutions:
1000 revolutions/sec= 1000*2π radians/sec = 2000π radians/sec
To convert to radians per sample, we divide:
(2000π radians/sec) / (11025 samples/sec) = 2000π/11025 radians/sample ~= .570
So at every time interval, we will increase the phase of the sinusoid by .570 radians to get precisely the 1000Hz sinusoid we wanted!