Basically, internals are the objects that come as part of the Pd Vanilla (the main binary distribution of Pure Data, provided by Miller Puckette : http://msp.ucsd.edu/software.html ) , whereas external objects are not! Besides internals, the Pd Vanilla distribution also comes with a few "extra" objects that are not part of its binary. Therefore, Vanilla objects (the built-in objects in Pd) include internals and externals.
Nonetheless, "externals" most commonly refer to objects that do not available in the Pd Vanilla distribution, meaning that usually you have to download these objects and install them properly so they can be loaded into Pd patches.
Figure 4.1 - Excerpt from list of Vanilla objects (help-intro.pd file)
To get a full list of all objects in Pd Vanilla, go to the Help menu and then select List of Objects, or alternatively right click on an empty spot of a patch's window and select "help" - this loads the help-intro.pd file.
Figure 4.2 - Extra objects from Pd Vanilla
The extra objects, which reside in a folder named "extra" inside the Pd application, are presented at the very end of the "help-intro.pd". They can also be viewed in the Help Browser menu (Help => Browser). See Figure 4.2 above, which shows how the browser looks in a fresh install of Pd and lists the objects in the extra folder.
An object in Pd can be either a patch - meaning a Pd file (a.k.a abstraction) - or a compiled binary (note that a binary can contain only one or several external objects, as discussed further on). More details about these two possible types below.
These are Pd objects compiled to binaries from programming code (like in C or C++). They have to be compiled for your operating system, which means the binaries have different extensions according to each platform. For instance:
You can save pd patches and make them behave like objects by loading them into your patches, these are usually called "Abstractions". Note that some of the "extra" objects from Vanilla that you can see in Figure 4.2 are Pd files/patches. Note that abstractions, like any other Pd file, may contain any kind of objects (internals, compiled externals and even other abstractions).
In practical terms, an external library is a collection of external objects of any kind (abstractions or compiled objects). But when it comes to compiled objects, a library can provide several objects as a single binary pack or as a set of separate binaries (where each object has its own binary).
The "classic" library is a single binary pack (with two or more externals), but splitting into separate binaries became very common. A single external binary (not part of any set of objects) is still technically a library with just one object, and a library with separate binaries could be considered as a set of libraries. But again, in practical terms, the more general concept of a library is that it is just a set of objects. What’s important to note is that there are significant differences for loading externals wether if they are a single binary pack or a set of separate binaries (as we’ll see in this tutorial later on).
Libraries can come in all sorts of ways; as only a collection of abstractions (like "list-abs"), only compiled objects, or both. It can even mix compiled externals both as a set of separate binaries and a single binary pack. Basically, any combination is possible for a set of external.
One example that combines all external options is cyclone 0.3, which provides most of its objects as a set of separate binaries, but also includes a small collection of 12 objects as a single binary pack plus a few abstractions.
You can write your own objects that you and others can use in their Pd applications. You can write them in C or (if you're smart and brave) in C++ or FORTRAN.
HOW EXTERNS ARE LOADED
Whenever you type the name of an object (into an "object" text box) that Pd doesn't yet know about, Pd looks for a relocatable object file, named, for instance, "profile.pd_irix5". Pd looks first in the directory containing the patch, then in directories in its "path." Pd will then add whatever object is defined there to its "class list," which is the set of all Pd classes you can use. If all this works, Pd then attempts again to create the object you asked for, this time perhaps successfully. There is no difference between an object defined this way and an object built into Pd.
Once you load a new object into Pd, it's there for the duration of your Pd session. If you load another Pd document which supplies a different version of some Pd object, the object won't be updated. IF you're working on a new object and decide to change it, you have to exit and re-enter Pd to get the change to take.
In the "externs" subdirectory of the documentation you can find simple examples of "externs" with their source code and test patches; there are many other on the web (see section 1.2 ).
IOhannes zmölnig has written an excellent guide to writing externs at http://pdstatic.iem.at/externals-HOWTO/ .
Installing externals in Pd is quite simple, all you need to do is download your externals from somewhere, such as from Pd Vanilla directly, and include them in a proper folder.
You can have externals basically anywhere in your computer, but Pd must know where to look for them. Since Pd 0.48, Pd can automatically create a documents directory for patches and external libraries. At launching Pd for the first time, it asks you to create this folder, which is the current best practice. This automatically includes the folder in the search paths (under Preferences => Path).
Figure 4.3 - Preferences => Path window
If you accept that Pd creates that folder for you, you should have something like this in a fresh install of Pd under Preferences => Path. This is for macOS, where the "Pd" folder is created under ~/Documents, and inside it we have a folder for externals. Even if you did not create this folder, here is where you can create it by clicking the "Reset" button under "Pd Documents Directory".
Pd can actually search for externals anywhere, they just need to be included in the search paths. Nontheless, Pd also has other places it can search for externals. This can be the same folder that your patch is saved on (the Relative Path) or the Standard Paths, which are:
The Standard Paths are not listed in Preferences => Path, as those only include paths added by the user. And again, the current best practice is to have external folders inside an external folder added to Pd search paths (as ~/Documents/Pd/externals). Earlier practices made use of these standard paths above, but note that the user-specific and global standard paths are not automatically created by Pd.
This structure is still kept as an old heritage of Pd and is documented here because of that. It may also serve some edge cases. The Global folder affects all Pure Data Applications for all users. The User-specific folder affects all Pure Data Applications for that user. And since you can have different versions of Pd installed in your system, the Application-specific folder affects only that particular Pd Application. This can be not only an older and a newer version of Pd, but also both 32-bit and 64-bit versions. For reference, here's the list of the Standard Paths for all operating systems:
A) macOS:
B) Windows:
Since version 0.47-0, Pd Vanilla has its own external manager! This is a
built in .tcl plug-in named "deken" So you can just open Pd, click on the "Help" menu and select Help >
Find externals. Then you can just type the library's name you want and hit
enter or click "search". You can also look for an external name and the library
that contains it might be shown. All available versions of the library specific for
your operating system will be shown to you. See figure below.
Figure 4.4 - Searching for External Libraries from Pd Vanilla
When you click on the version you want, by default, Pd asks if you want
to download it to the external folder set under Preferences => Path. If you say
no, you can specify somewhere else to download it to. If you say yes, there is
where it gets downloaded to.
The current best practice is to use the [declare] object, but there are
alternatives. If the library is a single binary pack, it needs to be loaded so you
can create externals. This is done either via the [declare] object or manually
via Preferences => Startup.
Now, if the external library only contains abstractions or objects
compiled as a set of separate binaries, Pd just needs to know its. Again, this
can be done with [declare] or manually (via Preferences => Path).
The [declare] object from Pd Vanilla behaves quite similarly to adding
search paths to the user added paths (under Preferences => Path) or adding
libraries (under Preferences => Startup). The difference is that it'll only work
for the patch containing the [declare]. This means that when you add
manually via preferences, it installs it permanently and for any patch.
Let's take for an example the ELSE library (http://github.com/porres/pd-else) . This library contains 2
separate binaries and abstractions, so Pd only needs to know its location
path. So we can do something like [declare -path else] and Pd will look for a
folder named else to add it to the search path.
But where does Pd look the else folder? In the locations it knows where
to look (the Relative Path, the Standard Paths or the User Added Paths). So
let's say you downloaded the else library folder into "~/Documents/Pd/
externals", which is the current best practice. Pd will know to look for it there
and will find it!
This is needed for the classic Pd library format, which is a single binary
pack with many externals. One such example is the "zexy" library. So once
you have downloaded it, you can use [declare -lib zexy]. In the same way, Pd
will search for the zexy binary in locations it knows where to look (as in "~/
Documents/Pd/externals").
Does this mean you need to also include the zexy folder path, so Pd
knows to search for the zexy binary inside? Not really, because there's a trick
here. If Pd finda a 'zexy' location, it knows it can look inside it for the 'zexy'
binary, so it will succeed in finding it just with that!
This is basically the same as using [declare] but it will permanently work
every time Pd starts and for any patch.
You can add User Added Paths in Preferences => Path. We've seen
that even if you have a folder into "~/Documents/Pd/externals" you still need
to tell Pd to look for it. You can do this manually added to Pd's search paths
so it can be automatically by clicking "New".
Another possibility is that "Deken"offers a preference tabs where you
can click once on "Should newly installed libraries be added to Pd's search
Path?" to prompt you if you want to add a downloaded library to the user
added search paths after you download it. By default, it never asks you to do
it. You can also click twice so it always add anything you download from
deken to the search path, which is not quite recomended as sometimes you'll
download a single binary pack, where adding it to the search path doesn't
really help.
In "Preferences => Startup", you load a window that says "Pd libraries
to load on startup". This is where you can manually and permanently load
single binary pack libraries. As we've seen with 'zexy', it's common that the
name of the binary is the same as the library's, so you don't need to worry
about setting the path. Another example is the 'cyclone' library,
Figure 4.5 - Loading the cyclone and zexy binaries/libraries in "Startup"
As previously mentioned, cyclone 0.3 is a special case that includes
objects as abstractions, as a set of separate binaries but also has a set a
single binary pack that loads objects with non alphanumeric names, which
need to be loaded as a single binary pack to avoid issues. One particularity of
cylone is that loading its binary will also force Pd to add its path to the search
paths, so you don't need to bother adding it to the path as well so you can
load its abstractions or separate binaries.
It depends on the developer, but it is common and a good practice that
when you load a library, Pd's terminal window will print something to tell us
that the libraries were loaded successfully. Here's a screenshot of the result
of loading cyclone and zexy via the startup (same happens if you load them
via [declare], clearly).
Figure 4.6 - Pd's terminal window after loading cyclone and zexy
You can also use slash declarations to search for libraries in
paths that are relative to these. For instance, let's say you downloaded the
ELSE library into ~/Documents/Pd/externals, or any other folder Pd will
eventually search for. Instead of using [declare -path] or adding the ELSE
folder to the user added paths, you can just prepend "else/" before an object
name that Pd will try to find this object in a folder called else in one of its
search paths! Here's an example:
Note that if you do that, you can still add the 'else' folder to Pd's search
path or use [declare -path else], but it will just be redundanct. Now, what are
the diffences of this method over using [declare] or adding the path to the
user added paths? The only use case is if you have two externals with the
same name from two different libraries in the same patch. With this method
you can specify which one is which!
A library name prefix may also be pertinent in the context of single
binary packs. The cyclone library has a set of 12 objects with non
alphanumeric names, such as [>~]. But it uses an internal trick of adding a
class creator, so creating the object as [cyclone/>~] also works. But note that
the library still needs to be loaded anyway (via startup or [declare]).
There's also the case where you can find a single binary pack that has
a different name than that of the library. One example is timbreID, which has
a timbreIDLib as the binary file. In this case you need to specify the timbreID
folder with a slash declaration as in "timbreID/timbreiIDLib" in Startup. This
also works in declare as in [declare -lib timbreID/timbreiIDLib].
4.4. Loading Externals
4.4.1. Using the [declare] object:
4.4.1.1. [declare -path]:
4.4.1.2. [declare -lib]:
4.4.2. Using Path and Startup:
4.4.2.1. User added Path:
4.4.2.2. Startup:
4.4.3. Slash declarations: