*** MUS171 #05 01 18 (Lecture 05)
This is the familiar network where you have an oscillator with a controllable amplitude.
Amplitude of course you control by multiplying the output of the oscillator, that's the easy way to do it.
And the frequency of the oscillator you control by sending it the appropriate input.
So here it is: [Tone]
You can do them both simultaneously, maybe not. Wizard of Oz.
And if you want to sequence that, why you don't get some delay objects, so maybe the good way to do this is give yourself a button, and then you can have delays.
"Delay" you can abbreviate as "del"; there are abbreviations for some of the most frequently used objects.
And it's going to become important in this particular case. You'll see why.
So let's have the button turn this on, and have it to be at 440. The recording will jump to 440; I'll tell you why in a second.
You don't want to necessarily slide to the note, if you want to start a note at the beginning of something.
You might want to have it just jump there.
So this is now a button that makes sure that we're at 440 when we turn this thing on. [Tone]
When you turn something off, you don't have to do anything to its pitch, because just turning the amplitude of the thing by multiplying it by 0 turns it off.
It's still playing A-440, this oscillator is, but we don't care about it.
So now a...[Tone]
You do want one of those -- it also turns this off, right?
So hit that button and turn it off.
So you want it to slide to 440 and turn it off.
Ah! That sounded horrible.
Let's not do that! OK.
So now what we're going to do is make a nice little sequence by having "delay 500" successively, which will be setting these delays every 500 milliseconds.
As a matter of survival, if you're going to have a bunch of delays, don't daisy-chain them but have them all come off of the button or whatever triggered them.
Because, why?
Because that way when you start it again it restarts all the delays and you won't have messages trickling down the delays when you're no longer trying to do certain things.
So now what's going to happen is every time I press the button ... yeah, I should do this
(puts indicators that show the delays being triggered)
Every time you press the button you start a sequence of delays going. [Tone][Over sound]
And furthermore, here's a subtlety, when you start a delay, if it was already started, it forgets the previous time it had been started for and resets it to the new time you're starting for.
That's a good way for a delay object to behave, because then it doesn't go off and do something in the wrong order, because you told it to do something and then changed your mind later.
If you changed your mind about what you wanted to do.
It is now only doing the new thing, so you can actually believe that things are going to do what you ask them to when you start something -- if you connect to the delay this way.
If you decide that you want to connect to the delays successively one to the next, then that won't necessarily be true,
each one will set the next one off, and if you reset the first one, depending on what phase the others are in, they'll continue doing their things, and then you'll have different delays fighting each other for control of your oscillators, which will not be as good.
So it is a good thing not to daisy chain your delays, but to have them all come off the same source like that.
Now I'm going to make beautiful music.
That's going to be, nothing?
Oh, it's going to be a rest.
... Yeah, that'll suit fine.
And then they'll go over there, and then they'll wait another second.
I won't even put that delay in there.
It should be 2500. And here it'll go back down to A and here we'll stop.
And now, here's one of the things that's problematic about patching, and I will show you strategies later to deal with this:
Your patches get messy after you've done a certain amount of stuff.
Technique number one:
Turn the font size down.
Other techniques are going to be use more than one window, but I haven't shown you how, and also use names for things so that everything doesn't have to be a connection.
I haven't shown you how to do that either, but that's all coming.
And now if I have this right I'll have this this beautiful composition. [Tone]
Ta-da! The marching demons in the Wizard of Oz.
So this is how to make sequences that do things like control amplitudes and frequencies.
Questions about this? -- What I did and why? ... Yeah??
Student: I forgot, for the first number in these messages is for frequency? There's a .03 there.
Oh! OK, yes.
That's the thing.
These numbers, what they are depends on where you put them.
Or rather, how they're interpreted depends on where you put them.
So these numbers are frequencies by virtue of the fact that they're talking through this line to this oscillator.
But these other numbers are amplitudes because they're talking and this line is getting multiplied by the oscillator.
So even though the data goes down, in some sense the meaning bubbles up.
Student: So it's on the line that goes amplitude and then time...?
Right. -- Or value and time or target and time.
I think of it as target, because it's the place where the line will eventually be, or the thing that the line will eventually be emitting, I guess is the right word after the time elapses.
Student: So it's another process that determines what they're lined up to.
... Yeah. Other questions? ... No? I'll leave this then and get onto fun topics.
Not that this isn't a fun topic, but there are other fun topics. ...
I'll just do a "Save As", remember the font size and start all over again.
I'll just do three... table... Oh, no, wait.
I neglected to tell you a bunch of things last time.
Table oscillators first, and then units, psychoacoustic units which is MIDI units of pitch versus frequencies,
and decibels versus linear amplitudes, which I will show you after I show you the basic yoga of table lookup in computer music -- Well, phase generation and table lookup, which is how oscillators are made, which is the bread and butter of computer music.
And the fact that it's taken me five classes to get here says something either about the indirectness with which I'm approaching the thing, or the fact that perhaps it is actually more complicated than I'm thinking to myself it was supposed to be.
OK, so we're going to do phase and tables. (saving "3.phaseandtables.pd")
Do this one.
And, we don't need any of this except the time for that, so.
But we'll keep this around for this, just to be able to use it.
But... here's where I'll stop, maybe on this.
So the first thing to comment on is the following:
There is an object, whose name is phasor, which generates phases.
These are not useful things to listen to.
In fact, let me prove to you this is not useful to listen to by playing it.[Tone]
This is a bad sound.
The reason is that it sounds like a mosquito is what's called fold-over.
Well, there are several reasons it sounds like a mosquito.
But the reason it sounds bad in computer music ears is because of fold-over, the fact that this signal is not a good band-limited signal that is limited to 22 kiloHertz and a half.
It is an un-bounded signal that has theoretically an infinite trail of partials, and in a digital environment such as in any computer music environment, you will hear various kinds of badness happen.
What it sounds like is just not exactly a stable quality of the signal.
It sounds like it's fluttering a little bit.
That is fold-over.
There are better examples of fold-over that I could show you, but they would be piercingly ugly to listen to and I don't really want to deal with them.
Go look at the Pd documentation; you'll see a wonderful fold-over generating patch which will make you jump out of your chair and spit out your gum.
So now why am I showing you this, then?
Because you use it to do things like look up wavetables.
To show you this, I have to get out my array so you can see what's happening.
I'll do that now.
Sorry this is getting repetitive, but it is what it is.
I'll call it
(the Array) "array.1.18a"
And then just going to use a nice tabwrite~ write it.
Wow. I shouldn't really have given a long name, should I?
"array.1.18a" ...
I don't want these to fight with each other if you happen to load more than one of these up while you're looking at old patches, which is why I'm making these awful names.
I'll show you a better way later, but that will wait.
So now, one of the things the phasors do that makes ...oh! Duh! I thought it was me.
It actually was me but at a deeper level.
Here's a crucial thing to get:
Here's a sawtooth wave...
notice how there are bad kinks in this?
That's actually graphics.
But there are bad kinks in the thing, because sometimes when the thing wraps around, actually let's go to 440, sometimes when the thing wraps around...
Since we're at 44,100 points per second, 440 Hertz means how many samples per cycle?
100 and a fraction, I think, if I'm doing this right.
(41,100 samples/second)/(440 cycles/second) = 100.22 samples/cycle )
So it's (a cycle is) about 100 samples long.
Oh yeah, it's about a hundred samples long 'cause the table's about a 100 samples big.
But it's not exactly 100 samples long from the bottom to the top, it's just that sometimes it's 100 samples and sometimes it's 101 samples.
(A cycle is usually 100 samples but sometimes -- approximately every fifth cycle -- it's 101 samples.)
It's not a decent periodic signal, really, it's a sawtooth wave being represented digitally and it sounds bad.
What you do to make it sound good is you use it to look up a table such as ... -- And here's object number two for today:
Phasor and cosine are both objects you haven't seen yet.
The cos takes whatever goes into it and reports its cosine, or outputs its cosine. [Tone]
And that's when you get this kind of thing:
That's a nice sinusoid.
So your cosine is not a sine, because cosine is the simple function and sine is the complicated function to deal with.
There's only one wavetable, so it became cosine.
With an oscillator, really, you've seen this as osc~. The osc~ is in some sense equivalent to (phasor and cosine).
Phasor is an object which just generates a phase that goes from left to right if you'd like, a certain number of times a second you specify, for instance by an input.
And cosine is a table lookup which if you give it 0, it gives you 1; if you give it 1/2, it gives you -1. And if you give it 1, it gives you 1 again.
And I happened to click it just at a moment when it was going from 0 to 1 in the space of the window.
But if I do it again, you'll see in fact that it's just moving between those two values.
That was an accidental click.
Now, this is interesting because you don't have to use cosines.
You can use other waveforms.
And what would be another good waveform?
Well, for instance, I could ask for the cosine of twice the thing which would be two cycles of the cosine wave and do that like this:
Multiply the phasor by two so that it doesn't sweep from 0 to 1, It sweeps from 0 to 2.
And then, when I connect that, you hear [Tone] the octave.
So, there's twice as fast as this. [Tone]
Well, "twice as fast," that might be confusing.
What's really happening is, think of this as a function.
This function is a cosine of twice the input which is to say it doesn't just go from one, to minus one, to one once as the phasor's output goes from 0 to 1.
As the phasor's output goes from 0 to 1, this goes from 0 to two and so this thing goes through two cycles.
So, you're looking up the second harmonic.
So, now you can do groups of harmonically related sinusoids.
You can build up tones out of amplitudes of individual harmonics by combining cos~, and cos~ of the octave with the cos~ of the twelfth, and so on ... like that until you get tired of making the patch.
This is a very simple ... What's the right word?
... a very simple example of using wavetables, of using waveforms, specifying waveforms, which are things which you index by giving it a number from 0 to 1 so this phasor does repeatedly at some number of times per second given by its frequency.
Phasor has memory.
It has to remember its phase from sample to sample.
So, it is an effective integrator.
The frequency that you put it tells it how much it's going to add to each previous sample to make the next one.
cos~ doesn't have any memory.
It's just a pure function that takes whatever you put in and puts something out.
So, phasor is the real oscillator here and cos~ is a wavetable that the oscillator is indexing.
And furthermore, this combination of (phasor and cos~) is what you previously have known as osc~. All right?
Now, I told you that so I can tell you this next thing:
You can make your own tables up.
Here's where, at least in some respects, things start to get fun.
So, how am I going to do this so it's in the right space?
There, I can't see that so I'm going to cheat a little bit.
I'm going to make a window as big as I possibly can so I can keep this font.
That will hopefully make something that can be understood.
I'm going to make another table and I'm going to give it, again, I didn't think in advance, I'm going to give it 8 points.
... And this is now going to be a table, "tab.1.18"
-- Sorry. That's a bad name. Everything is bad about this ...
Here's the graph. Yep. We're happy.
Everything is good.
Now, last time I did this, I forgot that I asked you to do the points instead of polygons.
Points. So check that we did.
I forgot, OK.
Now, we have something which we can edit and it's just a bunch of numbers.
8 of them.
So, you've seen all of this before except I don't know if you've seen me drawing one, but that's one way of getting things into the table.
There are other ways.
You can have text in a file.
You can, if you want to, save the properties and somewhere in here it gives you the opportunity to...
What does it do?
What does it allow you to do?
Edit this in by...
Oh, got 'em .. where am I now?
I'm looking for features that isn't there -- OK.
I'll show you how to get numbers in there in a good way later.
That's going to be a whole other thing.
So, I just put a waveform in here.
Now, what I can do is say, "Oh.
Let's listen to it by..."
Some pedagogical sense tells me I should do this first.
We're going to read out of the table and the table is going to be "tab.1.18a."
Notice, I did not put a tilde in.
I'm going to do this just with messages to start with because it's going to be easier to understand what's going on.
And then, I'm going to add a tilde and we're going to be operating with signals.
So, on that
Input number ... and beside it
So, I'm using a Macintosh keyboard on a Linux machine.
The little Apple key doesn't do anything in Linux.
It doesn't think it's an Apple.
So, I give it numbers like 0and it gives me this value.
I give it a number 1 and it gives me this value and so on like that.
And now, I can just go sweeping through the thing looking at the values in the table.
So, we've got storage.
Not only storage, but storage of as many numbers as you want to put in the array.
Student: How come when you go negative three, it still gives you a value?
Yes, thank you.
What happens when I go off the end of the table is, it says, "Well, that's OK.
I'll just give you the closest point to what you had."
So, in general, Pd's approach to errors -- this is not good computer science -- is it just puts guardrails on everything.
So, if you divide by 0, it doesn't give you an error.
It just gives you 0. If you try to read off the (end of the) array .. Actually, there's several things it could have done.
It doesn't give you an error because then you wouldn't hear anything.
It's better to hear something that's wrong than not to hear anything. Maybe.
You could also say that "if I gave you a negative value, the thing that you should do is wrap around to the other end as if you were an endlessly repeating waveform."
That (wraparound) is done using a different object in Pd.
The table doesn't do that and if you want that, you have to use an object called "wrap" which I will introduce later if needed.
Instead, it simply says, "If you're between 0 and 7, it will read the value out of the table.
And if you're in excess of 7 or below 0, it will simply give you the last or the first value."
Which is good enough for us right now.
Furthermore, if I give it a number like, let's see...
If I give it 0 as the first value, and the last value is 7 because there are 8 numbers -- That's one possible way of counting.
That's the modular arithmetic way of counting.
The other thing is, if I give it a half, what should it do?
That's a trick question on two levels. ... ... Yeah??
Student: You can give it a 1, possibly.
Or you can give it less than 1?
Well between this and this.
So, you could just do what you said, which is to say, just call it 1 or just call it 0.
Oh! And then, should you round, in other words, if I give it a half should round it up to one, or should it just truncate it down to 0?
Another thing that... ... Yeah??
Student: Could it do interpolation?
Another thing it can do is interpolation.
But then, the question is, how many points of interpolation should you do?
And if it's two points, there's really only one good interpolation algorithm.
But when you have four or 8 points, there are several different ways of interpolating that have different properties. --
So, it just doesn't interpolate.
If I give it numbers between 0 and one, it declines to act smart.
It simply truncates the 0 and gives you that value until I hit one, at which point, it gives you the next value and so on.
Student: So, if you were to go below this number now, does it round down or does it just round one of them up?
It rounds down. Oh, yes. There's no memory again so it doesn't know what I asked it previously.
So, everything is as if there's no yesterday and it always rounds toward minus infinity.
Actually, in table land, it only counts from 0. So it rounds towards 0, we'll call it. OK?
If you wanted to... ... Yeah??
Student: Can you go and put the numbers in again?
Yes. I'm trying to decide which is the best way to show you how to do that and which requires the least constructs.
There are about five ways of doing it and I didn't realize I was going to have to do that today.
So, I didn't think in advance about which one to show you so I'll get back to that.
You will eventually want to be able to do things like throw values in a table.
Oh! There's a tabwrite~ you can see here, so you can guess that there might be a tabwrite 'without a tilde'. But it's not.
Remind me to get back to this.
The tabwrite is not a tabwrite~ without a tilde. --
It doesn't turn out to make sense to just write sequentially through the table in message land so it works differently.
So, here's tabread.
Now, you could say, "tabread~" And now that you've heard everything that you've heard, you know exactly what will happen when I run a phasor into tabread~ and then, listen to the result.
Why don't I hear anything?
Do I look surprised that I don't hear anything?
I'm not trying to project surprise here.
What are the values coming out of phasor?
0 to 1, not inclusive.
And what does tabread~ do?
It rounds down to the nearest integer.
The nearest integer down is always 0 so we're getting out solid, whatever that number was, -.21 and the mixer is then forgetting it because it's AC-coupled.
So, if I want to hear something, I would take this phasor and multiply its output by the size of the table.
Oh. Here's a thing:
You will learn various ways of making your patches not occupy a huge amount of space.
Something that I do but you don't have to, is when you're multiplying by a line, you put the line next to the multiplier instead of above it.
And if you do that consistently, then you learn to expect it and then it looks normal when you do this, even though, this line almost looks like it's going up.
This is the way that I normally do this when I'm working.
Now, I'm going to say, "Multiply by the size of the table, please."
Oh, I forgot to put a space.
Oh, hey! Sorry.
I need a tilde because I need a signal multiplier because there's a signal coming out of phasor~.
And now, this is sounding better than the phasor.
And I have a little timbre-editor.
This is not beautiful sounds yet because there are discontinuities in the table.
Let's turn this off.
Student: Doesn't the table go from from 0 to 7, though?
Instead of 8?
Ah, thank you, right.
So, why am I going up to 8?
It's because if I went from 0 to 7 you would never hear this last value because the phasor would go from 0 to 7 but it would never get to 7 because the exact value of 7 would wrap it down to 0.
So if I want to read the entire table, I want to go all the way to 8 even though I know nominally the table stops at 7. So it's confusing for two reasons that cancel each other out.
There are 8 things in the table so 0 to 8 sounds natural until you realize that actually they're indexed from 0 to 7. So it sounds like you should go only to 7. But in truth you should still go to 8 because otherwise you wouldn't get any of the 7 because it would not do it.
Is that clear?
That is either clear or not depending on whether you could follow about three different facts that I introduced in the last half hour all at once.
So you can think of the horizontal axis here as going from 0 to 8.
In fact I think of it that way, even though the place where the individual points live are just in integers from 0 to 8 which are 0,1,2,3,4,5,6 and 7 -- but not 8, because then there would be nine of them.
And furthermore, for it to "spend just as much time," if you like, between 7 and 8 as it does between 0 and 1, you should multiply the phasor's output by the whole number 8 -- the number of points:
8. This will change when we start interpolating the table, because then there will be fewer values that are useful.
But that will happen later. ...
Next thing about this, what if...
There is one way of getting values into the table.
But we can do it anyway.
Let's put a sinusoid in here.
I am going to be a little sloppy, but not terribly sloppy.
We're going to say, osc~, and I'm going to give it a frequency which is equal to (the sample rate)/8, so that its period in samples is 8. Right?
And I'm going to be lazy and say, give me a message box which gives me the sample rate which I believe to be 44,100. And then I will say divide it by 8, the number of samples in the table.
That will be the frequency for an oscillator.
And then I'm going to write that into the table.
This is called "tab.1.18a" ... confusing, all of the above ... OK. Write it.
And there is our nice sinusoid.
Oh, that didn't appear... 'The first value in the table is hidden by the top border of the table.' ...
Oh, yeah, I started this oscillator up and it had initial phase 0 and its frequency happens to be such that it repeats every 8 samples, so every single time I whack the button it will see it on a 64-sample boundary for technical reasons.
And I am always going to see a phase that is magically 0 here.
That is a weird accident.
And now I have this nice table which will sound just like a sinusoid when I play it for you. [tone]
... NOT.
This is in fact not a sinusoid but it is the function which is...
the same points as the sinusoid every eighth of the cycle, but flat everywhere between it.
And that is not very sinusoidal.
If you did a Fourier analysis of this you would see mostly this nice sinusoid but then you would see a very jagged difference between that and the sinusoid it's imitating.
And that jagged function would have lots of high frequency information in it which would sound like ... that kind of stuff. [tone]
It is even better ... Because now if I go up in frequency. [more tones] -- I'm not going to make you hear a whole number of them; I'm not that bad.
How would you make that better?
Put in more points, maybe.
So now we can say... Yeah, so let's get the "Properties" out.
I'm going to say the number of points I want ... I don't know, 1,024 -- I am just making up a number.
Oh, I don't have to use a power of two if I don't want to.
Let's make it 1,000. That's just a bad reflex of mine. OK, 1,000 points.
Now, the points that were there are still there and it's going to sound horrible if you listen to it. [original tone]
It's just using the first table.
Now I'm going to use 1,000 of them.
First I am going to put a sinusoid in.
OK, there is a good sinusoid with lots of points in it, right?
And now I have to remember to change this 8 to 1,000. Now there's your sinusoid. [tone]
Don't buy this sinusoid.
This sounds good under our current listening conditions, but if you think about it, the error here is going to be on the order of 1,000 ... well it's going to...
the phase is going to be off by a thousandth of a cycle or so.
So there is going to be a little lookup error in the amount that you get here which will be something like 2*pi/1000 .
And that sounds quiet but that's about a part in a hundred. 'extraneous room noise here'
In other words this thing is making its error on the order of part in a hundred.
And that is loud -- that's minus 40dB.
And if you want to hear it, I can prove that that's bad.
I will give you that at much lower frequencies and then you will hear a characteristic computer music error...
Let's make it...20 ? ... All right,we'll start it at 55 Hertz.
I can't hear anything wrong yet.
Can you hear bacon frying in there?
I don't hear anything wrong.
I guarantee you will hear the problem if you listen to this carefully.
I am going to turn the whole thing up to prove that this is bad.
Leave it there and I am going to turn the volume up a little bit.
Before I destroy these speakers.
Hear that stuff?
When you are in a good listening environment, you will hear that a lot louder than you hear it here with this all these fans and everything else.
And what that is is about 40dB down from the sound of the sinusoid, but I am moving the sound of the sinusoid out of the way so that all you hear is the forty decibel down nonsense. [tone]
Furthermore, it's still there when you do this kind of stuff.
You might be able to hear it, and you might not.
But if you listen to this in a good studio, you will hear it and it will not be appropriate, not be a good thing.
Furthermore, that was only a nice sinusoid here.
And of course the reason we are doing table look up is so we can do other stuff besides sinusoids.
And "other stuff besides sinusoids" has higher harmonics in it, perhaps.
So in fact what about the, what about if the signal that I put in here had a little bit of energy in the harmonic?
Then what would I be listening to? [tone]
This stuff. [sliding tones]
You could want this, but you might not want it too.
Let me shut that off.
So whatever you put into that wavetable to the tenth harmonic didn't sound like a sinusoid, it sounded like that thing.
And the hundredth harmonic sounded a whole lot worse.
Questions? ... So table lookup is not the panacea that...
well, sorry -- Table look up is not trouble free.
You have to pay your dues and figure out how you are going to use this effectively.
And cos~, that one is a table lookup that happens to be a cosine that's worked out in such a way that it gives you nineteen bits of precision, which is usually good enough.
And so if you can live with cosines you will not have to deal with this situation.
But there are moments when you will have to do real table lookup.
In particular as soon as you have a sample going into the computer ... As soon as you're doing a recording you're putting a recorded sound in here and then playing that back using an oscillator, or using a sampler.
You will have to deal with the issue of how well you are interpolating it and what kind of numerical accuracy you are getting out of it.
We can avoid that for right now because basically, we are not going to be careful about that yet.
I am going to show you that I think next week when we get into how to do sampling.
And right now I will just go back to...
OK, this looks good and now we can have a quick look at what waveforms sound like.[tone]
Here's a nice pulse.
It's one of the simple waveforms.
And that's sort of "pulse width modulation," if I could draw something perfectly horizontal here.
There is that kind of thing.
Triangle waves like this:
And so on. ...
Maybe you want to have a better way of putting things in wavetables than this, right?
So that is all programming.
And I am going to show you pretty soon how to record a sample.
But for right now, this is by and large how most of computer music works.
You generate phases.
Which is done by, typically by eventually, a phasor object ... at some point inside your patch there's going to be one of these generating phase.
And then at some point you are designing or finding waveforms.
You could be adding up partials to make a Fourier-synthesized waveform, or you could be recording a waveform, or you could have some for some other reason.
And that typically finds its way into storage into an array, and then you look the array up using the phasor.
In other words, the phasor generates the index that changes your array that is telling you what the waveform is.
And then you are playing it and you're making a tone whose timbre depends on the waveform and whose amplitude and frequency depend on what you multiply the table lookup by at the output.
So here I am controlling amplitude, and here I am controlling frequency.
Frequency control is going into the phasor and amplitude control is happening at the output of tabread~. And these three objects are replacing the one object osc~, the oscillator.
You can deal with that right?
And now we can do all three...
So let me save this and make another one. (saving "4.moretables.pd")
So I can get rid of some of this.
So tables can be waveforms, or they can be other computer music items.
And one thing you can imagine wanting to do is make this thing be...
either the amplitude or the pitch of something changing in time.
Let's make it amplitude to start with because that will be easier to hear.
And then I will show you how you can control pitch using a table.
So I am going to make a nice envelope.
So now we have an oscillator, and I am going to tell the oscillator to go very slowly.
But rather than listen to this as the output, I am going refer this as the amplitude of something else.
What? ... So we're going to take this and...
just by convention I have been putting the amplitudes to the right, so we'll continue doing that.
Like this.
So I am giving myself a way to turn the thing on and off too.
But meanwhile I am going to multiply a regular oscillator by this: [Tone] Ta-da.
This is not perfect ... This is not a perfectly good example.
This is now taking what is in here 'tab.1.18.a' and making an oscillator out of it that is running at three cycles per second,
and is then multiplying that by this oscillator 'osc~ 220'.
And I asked it for, well just by drawing I asked it for something that goes up quickly and comes down more slowly. ... Yeah?
Student: What is the "*~ 1000" doing?
Ah, right.
So this phasor is outputting values from 0 to 1. And the table needs an input which is in points; and there are a thousand points here.
So this is an adjustment to the range which is the size of this table.
Or another example -- This is more along the lines of classical electronic music.
Let's go back.
This is kind of a bad example but I'll look at it anyway just to see the badness in a bad example.
And now:
Table Controlling Pitch -- Why not?
'saving "5.table-pitch.pd'
I haven't changing the name of the tables ... So I have to get the "Properties" anyway .. Points?
-- I'm going to change it back to ... what? -- 12 .
I'll make it "d" now. 'array is named tab.1.18d'
Change that to "d" 'in the tabread~ box'. So now we have a nice oscillator that is reading this table.
And it's giving us values that are ranging from -1 to 1 ... but I want to change that -- Let's make it have a range that is appropriate to frequencies, which might be 1000 to 0. ... So now everything at the bottom is 0. I can't edit it now ?
... Let's see what I can do about this ...I'm going to put something in.
Here's how to generate a 0 without any object ...
Student: It should be "1.18.d" -- "tab.1.18.d"
Oh, thank you. "d"
That didn't do any thing either ... Sorry I am just trying to get this thing through to where I can edit it, and I am not succeeding.
That didn't do anything either.
That's "tab.1.18.d" 'not array.1.18.d'
How about I just put some value into here directly?
... 57 ... All right! Now this is nothing to listen to.
These values are now ranging from 0 to 1000 so they are too big to use for amplitudes.
But they are perfectly good to use for frequencies.
So we could for instance, instead of using this as the amplitude of the oscillator, we can do the frequency of the oscillator.
And .... [tone]
Oh!? ... You know what? We need to change this:
'output range of phasor changed from 1000 to 12'. 'varies the values by writing in the table tab.1.18d'
So this is an old electronic music trope.
For those of you who listen to old electronic music like from the era of Morton Subotnick and those kind of people.
This is called a sequencer, an analog sequencer even though it is digital.
Because the way analog sequencers used to work is they used to have a collection, typically of twelve, occasionally of sixteen voltages that you would set with knobs.
And then you would give it usually a trigger and ask it to advance it to the next voltage.
That was an analog synth board.
This is how to make that sort of thing using digital technology.
And by the way everything is in Hertz, so this is 0 to 1000. And this kind of doesn't work very well for specifying pitches.
In fact, you will notice that all of the pitches were within a couple of octaves of each other.
That is because from a quarter of the way up to all of the way up is two octaves because each octave is doubling.
So if this is a thousand, an octave down is 500, an octave down is 250. So this is an ugly scale to be trying to do musical pitches on.
That is going to bring me to the next topic which is:
units in computer music. ...
So now what you have seen so far in 45 minutes is two objects really.
Well, maybe three, mostly two.
phasor~ and tabread~ -- whose jobs are to remember where you are and scan through something, which is the basic thing an oscillator does and to hold and retrieve values.
And these values ... So far you know how to get them in by using tabwrite~ --
And I am going to tell you about the best way when I figure out what the best way is.
But I am going to do units first, because we need units badly now so that you can start making music.
So just try to make this thing do a C major scale.
First off, a twelve note system isn't a good choice.
So let's just use the first eight points.
Right! ...so nobody said that you had to use the entire table. [tones]
So if you use some smaller number ... depends on the size of the table.
[changing the output range of the phasor to less than 12. changed to 6]
Now you get the first 6 values of the table.
Now I've got a more powerful scheme because ...
... Add to this ... "+~"
Now what I am doing is I am looking at a little window inside the table of six notes.
And I am sliding the window over.
If I change the value from 6 ...
Now it's multiplied by 0; I am not getting anything at all.
But if I add 0 multiplied by twelve, that is the original thing.[tones] ...
[changes phasor output from 12 to 3. Tones change]
Oh yeah, right! So I am only ranging through 3 values, if I'm doing that once per second, that happens at a much slower speed than if I range over 12 values in a second.
Why a second?
Because this phasor is going at 1 Hertz so it is doing that.
And then if I say, look at three points, it is doing three points per second.
But if I tell it to do twelve it is doing twelve points per second.
Student: What does it sound like if the phasor is at 2Hz?
Two?
Let's try 440. ... All right, so let's see.
Let's turn it on again.
First off -- 2: [tone]
The rule is that when you are doing things faster than 30-ish times a second you don't hear them as individual events.
And so all that you can possibly hear them as is sound I guess.
And so now we are changing the sound of the thing by playing them supersonic with melody.[tone, varying with frequencies of phasor]
Now if we say -1 Hz?
... It is going backwards from right to left.
Backwards.
Meanwhile ... Adding does that: Furthermore, let's say I add even a fraction ... 3.5:
And then it is four long, but it is actually not aligned with points in the table, so it hits 3 in the middle of it and then 2 at the outside, that you get 1/2 of.
Oh, right:
If you run off the end of the table, it's kind of just your tough luck. ...
Whoops, now we are really off. ...
There are twelve points in the table; let's make it fall off like this:
You're getting the last four points on the table and then it is sticking on the fourth one.
Now you know how to make computer music.
Actually, this is even more like '60s-style analog music.
This is stuff that you would hear out of the San Francisco Tape Music Center
[Morton Subotnick, Ramon Sender et al.]
That belonged to a certain generation.
Many of those people are still alive, by the way.
You can send them emails.
Questions about this? Is it clear what I just did? ... Yeah?
Student: I'm not too clear on the +~. You said it moved the window?
OK, yeah. Meaning in some sense it bubbles up from the bottom in the sense that for tabread~ I have to provide a number which will tell it where it's going to look.
See, if you think of those numbers as living horizontally from 0 up to 11 and then 12 being that you put in twelve but the integer is never twelve -- really 0 to 11.
Now if I say, for instance, take the phasor, which ranges from 0 to 1, and multiply it by 5 then I'm going from 0 to five which means I'm scanning through the first 5 points in the table.
If I add now 2 to that, it adds two to those points -- to that range.
Well, actually it adds two to every value, which de facto adds two to the range of possible values that those results occupy.
In that case, after I've done that, the phasor which went from 0 to 1 goes from 0 to five now goes from 2 to 7 and therefore reads points 2, 3, 4, 5, and 6 -- which gives you five points in the table.
Student: Then that number 12, is that arbitrary?
That's arbitrary/historical.
If you go look at an old synth they typically have 12 on them. ... ... Yeah??
Student: Just to make sure ... Do you need a tabwrite~ to mess around with [manually changing] the graph?
I'm running this version 43 test three, which doesn't let you edit the thing when the graph goes outside of the bounds and I had a negative number in there and I changed the range so that I couldn't edit anymore.
So I threw that in [the number-box input] so I could bash it to a constant.
Now that I have it, it's kind of useful because I can now say "Just play A 440 please" and it giving me consistently A 440.[tone]
I was going to put some message boxes in to try to make a nice sequence of pitches in the table but then I realized that I'd have to press them all within a few 44,000ths of a second ... and that wasn't going to work terribly well. ... Yeah??
It's boring; in fact, I could, no let's not do that.
Student: The oscillator for the tabread~ is that 220?
Thank you. Yeah; that 220 is obsolete.
It got overridden by the input.
Student: Can you input something to an oscillator that already has a value?
It forgets the value and adopts the value.
Except if I disconnected the input it would jump back to the 220 and then you'd be even more confused.
So it's best not to have that 220 there.
Bad style.
Student: Can you show the properties for the table?
[tab.1.18.d]
OK, so take this one here?
So ... its size is 12. I don't mind "Save Contents" because it will add 48 bytes or something ...
The X range is from 0 to 12. Oh, by the way, if you change this and if it agrees with this range when you change it it'll update this range for you.
You don't have to set that.
Here I wanted to go from 1,000 at the top to 0 at the bottom -- which is a reasonable range of pitches but not the only possible range.
Let's see.
I'm going to next talk about units.
And to do that I think what I would do, I'm going to save this now as patch number 7
because I'm going to have to have a patch number six in the middle.
So by the time we get to 7 we're going to be putting MIDI numbers into the table instead of frequencies in Hz -- which will make everyone breathe a sigh of relief.
But meanwhile, I have to go back one.
Student: You are putting all of these patches on the website, right?
Oh, yeah.
... Yeah, I believe it's true the patches from last Thursday are on the website, but if you look and don't see them it's because I forgot to put them up and I need to...
So they're not there?
... I need to put them up! I'm sorry.
I'm forgetful.
So now we're just going to talk about units.
To talk about units we don't need this stuff, but we still need our nice oscillator and our multiplier.
There. Same thing as always.
Now, the objects of interest are as follows:
The one that's the easiest to understand probably is "MIDI-to-frequency" [mtof] and its companion, "frequency-to-MIDI."
For mtof, you just give it a number and out comes the frequency in Hz that would correspond to that value in MIDI.
For instance, 69 is the MIDI number which is associated with the A above middle C which is sometimes called A440. So this is a pitch and this is the value in Hertz.
The pitches are good to use because you can look at two of them and know exactly what the interval is between them, that is the musical distance between them.
You can't necessarily do that with two of these numbers [frequencies]
Like if I gave you 261.62 and this [440] you wouldn't necessarily know right off the bat that's a major sixth, if I've got it right.
But here if I say OK give me a major sixth that's 60 to 69 then you can know that.
So, for instance, if you want to make oscillators make a chord. ...
First off -- before I even do that, let's just play this: [tone] (changes with inputs to mtof)
I'm too lazy to get the piano out, but if I whacked A I believe I would hear the same pitch as I heard here.
There is one situation in which that wouldn't be true which is if I was wrong about the sample rate of my conversion hardware.
That's probably right.
So now, for instance, if I want to play [tones] a musical sixth or seventh tone.
It's a much easier job than multiplying by one and a half.
Now if we want to go up by a musical third here that's easier than multiplying by that ratio, which is a number that you all know from acoustics.
What's a tempered major third interval ... or the ratio?
That's not the easiest possible computation you could be doing. ... ... Yeah??
Student: How did you change the number so quickly?
Oh, how did I change it so quickly?
I click on this thing and then I start typing and I hit enter.
And, I've had a lot of practice.
So 12 half steps are a factor of two, so four half steps is a factor of 2^1/3 because 4 is 1/3 of 12. So the cube-root of 2 is the musical major third, tempered.
That's weird, isn't it?
... I tritone the easiest one of all besides an octave.
Even though it's the worst interval -- It's the square-root of two, 6 half-steps out of 12. They're all irrational except for the octave. (all the half-steps)
OK, so here to make, for instance, a nice major chord, just as an example, you could say,
"All right I will take this frequency and I will multiply it by 1.25 and by 1.5." That's 5/4 and then it is 3/2. Those are the musical perfect third and perfect fifth, perfect major third and perfect fifth. ...
Now let's see if it's going to work for me. [tones](major chord at various frequencies)
That's OK as long as you're doing tempered chords and you happen to know those numbers.
More musicians know these numbers in half step and they would rather do the whole thing -- instead of in frequencies -- in pitch -- Where going up a major third is not multiplying by a ratio (which is what you do to frequency), but it is adding the number of steps. (
Because pitch is in steps or in notes.)
We can say in steps.
So here we say "+ ..." -- How many half-steps are in a major third? -- Four.
And in a fifth? -- 7.
This might or might not be easier: [tone]
And by the way, it's no longer a perfect major chord.
It is a tempered chord.
It sounds different, especially here because there's some distortion.
If there weren't any distortion I don't think you'd hear that beat. [tone] ... Yeah??
Student: What's the 69 thing again?
Oh, thank you. 69, this is the MIDI pitch which corresponds to A440. I should probably tell you about the MIDI scale.
Student: That's pre-specified already?
That's pre-specified.
That was specified by the musical instrument digital interface standards board back in the '80s, I think.
This is basically never going to change.
60 is middle C.
Why 60? Because they wanted all the pitches to be positive numbers.
In fact, they wanted to fit the whole thing in a 7-bit word, so everything is between 0 and 127. The definition of MIDI pitch is that 60 is middle C and values that are not 60 are counting away from middle C up or down in half steps.
So a major chord in middle C. [tone] Going up a half step, add 1 ...
Subtracting 1, going down a half step. [tones] ... Yeah?
Student: Does a MIDI have to be integers?
If it's real MIDI it does, but we don't have to obey that.
60.5 (a quarter-tone above middle C) [tone]
Why do you call one half of a step a quarter tone?
That is music history that we just have to live with.
Along with the fact that they used letters A to G and five of them have sharps and the other two don't.
... all that stuff we inherited from people who thought differently from how we think.
I hope you prefer typing 64 and 70 to typing 261.62 -- you don't see the whole thing here. --
And those numbers which are frequencies that I don't even know.
And just for the sake of being thorough:
If you ever want to get back, there is a frequency-to-MIDI. (ftom) And that will do this for you:
It will figure out what you have to say in order to get a given frequency.
So if I happen to know that the thing I am listening to...
let's see, to avoid re-using the number 60 ... suppose we're in Europe and we've got line-current to listen to, which is 50 Hz.
So that is pitch 31.35, which is, let's see thirty ... 60 is middle C ... Then 31.35 is a G, a little bit north.
Which is the sound of a ground loop in Europe. --
So Hertz to MIDI to Hertz.
If you have an integer here, you are not always going to get an integer here and vice versa.
The only situation where both of these happen to be an integer is when you use numbers like 220 or 440, which correspond to A, which is 69, or 57, or 45, etc. ... Yeah??
Student: This may be pretty unrelated -- But do you have any idea why they arranged it so that notes in MIDI are like 69 for A 440 and then they have negative numbers which correspond to Hz?
Oh yeah, right.
... Yeah. So what is MIDI 0 here? It's 8 Hertz and change.
So if you want something to go at four Hertz you have to say, go down an octave from 0 in MIDI, which is -12 MIDI.
Isn't that horrible?
And this is a perfectly reasonable vibrato rate, in fact a good vibrato rate is -6 or so.
By the time you get up into non-negative MIDI frequencies you are really too fast for doing nice vibrato.
Why did they do that? -- Because pitch originally was supposed to live on an 88-key keyboard.
Because this was invented by instrument manufacturers. They thought about selling keyboards.
So they invented a 7-bit protocol that can describe 88 keys.
You can do that in a variety of ways like you can count the bottom of the piano as being 0. But what they wanted was for middle C...
Well, for C's in general to be multiples of twelve.
That makes the arithmetic easy.
So then you could make the bottom of the piano be -3 ... No, you can't do negative numbers -- That's an A, usually.
So then it could be 9. ... But in fact they made it 21 so that middle C would be about halfway up the range from 0 to 127 I guess.
Anyway ... It works OK.
The highest frequency you can talk MIDI into talking about...
I can set the width of the number box; occasionally you have to. ...
So you will have trouble specifying pitches above... --
ooh. That went the wrong way.
You can't describe things in classical MIDI, hardware midi, above this pitch here, which is not going to bother any musicians.
Oh and by the way, 0 - Even though 8 Hertz as a frequency is subsonic.
So we did cover the range of hearing decently well, although not perfectly.
And of course you can go out of the range negatively, you can also go out of the range positively.
200 MIDI is almost a megaHertz.
1000 MIDI is almost 10^26 Hertz.
It's exponential -- every time you add twelve here, you are doubling this number.
Student: How do you get that number box?
Here? Oh, I just clicked on it and it said one, 0, 0, enter and then it did it for me.
Student: The width of the number box, though?
Oh, right, OK. ... Yeah, yeah. So this thing?
This is because my number box by default is only five units wide.
And I went into properties and told it to make this one 8 units wide so that I could see bigger numbers.
It is a trade off of screen space versus range of numbers you can see.
Actually five is almost never the right number.
It is almost always either 3 or else it's 8. Five is almost an anti-...almost a local-minimum of utility.
And of course, minus a thousand is a very low frequency.
Like a once-in-the-age-of-the-universe type frequency.
So that is units of frequency and pitch.
So MIDI is a unit of pitch, and that is suitable for describing musical intervals because when you add some fixed number of steps to a pitch you move by the interval no matter where you are.
... Whereas frequency has a more dubious range...
the audible frequencies anyway, roughly speaking, range from 20 to 20,000. So it is a more unruly scale for typing numbers in.
And that is all I should say about that.
Oh, if you want to have an interval, you multiply the frequency by a number to get the interval, as opposed to adding.
And this is in fact exponentiation.
It is a normalized kind of exponentiation so that adding here is the same as multiplying here.
Because when you add something to something that you are going to exponentiate, you multiply.
Similarly to pitch and MIDI, we have objects for doing amplitudes.
And I have been using these numbers like 0.03 for amplitudes all quarter so far.
Now we can start using amplitudes in decibels, which might also be a nice range from 0 to 100-ish.
So the objects in question are called "decibels to root mean square." (dbtorms) That is a horrible name, isn't it?
"Root mean square to decibels." (rmstodb)
I don't know a better name for these, but this is not a good name.
100 decibels corresponds to one volt, if you like.
And then every increment of 10 db is a multiple of ten in power.
Multiplying power by 10 means multiplying amplitude by square root of 10.
Because power is proportional to the square of linear amplitude.
A good measure of linear amplitude is root mean square, which means "the square root of the average of the squares of the sample." --
"Mean" means "average" in this context.
So that root mean square is:
"Take your signal, square it, take the mean and then take the square root of it."
That is what the letters are and that stands for.
And decibels-to-rms means get this thing (100) and make it that or get 90 (which is ten fewer and turn it into 1/(square-root of 10) (316) ... which you all know by heart.
And then 80 then becomes [1/(square-root of 10)]^2 because we divided by the square root of ten twice. --
And that means dividing by ten.
And now you can see why it is a reflex of mine to always say 0.03...that's about 70 db. .
3 is about the square root of ten, .1 is a tenth, .03 is about ten to the minus three halves and so on like that.
It's 10 db every time you multiply by three-ish. Yup.
Student: Aside from just knowing that knowledge, is there any practical benefits to what you just showed us?
The dbtorms? Well, there's this ... Now I can stop doing this and start doing...
Ooh, I'm going to have to introduce a new object and there are only five minutes to go. I don't know if I should do this.
In fact, what I'll do is I'll quit doing the niceties and just give myself a number box. Like this.
Now I can say "Give me seventy db please," -- and you can't hear anything because I don't have any pitch here. [tone]
So this seventy is an easier thing to think in terms of than this 0.03. Not only is that easier, but also at this point I've got something that operates reasonably as a control.
I can mouse on this without having to hit the shift key -- that is a good thing.
And furthermore, every time I push this by a fixed amount, like 10, say, it gets the same amount louder as the last time I pushed it by 10. Or I can take it down.
So if you like ... five db, five or 10 db is a musical dynamic.
And if you think in terms of there are six dynamics all the way from triple-f (fff) to triple-p (ppp).
If you think that is a 35-decibel range of loudnesses, then then make it be 5db per dynamic.
And then you've got a decent way of controlling dynamic that doesn't have you typing lots of decimals.
Unfortunately, what this would mean is that 0 should be 10^-5. But the dbtorms object cheats, and when you say 0 it gives you a true 0 out so you can just turn the thing off.
That's important -- because otherwise, it being digital, even if you had an amplitude of 10^-10, it might be doing 0 crossings, and it might still make its way to your speaker.
So 0 is true 0, but as soon as you get off of 0, it gets to real numbers that are too small to show.
... Yeah, I need to make this number box fatter again.
Now 0 is 0, but one db is about 10^-5; 20 db 10^-4 (.0001) and so on like that.
And negative db you just truncated to 0.
You can tell this thing more than 100db --I'm not going to do it right now, because it's connected to sound.
But if 100 db is an amplitude of 1, then 120 db is an amplitude of 10, which is too loud to play, but not too loud to think about; maybe you are going to attenuate it later.
And 140 is an amplitude of 100 and so on like that.
Questions about that ... in 30 seconds?
So those are acoustical units, and that was table lookups and phasors.