*** MUS171 #10 02 03 @0000 There's one sonic aspect of sampling that I didn't stop and explain as well as I wanted to explain last time. @0015 So, I want to go back and ... just do it harder. And that is the business about, if you have a looping sampler, there are two regimes in which you can hear the thing: One is where you have @0030 the sampler playing back, either looped or not looped but at least slowly enough that you hear individual starts and stops as events. ... And that would mean perhaps playing fewer than 30 different things a second. So, here the example would be. .. @0045 Whoops, that's not a good example. [audio tone] Miller: So, now you just hear one of the dude's phonemes six times a second. Right? This by the way, is a copy -- annotated and then partly de-annotated -- @0060 of one of the patches that I made last class. And this is up on the Web. And my purpose in making the patch was to show you how to add the "envelope generator shaping" to a phasor. @0075 But now what I want to do is -- continuing to look at the phasor-driven sampler, because it's the more appropriate way to look at this -- to compare again what happens at low and high frequencies of phasor. What happens at low frequencies is kind of @0090 exactly what you would expect, which is ... [audio tone] Miller: You hear stuff at a certain number of times per second, and furthermore ... OK, so what's happening here is this 34 @0105 is the beginning place. Oh, it's in 100s of samples, which means 441 of these make a second. ... @0120 [interruption] ... @0135 Back to normal. All right. So, what's happening is we're looking at this array, and we're looking, starting at whatever 34 corresponds to here. @0150 And then we are sliding forward 78 of them. ( ... Is that me shaking? How is that happening? Student: Maybe it's just an earthquake. Miller: I think we were having a nice little earthquake. @0165 We just invented a new kind of seismograph. Maybe I'm wrong; maybe it's something totally anodyne.) OK. So this 78 is now being multiplied by the phasor, so the phasor is going from 0 @0180 to one, and now we're making the phasor have a range, which, in 100s, anyway, starts at 34 and goes to 34 plus 78. So, this is the amount of sample you hear each time. So that ...[audio tone] Miller: Once you've got the units right, anyway. If this @0195 thing times this thing equals 1, you've got the straight-ahead transposition, that is to say, the original pitch. And what would that be? Actually, let me change the unit so that it's easier to think about. I'm going to make this be units of 441, so that these are hundredths of a second. @0210 And now this'll be something like nine, and this'll be something like 20. [audio tone] Miller: Yeah, there we go. So now what's happening @0225 is this is .17 seconds, because 441 samples is 0.01 seconds at our sample rate. And this .17, that times 6, if you multiply it out @0240 in your head, turns out to be very close to 1. Actually, one-sixth is, as you all know, 0.1666, so we'll do this: And now we'll get the original transposition. This number in hundredths, @0255 that is to say, 0.1666 repeating, times six is 1. And now if I choose some other pair of numbers which also multiplies out to 1, such as make that five and make that 20 hundredths ...[audio tone] Miller: Then I've changed @0270 the speed at which the thing's happening but I haven't changed pitch that you hear, or the transposition that you hear, of the sample. OK. Is it clear why this is working? So, the transposition that you're hearing @0285 is proportional both to this number. [audio tone] ... Miller: ... and also this number. OK. Next thing about that is this: This is @0300 what you hear these numbers are below about 30. That is to say, the number of things you can hear as happening as discrete events. So even if I push this to 20 and drop this to five. .. @0315 Whoops![audio tone] ... And find a good place ... You hear the event as a repeating thing but if I push this past about 30 you won't anymore. I don't know 30. It's iffy. But of course, this is a very particular @0330 spiky part of the sample. If I get somewhere else in the sample. .. [audio tone] Miller: It becomes very hard to hear that as a sequence of things and easy to hear as just a continuum. If I push this higher, then at some point your perception @0345 of this as having a pitch becomes more important than your perception of it as number of times per second. This is just acoustics, if you do anything repeatedly fast enough it becomes a pitch. @0360 For instance, if I want to use this Western-style musically we'd want a MIDI to frequency converter. ... @0375 make another number box ... Then I can say, "Well, play that for me at play it at middle C, please." Which is 261 Hertz and now we've got middle C. [audio tone] Miller: I could check it on the piano @0390 if I cared. Oh yeah, let's go down an octave. That's a little too harsh. Oh. Why does that sound so ugly? @0405 There's something going on here that I don't understand. That should be a smoother sound than that, but we'll go for it for now. If I ever find my mistake I'll tell you. So, at this point, we're playing five milliseconds @0420 of sample at a time. But we're transposing up a quite a bit because we're playing 130 of these per second. So really, this should last something under @0435 one millisecond. Should last about .7 milliseconds, I think. Oh, this will sound better now, maybe. Yeah, there we go. [audio tone] Miller: All right. Then, we have the sample as before: @0450 [audio tone] Miller: Those are timbres taken from the voice. In fact, I could even try to move this continuously, except I'm going to get in trouble. @0465 You'll see. [audio tone] Miller: It's a little ugly because you hear it click every time this thing changes discontinuously. [audio tone] Miller: So, let's go find "soft." OK. @0480 And now, when you heard it coursing over the sample, then you heard the timbres or the vowel and consonants @0495 of the original sample going by. So, right now, you can sort of believe that this thing. [audio tone] Miller: Is the "O, " the short O of soft. Right? That's of course, assuming I'm playing everything at the correct speed. In other words, I've made this and this @0510 multiply to approximately one. I didn't check that it was exactly. Oh, I could. I could! Nah, let's not ... I could take this and divide 1000 by it, and put that there. Actually, that would be a good thing to do because I'm going to have to do it later. @0525 So, to do that, we're going to divide something, but we're not going to divide it by 100. We want to divide 100 by it. And, that's the thing I haven't shown you how to do yet. But, it's not hard. So, what you want to do @0540 is you want to take 100. Control-alt-2. Sorry, 100. We're going to take 100 divided by this, right? Because it's in hundreds of samples. @0555 We're going to take this and put it here. But then, we're going to have to bang the 100. And so, we need our old friend trigger to make the thing get banged at the appropriate time. So now we say, "Trigger, bang, float." @0570 Let's make this be reasonable. OK. And now, I'll show you. Oh,, rather than show it to you, I'm just going to use it. And, you'll see. @0585 So now, I'll say, "48 again, please." And, dada. It computed the exact value, which was 100 divided by this, which is the number of 100ths of a second, which would be the period if this is the frequency. @0600 This would be a good place to stop for questions. Student: Can you explain the abbreviation? <<"t b f">> Miller: Oh. OK. So, this is abbreviation for @0615 "trigger bang float". And, what trigger does is two things. It formats messages for you -- So, there's a floating point message coming in. And, what we want coming out is a bang here to send this 100, @0630 and then actually, before that a floating point number, which is whatever we sent in. So, this divide needs to receive 100 here. And then, it needs to receive this 130.8 here. But, @0645 the divide divides when it receives this number <>. And so, it needs to receive this number <> after it has already gotten that one <> -- so that it will do the division correctly. Sorry, there are two questions. You first? Student: So what's the purpose of the bang? Miller: @0660 Well, the bang is simply to get this 100 to send out, because if this 100 doesn't get sent out, this thing will never divide. Student: So there's a bang and a float? Miller: It sends the float, and @0675 then it sends a bang, which sends this 100. Student: And that's going to be top down, or? Miller: Uh, let's see. This is going to be 100 over this floating point number. @0690 Let me see if I can make this into a more synthetic example. Let's make a copy of this. @0705 So a number comes in, number comes out. And whatever I put in, what comes out should be 100 divided by this number. OK, so how do I do that? The number goes in, and I ask it first to put the @0720 number in -- OK, this is the divider. So what I need to do with the divider is first put five in here <> and then put 100 in there <>, so the thing will do 100 divided by five. All right? Yeah ... lots of questions, let's see, I don't even know @0735 who to ask. OK. Student: So, the float, how do you know it goes in first? Miller: Oh, trigger is defined to put its outputs out in right-to-left order. In general, objects that have multiple outlets @0750 that spit out messages at the same time (another example would be unpack) always do it from right to left order, so that you know what order they're coming into a subsequent box in. @0765 This order doesn't mean that time is passing. All this happens in one instant of time, or to put it a different way, between two audio samples, but the same two. In other words, it happens in a moment that isn't @0780 allocated any time of its own. And yet it has an order, because you have to have this thing go in the correct order, otherwise you could never program. OK. ... Pd is not a programming language, and @0795 this is asking Pd to do a programming language-ish thing, which it can do. But obviously, if you just had BASIC or C or something like that, you could do this particular thing a lot easier. You just say, "100 divided by f, " or whatever it is. @0810 But since we're in a graphical programming language, it's great for doing things like bashing signals around like that. And it's a little clunky for doing things like saying, "100 over f." This is the easiest way I know how to do that. @0825 There are others. Other questions about that? .... Yeah? Student: So, for when you're changing the range for the plus value, so if you wanted to. ... Not put this object value back to this top half. Miller: @0840 This value, OK. Student: Yeah. You just have to unpack or on the line? Or if you wanted not to click? Miller: Wanted not to click. In other words. .. Oh, you mean, if I wanted these things to be their values when the patch shows up? Student: @0855 Yeah, like cycle through that 60 times or so. .. Miller: Oh, I see. Yeah. So right now I haven't done anything to automate that. I've just left it as a number box. But in fact, that could be messages coming in from some other place if I wanted to. @0870 And then I could use the number box to override it, or I could just have it be what it is. But it's easiest, just for the purposes of showing the patch, it's easiest to have everything just be controlled by hand. Yeah? Student: @0885 Now if you put more floats in there? And you put a metronome in there? Can you create a loop to sequence things? Miller: Sure. Well, OK, sure, there would be some work to do, because. .. @0900 If for instance, I had a bunch of numbers in a message, like that. ... If I sent those to this, for instance, @0915 this number would become 1. And then it would become 3 and then it would become 5 and then it would become 7. And 7 would win. If I wanted it to do those things and have it be 1, then 3 at a later moment in time, and then 5 and then 7, which would be more like a sequence. .. @0930 Then the easiest way to do that would be to store those numbers in a table or an array, and then read them out of the array using a metronome. ... Yeah? Student: So, outlets send from right to left, but inside a message box left to right? Miller: Ooh! @0945 Yeah; outlets are right to left. Things inside a message box are left to right or in order that they are as text. Student: Oh. OK. Miller: Yeah, that's confusing, isn't it? It never @0960 occurred to me to think about those two things in the same thought. ... Yeah? Student: Can we depend on everything other than the trigger having regular order from the outlets? Miller: @0975 Well, what you can't do, or what you can't depend on, is this: ... I might have shown you this already. @0990 I can't remember ... I'm going to take this number and just square by multiplying it by itself, and I'll do it that way. This doesn't work because @1005 this multiplier got these two values all right, but it got this value first and that value afterward, and as a result it did the wrong multiply. So, to make that guaranteed @1020 you would put a trigger in to make sure everything happened in the order that you wanted. In other words, you would say .... Oh, I'll keep the wrong one and the right one. You would say ... ... @1035 "trigger float float" . And now we know that @1050 this float will come first <> and this float will come second <>. And then it will do my squaring job right, whereas here it didn't. Student: So not objects other than trigger are right to left though, like unpack? Miller: @1065 Yes. If the outlets are all, what's the right word? Well, an example of something that doesn't do that is "route" because it doesn't ever put something out @1080 more than one outlet as a result of a single message. But things that do put out more than one thing as a result of a single message, such as "trigger" or "unpack" -- or "notein" if you're doing MIDI ... @1095 I don't have a lot of other examples here. ... those are all arranged from right to left. That's simply because right to left is appropriate for inlets because it's best to get things left last. ... Yeah? Student: @1110 Would it be one multiply by a parameter and then add, would you have to make that separation? Miller: Yeah. @1125 It gets ugly. What's a good example of that? Yeah. I have a good example, but it's too complicated and @1140 I'd have to explain it. If you want to do A + (B * C) for instance. OK, so you put B and C into the multiplier and then you have A and you want to put it into an adder. Then you have to decide OK, do I want that number to change every time I change any of A, B, or C or @1155 do I want it to change only when C changes or so on like that? You could want it either way. For instance, if you're playing a MIDI keyboard and you want to transpose, when you change the transposition you don't want it to replay the note. That just means you want @1170 the next note you play to have the new transposition. So, in that case it would be appropriate not to recalculate the pitches of all the notes because you changed the transposition. Maybe. But in other situations, you actually want the output to change when @1185 any of the inputs change so it's always correct according to the last inputs. Those are just two different situations. So, you can get Pd to do it one way or the other. The way to get it always to follow what you do is @1200 to use triggers everywhere that you need to in order to make sure that everybody's leftmost inlet gets whacked last and then everything will stay up to date. That was a little abstract, but we'll hit examples of that I think later on, @1215 I think, in the quarter -- especially if I go back and show you pitch to MIDI conversion in general. Any other questions? That was useful because @1230 I think there were a bunch of things I wasn't saying that I should have been saying which that helped clear up. OK. ... @1245 So, now what we have is I've got this number here and I'm computing 100 divided by it to put here. So now, I can do this kind of thing. [audio tone] Miller: It's not @1260 perfectly smooth, but it's now figuring out what I have to put here to put timbre. In order to get the sample to play back at the recorded speed, regardless of how many times per second I'm asking it to play back. @1275 So, the faster I ask it to play back, the less of it I can play back each time if I'm trying to constrain the speed. Now the other thing to mention about this is that ...[audio tone] Miller: @1290 Now we've got a nice pitch and now we could just go and change this segment size without changing the number of times per second and then we get this kind of thing. @1305 Notice there are clicks in the sound. That's because when I change this discontinuously or when I change this according to the mouse it changes the thing I'm multiplying the phasor by, so it causes the read into the table here to move discontinuously, which is a click. @1320 So if I want to do this correctly I'd have to use a line object to de-click this. Nonetheless, I now have my first nice timbre whammy-bar that you can use to make wonderful computer music. Right. In other words, this is the first example, @1335 (except for that attempt that I made to explain FM, which I shouldn't have ever done ...) This is the first example of a situation where you can change a control and it will actually make an audible change to the timbre of the sound. Which, of course, is what computer music was supposed to be about back in the day. @1350 There will be many more examples of this, because eventually you will be able to make filters and frequency modulation -- once I get that straightened out -- and other things like that. Right now, the reason this is happening, I can actually show you using this table. @1365 So, just for emphasis sake. .. [audio tone] Miller: If we go down to a frequency where you can actually hear the things then what @1380 I'm doing is actually changing the size of the sample we're playing, which is changing the transposition. But then if you make that happen at an audible rate then @1395 we're changing the transposition again, but it doesn't change the pitch that you hear. [audio tone] Miller: ... Because the pitch that you hear is now no longer the pitch of the original sample. But it is the new pitch from just being imposed on it by the fact that I'm reading it at a fast rate. @1410 And that is in fact a continuum. [audio tone] Miller: So for instance you can say ...[tones] @1425 And now I have a continuous way of moving back and forth between pitchy sounds and sampled sounds. [audio tone] Miller: And that a lot of people heard for the first time when @1440 Fatboy Slim did that song "The Rockafeller Skank" -- That was this. Miller: OK, questions about that? Student: Was he actually using Pd? Miller: No. [audience laughter] Miller: @1455 But he wasn't using Supercollider either -- He was using commercial stuff. All right. [audio tone] Miller: @1470 So now, this, which becomes a transposition when we do it slow, is a timbre-change when you do it fast. [audio tone] Miller: @1485 And another way of seeing that is to take this thing and graph it. Which is what I now propose to do by using these graphs over here. So I'm going to keep the phasor and instead of graphing the envelope, which is what this graph is here to do earlier ... I just want to graph the output of @1500 the tabread~ object. Oh yuck! --- Oh, I see. I've got this thing so high that the graphing doesn't look good. So let's change the properties here. @1515 I had 44 -- that's a tenth of a second. I'm going to need like a 50th of a second. So let's make this a thousand. <<"Size" in the Array Properties of Array "scope">> That's actually @1530 a 44.1th of a second. And let's see. Will this work? Still looks, oh whoops! I didn't do that quite right, I need to change this too <<"X range in the Canvas Properties>>. ... @1545 Oh, and this! <<"Size" in the Array Properties of Array "scope2">> Sorry -- I've got two arrays in there <<"scope""scope2">> which is why I got confused. So OK now what we see is there's a nice phasor and it's going at 48 times a second. @1560 And each time it goes you see the same waveform, which is in fact the waveform which is stolen from the original recording. And now if I ask it to graph again, you'll see that it's in a different place, because I don't know @1575 how to make the graph start right when the thing wraps around. ... That's for later ... But you can see that it's the same waveform. Now if I say, "OK, do that but make this number larger. In other words, make there be more of the sample." Actually, let's have there be less of the sample first. @1590 I'll drop it to one. Then when I graph it, you'll see that there was just less waveform stuffed into there. ... Is this clear? @1605 Now you can do wonderful things because, what would happen if you just stuck a sinusoid in here? Actually, that would be a useful thing to be able to do, so let's do it. So now what we're going to do is we're going to say, "tabwrite~" @1620 and I give the name of the thing, Table "t2.03a" ... Now I'm just going take a nice sinusoid, @1635 maybe 110 Hertz, so it won't be too different from the sound of the dude's voice. And I don't want it to be quite that loud because I don't have a good volume control, @1650 so I'm going to protect us by multiplying this by some smallish number. And now we need a button to make this thing happen. @1665 Wait two seconds ... And sinusoid! -- although you can't really see it as such. And now here: <> Sinusoid! Except, of course, the sinusoid has a discontinuity every time we restart the sample. @1680 And now the bigger a chunk I read hear of the sample, the more cycles of the sinusoid have to slap into the same amount of time. If you can imagine what that sounds like, @1695 it's got this period, so the pitch of it isn't changing, but you can tell by looking at it that it's got a lot of stuff at this frequency and maybe not a whole lot of stuff at fundamental. So now if we listen to it. .. [audio tone] Miller: @1710 We've made ourselves a nice little formant. ... Is that clear? Student:@1725 Are those pops because of that repeating ... ? Miller: Yeah, the pops happen whenever I change this. @1740 And what that does is that changes the amount I'm multiplying this phasor by. If I happened to do that right when the phasor was at 0, it wouldn't make a discontinuous change. Student: So you're re-ranging? Miller: As it is, it gets up to a half or something like that, @1755 and then suddenly it re-ranges, and that pushes it off to a different value. I'll show you things about that later ... after I've stuffed all these more fundamental ideas into your heads. @1770 The object you want is "sample and hold" because you want to sample this number only when the phasor changes value. @1785 But, of course, the thing that I had originally was not a sinusoid, it was the man's voice. Then you get @1800 this look and this sound: [audio tone] Miller: And, of course, different @1815 parts of the sound file different things, but they all have the same basic behavior. All right. ... So that is basically @1830 a thing about sampling that everyone can use. ... Questions about this before I go on to other things? What I want to do now is go back to polyphony and voice management, which I started talking about last time, but @1845 about which there is much more to say. Yeah. Everyone's tired of this topic anyway. ... Yeah? Student: Are you going to put these patches online? Miller: Oh Sure. Yeah, this one is going to be patch ... I have to change the order@1860 of these because I didn't plan very well .. But all the patches up until last time are up on the web. It takes me a day or two, but I eventually get around to putting good comments on that actually mean something, when I'm putting them up. @1875 Yeah -- this is a good trick. OK. So now I have several matters to go over. First off, @1890 here's the example of a multiple-voice sampler: [audio tone] That was the thing I showed you guys last time. Right? The basic deal was, the new objects you needed were ... @1905 First off, just the notion of having a so-called abstraction. That's to say, being able to put a Pd patch inside a box, which would, in fact, be a sub-window. And "route", @1920 which is this object, which takes a message in with any number of numbers and looks at the first numbers and, depending on what it is, puts it out one of the several outputs. Since there are eight arguments here there's nine outputs because there's one for @1935 if it didn't match anything. (That way you can gang several route objects together.) Although here I happen to know that this number will always be 0 to seven because I have this "mod 8" here. @1950 This is an example of polyphonic voice allocation and there are other examples of things that you can do with polyphonic voice allocation -- which I will actually show you by taking you through some pre-existing patches. @1965 -- a slight departure from the custom. So, this right now is just a copy of what there was last time. The first thing I want to mention before I go ripping through the pre-existing examples @1980 is a thing about abstractions I haven't told you about, which is this: Here's another abstraction. Get in edit mode ... You can do something like. .. @1995 Well, I have an abstraction, which I moved into this directory beforehand, called "output~". This is interesting because it's not just an abstraction that has a patch inside it, @2010 but it also has controls, which it printed on its "faceplate", if you like. So, this is a technique for being able to make things like modular synthesizers give you -- which are modules with audio inputs and outputs, but which also have controls like knobs. @2025 So, I'm just going to tell you now that this thing exists and how you can deal with it. First off, it's just an object like any other, so I can retype this and it would become some other kind of object. But this is a particular @2040 kind of abstraction, which does this for us. If you want to see inside it, it is not good enough to click on it because clicking on it means doing that kind of thing<>. @2055 Oh yeah, by the way, this is an output level in decibels and you would use this if you wanted to have a patch whose output level you could control on the fly, which is a good thing to be able to do. @2070 The other thing about this is, of course you might want to be able to see what's inside it, but clicking on it doesn't do that because clicking on it does that kind of stuff. So instead, you control click or right click depending on what kind of mouse you have @2085 and say "Open." Then you will see the contents of the thing as an abstraction. Then it's nothing much more than what you've seen already except there are some tricks here that I haven't told you about yet @2100 which I hope to tell you about today. Then closing it's the same as it always is. You just close it. All right. This has a name. It's called a "graph on parent" abstraction -- the reason being that @2115 it shows a certain portion of its GUI objects, its controls, on its own surface as an object. You can learn how to make these and so on. @2130 Well, OK ... You would say... "Properties" . <> Notice here it says "Graph-On-Parent"? You have to click that and then that turns your abstraction into one of these things, but then there are things you might want to set that I have to explain in detail later. @2145 I'm telling you that because I'm going to take you through some patches that are going to use this and I want you to know about this thing's existence. If you want to use this you have to get this thing and copy it into your own directory. I'll throw it up on the website, but it is also on all of your computers because it's @2160 actually in Pd, in the help patches. And that is in fact, where we're heading next. I've been studiously avoiding the help patches because I've been building everything from scratch, but by the time we're getting into voice-banking stuff, @2175 some of the examples maybe are better just looked at and described than they are built up from scratch, because ... ... you have to do several things at once and get them all working together. So, I'm just going to close this and open @2190 some other patches that do other things. ... So, in Pd, if you say, "Help, " one of the things you can get is this:"Browser". And the browser has @2205 far too much stuff in it, but if you go looking for "Pure Data" ... -- Oh, by the way, if you have Pd Extended this really has a lot of stuff. Right now it merely has a bunch of useless stuff. "Pure Data" .."audio examples/" -- Oh right, there's a manual. This has a bunch of @2220 HTML stuff, which is very telegraphic and, what's the right word? "Short". "control examples" -- later."audio examples" -- which are examples about @2235 how to do synthesis, processing, and analysis of sounds. -- These examples correspond to the textbook, which I haven't been referring to very religiously, but we're now somewhere in chapter four of the textbook, talking about voice allocation. @2250 The A's are all chapter one, the B's chapter 2 and so on like that. And so, all of this stuff, if you want to see more description of what it's about and how it works and why, look in the book in chapter four @2265 and the book actually talks about all of these patches in some detail. The things I wanted to show you were, for instance. ..."additive synthesis". <> @2280 Here's the reason I showed you output is because we're now going to be starting to use output to set the. ... [bell tone] Miller: Volumes of things. Notice these values are in decibels, which means 100 is full-blast and 75 is likely to be quiet. [bell tones] Miller: @2295 So typically I put these close to 100. [bell tones] Miller: This means nothing to people who weren't in the computer-music scene in the sixties and seventies, and then it means a lot because this is one of the classical @2310 computer-music designs done by Jean-Claude Risset at Bell Laboratories in Murray Hill back in the day when people were first doing things with computers. And what it is. .. let's see if I can make it sound better. [bell tones] Miller: @2325 It's called a Risset Bell. And it's just Jean-Claude Risset having found some parameters somewhere that make a nice. .. [bell tones] Miller: ...bell sound, that can do that kind of stuff, or this kind of stuff, [bell tones] Miller: @2340 Or of course, this kind of stuff. [bell tones] Miller: Actually, better yet. .. [bell tones] Miller: Ta-da. It's not rocket science. @2355 What it is .. the old term for this was "additive synthesis." It's a synthesis technique that you all know because all you do is add up oscillators. And the oscillators in the examples @2370 I've shown you have all been tuned to multiples of a fundamental frequency so that they all fuse into a harmonic sound. In this case it's additive synthesis in the sense that it's a bunch of sinusoidal oscillators being added together, but the oscillators are imitating the modes of vibration @2385 of a bell. Although, I don't know if this corresponds to a real bell. ...[bell tones] Miller: ...or something fanciful. [bell tones] Miller: And, the controls that you get are going to correspond exactly @2400 to the controls you saw in the sampler example last time, which is, you get to control pitch and duration. Differences between this and the previous example -- There are going to be a couple of differences when you get into the voices, but @2415 there's a huge conceptual difference: Which is that this isn't a polyphonic instrument. It only plays one note. But there's still voices, adding up @2430 to that one note. And the voices are, instead of making different notes, making different partials which added up into a single note. It's polyphony in one way of thinking, because it's realized like a @2445 polyphonic instrument. But psychologically, it's monophonic. So it's showing the use of voicing and abstractions, in a non voice-allocating way. A key difference between this and the previous example is @2460 there's no route object. In the previous example, you decided every time you asked to play a note, which of the voices was going to play it. Here, all the voices play every single note. ... Yeah? Student: And those voices are the partial voices? Miller: Yes, right. So now I have to show you @2475 what's in there. Student: So do we'll look inside the patch? Miller: Yeah. Next thing is, notice that I'm feeding the thing arguments. I'll tell you what the arguments mean in a moment when I show you what's inside it. But @2490 when you have an abstraction -- which is to say an object which is a separate patch being written into a window -- Usually, not quite always, but in most situations -- You're going to want to throw in arguments to specialize it to do one thing @2505 or another. For instance in this case, each of these partials has to know which partial it is, so they don't all decide to play the first partial together. They each have to play different partials. So each one of them has to know which partial it is. @2520 And to do that, you have to pass each one arguments that disambiguate them. That tell them how they are going to be specialized. All right? Other huge difference @2535 and a small related difference to the huge difference: There aren't wires going into these things and inlets. So the mechanism for getting messages inside here is not inlets, it's "send" and "receive". ... For the simple reason that, @2550 and here's the small conceptual difference, frequency and duration and trigger are being sent separately in this design. I thought, at the time, this was actually a simplifying this, although I don't know now whether I think it's more simple or more complicated. @2565 So in this particular design you give it any pitch and any duration you want and then you say, "OK go ahead" and then it does it for you. You could now take a packed pair @2580 of "pitch and duration" and make it act like the previous one if you used an unpack and a trigger in order to send messages in the right order to duration and frequency and trigger. @2595 So, what's going to happen inside here is each one of these things is going to have a receive frequency and a receive duration, which will tell it the global frequency and duration of the tone, and then it's going to have another receive for trigger, which will set the thing off. @2610 Now, just to hearken back to Music 170 for a moment: This is imitating how a bell actually vibrates. @2625 One way, maybe the best way, of thinking how a metallic object would vibrate is you strike it and in striking it you activate the modes of vibration the thing has. Those are functions of the shape and construction of the object itself, @2640 not of how you whacked it. They don't move. But the modes each have a frequency and a time constant. The frequency is how fast the mode vibrates and the time constant is how fast it's damped: whether it vibrates forever, @2655 which it would do if it had no damping at all, or whether it dies out very, very quickly. So what's happening here is we're pretending there's a metal object that has 11 modes in it, each of which has a @2670 different frequency and a different damping. But then there are global frequency and duration (which is damping), controls that are multiplied by each one's individual frequency and damping factor. @2685 Now, to go look inside "partial", which I've been putting off: Here's how you do a partial. This is being done in gory detail in the most @2700 carefully explained, boring, pedagogical possible way. Let's see. I can do this. @2715 I haven't told you this and probably shouldn't tell you this now, but @2730 line~ generates line segments and if you want a line segment to feel like an exponential just raise it to the fourth power. Then instead of going down like this in time <> it goes down like this in time <>. @2745 Then it's not exactly an exponential, but it's pretty good. What that means exactly is explained in chapter 4 <> of the book, so you can look it up if you don't believe me. But the signal processing aspect of this is being done here. @2760 What you see is an oscillator and a line~. I'm raising the line~ to the fourth power so it will go down more @2775 exponentially than just a line segment would. Then I'm multiplying it by the oscillator then I'm introducing a new object, "throw~", which I'll not dwell on right now. @2790 I didn't even tell you about send~ ... This is a way of avoiding having an outlet by asking a Pd to set up a "summing bus." In other words, what's happening is somewhere there's a "catch~ sum", @2805 which is automatically going to get the sum of all these signals. It's a good thing, but it's not a thing that you absolutely need to know right now, so I'm going to not dwell on it but just sort of say that's what's happening. This is like dac~. @2820 In fact, it could be dac~ except that I wanted to be able to use the "output" thing I showed you earlier. So, instead of just putting the dac right here I put a "throw~" and it all collects in this "catch~" and then it goes to this output object @2835 where I'm controlling the amplitude for output. All right. Student: Can you play them all at the same time? Miller: Actually, it's so I can control the volumes of them all in parallel. ... @2850 this is controlling globally @2865 the amplitude of the thing by virtue of the fact that each one of these partials, using the "throw~" object, has added itself at full strength to this "catch~", which then is going to be sent @2880 to the "output~" which will control its amplitude. So that's controlling all the amplitudes in parallel. Yeah? Student: So it's like a send and receive for multiple things going to the send box? Miller: Right. So send and receive work for messages. There's a send~ and a receive~ for signals, but in audio signal land @2895 the situation's a little bit more complicated. Because it would not be clear what to do if you had a bunch of sends and a bunch of receives. In message land, you just send all the sends to all the receives. Student: So like a patch bay? Miller: Yeah. It is exactly like the patch bay. So here what's happening is @2910 all of the throws are throwing to the single catch. There's a fan-in thing, which is a summing bus, which is done by throw~ and catch~. And there's also a fan-out mechanism, which is accomplished by send~ and receive~, which I haven't shown you. ... Yeah. Student: So you can sequence them as well, going into the catch? Miller: @2925 No. It's like cables. So they're happening in parallel. Miller: Right. So sequence. .. yeah. Only messages can be sequenced. Signals can't really be sequenced; they're all happening all the time -- @2940 which is one of the good reasons to have messages around. OK. Now the partial, is showing off ... @2955 the arguments to this partial were these numbers:" 1, 1, 0.56, and 0". Those numbers are @2970 what showed up here. ... ... Oh, there. So these numbers 1, 1, 0.56, 0, @2985 which are customizing this particular partial, are displayed here. <> And they are expanded by $1. Where did $1 go? Here. .. No, sorry. That was wrong. @3000 I don't see $1 yet ... Here! In object boxes if you put a"$" sign, it is the argument you got called with as an abstraction. And here there @3015 is one of the half dozen truly hard to understand things about Pd. Because dollar signs are also available inside message boxes, except that they have a different function @3030 inside message boxes than they do inside objects. This is all for a good reason because conceptually it is all very simple, even though it looks completely arbitrary and stupid. @3045 So, what I want to do is show you ... Just to help confuse you now, I'm going to show you message boxes with dollar signs inside. So, "1 2 3" -- We all know what this will do. Let's see I'll put a number in. @3060 And I'll print it out. And then, no matter what I put in, the print out says, "Hi, I was 1, 2, and 3." All right. You can't even @3075 see that this was getting repeated. Oh, I'll hit alt again. Alt, alt, alt. OK. Now suppose I want these numbers to vary as a function of this <>. I can say, for instance $1. << 1 $1 3 >>. @3090 And $1 means, give me the value that was the number that came in this message box. I haven't shown you this because it was possible to do this already with pack. So, @3105 the easy way of getting this effect -- I had to do it once before when I had to do it in order to make triples of those numbers that went to the voices of the polyphonic sampler, two days ago. Right? So this is another @3120 function of dollar signs. You can put a dollar sign inside a message and it will insert the number that you put in, as part of the message. And the 1 here, the $1, is which of these numbers it is. If for instance, @3135 I gave it a packed message ... Let's see this example. Now $1 is 45. @3150 That and $2 is 78. Those of you who have programmed shell scripts in either Macintosh-land or Linux, this is @3165 exactly the same argument expansion that holds in Shell scripts. Also, I think perl may look this way, I'm not sure about that. The computer scientists have a name for this type of expansion, but I forget what it is. ... Yeah? Student: Can you add another inlet to the message box? Miller: @3180 No. You could in Max, but here you actually have to use a pack object. ... So for instance, here's another perfectly good way @3195 to make a message that has a bunch of variables in it. And now actually, at this point, I could now do this. And now I could set $2 @3210 this way, and $1 this way. OK. Since you have already seen pack this is not something that you need. You will need it later perhaps, because @3225 certain things like. .. Oh right -- tables: If you want to tell a table what size it is, you say "resize" and then you give it a number. If you want that number to be a variable, then you have to say "re-size $1" inside a message box. That's the only way to generate that kind of message. @3240 So this is a more general facility than pack. And as a result, it runs a little slower than pack too, so it's not necessarily the right way to do things in every case. Now I told you that because I'm trying to confuse so that you will later on be enlightened. @3255 The confusing thing is this. If you put $1 inside a message box, or"$anything" inside a message box, it means the incoming message that's making me now send the message, right? Because message boxes take messages in @3270 and then send messages out. Object boxes, what you put in an object box, is a message. It's a message whereby Pd makes the object and that message can have dollar-sign arguments in it, too, but those dollar sign arguments @3285 are the arguments to the patch because the patch is running the message to make the object. ... Yeah? Student: Can you send object names that are variables inside? Create? Miller: @3300 Yeah, if you really want to. For instance, "apply + 5", @3315 if you're a list person. Well, let's make a nice thing called "apply". -- You don't want to do this. -- Apply is now going to say, @3330 " $1, $2" ." Oh, come on, let me type in there. All right. Then I'll make an inlet and an outlet just for fun. @3345 Pd hates me for doing this. It has no idea what $1 means in an object box like this. But now if I retype this I now have a nice little "plus five" thing. @3360 OK, Go find a use for that ... Oh, does it actually work? I don't think I've done this in a decade, so. @3375 It works. Yeah, don't do it. It's stupid. ... Oh yeah, dollar signs can either be numbers or they can be symbols. "Symbols", which means strings, things that aren't numbers like file names @3390 or names of objects like "+". Those are different kinds of data. For the most part I've only been using numbers except in the very rare occasions where I've had to specify a file name, like voice.wav. @3405 I'm doing that on purpose. I'm trying not to get any deeper into the soup of language complexity than one absolutely has to, to do computer music. So this is message boxes @3420 and that apply example, was object boxes, but it was object boxes in such an abstruse example that I don't want to talk about anymore. Oh, almost saving there, which is bad. Don't want to put it there. @3435 Let's just not save this. This is better explained somewhere else probably. That was all to say this ... Next it's time to say, @3450 "What do these things mean?" This thing, this thing, that thing, and that thing. Well, this is a relative amplitude. This is a relative duration, @3465 this is a relative frequency, and this is a de-tune, which is to say a frequency offset, a frequency that's added to it. So we're talking about individual sinusoids, which are imitating individual modes at the sound of the bell. @3480 So each mode might have a different amplitude. That's actually not acoustically correct because the amplitude would depend on how you struck the thing, but we're just pretending now. So each one is given its own amplitude, its own @3495 time constant, its own damping, which, in this example, just because Risset did it this way, is realized simply by changing the overall duration of the amount of time it rings. The correct thing to do, acoustically, would be to have it be @3510 a dying exponential and to have it go on forever, but that's not practical, so we just give each partial a duration. So ... first argument is amplitude, second argument is duration, third argument is frequency. @3525 Now I have to tell you something else. All these things, well not all these things, but the duration and the frequency are also controlled globally by the controls in the outer patch, which was here. Miller: @3540 So there's a pitch and a duration. Those are things, which once they've gotten to the right units, will have to be multiplied by the relative frequencies @3555 in order to figure out the real frequency to give the partial. So this partial, which has a relative frequency of 0.56, what that really means is that it's 0.56 times the @3570 global frequency that I asked the bell to be. So that when I change this frequency the frequencies of all the partials change in parallel. [audio tone] Miller: @3585 So how do we do that? What that means is we're going to have to take this thing which is being sent and multiply it by this number and that will become the frequency that we send the oscillator. Except I didn't tell you another thing. @3600 You get a de-tune in here, which is after you multiply this factor by the global frequency then add an offset so that the partials can be paired @3615 in beating combinations. This is all just history. You can read this in books like the book by Charles Dodge. <> Here are 2 partials @3630 that have the same relative frequency, but one of them has an offset of nothing and the other has an offset of 1 Hertz. So, after they compute their base frequencies, this one adds 1 Hertz to itself so that it will beat with this one once per second, according to another principle @3645 you saw in Music 170. So how do you do that? What that means is that the oscillator that's inside here will get a frequency, in fact, which is 0.56 times @3660 this frequency plus this offset. So is that true? So, here we are: Every time we get a trigger we re-compute the frequency. Oh, by the way, the thing is designed @3675 so that you hit the trigger and then you can start mousing away at the frequency -- And it doesn't change the frequency of the bell while it's ringing. Which, you know, is one possible way you could design the instrument. It's the way the original instrument worked, so maybe it's a good way for us to do it. OK, so @3690 this is $1, this is $2, this is $3, and this is $4. Those are the arguments that we've got as a sub-object, as an abstraction. So $3 is a. .. @3705 $3 will come out. .. OK, this, we're just going to store $3, and then when this thing gives us a bang, we will read $3. Oh, this is one voice that I'm triggering now, not the whole bell. [audio tone] Miller: @3720 And $3 will come out here, it's 0.56, and it's going to get multiplied by a value, which is "receive frequency", <> which got sent from the main patch. And then we're going to add $4, which is 0, which is the de-tuning. @3735 And that is the frequency for the oscillator. And all that stuff got done as messages, you can see the thin traces, and then the oscillator then is the first thing in this chain that makes an audio signal. @3750 That's the easy part. Well, it's the easy part -- it does have two variables controlling it as opposed to one, but it's easy in the sense that now you just feed it as the frequency of the oscillator. The amplitude control, @3765 as you know, things have to get turned on and then turned off, and so the amplitude control has more pussy-footing around setting the amplitude. So I'll show you that next. That's this: ... So the amplitude is @3780 being controlled by line~. Now, the amplitude ... There are two things that are being told us that are relevant to the amplitude: One is the first argument of the abstraction, this one here, is the relative amplitude of this voice. @3795 And the other is the length of time, the relative duration of the voice, because to know how to do an envelope generator you're going to have to know how high to make it, which is the amplitude that you're going to reach, and then you have to know how long to make it. @3810 Here's the line~ that's going to do it, and by the way, I raised the line~ to the fourth power, I didn't say how -- But if you take a signal and square it, @3825 then you get the signal to the second power. And then if you take that thing and square it, then you get the signal to the fourth power. And why fourth power, not squared? Just so the thing will really hug 0 and go up like that, because that resembles more @3840 the exponential curve that this thing would really be doing in real life. It's just hand-waving. There is no deep psycho-acoustical truth to this that I know of. OK. So what we have to do is configure or confect @3855 two messages to line~. This is a little bit like what we had to do for the sampler, except in the opposite order. You have to turn it on and then we have to turn it off. In the sampler actually, we had to do three things. We had to mute and then turn it on, and then turn it off. So this is simpler than the sampler in terms of @3870 the sequence of the operations that has to take place. OK. So the attack portion over here is: Look up $1 which is our amplitude. -- The attack portion is just going to go up to the amplitude and do it in five milliseconds, come what may. @3885 Why five milliseconds? It's a fast attack but it's not quite a clipped attack. ... Yeah? Student: What is happening to the dollar sign going in there? Miller: The dollar sign? OK. So the dollar sign tells the float to substitute one of these arguments @3900 to the abstraction. Student: I mean it's in there trying to get a number? Miller: Yeah. So $1 gets this one, $2 gets that one, $3 gets that one and so on. Student: It's a "positional argument." Miller: It's a "positional argument." That's the correct word for it. Student: @3915 OK. A positional parameter? Miller: A "positional parameter" ? I'm not sure. OK. So this one, when it's built -- this is going to be float 1. And when it gets a bang, out is going to come the number 1. @3930 So this is just going to be 1. We're going to multiply by 0.1 to save our ears. Everything is going to get multiplied by 0.1 in parallel. And then because we are going to raise this to the fourth power ... ... We should probably take the fourth @3945 root of this, so when it gets raised by the fourth power, it's the right number. So to take a fourth root, you take a square root twice. And then here, I didn't have to do this; I should have done this. I think in the current context anyway @3960 "pack 0 5", which would then take this value and would replace 0 with it and then pack a 5 which would be the number of milliseconds the line would ramp to that value in. But instead, @3975 because I had just spent pages in the book describing this $1 madness, at this point it seemed appropriate to put dollar signs in messages. And so this is, "Make a message whose value is this number @3990 and then 5." And here it is again -- the distinction between objects and messages and dollar signs: Dollar sign inside an object means "in the context of when the patch is created, you have to build this thing." And so the dollar sign is evaluated @4005 when the patch is created. And it's created with these arguments. Dollar sign here <> is in the context of the message that it is sent, which is the thing which causes to send a message itself. @4020 So this is in the "run-time context" if you like, and this is in the "build-time context", or something like that. ... Yeah. Student: Why do you need @4035 the trigger there when one of the bang has gone through? Miller: You don't. The only reason that trigger's there is to make this thing a little prettier. Oh, it's psychological. It's to group these two things. @4050 But, in fact, it has no function because you're quite right, this delay would ensure this thing happens after this thing anyway. OK. If only this existed and not that then @4065 you would get this: [audio tone] Miller: The attack shape of the envelope and no decay shape. [audio tone] I'm going to do this to make it shut up. ... Miller: As it is, you do that and then you decay @4080 and decaying is actually easier than attacking. It is ... We wait five milliseconds because the attack took five milliseconds. We wait for the line~ to get up to its apex and then we start the decay portion of the envelope, @4095 which is: Look up the duration. -- OK, so the attack is five milliseconds regardless of the duration. -- The decay, now, we know what the target is, it's going to go down to 0 so it'll shut up. But what we don't @4110 know yet is how long it's going to take in order to get there. That, we have to now compute. So we're going to make a message again, but whereas the message in this case had a constant time but a variable amount that it went up. @4125 In this case it has a constant that it goes down to, which is 0, but a variable amount of time to do it in. How do you compute that? Well, after five milliseconds when it's time to start doing this, @4140 pick up the value $2, which is this value. (It's 1 here, but it will be different numbers for the different partials.) Multiply it by the global duration. That was sent to us @4155 there. Student: Was it 800? Miller: Yeah, it's 800. So this duration is 800. But this is now 1, so this is going to be 1 times 800, which is 800 again, so this will be the message 0 800. @4170 So that means this thing should last eight tenths of a second. [audio tone] Hard to tell because it dies out inaudibly. Now if I get another one out, @4185 this one, this one will be higher and lower. [audio tones] There's a longish one. Here's a short-ish one with a higher pitch and a shorter decay. [audio tone] That's because @4200 here, the arguments are ... we're louder. We're a relative loudness of 1.46, relative duration only a quarter as long. @4215 So this thing lasts 1 quarter as long as the other one did. Then the frequency is 2 as opposed to this frequency, which was 0.56, so it's almost two octaves up. .... Student: @4230 Decays can multiply by the total duration message, I'm still confused about that $1. I understand that $2, that's the parameter, but partials, the second one, what's coming out of that? Miller: @4245 So what goes in here is $2. $2 here is 0.25, so it's going to multiply 0.25 by 800, which is duration, so it will get @4260 200 here. So this will become the message 0 200. Student: And the other one is computed? Miller: The other one here. ... I don't know what the amplitude is, but it would be that number 5. So this @4275 is 0 200 and blah 5 -- something 5. All right. So if you hear all these things together. [audio tone] ... Miller: @4290 You get beautiful computer music. [audio tone] Miller: There's some psycho-acoustics there, too. @4305 You can pick this up; this was in the help browser, @4320 "D07.additive.pd" This is the first example in the Pd examples, I think, of something that does multiple voices and there are two others of note here that I want to show you, that I will get to next time. @4335 Oh, homework. The homework is just what you've heard done. Do I have the patch that does it? I can't remember. ...a @4350 @4365 Missed it ... Close that. This is wrong. [audio tone] @4380 Oh, there it is: [audio tone] Miller: Isn't that its own antithesis? [audio tone] Miller: So you all know how to do this because it's nothing but a looping sampler, @4395 you're just going to have to figure out how to get it the appropriate original pitch, but last a lot longer than it would have lasted. And envelope it so it doesn't sound buzzy. @4410 So, it's a straightforward application of what I've been showing you the past couple of days.