*** MUS171 #06 01 20
@0000 Here's a thing I'm going to forget to tell you, so I'll tell it to you now while only the early birds are here while I'm thinking of it. You can set the screen
es: @0000
@0015 size of tables. So if the "one size fits all" size that you're all used to is not what you really want...Like in this example you can do something else. In this case my table is too fat and it's not tall
es: @0015
@0030 enough. So if I do that one, then I have...Oh, maybe that's too tall for my screen. Anyway. Yeah, not good.
es: @0030
All right lets make it 400 pixels tall and 100 pixels wide. @0045 No, looks like I have 300 pixels. All right, there it is. OK. My reason for doing that was
es: @0045
@0060 because the bigger you make something vertically, the more accurately you can control it with a mouse, assuming you're controlling all the way down to the pixel, which is the way tables work. Actually they maintain floating point values, which are to high precision.
es: @0060
@0075 But when you're editing you can only push them onto a pixel value, which might or might not be available, but it's more likely to be available the bigger you make the thing. So that's a trick.
es: @0075
This is just a review from last time. @0090 Right now what we're doing is we're looking at the first seven values of this table. Bring this up to here. And the reason I know that we're doing that is because I'm taking this phaser
es: @0090
@0105 which goes from zero to one in value and multiplying it by seven. Which means now you're going from zero to seven. And then values from zero to seven truncate down to values from zero to six, when you truncate them to the greatest
es: @0105
@0120 integer below them.
es: @0120
And as a result you're looking at the first seven values of the table which are numbered 0, 1, 2, 3, 4, 5, 6. And the others are just there in case you want them later. You don't have to have them in fact I could resize @0135 the table to seven values now, but I might decide that I want a different size sequence later, and I can do that just by changing the number. And now we're looking at , 1, 2, 3, 4, 5, 6, 7, 8, 9 ..
es: @0135
@0150 0nine out of the twelve values.
es: @0150
Notice that it gets faster as I ask it to use use more values. That's just because the frequency that I'm giving the phaser is setting the period for the entire @0165 sequence and the more notes I stuff in there, the faster the notes are going to be going. Or to put in another way; the more you multiply the phaser by, the faster the output is changing within time, because the more it travels all told. Student: So what's the "0.7" ?
es: @0165
Miller: @0180 That is the frequency in hertz of this phaser. Student: What units is that, .7 of what?
es: @0180
Miller: It... let's see, it does 0.7 of that sequence @0195 every second. So if I set this to 1, it's one cycle per second, if I set it to 2, it's two cycles per second. So here's 1: [tones] If I say 2 it'll go twice as fast.
es: @0195
@0210 Oh, so right now it's every second. 2 is not every two seconds, but every half-second. So 0.7,
es: @0210
@0225 what's that? That's one over 0.7 seconds in period. And I don't know why I chose that value. Actually I know why. I tried 0.5 and it was too slow for my taste.
es: @0225
@0240 OK. So the purpose.... does everyone understand how this example works? Or, can you formulate questions
es: @0240
@0255 if you don't? ... Yeah? Student: Why would you have both the multiplier <<*~>> and the adder <<+~>> after the phasor?
es: @0255
Miller: Right, OK, so the multiplier is taking the phaser's output and re-scaling it so that it goes from zero @0270 to seven in this case. And the adder, I'm not using at this point, I'm adding zero which isn't doing anything. But if I wanted to instead of looking at the first seven points, look at the points two through eight or three through nine, I would add something to the scaled value and that would be
es: @0270
@0285 reading at that place in the table. Student: Is that a phase-shift? Miller: Yeah... Oh boy -- it's short of a phase shift, but it's also... it's just a shift-shift. Student: So it's like a range-shift maybe?
es: @0285
Miller: Right, yeah. This @0300 is worthy of... what's the right word? This is worthy of just mastering in it's own right. This is the general formula for "I want a range and I want it to be seven wide and I want it to start at zero." In general, if you have something that goes from
es: @0300
@0315 zero to one and want it to go from A to B, you multiply by (B - A), which is the size of the range, and then you add A to slide it over to where you want it to go. And you do this all the time in computer music.
es: @0315
@0330 You can do the opposite as well, which is you have something that's going from A to B, where A and B are numbers, and you want it to go from 0 to 1. ... Because you then want to give it another range, say. So, to do that you would subtract A to make it start at 0, and then it goes from
es: @0330
@0345 0 to (B - A), and you would divide by (B - A), so that goes from 0 to 1 . ... Yeah? Student: So, if you add 3, start with 3 will it stop or wrap around?
es: @0345
Miller: It'll... Neither. If I give it 3, instead of going @0360 0,1,2,3,4,5,6 it would go 3,4,5,6,7,8,9 . Student: What if you don't have enough values? Miller: Sure I do. I've got twelve numbers in here. Student: What if you don't have them?
es: @0360
Miller: Oh, if I didn't? Then, OK, then it's up to the object @0375 tabread~ to figure out what to do with when I give it a number that's out of bounds. And what it does is it simply clips it. That's to say it simply limits it. So it doesn't wrap around. You could make it do that. In fact, if you wanted to make it do that, you would, before this,
es: @0375
@0390 you would say, "modulo twelve." <<mod 12>> Which you all learned about in high school, right? So "mod" is a good object. Yeah. And you would do something somewhat different
es: @0390
@0405 in signal-land. Because mod works great for integers, but for floating point you might want to have something that's defined a little bit differently from mod.
es: @0405
So, that gets us down to there, and then it's just the same @0420 stuff that you know about from before.
es: @0420
The reason I'm bringing this up today is because I want to use this as the starting point, because it might be nice to know different ways of getting values in and out of tables, of which there @0435 are a half dozen. And I was having trouble figuring out which one to show you, so I just decided to show you all of them. At least, all of them that I could think of. And because actually it's pedagogically valuable to know them. And we're all about pedagogy here.
es: @0435
@0450 So here goes. I have a list.
es: @0450
The first thing that you might want to know about is a wonderful object called "tabwrite." In fact, I told you about this, but I didn't tell you all about how to use it -- without a tilde. @0465 And then we give it the table name, which I'll just get from here. And this is a thing which takes two numerical values, which I'll start out by using the number boxes
es: @0465
@0480 to specify. And here <<right inlet>> you say which value in the table you want, "3" say, and here <<left inlet>> you say what you want it <<that value in the table>> to be.
es: @0480
And, tada, you're moving value three around in the table. So, you can see this thing is going up and down @0495 as I'm doing this. OK. This would be kind of--what's the right word?-- "hideous" to have to make a patch that did this to every single value of the table. Because you would need a different tabwrite object for every number that you wanted to set, which would be ugly.
es: @0495
@0510 So, you want to do it a little bit more smart than that, for which you will need some objects that might generously be referred to as glue.
es: @0510
So, there's some glue involved in using things like tabwrite most effectively. @0525 Glue. So, suppose I wanted the values to be the following, which I'll stick in a message box. Is this what I want to do? OK. I'm not going to use this message box yet. I'm just going to have these values here so that you can see them.
es: @0525
@0540 All right. Do I want seven of these things? Yeah. Let's have seven of them.
es: @0540
So, now... I'm just making multiples of 110, @0555 because since I spend a lot of time in music studios, I like things to actually belong to the western scale. And 110 is an A. So, these are easy numbers to just sort of fetch out of nowhere that happen
es: @0555
@0570 to have at least some reasonable western meaning.
es: @0570
And suppose I want to get these values into this table, what would I do? OK. Technique number one. We could use tabwrite. But @0585 of course, I don't really want to type all this stuff in. I want to just have it in a message box. How would I get that to happen? Well, there are things that you can do. One thing is this. ...
es: @0585
@0600 Message box.... Saying that the first number is going to be 990, is the same thing as putting a zero here <<right inlet> and then putting a 990 there <<left inlet>>.
es: @0600
And a short-hand for doing that, @0615 in Pd anyway, is you can give it a list of values. And what this means to an object like this...What does an object like this mean? -- An object, except for a couple of exceptional objects -- will take a list of numbers
es: @0615
@0630 and interpret them to mean, "Put those numbers in the inlets." So, this is saying, "Set the value at slot zero of the table to the number 990. So, this thing jumps up to there.
es: @0630
@0645 I don't have a good range with for numbers, do I? Let me change my range, slightly. So, let's go up to 1,500 Hz. All right.
es: @0645
@0660 And this is OK, except of course now I can't do this any more. I can just click it. So, it might be nice to know how to do this, but do it in a way that has a variable associated with it, so that I can make that
es: @0660
@0675 not be a thing that's known already. So, that's one thing that I want you to just wonder about for a second while I show you something else, which is this:
es: @0675
OK. Now, I can say, here are a bunch of message boxes. And @0690 if I had all seven of these that correspond to these numbers, and gave their locations, and if I set them all in sequence to tabwrite, then I would set the table to these values.
es: @0690
@0705 So there's the first one, there's the second one. Oh, I didn't connect it. There's the second one, there's the third one. That's ugly. And of course, now yow know that if you just wanted to have some way of doing them all... In fact, I can
es: @0705
@0720 bash it to something nonsensical like that: <<all values set to 98 via a message-box to tabwrite~>>
es: @0720
... I could just give myself a button that activated all these message boxes. A message box actually will respond to any message at all -- so a bang would be perfectly all right -- @0735 and will output its contents. So now, (let's bash it again) ... if I whack this button it puts all the values in the table. ... Yeah? Student: Could you connect the other message boxes to the first message box, that sort of thing?
es: @0735
Miller: @0750 You can do that. I didn't do that because I was afraid of confusing people, but you could do this: I wouldn't regard this as terribly good style. But why? Because,
es: @0750
@0765 in fact, what this is doing is confusing. Because I'm sending this message to this message box which is ignoring it. Someone could look at that and wonder what on earth I was doing.
es: @0765
So it's a little bit better to do it the way that I did it, but you could indeed do it that way. ... @0780 Oh, come on. Let me select this other thing.... This is still a little bit ugly. So let me show you the next thing that's a little bit less ugly, which
es: @0780
@0795 is this. I can always say, still using tabwrite. I can say, "Pass the following messages, please."
es: @0795
@0810 OK, I'll keep going. OK, I'll stop there because I'm going to run out of screen.
es: @0810
Now, what this is, is four @0825 messages in a single box which are "delimited," or separated by, commas. So commas are special characters in Pd. There are four special characters in Pd.
es: @0825
@0840 The comma, the semicolon, dollar signs, and spaces. Spaces you know about because you just use them to separate things. Commas separate things, but in a way that means to a message box, "Let there be another message now," and it's going to start here,
es: @0840
@0855 with this thing.
es: @0855
So this is different from this message box because this contains one message with seven numbers and this now contains four separate messages which will all be sent in sequence. @0870 I have to tell you about how long it takes this to happen, but that's perhaps for a little bit later. It doesn't take any time for this to happen, is the short answer. And so this is now a short-handish way of saying, "OK, go ahead and send
es: @0870
@0885 these four messages that do this thing." Furthermore you know what order they happen in -- and here <<with the bang to separate message boxes>> you don't actually know what order these three things went off in because it really is just whatever order I connected these things in. The order that the things happen in is sometimes very important.
es: @0885
@0900 And I've been avoiding getting into situations where the order matters, but I'm going to start making situations like that today, because that's part of the "glue." ... Questions about this? Yeah?
es: @0900
Student: @0915 What are the table properties there now for tab.1.20.a ?
es: @0915
Miller: Oh. So this is the important stuff ... there are twelve points in it and Y --the vertical axis is @0930 running from 1500 to -1. (I made it -1 so you can see 0). And there are twelve points in it. And this is the screen size of the table which I changed also.
es: @0930
Yeah. @0945 All right. Other questions about this? ... Everybody's totally happy.
es: @0945
Let me show you another thing that @0960 will save you some typing. If you really just want to put a bunch of numbers in the table, another short-handish way of doing it is to say... Hmm, should I tell you this? Yeah, I can tell you this. OK. Second technique of
es: @0960
@0975 doing things, the second flavor of glue that exists in Pd that you'll want to know about: And I'm going show this to you now because it easily confuses with what I'm doing now, and it's different.
es: @0975
So right now what I'm doing is I'm sending messages to this object tabwrite. @0990 You can also send messages straight to this object. << the table itself>> And then you're not talking to a particular auxiliary object like tabwrite or tabread~, or what-not.
es: @0990
@1005 You're talking straight to whatever the table itself thinks that it likes to do with messages. And what it does is design for what it is. And how you get a message to it is
es: @1005
@1020 you say "Send."
es: @1020
So let's get an object, and the object is going to be send, and then I'm going to give it the name of the table as an argument. @1035 And then I can actually send it a message which consists of the following stuff: It has a place in the table that we want to put a value in, and then it has the numbers that I want the table to have.
es: @1035
Student: @1050 So the number "990" is the starting point where you want the sequence of stuff?
es: @1050
Miller: That's right. So this is now... that's on the horizontal axis. @1065 "Starting point 0, please." And these numbers -- any number of numbers that you wish -- are the numbers that you're going to put into the table. All right. This is a good thing because now there's an easy way just to
es: @1065
@1080 write numbers into the table.
es: @1080
All right. So this -- sorry I have to think about something here. @1095 I'm going to have to start saving parts of this patch because it's too big for the screen. Well maybe this is just what it is for now. ...
es: @1095
@1110 OK, so here's technique number one, down here is what looks like a far better technique. Oh, I don't need this any more. That was just to make the example, but here's the thing that actually did it which has all the information.
es: @1110
@1125 Now... Sorry, I'm just cleaning up. ... OK, so "send" is the thing which
es: @1125
@1140 will allow you to send a message to any named objects. The only object that you've seen so far that has a name is this: array or table. Another thing that can have a name is
es: @1140
@1155 an object whose only purpose is in fact to have a name, which is called "receive." So, let me give it a different name. Oh, you know what? This belongs in a different patch.
es: @1155
@1170 I'm going to save this patch.<<starting patch "3.send-receive-etc.pd"
es: @1170
This is going to be two and then three is going to be send and receive...@1185 and some other stuff. All right. Let's see, we don't need this.
es: @1185
@1200 By the way I'm going to get rid of this because...
es: @1200
@1215 I'll try to develop this as I do it. OK, so first off, send and receive as objects. So, well I don't want to use the word "foo," that's too frequent. So, dog.
es: @1215
So here's a message @1230 that we're sending to dog. In fact so that we can see it, I'll use a number box. (Ctrl-3.) And then I'm going to say "receive dog,"
es: @1230
@1245 and it gets an outlet. Oh, so "send dog" only got an inlet and didn't get any outlets. Receive dog gets an outlet and no inlets. And now I have this going on. All right. So now what you've got is:
es: @1245
@1260 I was able to put values in the table by sending to the name of the table, but I can also put values into "receive" by sending messages to "receive."
es: @1260
And to be a little bit more parallel to what I did, something a little bit more similar @1275 to what we saw above was, I was sending a list of numbers like this and a number box will take a list of numbers and it will pick off the first number, as it can only
es: @1275
@1290 deal with one. All right. This is all going to require five objects. ... Yeah?
es: @1290
Student: @1305 How could you receive the whole list?
es: @1305
Miller: Yeah, how could you retrieve all that? OK, this is another topic... Yeah ... @1320 Which I'll get to in a moment. I'm afraid to talk about it right now. OK, so send and receive are useful
es: @1320
@1335 because by now you've probably noticed that your patches are starting to have lots and lots of cords, many of which are short because things are local, usually.
es: @1335
But occasionally your patch, no matter how hard you try to figure out how to lay it out, will have a line like this: <<draws a very long connection, all the way across the screen>> @1350 And one way of dealing with that is simply to put a send object up here and put a receive object down there, and that way you get the connection and not the awful line going through the patch. Later you'll find that it's even better than that because you can have patches
es: @1350
@1365 that have multiple windows in them, and send and receive is a good way to get from one window to some remote, not very directly related window. ... Yeah? Student: So can you send and receive between different patches?
es: @1365
Miller: @1380 Yeah. So for instance, here's a new patch and here's an object. I'll give it the same name, and then I'll hook it up to the number.
es: @1380
@1395 Now over here, I say send dog. <<values change from "receive dog" in the new patch>>. By the way, one thing that you can like about Linux is that you can do this. <<changing numbers in one patch and seeing changes in the other>> In your computers you have to click
es: @1395
@1410 this thing <<the main patch>> to the front and you won't see this<<the patch hidden behind it>>. Most people hate that though. OK. .... Yeah? Student: You said it was wireless though?
es: @1410
Miller: Yeah. It's a @1425 wireless connection. And because it's wireless, it even works from window to window. Oh, and this is why I've been giving the tables all these funny names, because the tables will confuse themselves across patches just as the send and receives do. So if you use the same send and receive name in two different patches
es: @1425
@1440 and have them open, they will get tangled up into these messages. Yeah? Student: Can you send and receive between different computers? Miller: You have to work harder to do that. [laughing]
es: @1440
Miller: And furthermore, the timing @1455 semantics will be different if you have two different computers. If you do it in one computer it's instantaneous, but there will be network delay if you do it across two. The objects you need are "netsend" and "netreceive," instead of just "send" and "receive." Yeah? Student: So it's all just one giant namespace?
es: @1455
Miller: @1470 Yeah, right, which makes it even easier to get confused, because your patches could be things you develop in different years, right? Or, by different people. And they could still be talking to each other and getting you in trouble.
es: @1470
Student: @1485 Only if the patches are running?
es: @1485
Miller: Only if the patches are open -- in the same Pd. (You can also run several copies of Pd, in that case you'll get away with it.) But at the same time it will turn out to be good practice some time in the future to @1500 figure out how to localize your send and receive names so that your patches don't crosstalk on that. That will be a thing later on in the quarter. All right, so, next thing I
es: @1500
@1515 want to tell you about is packing and unpacking. This is partly in response to one question I think. But it's partly also just a thing we need. So the question was, how could you actually retrieve all this stuff if you wanted to? Actually there are two related questions.
es: @1515
@1530 First off:
es: @1530
"I know how to send a variable message with one number in it, but I don't know how to send a variable message with more than one number in it." Which for instance you would want to do if you wanted to change...let's close this now. We don't want to save this. @1545 So now suppose I want to have a number box that changes this fourth number in the table?
es: @1545
Well, we could go back to what we were doing. Let's see, of course it erased it, but I'll put it back. @1560 tabwrite, without a tilde though by the way. If it's a tilde it wants to take a signal and it will write the signal sequentially into the table. But without the tilde it needs two numbers which are where you write into the table
es: @1560
@1575 and what you write into the table. So if I want to change the number at location three which is the fourth number here to
es: @1575
@1590 some new value like 1,000, I have to type three there and I have to type 1,000 there.
es: @1590
It would be nice to be able to do this and move it up and down without having to set this, or whatever. @1605 Or, to be able to have this thing be controlled programatically by something else for instance, that sort of thing.
es: @1605
So ... ways of doing that: There are two things that you can do to get this to happen. The first is @1620 just using a message box. Oh no, let me tell you the other way first because you need this first. So one thing you can do is you can pack and unpack messages that have multiple numbers in them. So the way
es: @1620
@1635 of putting two things together...I'm going to get rid of this because we already have it. ...
es: @1635
So I'll go back to patch number two and show you some stuff about @1650 that signal processing network a little bit later. But first off, here's a thing: I'll get two numbers and I will pack them into a message using an object which is called "pack."
es: @1650
@1665 And then just to show you what's...Oh, so just to show you what's happening the easy way... I'll say "print." And then we will see
es: @1665
@1680 packed messages.
es: @1680
So as a rule in Pd, when you throw things into inlets that are not the first inlet -- If it is not a tilde object, if it's a control object, like pack, you put things in the inlet and it @1695 changes the object, it advises the object, in some sense. It changes its internal state. But output in general, or whatever the thing does, is typically engendered by putting something in the first inlet: So now we get this message out, "2 79."
es: @1695
@1710 So it has two numbers in it, and this message is those two numbers packed into a single message which you could call a list. It's a list of numbers. All right.
es: @1710
@1725 So I can change this all I want and nothing happens, but then as soon as I put in another value in here <<the first inlet>>, I get to see another pair of numbers. And now I have that...that hasn't helped me yet,
es: @1725
@1740 has it? Oh, here is the thing that might help me. If I want to have a way just to write into location 4 of the table, one thing I can do is say "pack 0 4" and then
es: @1740
@1755 I will a put a number in there. And nothing happens...oh, because I'm not doing anything with it -- duh .
es: @1755
OK, where is my tabwrite here? @1770 To try to avoid confusion, I will make a different copy of the tabwrite object, and now I have got a message box. It is being converted into a message which is this value and
es: @1770
@1785 4. I should print it, so you can see it. I told you about print, but I didn't tell that you
es: @1785
@1800 can actually give it an argument to specify what you print. Sometimes you need that.
es: @1800
OK. So now what is happening is that I put a 450 in and this becomes the message "450 4". I could change the value of 4 by putting a message in that @1815 inlet or I can just leave it and it would just say whatever it is, space 4. Yeah? Student: Is 0 -- where you have "pack 0 4" -- specifying how many values there are?
es: @1815
Miller: Oh, thank you. Zero is there @1830 simply to say the initial value of this inlet is zero. But in fact it is never used because in fact I immediately override it by sending it values. But if I didn't put it there, it would just be packing the message which consists of 4.
es: @1830
@1845 And then I would just be generating a single number. All right, now you know how to do something that
es: @1845
@1860 you didn't know how to do before, unless you've been looking ahead, which is I've been making these... OK, so
es: @1860
@1875 what I'm going to do is save patch number two as patch number four. And I don't know what it's going to be named, maybe "table-pitch-again" again <<saving 4.table-pitch-again2.pd>>
es: @1875
Do you remember that @1890 I was making myself a message box to start the thing, and then another one to stop it?
es: @1890
@1905 Now I can do that much better. This is ugly because this value is not in decibels, it's in linear units. And I would love to be able to use dbtorms to be able to specify
es: @1905
@1920 that number in decibels. But db2torms only has a single number that goes in and a single number that goes out. Here's dbtorms: Lets see, can I get rid of this? OK.
es: @1920
@1935 I'll have to go back to this later, but for right now I'll just leave it like that. So, recall that dbtorms does this:
es: @1935
dbtorms ... You put a number in @1950 and out comes the amplitude that you would need to have that number of dB in your signal. This is a perfectly good way of turning things on and off. So 70 dB is about .03
es: @1950
@1965 as I was explaining last time... By the way if your going to do this... I'm just going to disconnect this before I do the next thing. Make this wide. Perfectly reasonable numbers
es: @1965
@1980 of decibels, like 160, are very bad numbers of amplitude. So it would be very easy for me -- notice I've disconnected this for this very reason. So I'm sitting here at zero, say, and let's turn it on
es: @1980
@1995 to 70 or so. Whoops, just 70. <<mouse had generated a value of about 150>> If I did that, I might have just destroyed my speakers. So if your going to do this, take this message box --I suggest you take this message box and fix the upper limit
es: @1995
@2010 to something _reasonable_. Oh, let me show you that slower. So the message box, atom boxes also have properties. It has a width... But you can specify a lower and upper value. If those values are both zero, that means the thing is just whatever it is,
es: @2010
@2025 and it can be positive or negative or anything.
es: @2025
But if I give it values that are non-zero, it would interpret that as a range. And that range will be enforced, which is good. But what this means is I have something that I can mouse at @2040 very conveniently. So getting the thing to be zero, is that. Whereas if I did that to a regular old unvarnished message box like this? I'll turn it off and it will do that <<message box value mouses to -194>>,
es: @2040
@2055 which is stupid. At least, that would be stupid for a value in decibels. Zero is perfectly good for "Just turn me off."
es: @2055
So it's a convenience to have it so that your number box goes to zero @2070 when you drag it all the way down to the bottom. And to do that you set the range of the number box to be the values that you believe will be reasonable. ... And then, if you repent later and say, "I really want 90 dB,"
es: @2070
@2085 you can always type it in. -- It won't enforce the range. It's simply a thing that detects how the mouse operates on it. So, this is now a good volume control except for one little thing:
es: @2085
@2100 and the one little thing is that it clicks when you turn it off and on. That's why I was using these things <<line~>> that have time values. Of course, when you have message boxes for the time values
es: @2100
@2115 you have to decide what the thing was in advance. But now that we have the pack object, we can do it all, right.
es: @2115
We can now say "pack 0 @2130 50". And now,
es: @2130
@2145 what's going into this multiplier is the output of line~ which is getting messages which are "0.2 50" -- those two numbers -- and that will turn the line on and off in a way that will not click.
es: @2145
@2160 So, this is a correct -- or at least a not incorrect -- way of managing
es: @2160
@2175 gains in dB.
es: @2175
You can do even better than this, but this is the first time I've shown you how to do it well enough that you would actually want to do this to someone else who had to use your patch. @2190 Are there questions about how this works? ... Yeah? Student: Can you explain the two numbers in the pack?
es: @2190
Miller: Yes. So, the two numbers in the pack serve to do two things; they initialize the values of the inlets in the pack. @2205 So, this value is initialized to zero and this value's initialized to 50. They also serve to tell you how many inlets the pack will have because, you won't have to do this any time soon, but
es: @2205
@2220 some day you might have to have a message that has six or ten values in it and you can tell pack to have more than two things by doing that.
es: @2220
If you just say "pack," by default it assumes you mean "two" <<inlets>>. @2235 If you want something else, give it numbers, numbers which will initialize the inlets, but by the way will also specify how many inlets you want. ... And you had a question, too?
es: @2235
Student: @2250 Yes. Is the number box after dbtorms affecting the value that goes to pack?
es: @2250
Miller: No. It's just so you can see it. And furthermore, there are differences of opinion about whether this is good style. @2265 So, there are people around who will pontificate about the proper programming style in Max and Pd, more in Max, actually, than Pd. The Pd community is kind of forgiving that way.
es: @2265
But some people say that you shouldn't do this because someone could walk up to your patch and do this: <<type in a new value into the number box>> -- @2280 And this would be in a bad state now. Because if I "moused" on this thing, it would suddenly jump from 0.3 to whatever I just made here, which wouldn't agree with it, right? And that might not be a good thing. Yeah?
es: @2280
Student: @2295 Can you make the other boxes un-editable, so you can't edit them? Miller: Inedible? [laughs] Oh, un-editable.
es: @2295
I don't think they're edible ... But you can't, no. Oh, wait a second. @2310 No, you can't really. You could set the range to be from two values that are equal, but then if you touched it, it would jump to that value. So, actually, yeah, they're always going to be editable.
es: @2310
But one thing that you can do that sometimes helps @2325 people--and this is programming style, you can do it or not--is make the thing hang like that <<is not in series with "pack" any longer.>> So, that it is clear that it is only there for the purposes of showing me what the number is, and it's not there for you to mouse on.
es: @2325
@2340 That won't stop you from mousing on it, but at least you can tell that mousing on it is not going to do anything for you. So, there are people who argue strongly that you should do this, instead of what I just did.
es: @2340
@2355 And me, I'm agnostic about it. I do it sometimes one way and sometimes the other. Other questions?
es: @2355
So, that is pack and unpack, @2370 which we use for two different purposes. Actually, pack seems to get used a lot more than unpack, because there are objects which you have to send messages to that have more than one number in them or more than one argument, as you might call it.
es: @2370
@2385 Unpack, you use if you want to make your own thing that takes pack messages and distributes the numbers in some way or another. Student: I don't think you've showed us unpack yet.
es: @2385
Miller: Oh, I haven't shown you unpack. -- @2400 Sorry, yeah, better do that! OK, so this is now number four. The reason I didn't show you unpack is because I forgot to finish number three. So, let's go back here.
es: @2400
So, this is pack. I was just showing you this, and then @2415 it wasn't obvious why this was a good thing except for putting numbers in a table. But the other good thing that you could do with pack is controlling volume, controlling volumes in a way that it would operate in dB, which you couldn't do before.
es: @2415
Now, unpack is this one: @2430 Again, you give it arguments. By convention, I just use zeroes for unpack, and the arguments do nothing but set the number
es: @2430
@2445 of outlets, and the outlets are going to be the two numbers in the message. Whoops. So now, it's showing me the numbers that
es: @2445
@2460 I was previously using print to see. The reason I used print before was because I hadn't told you about unpack. But now that you have unpack, you can now make things. Assuming you know when you're building the patch, how many items are going to be in your message, how many numbers are going to be in your message,
es: @2460
@2475 then you can put an unpack there to show yourself what those things are, or to distribute them in some way that does something useful.
es: @2475
All right. @2490 So, yeah? Good. So now, having seen that,
es: @2490
@2505 the next thing to do, I guess is go to window number four again, and using send and receive, bash a whole ... --
es: @2505
@2520 You basically know how to do it all now. Except I want to show you one other good thing, which is that you can use text files to maintain numbers in tables, and that is a good thing, because that's one of the easiest ways of getting Pd and other software
es: @2520
@2535 programs to talk to each other. So do that, we'll go forward to ... no, we'll just stay here, actually. So, the table, here,
es: @2535
@2550 can be sent a message, which we can do using the "send" object. So we're going to send to tab, oh, we've got one of those.
es: @2550
We've got @2565 an object called "send." OK, so, since we have that object send tab, bla bla bla, I'll just re-use that object for all the other messages that I'll be sending this thing. There are plenty of things that you can send to the table.
es: @2565
@2580 This was a thing that got values in just by specifying your numbers, so there are also messages that you can send, which are ... I'm introducing too many things here: First off is fact that you can actually have messages that have commands in them, and
es: @2580
@2595 second, the fact, what the commands actually are. You can say, read some file, and it will look at the first twelve numbers that are in that file, and
es: @2595
@2610 put them in the table. And of course, what I have now is just an error message: "file1.txt: can't open"
es: @2610
OK. So, the other thing that we've got is, "write." @2625 Especially for those of you who have Macintoshes, it's getting hard to make text files on Macintoshes, because when you open the text editor up, it wants to do rich text for you, which you don't want, usually, if you're doing stuff with computers. So, sometimes you have to just make
es: @2625
@2640 yourself a nice seed text file. So here's "write file 1.txt".
es: @2640
And now that I've done that, maybe--oh, it doesn't--let's look at all files. Oh, we don't want to do that. Never mind. @2655 Sorry. I'm using an operating system and now I have to remember how you see files in this thing, which is you go get the little finder who-ha.
es: @2655
@2670 Tada! "File 1.txt". And now, we have a text editor -- this will work on your Macintosh, too,
es: @2670
@2685 or your PC -- which has the stuff that was in the table.
es: @2685
And since this is a text file, you can now read it. You can read it in the MATLAB or Octave, or what else? Well, you can dump it into HTML, @2700 or whatever it is that you want to do with it.
es: @2700
OK. Similarly, now if I want I can put new values in here. For instance, if I wanted to I could...@2715 Well no, I'll just do it. It doesn't matter whether they're on different lines or not. Let's see ... we had 12 numbers in the table, so I'll just give it 12 numbers.
es: @2715
@2730 It does the right thing if you have the wrong number of numbers. And now, we go back to Pd. Where was Pd? And say, "Read it." And there's the nice table I just edited. ...
es: @2730
@2745 Yeah? Student: Is that text file in the same directory as your .pd file?
es: @2745
Miller: Ooh, thanks. Yes. Well, you could give it a path. So, you @2760 could say, "Read ../blah/File 1.txt". And, yeah. But for right now just make everything be in the same directory. Also, you can give Pd a search path. So, there's directory
es: @2760
@2775 stuff to worry about.
es: @2775
One thing that will come up and bite you is that when you make a new patch, it doesn't know what directory it's in. And as a result, it might not be able to read @2790 a file that is in a directory because the patch itself -- before you save -- isn't in that directory. It's in no directory at all.
es: @2790
So, you might have to save your patch just to tell Pd what directory you want @2805 the thing to believe it's in, so that you can read files in from that same directory. All right. OK.
es: @2805
So, you've seen send. @2820 You've seen pack, you've seen message boxes, and you've seen files. And this is probably enough Pd lore for a day. So, I should show you some more
es: @2820
@2835 stuff of relevance in music for a while. I know, I haven't been making a whole lot of noise yet.
es: @2835
What I want to do to that end is start out with the assignment for next week, showing you what it is. It's on the web page. But @2850 the web page doesn't explain it very well. And so let me explain it better. So, I'm going to save this.
es: @2850
@2865 So, the near-term plan...
es: @2865
Miller: @2880 [pause for setup/logistics]
es: @2880
Miller: @2895 Oh, great. I'm running two Pds. So, I had it miniaturized somehow.
es: @2895
@2910 I didn't know it. What's going on? Oh, and I had this terminal. Oh, I see, I've miniaturized down to... Sorry, I'm getting myself confused here. OK. Now, I'm no longer confused, maybe.
es: @2910
@2925 [music plays from patch]
es: @2925
Miller: This is... OK. You know how to do this. Here's a cool thing. Let's see. Turn it up. This is an idea that's attributed to @2940 Steve Reich. Am I pronouncing his name right? Steve Reich, who invented the idea of having two tape loops with sounds on them, that had slightly different durations, and then playing them both in a loop, so that you would hear them
es: @2940
@2955 getting phased differently with time.
es: @2955
And then, OK. So he did that in a series of famous pieces in the 60s, the first of which I think is called "Come Out," which you should probably check out if you haven't checked it out. @2970 And then, he started writing these things like that for instruments, in particular, this one called "Piano Phase," which orders two pianists each to play a 12-note sequence
es: @2970
@2985 at very slightly different speeds, so that they would phase gradually.
es: @2985
And you would hear them juxtaposed at different phases essentially. It's the same kind of phase as the phase in an oscillator, @3000 except it's being used differently because it's a phase and a melody. Well, we can do that here: [music plays from patch]
es: @3000
Miller: @3015 Is it doing it? Oh, yeah. I'll let this go for another round or two. [music plays from patch]
es: @3015
Miller: @3030 All right. There's all sort of fascinating stuff that you can do with this.
es: @3030
@3045 Of which I'll show you just a little bit. One thing is, and this idea I believe is due to David Wessel. I'm not sure, I heard about it from him: You can make melodies, and this is the extra credit. You can make melodies that
es: @3045
@3060 have two different timbres as well as a repeating pattern ...
es: @3060
@3075 Actually, this doesn't sound as good on these speakers as it did at home.
es: @3075
By the way if I were doing this for real I would probably work on getting that better. But I'm doing this only with objects that you've seen so far. Turned out to be tricky to get it to be perfectly clean, until you have @3090 some more your objects in your arsenal. But what's happening now is there are two different tables of pitches... [music plays from patch]
es: @3090
Miller: And what you should hear is the same, @3105 what's the word, same series of pitches as you heard here. Except that every third pitch has a different timbre. [music plays from patch]
es: @3105
Miller: @3120 So here's the part of the sequence: All right, so you can also hear [snaps fingers]...
es: @3120
@3135 If I slow it down, then you just hear the thing as a sequence-- you can't actually hear the other point of view on it. Which is that
es: @3135
@3150 you can hear every third pitch as a separate stream. That only happens at particular speeds. This is the effect that Wessel I believe discovered. So now if I speed it up at some point you quit hearing that as a sequence
es: @3150
@3165 going at this speed, and you start hearing it as two different things. One of which is the sharp timbre, and the other which is the sinusoid.
es: @3165
All right, @3180 the original David Wessel was three pitches. And [music]
es: @3180
Miller: So it's going down. @3195 It's three blind mice now, right? No it's not, it's going up.
es: @3195
@3210 It's "Do-Re-Mi." Do, re, mi, like that. Actually, for some reason in this register the sinusoid doesn't sound like it's the same octave as the other ones, but I guarantee you it is. And then if you speed it up,
es: @3210
@3225 instead of hearing the thing rising like that, you'll hear it going down. OK. It's like now you hear two different melodies which are catty-corner,
es: @3225
@3240 right? And... [music]
es: @3240
Miller: So now, if you're good at math, you can figure out that choose any two relatively prime numbers, @3255 the number of notes in the melody, and the interval that you change from timbre A to timbre B, and then you can pick out, basically, permuted versions of melodies that exist within themselves.
es: @3255
@3270 And then, yeah? Student: What does "modulus" mean?
es: @3270
Miller: What does "modulus" mean? Well, OK. I actually don't know what the word means in fully general, but in mathematics land modulus means the range of a @3285 set of numbers that repeats. Student: OK.
es: @3285
Miller: So, if you say five is equivalent to two modulo three, in that statement the modulus is three. @3300 I don't know of a better way of explaining it than just by contextifying it like that. OK. And, of course, you can do this with...or can you?
es: @3300
@3315 I don't know. I don't know why my patch isn't working today. Yeah. You should be able also to hear that phase -- But I seem to have forgotten to connect something in the patch to let you hear that.
es: @3315
@3330 So, here is the basic homework thing: Just do this. And then if you want to make it hard, do that, except that every third note should be a separate timbre as well.
es: @3330
@3345 Then you'll hear really wonderful stuff. All right. Qustions about that? ... Yeah? Student: Is there another patch behind there?
es: @3345
Miller: Oh, is there another patch @3360 behind here? I didn't tell you this: If you're working on a patch and you run out of room, you can just say "Pd" and either give it a name or not. Usually I give it a name just so I can tell what's what.
es: @3360
@3375 And up will pop another window, and this window is inside this box.
es: @3375
And this is what you do... -- I've been avoiding doing this because I don't think you should be using patches this complicated, that you need this yet. ... But this is what you do when your patches @3390 get too complicated to hold on one screen. You start encapsulating parts of it into sub-patches. And then when you close the sub-patch...oh, let me put something here...
es: @3390
@3405 when you close the sub-patch, it's still there in this box. And you can see it again by clicking on it.
es: @3405
So, if you look at a real piece of music realized using either Max or Pd, @3420 it will typically have hundreds of windows in it. Because all this easy stuff I've shown you so far fits in a window, but by the time you really want to do something specific and you want it just so and you want to have voices and so-on like that, you're going to have windows
es: @3420
@3435 on top of windows on top of windows. This is the way of managing them. ... Yeah? Student: Is the a reason that the "pd ----doit----" patch has six different connections is the patch itself is behind the scenes here?
es: @3435
Miller: @3450 Right. Right, and the reason the patch is behind the scenes is because it implements the homework. [laughter]
es: @3450
Miller: In fact, there's another reason, too, which is that I implemented the homework in an exceedingly messy way because I made a lot of @3465 mistakes and got confused on doing it and kept changing my mind about what you should do. And so it contains a lot of things besides the homework that I want to go back to later -- but I don't want to show you right now. [laughs] ... Yeah?
es: @3465
Student: @3480 In the text file that you did earlier ...? Miller: Yeah. Student: Is there a limitation on how long the path can be before it doesn't work? Miller: I think it's limited to 4,000 characters.
es: @3480
Miller: Should be OK. But message boxes don't like @3495 to be more than 80 characters wide, so that it will automatically wrap the file name in the message box. There is a thing which I should have told you about. If there's a space in your file name, Pd will think the space means that you have two different
es: @3495
@3510 file names. Yeah. So, spaces in file names are evil as far as Pd and Max are concerned. Student: So you can just use underscore, etc? Miller: Yeah. ... Yeah?
es: @3510
Student: Do you have a patch file on here that @3525 shows how complicated this can actually be? Miller: Oh, yeah. [laughter]
es: @3525
Miller: Here's the patch. This will take a moment to load, but... @3540 It's big. [laughter]
es: @3540
Miller: Yeah. This is a piece that I'm working on @3555 with a composer. I'll just talk over this while it struggles to load. Oh, here it is. So here are a bunch of control panels. This is an effects processor
es: @3555
@3570 and it has a frequency shifter with a bunch of parameters. It has a bank of comb filters. It has more comb stuff ...
es: @3570
a phaser, noise generator, flanger, harmonizers. OK. Then meanwhile, there is a sampler @3585 bank and there is a thing called Jack. It's just called "jack" because it's a name. Then, "eric" -- this is talking to the Synful synthesizer which we have upstairs if you want it.
es: @3585
Then pafs the phase-aligned formant generator @3600 which is a synthesis technique that has a bunch of parameters in it and has a bunch of voices in it. I haven't told you yet, but number of boxes can have sends and receives built into them -- which you need to do if you're going to make something this gnarly.
es: @3600
@3615 And how is it implemented? ...Oh, there's markov chains that can drive anything that you want.
es: @3615
But anyway. This machine will not be able to make sound with this patch, I'm afraid. @3630 It makes great sound, I'll tell you. So, here's the actual patch. Here's the sampler. The sampler has a few voices of samples, and this is a spatializer
es: @3630
@3645 that sums the first four voices into one place. Then these get spatialized separately and so on. The sampler itself looks like this, so there's a bunch of these guys.
es: @3645
@3660 Samp-controllers that control things. ... Here's the unpack and pack for you, I use that a lot. Here's polyphonic voice allocator. Go on like that ... "route" ... Student: You did this all in an hour?
es: @3660
Miller: @3675 No. I did this in a couple of years. Inventing all of this stuff as I went along ... hardcore stuff. Student: Can we hear something from it? [laughter]
es: @3675
Miller: Nope. You know, if I drop the sample rate to about a kilohertz I'd be able to do it on this processor. But this is an Atom processor @3690 and the patch needs Core 2 or so to run. Yeah. Then there's other stuff.
es: @3690
@3705 So, we can make arbitrarily complicated patches. Student: Are the Markov chains something that we're going to cover?
es: @3705
Miller: Yeah. @3720 That might happen later this quarter or it might happen next quarter. Most likely next quarter, but that depends on how things flow. You can make various kinds of stochastic processes in Pd, and people do use randomness computer music all the time.
es: @3720
Miller: @3735 OK. Back to "Lore with Tables" and whatnot.
es: @3735
@3750 Now I want to find the patch I just had. I must have closed it. [pauses]<<opening up "4.table-pitch-again2.pd">>
es: @3750
Miller: @3765 OK.
es: @3765
@3780 So, now, just to try to tie things together a little bit, I'm going to go back to using tables as waveforms and not as pitches.
es: @3780
@3795 Before I do that, let me show you something else. On the level of glue, there was something important that I didn't tell you. So, suppose I wanted to put values in the table, but suppose I didn't want
es: @3795
@3810 to type the values out in cycles per second. Instead, I want to specify a melody and pitch. That would be a good thing to be able to do.
es: @3810
So for instance, suppose I want to...Let's see what's the @3825 easy way to do this? Yeah. ... Trying not to introduce too many different objects here. ...
es: @3825
@3840 So I had to do it in this way because this is going to be the easy...well let me show you. Let me start doing it, and then try to explain what I'm doing as I'm doing it, because I can't figure out how to verbalize it without just showing it.
es: @3840
So, the first thing we're going to do is just @3855 say, OK, we're going to put a value on the table, and the value's going to be some number. And it's going to go into slot zero. And then I'm going to have a number box that puts the value in. Ugh.
es: @3855
@3870 Now I've got this thing going.
es: @3870
So now what you can see is this first value on the table is going up and down, depending on the number in the message box. But then--what did I figure? So the message now @3885 is "617 0". 0 is "where in the table", 617 is the value. Now you can sort of see why tabwrite takes the Y-value, that's to say the "value" value here <<left inlet>>, and the X-value in the
es: @3885
@3900 other inlet. It is exactly so that I can do this: <<mousing over the number box into the left inlet>> -- and it changes the value of the table instead of maintaining a single value and splashing it across the whole table, which is likely to be a less important to do.
es: @3900
There is a way to get it to do the other thing if you want, but I @3915 don't want to show that to you just yet because it's more glue. And now of course, if I want to talk to the next value in the table, I just say "1" here, and then I'm changing this next value. Oh, wait--connect it!
es: @3915
@3930 OK, so this is all clear, and now, ... Yeah? Student: Could you connect your number-box to the right inlet of pack, so you could mouse it and change the position in the table?
es: @3930
Miller: @3945 Except, that in fact it won't do anything. So here--so I'll say, "Put in 550 please, and put it in location 0." And I'll say, "Put something in
es: @3945
@3960 location zero." <<mousing over message-box connected to right inlet>> But then I'd have to bang this, or maybe resend "550." Student: Oh, OK.
es: @3960
Miller: And, yeah, @3975 there's a thing I have to tell you, which I've been putting off, but now that you've asked, maybe this is the moment. You can...OK, here, I'll do it the wrong way first, and then show you why it's wrong and then do it right. So the wrong thing to do is, (I have to
es: @3975
@3990 introduce another object to do it right) ... So the wrong way that doesn't require introducing an object is: 550, it's a message; I can throw the number in there. And then I can say...
es: @3990
@4005 Oh, that one. Oh, yes, thank you. So I can do nothing. <<connects the pack to the tabwrite>> OK: 0, 1,2,3,4 . OK, that's good.
es: @4005
@4020 It's not really quite right, because what I haven't done is I haven't actually verified that the 6 goes in here <<right inlet of pack>> before the 550 goes in there <<left inlet of pack>>. If the 550 goes in first, then it writes 550 to whatever this <<right inlet, "position">> value had been before, and then writes
es: @4020
@4035 the thing <<right inlet value>> in afterward. And that would be wrong. I'll make it clearer this way -- a sort of textbook example of how to do something wrong:
es: @4035
Let's take a number and square it by @4050 just using a multiplier. And now what I'll do is just multiply the number by itself.
es: @4050
@4065 Now I'll say five, and five squared is five?? -- actually I don't even know how that happened. But then six, and then I get 30. Why? Because you don't actually see it from the patch, but just from the way
es: @4065
@4080 I connected it, what it's doing is it's sending the 6 to this inlet <<left inlet>> first. And multiplying 6 by whatever is in this inlet <<right inlet>>, which is 5.
es: @4080
And then it's hiding the evidence by putting six in there. Right? And now, no matter how many @4095 numbers I put in, it's going to do it wrong until I happen to put a number in twice, at which point it'll do it right.
es: @4095
All right. This is confusing and bad. To make it good, @4110 you need an object which will actually force the order to be a particular order. Which is to say you want to put this value in first <<into the right inlet>> before you put that value in <<left inlet>>. And the object that does that for you -- this is object number
es: @4110
@4125 six for today, so I'll apologize, I think -- is "trigger," which, is named "trigger" just because that's the word that Max Matthews used to use for doing something.
es: @4125
@4140 So, you can think of this as a distributor in an automobile, if you're the type of person who fools with automobiles. And what it does is
es: @4140
@4155 it takes the value as a floating-point number and outputs it here and then outputs it here as another floating-point number. And again, I specify float, or bang if I just want to convert it just to a bang message, or other stuff that I don't have to tell you yet. And now,
es: @4155
@4170 I've got something that is guaranteed to do the squaring the right way no matter what order I connected it in. -- Trigger.
es: @4170
This is so useful, it's so useful @4185 and so long-winded that you can also just say trigger, float, float like that. <<t f f>> -- And this is what you see more often. So, here, what I want to do, really, is I want to
es: @4185
@4200 take this number six and I want to put it in the pack. And _then_ I want to send 550 in the other inlet.
es: @4200
@4215 And now I've got the thing in a way that it will work correctly. This does the same thing as the network that I had before except that before, I had this number box connected both
es: @4215
@4230 to the 550 and to the zero. And you didn't know that they happened in the correct order, which is to put it <<the position value>> in this inlet <<right inlet>> first and then put 550 here. <<left inlet>> Student: Could you have additional outlets from the trigger that you don't use?
es: @4230
Miller: @4245 Here? Yeah, yeah, yeah. So you can say whatever you want. Here would be a better style to say give me a bang
es: @4245
@4260 out this one. So this is the type of this outlet. And you don't need the floating number because just the message box will just convert it to the number 550 anyway. And so here you would just send a bang out
es: @4260
@4275 instead of a float. Although I've used float before, the possibility of float before.
es: @4275
Miller: So this is the way to get something into an inlet and then make the object do something anyway. @4290 Whereas if you just knew that this value <<right inlet>> was zero and wanted to control this number <<left inlet>> with a number box, it's the much easier situation to deal with. Which is that you just take the number box
es: @4290
@4305 in the pack like this. So this is the easy case, where you're changing this <<left inlet>> with the number box. This is the hard case, where your changing this <<right inlet>>
es: @4305
@4320 with the number box.
es: @4320
Sorry, this is much too much @4335 lore for one day. But lore is good. Rather, lore isn't good in it's own right, but knowing how to do this kind of stuff is good. Now I have to clean this up for you and put it on the website, so you can look at this in fullness of time.
es: @4335
@4350 Questions about this? .... Yeah. Student: I'm still not quite sure how the trigger sends values from its outlets.
es: @4350
Miller: @4365 The trigger object always sends messages to its outlets in right to left order. And it's right to left and not left to right because
es: @4365
@4380 typically you want the left-most thing to arrive last for the object afterward to work right. Yeah, I should have said that. That was a very good question!
es: @4380
OK. Now, that I've done this, @4395 I can go back and remind you of the wonderful midi to frequency <<mtof>> object. Now I have a
es: @4395
@4410 sequencer that I can control using midi numbers. I'm running out of room here, but
es: @4410
@4425 I guess I'll do just as much as I can make room for. We're going to have a seven note sequencer.
es: @4425
Yuck! OK. Got five of them. All right. @4440 Now, the only difference between these is that this one is going to go to cell zero, this is cell 1, this is cell 2, this is cell 3, this is cell 4 -- And let's
es: @4440
@4455 just have a five-note sequencer because I'm getting tired of this. Oops, no -- 5. We'll go once per second and listen to it: [music from patch]
es: @4455
Miller: Whoops. Yeah. So now, that's a good melody that has five @4470 notes in it? [music] Miller: All right. [music] [laughter]
es: @4470
Miller: @4485 All right. Now we're making western, tempered melodies
es: @4485
@4500 in a table. These numbers, now, are the frequencies in Hertz of the pitches which I specified in midi in these number boxes here. ...
es: @4500
@4515 Yeah?
es: @4515
Student: Could you just have midi values in the table and then use mtof to put those into the osc~? Instead of storing the table in frequency, @4530 can you store in midi?
es: @4530
Miller: Oh! Yes. Of course. Oh, yes. OK. You can do that, but notice that I'm reading it <<with tabread~>>: So I would need to use mtof~ @4545 because the output of the table is an audio signal. That would be another way to do it. But, of course, then you're doing the conversion every sample, which is more expensive computationally, whereas, this is cheaper.
es: @4545
@4560 Everyone's restive ... [laughs] I can see why. There was a lot of very dry detail today, for which I apologize. Yeah. Next time we'll get back to samples and tables,
es: @4560
@4575 and storing sounds in tables and using oscillators to get them out.
es: @4575