The purpose of this chapter is to describe Pd's design and how it is supposed to work. Practical details about how to obtain, install, and run Pd are described in the next chapter. To learn digital audio processing basics such as how to generate time-varying sounds that don't click or fold over, a good reference is Dodge and Jerse, Computer Music .
There are peak level and clip indicators for audio input and output; these report peak levels over all input and all output channels. Note that DC shows up as an input level; many cards have DC levels which show up in the 50s. To see an RMS audio level, select "test audio and MIDI" from the help window. The main window display is intended only to help you avoid clipping on input and output. You can turn the peak meters on and off using the control at bottom left.
At bottom right is a control to turn audio processing on and off globally. Turning audio off does not relinquish the audio devices, it just stops the computation. The "audio" menu is also provided, with accelerators "Control-." to turn audio computation off and "Control-/" to turn it on. When audio is on, Pd is computing audio samples in real time according to whatever patches you have open (visible or not.)
The DIO (Digital I/O) error indicator flashes if there is a synchronization error for audio input or output. Click there to see a list of recent errors. This indicator is normally red at startup, and will turn red whenever the computation runs late (so that the DAC FIFOs fill and/or the ADC FIFOs empty) or if audio input and output are not running at the same rate. See audio and MIDI support .
Pd documents are called "patches" or "canvases." Each open document has one main window and any number of subwindows. The subwindows can be opened and closed but are always running whether you can see them or not. Here is a simple Pd patch:
There are four text items in this patch: a number box (showing zero), an object box showing "print," and two comments. The number box and the object box are connected, the number box's output to the print box's input. Boxes may have zero or more inputs and/or outputs, with the inputs on top and the outputs on bottom.
Pd's printout appears on its standard output. Normally, you'll run Pd in a "shell" or "terminal" window which you'll keep open to see any printout or error messages.
Pd patches can have four types of boxes: object, message, number, and comment .
You make objects by typing text into object boxes. The text is divided into atoms separated by white space. The first atom specifies what type of object Pd will make, and the other atoms, called creation arguments , tell Pd how to initialize the object. If you type for example,
the "+" specifies the class of the object. In this case the object will be the kind that carries out addition, and the "13" initializes the amount to add. Atoms are either numbers or symbols like "+". The text you type into an object box determines how many and what kinds of inlets and outlets the object will have. Some classes (like "+" always have a fixed arrangement of inlets and outlets, and in the case of other classes, the inlets and outlets will depend on the creation arguments.
Here for example is a simple MIDI synthesizer:
This patch mixes control objects (notein, stripnote, and ftom) with tilde objects osc~, *~, and dac~. The control objects carry out their function sporadically, as a result of one or more type of event . In this case, incoming MIDI note messages set off the control computation. The result of the computation is, when the note happens to be a "note on" (and not a "note off", to compute the frequency in cycles per second and pass it on to the oscillator ("osc~").
The second half of the patch, the osc~, *~, and dac~ objects, compute audio samples, in the same way as an analog synthesizer works. The osc~ object is acting as the interface between the two regimes, in that it takes control messages to set its frequency but talks to "*~" using an audio signal. Audio signals aren't sporadic; they are continuous streams of numbers. As a result tilde objects act under very different rules from control objects. The audio portion of the patch is always running, whether MIDI messages arrive or not; the function of control computations is to insert calculations between the audio computation which may change audio computation parameters such as the frequency of an oscillator.
Whereas the text in an object or message box is static when a patch is running, a number box's text changes to reflect the current value held by the box. You can also use a number box as a control by clicking and dragging up and down, or by typing values in it. (There are also shift- and alt-click actions; see getting help to find out how to look this up).
You can also create a "symbol" box which is like a number box but deals in symbols like "cat." You can type your own strings in (followed by "enter") or use it to display strings which arrive as messages to its inlet.
A patch can be in edit or run mode; this really only affects how mouse clicks affect the patch. In edit mode, clicking and dragging selects and moves boxes or makes and cuts connections; in run mode clicking on boxes sends them messages which they react to in different ways. In run mode, number and message boxes can be used as controls. Normally, when you are in a performance you will stay in run mode; to change the patch you go to edit mode.
You can create the four classes of "text items" (objects, messages, numbers, and comments) using the "put" menu. (There are also "symbol", "array" and "graph" entries which you should ignore for now.) Note the handy accelerators. Boxes are empty at first; drag them where you want them and type in the text.
You will often find it more convenient to select a box and "duplicate" it (in the Edit menu) than to use the "Put" menu. If you select and duplicate several items, any connections between them will be duplicated as well.
To change a text item, you can select it and then edit the text. If you only click once, the entire text is selected and your typing will replace everything. Click again and drag to select a portion of the text to retype.
If there's more than a small amount of text (in a comment, for example) you might want to select the text and choose "text editor" from the Edit menu, which opens a text editing window with a copy of the text in it. Hitting "send" in that window is exactly equivalent to retyping the text into Pd; you can send it to more than one box in sequence if you want.
If you click a box and move the mouse without releasing the button this displaces the entire box. If you wish to displace a box which is already sepected, first deselect the box by clicking outside it; otherwise you will be selecting text instead of moving the box.
The updated text only becomes part of the patch when you deselect the object. Changing the text in an "object" box actually deletes the old object and creates a new one; the internal state of the old one is lost.
all the "clicking" mentioned above is done with the left mouse button. The right button, instead, gives a popup menu for "properties" and "help". Properties are enabled for number boxes and graphs (and in the future may be available for other things as well.) Selecting "help" on an object gets a Pd patch that demonstrates how to use it. "Help for the canvas as a whole (click outsize any object) gives a list of all built-in objects.
Control-q "quits" Pd, but asks you to comfirm the quit. To quit without having to confirm, use command-shift-Q.
In Pd, objects intercommunicate by sending messages and/or audio signals. Pd messages are sporadic, like MIDI messages or music N "Note cards."
When a message is passed to something (which is often an inlet of a box but could be anything that can receive a message), the selector of the message is checked against the receiver. If the receiver recognizes messages of that selector, it carries out some corresponding action. For instance, here is a "float" object:
The two rectangles at the top are usually both called "inlets" but the one at the left directs incoming messages to the "float" object itself, whereas the one at the right directs messages to an auxilliary "inlet" object. The float object proper (represented by the left-hand inlet) accepts messages with selector "float" and "bang". The right-hand inlet takes only the message selector "float". These two selectors, along with "symbol" and "list", are usually used to denote an object's main action, whatever it may be, so that objects can be interconnected with maximum flexibility.
It is possible to type messages which start with a number, which cannot be used as a selector. A single number is always given the "float" selector automatically, and a message with a number followed by other arguments is given the selector "list".
In Pd whenever a message is initiated, the receiver may then send out further messages in turn, and the receivers of those messages can send yet others. So each message sets off a tree of consequent messages. This tree is executed in depth first fashion. For instance in the patch below:
the order of arrival of messages is either A-B-C-D or A-C-D-B. The "C" message is not done until the "D" one is also, and the "A" is not done until all four are. It is indeterminate which of "B" or "C" is done first; this depends on what order you made the connections in (in Max, it's automatically sorted right to left).
Message-passing can give rise to infinite loops of the sort shown here:
Here the left-hand "+" can't finish processing until the right-hand one has been sent the result "2", which can't finish processing that until the left-hand one has been sent "3", and so on. Pd will print an error message reporting a "stack overflow" if this happens.
However, it is legal to make a loop if there is a "delay" object somewhere in it. When the "delay" receives a message it schedules a messsage for the future (even if the time delay is 0) and is then "finished;" Pd's internal scheduler will wake the delay back up later.
With few exceptions (notably "timer"), objects treat their leftmost inlet as "hot" in the sense that messages to right inlets can result in output messages. So the following is a legal (and reasonable) loop construct:
Here the "f" is an abbreviation for "float". Note that the "+ 1" output is connected to the right-hand inlet of "f". This "cold" inlet merely stores the value for the next time the "f" is sent the "bang" message. It is frequently desirable to send messages to two or more inlets of an object to specify its action. For instance, you can use "+" to add two numbers; but to do it correctly you must make sure the right hand inlet gets its value first. Otherwise, when the left hand side value comes in, "+" will carry out the addition (since the left hand inlet is the "hot" one) and will add this value to whatever was previously sitting in the right hand inlet.
Problems can arise when a single outlet is connected (either directly or through arbitrarily long chains of message passing) to different inlets of a single object. In this case it is indeterminate which order the two inlets will receive their messages. Suppose for example you wish to use "+" to double a number. The following is incorrect:
Here, I connected the left inlet before connecting the right hand one (although this is not evident in the appearance of the patch.) The "+" thus adds the new input (at left) to the previous input (at right).
The "trigger" object, abbreviated "t", can be used to split out connections from a single outlet in a determinate order. By convention, all objects in Pd, when sending messages out more than one outlet, do so from right to left. If you connect these to inlets of a second object without crossing wires, the second object will get its leftmost inlet last, which is usually what you want. Here is how to use "trigger" to disambiguate the previous example:
"Cold" (non-leftmost) inlets are almost universally used to store single values (either numbers or symbols.) With the exception of "line" and "line~", these values are "sticky," i.e., once you set the value it is good until the next time you set it. (The "line" exception is for sanity's sake.)
One more question sometimes comes up in execution order, which is the order in which two messages are sent to a single "cold" inlet. In this situation, since the messages are merged, the last value to be received is the value that is used in the computation.
The first of the message boxes above contains the single number 1.5; this message has an implicit selector of "float." The second is a list with three numbers in it, and in the third, the selector is "my" and the two arguments are the number 5 and the symbol "toes."
Multiple messages may be separated by commas as shown:
Here the three messages are the numbers 1, 2, and 3, and they are sent in sequence (with no intervening time between them, as with the "trigger" object, and having depth-first consequences so that whatever chain of actions depending on "1" takes place before anything depending on "2" and so on.)
Semicolons may also separate messages. A message following a semicolon must specify a symbol giving a destination (in other words, semicolons are like commas except that they clear the "current destination" so that the next message specifies a new one). The "current destination" is at first the message box's own outlet. In the example below, the leading semicolon immediately redirects messages from the outlet to an object named "fred" (which is here a receive object), and likewise the next message is sent to "sue."
Certain other objects (Pd windows, for example, and arrays) have Pd names and can be sent messages this way. Also, the special object "pd" is defined to which you may send messages to start and stop DSP.
You can put variables in message boxes as shown below:
Here, "$1", etc., refer to the arguments of the arriving message (and aren't defined if you send a "bang" message or if you click on the message box to activate it.) Dollar sign variables are either numbers or symbols depending on the incoming message; if symbols, you may even use them to specify variable message selectors or destinations.
Using Pd you can build audio patches which can synthesize musical sounds, analyze incoming sounds, process incoming sounds to produce transformed audio outputs, or integrate audio processing with other media. This section describes how Pd treats audio signals.
Pd's audio signals are internally kept as 32-bit floating point numbers, so you have all the dynamic range you could want. However, depending on your hardware, audio I/O is usually limited to 16 or 24 bits. Inputs all appear between the values of -1 and 1; and output values will be clipped to that range.
Pd assumes a sample rate of 44100 unless you override this in Pd's command line. Pd doesn't check that this matches the sample rate of audio input or output, nor does Pd attempt to set your computer's audio sample rate to its own. If the audio system is running at the wrong sample rate, audio output will be transposed (you can check this using the "test audio and MIDI" patch; see the help menu).
Pd can read or write samples to files either in 16-bit or 24-bit fixed point or in 32-bit floating point, in WAV, AIFF, or AU format, via the soundfiler, readsf, and writesf objects.
Inlets or outlets are configured in Pd either for messages or audio; it's an error to connect an audio outlet to a non-audio inlet or vice versa; usually these errors are detected at "sort time" when audio is started or the network changed with audio running. An object's leftmost inlet may accept both audio and messages; any other inlet is either one or the other. There is no quick way to tell whether an inlet or output is for audio or messages; consult the help window for the object.
The audio network, that is, the tilde objects and their interconnections, must be acyclic. If there are loops, you will see the error message at "sort time." When errors are reported at sort time there is no easy way to find the source of the error. You can build algorithms with feedback using nonlocal signal connections.
Your subpatches can have audio inlets and outlets via the inlet~ and outlet~ objects.
If you want to use a control value as a signal, you can use the sig~ object to convert it. The +~, -~, *~, /~, osc~, and phasor~ objects can be configured to take control or signal inputs.
The other direction, signal to control, requires that you specify at what moments you want the signal sampled. This is handled by the snapshot~ object, but you can also sample a signal with tabwrite~ and then get access it via tabread or tabread4 (note the missing tildes!). There are also analysis objects, the simplest of which is "env~", the envelope follower.
Larger block sizes than 64 should result in small increases in run-time efficiency. Also, the fft~ and related objects operate on blocks so that setting the block size also sets the number of FFT channels. You may wish to use block sizes smaller than 64 to gain finer resolutions of message/audio interaction, or to reduce "block delay" in feedback algorithms. At the (untested) extreme, setting the block size to one allows you to write your own recursive filters.
You can use switch~ to budget your DSP computations; for instance you might want to be able to switch between two synthesis algorithms. Put each algorithm in its own subpatch (which can have sub-sub patches in turn, for a voice bank for instance), and switch each one off as you switch the other one on. Beware of clicks; if you have a line~ controlling output level, give it time to ramp to zero before you switch it off or it will be stuck at a nonzero value for the next time it comes back on.
When a subpatch is switched off its audio outputs generate zeros; this costs a fairly small overhead; a cheaper way to get outputs is to use throw~ inside the switched module and catch~ outside it.
Send~ just saves a signal which may then be receive~d any number of times; but a receive~ can only pick up one send~ at a time (but you can switch between send~s if you want.)
Don't try to throw~ and catch~ or send~ and receive~ between windows with different block sizes. The only re-blocking mechanisms which are well tested are inlet~ and outlet~.
When you send a signal to a point that is earlier in the sorted list of tilde objects, the signal doesn't get there until the next cycle of DSP computation, one block later; so your signal will be delayed by one block (1.45 msec by default.) Delread~ and delwrite~ have this same restriction, but here the 1.45 msec figure gives the minimum attainable delay. For nonrecursive algorithms, a simple flanger for example, you might wish to ensure that your delread~ is sorted after your delwrite~. The only way to ensure this is to create the delread~ after you created the delwrite~; if things get out of whack, just delete and re-create the delread~.
In the intervals between, delays might time out or external conditions might arise (incoming MIDI, mouse clicks, or whatnot). These may cause a cascade of depth-first message passing; each such message cascade is completely run out before the next message or DSP tick is computed. Messages are never passed to objects during a DSP tick; the ticks are atomic and parameter changes sent to different objects in any given message cascade take effect simultaneously.
In the middle of a message cascade you may schedule another one at a delay of zero. This delayed cascade happens after the present cascade has finished, but at the same logical time.
The Pd scheduler maintains a (user-specified) lead on its computations; that is, it tries to keep ahead of real time by a small amount in order to be able to absorb unpredictable, momentary increases in computation time. This is specified using the "audiobuffer" or "frags" command line flags (see getting Pd to run ).
If Pd gets late with respect to real time, gaps (either occasional or frequent) will appear in both the input and output audio streams. On the other hand, disk strewaming objects will work correctly, so that you may use Pd as a batch program with soundfile input and/or output. The "-nogui" and "-send" startup flags are provided to aid in doing this.
Pd's "realtime" computations compete for CPU time with its own GUI, which runs as a separate process. A flow control mechanism will be provided someday to prevent this from causing trouble, but it is in any case wise to avoid having too much drawing going on while Pd is trying to make sound. If a subwindow is closed, Pd suspends sending the GUI update messages for it; but not so for miniaturized windows as of version 0.32. You should really close them when you aren't using them.
If a message cascade is started by an external event, a time tag is given it. These time tags are guaranteed to be consistent with the times at which timeouts are scheduled and DSP ticks are computed; i.e., time never decreases. (However, either Pd or a hardware driver may lie about the physical time an input arrives; this depends on the operating system.) "Timer" objects which meaure time intervals measure them in terms of the logical time stamps of the message cascades, so that timing a "delay" object always gives exactly the theoretical value. (There is, however, a "realtime" object that measures real time, with nondeterministic results.)
If two message cascades are scheduled for the same logical time, they are carried out in the order they were scheduled.
In an object box, as in a message box, the text specifies a message; but here the message is to be passed to Pd itself, once, and the message's effect is to create the object in question. When you open a file, all the objects created are created using their text as "creation messages." If you type a new message into an object box (or change it), the old object is destroyed and the message is used to create the new one.
The selector of the message (the first word in the message) is a selector which Pd interprets to mean which type of object to create. Any message arguments (called "creation arguments") are used to parametrize the object being created. Thus in "makenote 64 250" the selector "makenote" determines the class of object to create and the creation arguments 64 and 250 become the initial velocity and duration.
An exception is made for subpatches whose "state" is the configuration of the subpatch; as a special case, this configuration is restored when the patch is read from a file. Also, if you rename the subpatch, for instance typing "pd jane" instead of "pd spot," the contents of the patch are preserved and only the text in the object box and the window title of the subpatch are changed.
It is probably bad style to specify creation arguments ala "makenote 64 250" if you are going to override them later; this is confusing to anyone who tries to understand the patch.
Object boxes may have many different classes. The class is usually determined by the selector of the creation message, i.e., the first atom of the creation message which is usually a symbol.
Each class comes with a fixed collection of messages it may be sent. For esxample, the "float" or "f" object takes "bang" and "float." These messages are sent to "float" objects (objects whose class is float) via the leftmost, hot inlet. (The right inlet is a separate, auxiliary object.) Objects of class "float" respond to the message "bang" by outputting their current value, that is, by sending a "float" message to their outlet. They respond to "float" messages by setting their value and then outputting it.
Each other class (like "float") in Pd has its own protocol for responding to messages it is sent, and may take "float" and "bang" messages, or others in addition or instead of them.
Unless they arrange otherwise by defining a "list" method, objects respond to the "list" message by distributing the arguments of the message to their inlets, except for the first argument which is passed as a "float" or "symbol" message to the object proper.
Object boxes contain text wwhich forms a message to be sent to Pd to create and initialize the object. Here, $1, etc., are taken from the context in which the patch was loaded. When the patch is a new document or opened from a file the "$" variables are undefined. But if the patch is an abstraction (see the next section) they are taked from the abstractions' creation arguments.
Constructions such as "$1-x" are expanded by string concatentation. This is the mechanism for making local variables. In particular, $0 in an abstraction is a counter which is guaranteed to be unique to that abstraction, so sends and receives with names like "$0-bear" can be used as local send/receive pairs.
Inlets and outlets appear on the invoking box in the same left-to-right order as they appear in the subpatch.