Introduction to PD | |
PD, which stands for "Pure Data" or "Public Domain," is a graphical programming environment for MIDI and digital audio. This introduction is intended to help the reader better understand the design of my OSCAR system. Those who wish to become aquatinted with PD from a user's standpoint should consult PD's documentation, as well as the FAQ at Pure-Data.org. PD's interface is very similar to that of Max/MSP. Max's excellent documentation serves as an good introduction to PD as well. |
|
Objects | |
In the simplest terms, PD consists of boxes (called "objects") that "do stuff." These boxes have inlets and outlets, allowing them to be connected with other boxes via patch chords. It is through the interconnection of different objects that PD can achieve complex behavior. The PD has a class of graphical objects, incorporated from the IEM library of PD externals. One such object is | |
A Simple Patch | |
![]() |
This is an example of a simple PD patch (a program in PD is called a "patch"). The patch counts the number of times you click on the |bng| labeled "count." The number of clicks counted is displayed in a number box. The count is reset if you click on the |bng| labeled "reset." Clicking the "count" |bng| causes it to output a BANG message. This BANG causes the leftmost |float| to output it's value. This value is input into the |+ 1| object, which simply adds 1 to its input and outputs the result. The output from the |+| is sent to the number box, and is sent to the right inlet of the |float|. The value that is stored in the |float|, and the value that is sent to the number box, is increased by one with each click. Clicking on the "reset" |bng| causes the |float -1| to enter -1 into the |+| object; the number box and the value in the leftmost |float| are reset to zero. |
Encapsulation | |
![]() |
Patches can be encapsulated within other patches. This patch is an improved version of the simple counter created above. In place of |bng| objects, this patch has two |inlet| objects. |inlet| objects allow messages to be sent into a patch from the outside world. Similarly, |outlet| objects send information out of the patch; here, the number box is replaced with an |outlet|. |
|
In this patch, the counter we created above is encapsulated and nested inside another patch. The |counter| object contains our improved counter patch. The two inlets and one outlet of the |counter| object correspond directly to the two |inlet|'s and one |outlet| in the counter patch. Therefore, clicking on the left |bng| will increment the counter, and clicking on the right |bng| resets the counter. The count comes out of |counter|'s outlet and into a number box. Encapsulation has two purposes. First, it makes complex patches visually simpler by hiding a potentially large number of objects inside a single object box. Secondly, and more importantly, encapsulation allows the user to create a basic abstraction that can be reused repeatedly. Furthermore, specific instances of an abstraction can be given specific characteristics through the use of initialization arguments. |
![]() |
This example patch is identical to our encapsulated counter, with the addition of the |*| object, which multiplies it's input by a number (which comes either from the object's right inlet or from it's initialization argument). In this case, rather than supply the |*| with a constant, it contains the string "$1. This string will be replaced by the initialization argument supplied when an instance of the object is created. Specifically, "$1" will be replaced by the first initialization argument, "$2" by the second argument, and so forth. |
![]() |
This patch contains three instances of our |counter| object, each with a different initialization argument. As you can see, the argument sets the factor by which the count is multiplied before being output. The initialization argument essentially replaces the "$1" string inside the encapsulated patch. Through the use of initialization arguments, a user can create a template abstraction, and allow the instances of the abstraction to have different characteristics. |
Scheduling | |
In order for a patch to work, it is essential that operations defined within it be scheduled and executed in the correct order. The order of execution is defined by the layout of objects on the screen: PD works top-to-bottom and right-to-left. Furthermore, if an object's outlet is connected a number of other objects, the output is sent to the connected objects in the order in which they were connected by the user. This ordering can easily be checked and adjusted by viewing the patch with a standard text editor: the objects will be listed in the order in which they were connected. |
|
|
|
![]() |
![]() |