Excerpt from Designing Sound Practical synthetic sound design for film, games and interactive media using dataflow Andy Farnell ASP Applied Scientific Press Ltd.
c 2006, 2008 Andrew James Farnell. All rights reserved Published by Applied Scientific Press, London, England. Printed in England. The right of Andrew James Farnell to be identified as the author of this work is asserted in accordance with the Copyright, Designs and Patents Act 1988. Notes to abridged version This excerpt may be freely copied and distributed solely for purposes of teaching and promotion of the full textbook, provided this notice is not removed.
iii Contents 1 2 Introduction . . . . . . . . Starting with Pure Data . . . . 2.1 Pure Data . . . . . . . . . . . . Installing and running Pure Data Testing Pure Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 How does Pure Data work? . Objects . . . . . . . . . . . . . . Connections . . . . . . . . . . . Data . . . . . . . . . . . . . . .
Pointers . . . . . . . . . . . . . Tables, arrays and graphs . . . 2.4 Getting help with Pure Data Exercise 1 . . . . . . . . . . . . Exercise 2 . . . . . . . . . . . . Exercise 3 . . . . . . . . . . . . 3 Using Pure Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Arithmetic example . . . . . . . . Comparative objects . . . . . . . Boolean logical objects . . . . . . 3.7 Common idioms . . . . . . . . Constrained counting . . . . . . . Accumulator . . . . . . . . . . . . Rounding . . . . . . . . . . . . . Scaling . . . . . . . . . . . . . . . Looping with until . . . . . . . . Message complement and inverse Random selection . . . . . . . . . Weighted random selection . . . . Delay cascade . . . . . . . . . . . Last float and averages . . . . . .
5.5 5.6 6 6.1 Defaults and states . . . . . . . . . . . . . . . . . . . . . . . . . . . Common abstraction Graph On Parent . . . Using list inputs . . . . Summation chains . . . Routed inputs . . . . . Shaping sound . . . . techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Amplitude dependent signal Simple signal arithmetic . . . Limits . . . . . . . . . . . . . Wave shaping . . . . . . . . . Squaring and roots . . . . . . Curved envelopes . . . . . . . . . . . .
Loop player . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 7.3 Events and sequencing Timebase . . . . . . . . . Select sequencer . . . . . Partitioning time . . . . Dividing time . . . . . . Event synchronised LFO List sequencer . . . . . . Textfile control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1 CHAPTER 1 Introduction to PDF Pure Data guide This is a an excerpt from the textbook “Designing Sound”. Several years ago when I discovered the amazing Pure Data software I instantly knew it would be the vehicle for a book I was planning about sound design. Synthesis and advanced processing opens up a world of possibilities, limited only by imagination.
2 Introduction design more generally would diverge. At that point I decided my repayment to the community would be in the form of a subset of the book that worked as a basic Pure Data manual. For those not able to afford a textbook, and for those not needing the entire treatment of sound design for interactive applications, I hope this abridged PDF will be a useful introduction for Pure Data users. The remainder of this introduction remains as is, from the first edition of the published textbook.
3 later in a flexible way. A practical, systematic approach to procedural audio is taught by example and supplemented with background knowledge to give a firm context. From here the technically inclined artist will be able to build their own sound objects for use in interactive applications and other projects. Although it is not intended to be a manual for Pure Data, a sufficient introduction to patching is provided to enable the reader to complete the exercises.
4 Introduction to learn. Although Pure Data is the main vehicle for teaching this subject an attempt is made to discuss the principles in an application agnostic way. Some of the content is readable and informative without the need for other resources, but to make the best use of it you should work alongside a computer set up as an audio workstation and complete the practical examples.
5 CHAPTER 2 Starting with Pure Data SECTION 2.1 Pure Data Pure Data is a visual signal programming language which makes it easy to construct programs to operate on signals. We are going to use it extensively in this textbook as a tool for sound design. The program is in active development and improving all the time. It is a free alternative to Max/MSP TM that many see as an improvement. The primary application of Pure Data is processing sound, which is what it was designed for.
6 Starting with Pure Data deallocation of deleted objects and manages the execution graph of a multi-rate DSP object interpreter and scheduler. Installing and running Pure Data Grab the latest version for your computer platform by searching the internet for it. There are versions available for Mac, Windows and Linux systems.
2.2 How does Pure Data work? 7 fig 2.2: Test signal Linux or jack-pilot on MacOSX. Sample rate is automatically taken from the soundcard. fig 2.3: Audio settings pane. SECTION 2.2 How does Pure Data work? Pure Data uses a kind of programming called dataflow, because the data flows along connections and through objects which process it. The output of one process feeds into the input of another and there may be many steps in the flow.
8 Starting with Pure Data Objects Here is a box . A musical box, wound up and ready to play. We call these boxes objects. Stuff goes in, stuff comes out. For it to pass into, or out of them, objects must have inlets or outlets. Inlets are at the top of an object box, outlets are at the bottom. Here is an object that has two inlets and one outlet: . They are shown by small “tabs” on the edge of the object box.
2.2 How does Pure Data work? 9 new data streams. To construct a program we place processing objects onto an empty area called a canvas, then connect them together with wires representing pathways for data to flow along. On each step of a Pure Data program any new input data is fed into objects, triggering them to compute a result. This result is fed into the next connected object and so on until the entire chain of objects, starting with the first and ending with the last have all been computed.
10 Starting with Pure Data How we humans look at dataflow How Pd looks at the graph x Right to left 10 Distribute 10 t 7 10 Add one +1 2 5 * 5 Divide by four /4 55 100 11 100 *5 3 pow 2 + 1 Squared ^2 11 Times five 6 10 / 4 25 55 4 25 Depth first trigger f f 1 + Add both branches + 80 80 x2 + 5(x+1) 4 fig 2.4: Dataflow computation area displayed. When you save a canvas its size and position on the desktop are stored.
2.2 How does Pure Data work? 11 pd−watchdog pd (main engine) Filesystem pd−gui Devices Input/Output remote machine OSC sound.wav display MIDI keyboard UDP/TCP network intrinsic objects keyboard fader box MIDI abstraction.pd mouse Wii controller USB ports patch−file.pd joystick parallel ports external objects microphone/line serial ports textfile.txt loudspeakers audio I/O source.c Interface C compiler fig 2.
12 Starting with Pure Data create an object which always adds 3 to its input. Uninitialised values generally resort to zero so the default behaviour of + would be to add 0 to its input, which is the same as doing nothing. Contrast this to the default behaviour of * which always gives zero. Modifying objects You can also change the contents of any object box to alter the name and function, or to add parameters. In Fig. 2.8 the objects have been changed to give them initial parameters.
2.3 Message data and GUI boxes 13 Holding SHIFT while selecting allows multiple separate objects to be added to the buffer. • • • • • • CTRL+A CTRL+D CTRL+C CTRL+V CTRL+X SHIFT Select all objects on canvas. Duplicate the selection. Copy the selection. Paste the selection. Cut the selection. Select multiple objects. Duplicating a group of objects will also duplicate any connections between them.
14 Starting with Pure Data that they aren’t synchronised to any real timebase. Pd processes them as fast as it can, so when you change the input number box, the output number box changes instantly. Let’s look at some other message types we’ll encounter while building patches to create sound.
2.3 Message data and GUI boxes 15 one. A bevelled top right corner like this 0 denotes that this object is a number box. Numbers received on the inlet are displayed and passed directly to the outlet. To input a number click and hold the mouse over the value field and move the mouse up or down. You can also type in numbers. Click on a number box, type the number and hit RETURN. Number boxes are a compact replacement for faders.
16 Starting with Pure Data to +1.0 must first be scaled using the appropriate object. The VU is one of the few GUI elements that only acts as a display. General messages Floats and bangs are types of message, but messages can be more general. Other message types can be created by prepending a selector that gives them special meanings. For example, to construct lists we can prepend a list selector to a set of other types. Message box These are visual containers for user definable messages.
2.3 Message data and GUI boxes 17 Lists A list is an ordered collection of any things, floats, symbols or pointers that are treated as one. Lists of floats might be used for building melody sequences or setting the time values for an envelope generator. Lists of symbols can be used to represent text data from a file or keyboard input. Most of the time we will be interested in lists of numbers. A list like {2 127 3.14159 12 } has four elements, the first element is 2.0 and the last is 12.0.
18 Starting with Pure Data To create a new array select Put→Array from the menu and complete the dialog box to set up its name, size and display characteristics. On the canvas a graph will appear showing an array with all its values initialised to zero. The Y-axis range is −1.0 to +1.0 by default, so the data line will be in the centre. If the save contents box is checked then the array data will be saved along with the patch file.
2.4 Getting help with Pure Data 19 Exercise 2 Use the Help menu, select browse help and read through some built in documentation pages. Be familiar with the control examples and audio examples sections. Exercise 3 Visit the online pdwiki at http://puredata.org to look at the enormous range of objects available in pd-extended. References Puckette, M. (1996) “Pure Data: another integrated computer music environment.” Proceedings, Second Intercollege Computer Music Concerts, Tachikawa, Japan, pp. 37-41.
20 Starting with Pure Data
21 CHAPTER 3 Using Pure Data SECTION 3.1 Basic objects and principles of operation Now we are familiar with the basics of Pd let’s look at some essential objects and rules for connecting them together. There are about 20 message objects you should try to learn by heart because almost everything else is built from them. Hot and cold inlets Most objects operating on messages have a “hot” inlet and (optionally) one or more “cold” inlets.
22 Using Pure Data sides of a + . When connections are made this way the behaviour is undefined, but usually happens in the order the connections were made. The first one works because the right (cold) inlet was connected before the left (hot) one. In the second patch the arriving number is added to the last number received because the hot inlet is addressed first. Try making these patches by connecting the inlets to + in a different order.
3.2 Working with time and events 23 the currently stored value with a new float and immediately output that. This gives us a way to both set and query the object contents. Int objects Although we have noted that integers don’t really exist in Pd, not in a way that a programmer would understand, whole numbers certainly do. int stores a float as if it were an integer in that it provides a rounding (truncation) function of any extra decimal places. Thus 1.6789 becomes 1.
24 Using Pure Data The left inlet toggles the metronome on and off when it receives a 1 or 0, while the right one allows you to set metro 1000 the period. Periods that are fractions of a millisecond are allowed. The metro emits a bang as soon as it is switched on and the following bang occurs after the time period. fig 3.6: Metronome In Fig. 3.6 the time period is 1000ms, (equal to 1 second). The bang button here is used as an indicator.
3.3 Data flow control 25 Clicking the first bang button will reset and start timer and then hitting the second one will out2000 put the time elapsed (in ms). Notice that timer 250 0 is unusual, it’s one of the few objects where the timer delay 1000 pipe 300 delay right inlet behaves as the hot control. 214.6 0 shown in the middle of Fig. 3.8 will output a single bang message a certain time period after fig 3.8: Time objects receiving a bang on its left inlet.
26 Using Pure Data So, route badger mushroom snake will send 20.0 to its third outlet vca 5 when it receives the message {snake 20 }. Non matching lists are passed unchanged to the rightmost outlet. route vcf vco vca Arguments can be numbers or symbols, but we tend to 20 0 5 use symbols because a combination of route with lists is fig 3.10: Routing vala great way to give parameters names so we don’t forues get what they are for. We have a few named values in Fig. 3.10 for synthesiser controls.
3.3 Data flow control 27 appear, since the same number was sent when the input was 2. Without using change we would get {1, 1, 2, 2, 3, 3 ...} as output. Send and receive objects Very useful for when patches get too visually dense, or when you are working with patches spread across many canvases. send and receive objects, abbreviated fig 3.13: Sends as s and r work as named pairs.
28 Using Pure Data Message sequences Several messages can be stored in the same message-box as a sequence if separated by commas, so 2, 3, 4, 5 is a message-box that will send four values one after another when clicked or banged. This happens instantly (in logical time). This is often confusing to beginners when comparing sequences to lists. When you send the contents of a message box containing a sequence all the elements are sent in one go, but as separate messages in a stream.
3.4 List objects and operations 29 r packed The unpack s s f f will expect two symbols and two unpack s s f f floats and send them to its four outlets. Items are 1 packed and unpacked in the sequence given in the 2 bar list, but in right to left order. That means the floats foo from unpack s s f f will appear first, starting with the fig 3.17: List unpacking rightmost one, then the two symbols ending on the leftmost one.
30 Using Pure Data List distribution An object with 2 or more message inlets will distribute a list of parameters to all inlets using only the first inlet. 9 7 2 fig 3.20: Distribution The number of elements in the list must match the number of inlets and their types must be compatible. In Fig. 3.20 a message box contains a list of two numbers, 9 and 7.
3.5 Input and output 31 Pd is the Arduino board which gives a number of buffered analog and digital lines, serial and parallel, for robotics and control applications. Nearly all of this is quite beyond the scope of this book. The way you set up your DAW and build your sound design studio is an individual matter, but Pd should not disappoint you when it comes to I/O connectivity. We will now look at a few common input and output channels.
32 Using Pure Data which takes a note-number and velocity, and a duration (in milliseconds) as its third argument. After the duration has expired it automatically adds a note-off. If more than one physical MIDI port is enabled then noteout sends channels 1 to 16 to port 1 and channels 17 to 32 to port 2 etc. Continuous controllers Two MIDI input/output objects are provided to receive and send continuous controllers, ctlin and ctlout .
3.6 Working with numbers 33 SECTION 3.6 Working with numbers Arithmetic objects Objects that operate on ordinary numbers to provide basic maths functions are summarised in Tbl. 3.24 All have hot left and cold right inlets and all take one argument that initialises the value otherwise received on the right inlet. Note the difference between arithmetic division with / and the div object. The modulo operator gives the remainder of dividing the left number by the right.
34 Using Pure Data Object Function cos The cosine of a number given in radians. Domain: −π/2 to +π/2. Range: −1.0 to +1.0. sin tan atan atan2 exp log abs sqrt pow The sine of a number in radians, domain −π/2 to + π/2, range −1.0 to +1.0 Tangent of number given in radians. Range: 0.0 to ∞ at ±π/2 Arctangent of any number in domain ±∞ Range: ±π/2 Arctangent of the quotient of two numbers in Cartesian plane. Domain: any floats representing X, Y pair.
3.7 Common idioms 35 Boolean logical objects There are a whole bunch of logical objects in Pd including bitwise operations that work exactly like C code. Most of them aren’t of much interest to us in this book, but we will mention the two important ones || and && . The output of || , logical OR, is true if either of its inputs are true. The output of && , logical AND, is true only when both its inputs are true.
36 Using Pure Data Rounding An integer function, int , also abbreviated i gives the whole part of a floating point number. This is a trun+ 0.5 cation, which just throws away any decimal digits. For int i positive numbers it gives the floor function, written ⌊x⌋ 0 1 which is the integer less than or equal to the input value. But take note of what happens for negative values, applyfig 3.30: Rounding ing int to −3.4 will give 3.0, an integer greater than or equal to the input.
3.7 Common idioms 37 to y = 2x2 − 1 for the range −1.0 to +1.0 and fills a 256 step table with the result. As soon as the bang button is pressed a counter is reset to zero and then until begins sending out bangs. These cause the counter to rapidly increment until select matches 256 whereupon a bang is sent to the right inlet of until stopping the process. All this will happen in a fraction of a millisecond. Meanwhile we use the counter output to calculate a Chebyshev curve and put it into the table.
38 Using Pure Data since the distribution of input numbers is uniform they are sent to one of three outlets with 10%, 40% and 50% probability. Delay cascade Sometimes we want a quick succession of bangs in a certain fixed timing pattern. An easy way to do this is to cascade delay objects. Each delay 100 in Fig. 3.37 adds a delay of 100 milliseconds. Notice the abbrieved form of the object name is used. del 100 del 100 del 100 del 100 fig 3.37: Delay cascade.
39 CHAPTER 4 Pure Data Audio SECTION 4.1 Audio objects We have looked at Pd in enough detail now to move on to the next level. You have a basic grasp of dataflow programming and know how to make patches that process numbers and symbols. But why has no mention been made of audio yet? Surely it is the main purpose of our study? The reason for this is that audio signal processing is a little more complex in Pd than the numbers and symbols we have so far considered, so I wanted to leave this until now.
40 Pure Data Audio Audio object CPU use All the message objects we looked at in the last chapters only use CPU when event driven dataflow occurs, so most of the time they sit idle and consume no resources. Many of the boxes we put on our sound design canvases will be audio objects, so it’s worth noting that they use up some CPU power just being idle. Whenever compute audio is switched on they are processing a constant stream of signal blocks, even if the blocks only contain zeros.
4.2 Audio objects and principles 41 samples this depends on the sampling rate of the program or the sound card of the computer system on which it runs. The current sample rate is returned by the samplerate~ object. Typically a sample is 1/44100th of a second and is the smallest unit of time that can be measured as a signal. But the time resolution also depends on the object doing the computation. For example metro and vline~ are able to deal in fractions of a millisecond, even less than one sample.
42 Pure Data Audio phasor~ 3000 A B *~ 64 tabread~ A tabsend~ B *~ 0.1 dac~ fig 4.4: Table oscillator ; snum set kit1-01; phase 1, 4.41e+08 1e+07; ; snum set kit1-02; phase 1, 4.41e+08 1e+07; ; snum set kit1-03; phase 1, 4.41e+08 1e+07; ; snum set kit1-04; phase 1, 4.41e+08 1e+07; kit1-01 kit1-02 kit1-03 kit1-04 r snum r phase vline~ loadbang tabread4~ hip~ 5 read ./sounds/ttsnr.wav kit1-01, read ./sounds/jrsnr.wav kit1-02, read ./sounds/dlsnr.wav kit1-03, read ./sounds/ezsnr.
4.2 Audio objects and principles 43 Audio input and output Audio IO is achieved with the adc~ and dac~ objects. By default these offer two inlets or outlets for stereo operation, but you can request as many additional sound channels as your sound system will handle by giving them numerical arguments. Example: A simple MIDI monosynth notein Using the objects we’ve just discussed let’s create a little MIDI keyboard controlled music synthesiser as shown in stripnote mtof Fig. 4.6.
44 Pure Data Audio “take a certain time to get there”, which is the second number in each list. The last number in the list is a time to wait before executing the command, so it adds an extra wait for a time before doing it”. What makes vline~ cool is you can send a sequence of list messages in any order, and so long as they make temporal sense then vline~ will execute them all. This means you can make very complex control envelopes.
4.2 Audio objects and principles Object Function cos~ Signal version of cosine function. Domain: −1.0 to + 1.0. Note the input domain is “rotation normalised” sin~ Not intrinsic but defined in terms of signal cosine by subtracting 0.25 from the input. atan~ * log~ abs~ 45 Signal version of arctangent with normalised range. Signal version of natural log. * sqrt~ Signal version of abs. A square root for signals. q8_sqrt~ A fast square root with less accuracy.
46 Pure Data Audio
47 CHAPTER 5 Abstraction SECTION 5.1 Subpatches Any patch canvas can contain subpatches which have their own canvas but reside within the same file as the main patch, called the parent. They have inlets and outlets, which you define, so they behave very much like regular objects. When you save a canvas all subpatches that belong to it are automatically saved. A subpatch is just a neat way to hide code, it does not automatically offer the benefit of local scope1 .
48 Abstraction one envelope generator it’s a few simple steps to turn it into a MIDI mono synthesiser (shown in Fig. 5.3) based on an earlier example by replacing the osc~ with a phasor~ and adding a filter controlled by the second envelope in the range 0 to 2000Hz. Try duplicating the envelope again to add a pitch sweep to the synthesiser. notein > 0 sel 1 trigger bang bang 10 500 pd envelope 40 500 pd envelope mtof phasor~ 55 *~ 2000 vcf~ 1 1 *~ dac~ fig 5.
5.1 Subpatches 49 objects, build bigger objects from those and still bigger objects in turn. Make a new object pd squared and when the canvas opens add the parts shown in Fig. 5.6. To square a number you multiply it by itself.
50 Abstraction Consider the table oscillator patch in Fig. 5.7 which uses an array to hold a sine wave. There are three dac~ significant parts, a tabosc4~ running at 110Hz, a table loadbang to hold one cycle of the waveform and an initialisation ; array1 sinesum 64 1 message to fill the table with a waveform. What if we want to make a multi-oscillator synthesiser using this fig 5.
5.3 Editing 51 code, the message to create a sine wave is sent explicitly through a $0- inside a message box is treated in a different way. send because SECTION 5.3 Editing 110 220 330 Now that we have an abstracted table oscillator let’s instantiate a few copies. In Fig. 5.9 there are three copies. *~ 0.333 Notice that no error messages appear at the console, as dac~ far as Pd is concerned each table is now unique. There fig 5.9: Three harmonics is something important to note here though.
52 Abstraction loadbang inlet pitch f $1 f $2 sel 0 1 2 tabosc4~ $0-array1 outlet~ $0-array1 sinesum 64 1 0 0.333 0 0.2 0 0.143 0 0.111 0 0.0909 sinesum 64 0.5 0.25 0.125 0.062 0.031 0.015 0.007 sinesum 64 1 s $0-array1 fig 5.10: Table oscillator abstraction with initialised frequency and shape. SECTION 5.5 Defaults and states A quick word about default parameters. Try creating some instances of the abstraction in Fig. 5.10 (shown as my-tabsosc2 in Fig. 5.11)2 .
5.6 Common abstraction techniques 53 my-tabosc2 640 0 my-tabosc2 1280 1 my-tabosc2 1920 0 A pd grapha B pd grapha C pd grapha fig 5.11: Three different waveforms and frequencies from the same table oscillator abstraction SECTION 5.6 Common abstraction techniques Here are a few tricks regularly used with abstractions and subpatches. With these you can create neat and tidy patches and manage large projects made of reusable general components.
54 Abstraction Here is what the abstraction looks like when you create an instance (Fig. 5.13). Notice that the name of the abstraction appears at the top, which is why we left a little top margin to give this space. Although the inlet box partly fig 5.13: Appearenters the frame in Fig. 5.12 it cannot be seen in the abance of a GOP abstraction instance because only GUI elements are displayed.
5.6 Common abstraction techniques 55 pd programer t b f t b f t b f freq_1 freq_1 freq_2 freq_2 freq_3 freq_3 freq_4 freq_4 list prepend set 0.165354 0.19685 0.165354 0.110236 pack f f f f pd patch outlet dac~ 0.346 0.251 0.22 0.1653 (a) Packing a list (b) Making a programmer fig 5.16: Packing and using parameter lists the keyword set to a list, a message box that receives it will store those values.
56 Abstraction 1000 2000 3000 4000 1000 2000 3000 4000 unpack f f f f unpack f f f f pd harmonic inlet~ inlet f pd harmonic osc~ pd harmonic +~ pd harmonic outlet~ *~ 0.25 pd harmonic pd harmonic pd harmonic pd harmonic so you can do this *~ 0.25 instead of doing this A pd grapha each harmonic is like this inside fig 5.18: Stacking subpatches that sum with an inlet paths like URLs to break subpatches into individually addressable areas.
57 CHAPTER 6 Shaping sound The signal generators we’ve seen so far are the phasor, cosinusoidal oscillator, and noise source. While these alone seem limited they may be combined using shaping operations to produce a great many new signals. We are going to make transformations on waveforms, pushing them a little this way or that, moulding them into new things.
58 Shaping sound unless you need irrational numbers with high accuracy. This habit highlights the importance of the function and makes your patches easier to understand. Arithmetic operations are used to scale, shift and invert signals as the following examples illustrate. A signal is scaled simply by multiplying it by a fixed amount, which changes the difference between the lowest and highest values and thus the peak to peak amplitude. This is seen in Fig. 6.
6.1 Amplitude dependent signal shaping 59 phasor~ 640 A B For a signal a in the range 0.0 to x the repd grapha pd grapha s~ A ciprocal is defined as 1/a. When a is very +~ 1 large then 1/a is close to zero, and when a sig~ 1 is close to zero then 1/a is very large. Usu- /~ ally, since we are dealing with normalised s~ B signals, the largest input is a = 1.0, so befig 6.5: Signal reciprocal cause 1/1.0 = 1.0 the reciprocal is also 1.0. The graph of 1/a for a between 0.0 and 1.
60 Shaping sound a square wave, limited to between 1.0 and −1.0 and crossing suddenly halfway through. This method produces a waveform that isn’t band-limited, so when used in synthesis you should keep it to a fairly low frequency range to avoid aliasing. A triangle wave moves up in a linear fashion just like a phasor, but when it reaches the peak it changes direction and returns to its lowest value at the same rate instead of jumping instantly back to zero.
6.1 Amplitude dependent signal shaping 61 phasor~ 1290 s~ A *~ -1 +~ 1 min~ s~ B s~ C -~ 0.25 *~ 4 s~ D A pd grapha B pd grapha C pd grapha D pd grapha fig 6.9: Another way to make a triangle wave Squaring and roots One common function of a signal a is a2 , another way of writing a × a. A multiplier is the easiest way to perform squaring. If you connect a signal to both inlets of a multiplier it is multiplied by itself. The effect of squaring a signal is twofold.
62 Shaping sound of the multiplier, a positive signal is output in graph C. Making either sign of the cosine wave positive like this doubles the frequency. In graph D an absence of negative square roots produces a broken sequence of positive pulses, and the effect of the square root operation is to change the cosine curve to a parabolic (circular) curve (notice it is more rounded). Curved envelopes We frequently wish to create a curve from a rising or falling control signal in the range 0.0 to 1.0.
6.2 Periodic functions 63 Wrapping ranges The wrap~ object provides just such a behaviour. It is like a signal version of mod If the input a to wrap~ exceeds 1.0 then it returns a − 1.0. And if the input exceeds 2.0 it gives us a − 2.0. Wrap is the “fractional” part of a number in relation to a division, in this case the unit 1, a − ⌊a⌋. Let’s say we have a normalised phasor which is cycling up once per second. If we pass it through wrap~ it will be unaffected. A normalised phasor never exceeds 1.
64 Shaping sound SECTION 6.3 Other functions From time to time we will use other functions like exponentiation, raising to a variable power, or doing the opposite by taking the log of a value. In each case we will examine the use in context. A very useful technique is that arbitrary curve shapes can be formed from polynomials Polynomials phasor~ 670 A polynomial is expressed as a sum of different *~ -5 *~ power terms.
6.4 Time dependent signal shaping 65 graph1 phasor~ 646 graph2 tabsend~ graph1 expr~ $v2* (sin(6.283 * $v1)) + (1 - $v2) * ( (sin(5 * 6.283 * $v1))) tabsend~ graph2 graph3 phasor~ 646 sin~ *~ 5 swap 1 - sin~ *~ *~ tabsend~ graph3 fig 6.16: Using an expression to create an audio signal function SECTION 6.4 Time dependent signal shaping So far we have considered ways to change the amplitude of a signal as a function of one or more other variables.
66 Shaping sound Phase cancellation Assuming that two adjacent cycles of a periodic waveform osc~ 312 are largely the same then if we delay that periodic signal delwrite~ d1 200 by time equal to half its period we have changed its phase A pd grapha by 180◦. In the patch shown here the two signals are out of phase. Mixing the original signal back with a copy that 1.6 is anti-phase annihilates both signals leaving nothing. In vd~ d1 Fig. 6.18 a sinusoidal signal at 312Hz is sent to a delay d1.
6.4 Time dependent signal shaping 67 terminology and talk about bands which are passed or stopped. A band has a center frequency, specified in Hz, the middle of the range where it has the most effect, and also a bandwidth which is the range of frequencies it operates over. Narrow bands affect fewer frequencies than wider bands. In many filter designs you can change the bandwidth and the frequency independently.
68 Shaping sound Integrating a square wave gives us a triangle wave. If a constant osc~ 670 *~ 10000 signal value is given to an integrator its output will move up or clip~ -0.9 0.9 down at a constant rate. In fact this is the basis of a phasor, so A pd grapha a filter can be seen as the most fundamental signal generator as well as a way to shape signals, thus we have come full circle and can see the words of the great master “It’s all the same thing”. A square wave is produced by the method shown in Fig.
6.4 Time dependent signal shaping 69 wave? The scaling factors in Fig. 6.21 are given for the benefit of the graphs. Perhaps you can see from the first graph that d cos(x) = − sin(x) dx (6.3) and d sin(x) = cos(x) (6.4) dx More useful perhaps, is the result of differentiating a phasor. While the phasor moves slowly its gradient is a small constant, but at the moment it suddenly returns the gradient is very high. So, differentiating a phasor is a way for us to obtain a brief impulse spike.
70 Shaping sound
71 CHAPTER 7 Pure Data essentials This chapter will present some commonly used configurations for mixing, reading and writing files, communication and sequencing. You may want to build up a library of abstractions for things you do again and again, or to find existing ones from the pd-extended distribution. All the same, it helps to understand how these are built from primitive objects since you may wish to customise them to your own needs. SECTION 7.
72 Pure Data essentials block, normally every 64 samples. Move it up and down quickly and listen to the result. Fading is not perfectly smooth. You will hear a clicking sound when you move the slider. This zipper noise is caused by the level suddenly jumping to a new value on a block boundary. Using a log law fader The behaviour of slider objects can be changed.
7.1 Channel strip 73 Mute button and smooth fades After carefully adjusting a level you may want to temporarily silence a channel without moving the slider. A mute button solves this problem. The fader value is stored at the cold inlet of a * 100 while the left inlet receives a Boolean value from a toggle switch. dbtorms The usual sense of a mute button is that the channel is silent 1 == 0 t b f when the mute is active, so first the toggle output is inverted.
74 Pure Data essentials 1.0, is fed to the left channel multiplier, while its complement (obtained by subtracting it from 1.0) governs the right side. With a control signal of 0.5 both sides are multiplied by 0.5. If the control signal moves to 0.75 then the opposing side will be 0.25. When the control signal reaches 1.0 the complement will be 0.0, so one side of the stereo image will be completely silent.
7.1 Channel strip 75 Linear Square root 0.5 1 1−x 1 Output 0.4 0.2 sqrt(1−x) sqrt(x) 0.8 0.6 0.4 0.2 0.2 0.4 0.6 Control 0.8 1 0.4 Left Right 0 0 3dB 0.6 0.2 Left Right Left 0 sin(x) cos(x) 0.8 0.6 Output x 0.8 Output Sin/Cos ~~0.7 1 Right 0 0 0.2 0.4 0.6 Control 0.8 1 0 0.2 0.4 0.6 Control 0.8 1 fig 7.
76 Pure Data essentials crossfader, but in some situations crossfades may be better with constant power fading done using sine or square root transfer functions. Demultiplexer A demultiplexer or signal source selector inlet~ s1 inlet~ s2 inlet~ s3 inlet routing sel 0 1 2 3 is a multi-way switch that can choose be0 0 0 tween a number of signal sources. Fig. 7.13 1 0 0 is useful in synthesiser construction where 0 1 0 you want to select from a few different wave0 0 1 forms.
7.2 Audio file tools 77 Using the sampler is very easy. Create an instance and connect it to a signal source via the first inlet. In Fig. 7.15 the left audio input is taken from adc~ . A slider with a range 0.0 to 1.0 connects to the gain inlet and two bang buttons are used to start recording or playback. Sound files of up to 3min can be stored happily in memory. Beyond this limit you need to use other objects for 32 bit machines because the sound quality will suffer due to pointer inaccuracies.
78 Pure Data essentials a counter and the value of this is appended to the current file name using makefilename which can substitute numerical values into a string like the C printf statement does. This string is then substituted after the open keyword in the following message. As soon as this is done a start message is sent to writesf~ and a bang to the delay which waits for a period given by the first argument before stopping writesf~ .
7.3 Events and sequencing 79 metronome and counter. A more useful timebase is given in Fig. 7.19 that allows you to specify the tempo as beats per minute (BPM) and to add a “swing”1 to the beat. Notice first that start and stop control via the first inlet also resets loadbang t b b b inlet control sel 0 0 inlet bpm inlet beats inlet swing percent f $1 f $2 f $3 swap 60000 t b f / 100 / + 1 / 4 t f f metro 125 t b f * t b b del t b b f 0 + 1 outlet bangs outlet time fig 7.
80 Pure Data essentials bination of == and select with a number box attached to the cold inlet of and the current time going to the left inlet. == Partitioning time For long musical compositions, interactive installations or generating event structures for a long game or antimebase 60 4 0 imation you may want to offset timing sequences by s time r time a large number but keep the relative timings within a 208 moses 128 section. This is how bars and measures work in a tradimoses 256 127 tional sequencer.
7.3 Events and sequencing 81 timebase 60 4 0 s time r time r halftime r quartime r time mod 16 mod 16 mod 64 / 16 / 16 / 64 * 6.282 * 6.282 * 6.282 sin sin sin s lfo1 s lfo2 s lfo3 0 trigger float float / 2 / 4 change change int int s halftime s quartime r lfo1 r time r lfo2 tabwrite a a r time r lfo3 tabwrite b b r time tabwrite c c fig 7.
82 Pure Data essentials 61 0 60 500 59 500 r synth t f b mtof list split 2 unpack f f del t b b list append f s synth 0, 1 1 0, 0 400 1 phasor~ vline~ *~ 2 *~ -~ 1 *~ 600 *~ +~ 100 vcf~ 1 1 *~ 0.35 dac~ fig 7.24: An asynchronous list sequencer banged so the remainder of the list is passed back to list split 2 and the whole process repeats, chomping 2 elements off each time until the list is empty. To the right of Fig. 7.24 is a simple monophonic music synthesiser used to test the sequencer.
7.4 Effects 83 r synth notein pd synth load-playback stripnote start-record t b b b t b b b t f b b rewind clear read ./sq.txt timer write s synth pack f f textfile t l t b b list split 2 list prepend write ./sq.txt cr unpack f f list append list append del list prepend set t b b f textfile s synth fig 7.25: A MIDI sequencer that uses textfiles to store data restart from zero.
84 Pure Data essentials inlet~ r~ $0-fb inlet fb inlet rate inlet depth clip -1 1 * 5 * 2 * 0.4 + 1 osc~ osc~ *~ *~ +~ +~ vd~ $0-a1 vd~ $0-a2 r~ $0-d *~ 0.3 s~ $0-d *~ 1 +~ delwrite~ $0-a1 100 delwrite~ $0-a2 100 *~ s~ $0-fb outlet~ l outlet~ r fig 7.26: A chorus type effect A small part, scaled by the feedback value on the second inlet, is sent back to be mixed in with the input pd sample_loop_player signal, while another copy is sent to the left stereo outlet.
7.4 Effects 85 inlet~ delread~ A 101 delread~ B 143 delread~ C 165 +~ +~ outlet~ l outlet~ r +~ -~ +~ +~ delread~ D 177 -~ +~ -~ -~ *~ 0.4 *~ 0.37 *~ 0.333 *~ 0.3 delwrite~ D 1000 delwrite~ C 1000 delwrite~ B 1000 delwrite~ A 1000 fig 7.28: A recirculating Schroeder reverb effect theory. An apparently well designed reverb can mysteriously explode after many seconds or even minutes so a common design safety measure is to attenuate the feedback paths as the reverb decays away.
86 Pure Data essentials • • • • Hierarchical structure Microtonal tuning scales Polyrhythmic capabilities A way to load and save your compositions Exercise 3 Design and implement a mixing desk with at least three of, • • • • • • • MIDI or OSC parameter automation Switchable fader and pan laws Surround sound panning (eg 5.1, quadraphonic) Effect send and return bus Accurate signal level monitoring Group buses and mute groups Scene store and recall Exercise 4 Essay: Research datastructures in Pd.
7.4 Effects 87 Beau Sievers “The Amateur Gentleman’s Introduction to Music Synthesis” An introductory online resource geared toward synth building in Pure Data. http://beausievers.com/synth/synthbasics/ http://www.musicdsp.org/ is the home of the music DSP list archive, with categorised source code and comments. http://www.dafx.de/ is home of the DAFx (Digital Audio Effects) project containing many resources.
88 Pure Data essentials
89 Abstraction, 49 edit, 51 instance, 50 parameters, 51 scope and $0, 49 Accumulator, message, 35 Array Pure Data, 17 Audio effect, see Effect Bandpass, 66 Block Pure Data, 39 Canvas, 8 create, 9 Channel strip, 71 Cold inlet, 21 Connection audio fanning, 40 merging message, 23 Connection, programming, 8 Counter, 24 constrained, 35 CPU efficiency, 40 Crossfader, 75 Dataflow, programming, 8 Delay cascade, 38 Demultiplexer, 76 Depth first, 9 Effect chorus, 83 reverberation, 84 Envelope curve, 62 vline object,
90 list, 17, 28 list distribution, 30 list pack, 28 list unpack, 28 persistence, 29 pointer, 17 selector, 14 sequence, 28 substitution, 29 symbol, 16 trigger, 22 Message, Pure Data, 13 Metronome, 23 MIDI controller, 32 note in, 31 note out, 31 note to frequency, 32 object summary, 32 sysex, 32 Mute button, 73 Normalisation parameter, 55 Number comparison, 34 complement, 37 last, 38 LFO, 80 logical, 35 random, 33 reciprocal, 37 rounding, 36 running maximum, 38 scaling, 36 stream lowpass, 38 Number box, 12 Ob
91 test, 6 watchdog, 9 Sampler, simple audio, 76 Select random, 37 weighted, 37 Sequencer division, 80 list, 81 textfile, 82 time, 78 using select, 79 Signal arithmetic, 44, 57 audio, Pure Data, 39 cosine, 63 delay, 45, 65 filters, 44, 66 input/output, 43 math, 44 periodic, 62 send/receive, 41 shaping, differentiate, 68 shaping, expression, 64 shaping, integrate, 67 shaping, invert, 58 shaping, limit, 59 shaping, line envelope, 62 shaping, phase, 66 shaping, polynomial, 64 shaping, root, 61 shaping, scale,