Archive for the ‘ Pure Data ’ Category

News – 4/21/2012

Some news:

  • My short paper “DIY Hybrid Analog/Digital Modular Synthesis” – which covers the USB-Octomod, tabulaRasa, and snake.corral –  has been accepted for NIME 2012, and I will present a poster version at the conference. The conference runs from May 21 – 23, in Ann Arbor, MI.
  • I will perform 4/27 at UCSD and 4/28 as part of the California Electronic Music Exchange Concert series.
  • Finally, I’ve started posting some live coding videos:

Preset Management in Pure Data

96 Independent Parameters

I recently spent a few hours putting together a preset manager in Pure Data. The above image shows a set of controls for 8 independent (but identical) signal processing channels. Clearly, 96 parameters is too many to realistically handle in performance, so I needed some way to store and recall settings. As shown in the image, each parameter has a [receive] object which listens for messages of a specific type. Then, a [route] object filters out all messages except those meant for that specific parameter instance.

Here’s the object preset-manager.pd - though it will take a decent amount of modification to get it to work for another patch.

The preset manager interface.

Above is the preset manager interface. A particular slot is accessed via the number box, and that slot can be read or written to with a message box.

Innards of the preset manager object.

Here are the innards of the preset manager object. The block on the right stores presets, and the block on the left recalls them. Presets are stored as raw text files, named with sequential numbers, and are formatted like this:

filter-bypass 1 1 1 1 0 0 0 0;
filter-rate-mod 0.02 0.81 0 50 0 0 0 0;
filter-rate 0.22 0.66 0.95 106 0 0 0 0;
am-bypass 1 1 0 1 0 0 0 0;
am-width 0 0.5 0.52 87 0 0 0 0;
am-rate-mod 16 0.38 0.54 46 0 0 0 0;
am-rate 2.02 1.48 2.54 3.83 0 0 0 0;
fm-bypass 0 0 0 1 0 0 0 0;
fm-rate 173 97 25 1.64 0 0 0 0;
fm-pos/width 55 64 108 96 0 0 0 0;
fm-mode 2 2 2 1 1 0 0 0;
fm-register 1 0 2 2 1 1 1 0;

Each parameter type is followed by eight values – one for each channel. The [textfile] object works really well for reading and writing text files line-by-line.

Code for writing a preset.

Code for reading a preset.

Octomod PD-Extended object, and modified NRCI library.

Hi,
I’ve made an Octomod object in PD-extended and bundled it with a modified version of the NRCI library I co-developed a few years ago. It’s got a great set of control data and rhythm generators, which make it really easy to get some interesting patterns up and running quickly – and now sent out over OSC to the Octomod Processing app.
Here’s the PD-Object and library:
http://gregsurges.com/wp-content/uploads/2010/08/nrci-octomod.zip
(open the -workspace.pd file)
And for more info on the use of NRCI:
https://ccrma.stanford.edu/~cburns/NRCI/
Check it out, and let me know what you think!
- Greg

Screen shot 2010-10-19 at 4.27.05 PM

I’ve made an Octomod object in PD-Extended and bundled it with a modified version of the NRCI library I co-developed a few years ago. It’s got a great set of control data and rhythm generators, which make it really easy to get some interesting patterns up and running quickly – and now sent out over OSC to the Octomod Processing app.

Here’s the PD-Object and library. (open the -workspace.pd file)

And for more info on the use of NRCI:

https://ccrma.stanford.edu/~cburns/NRCI/

Write your own Pure Data External! (Part 4)

In this section of the tutorial, I’m going to write about the randomwalk_new() function.

As you can see (in the code available here), the function takes three arguments. These are generic arguments, used in the *_new() function of every external you’ll write. The arguments are as follows:

t_symbol *s – a pointer to the symbolic representation of the objects name. You don’t have to worry about this, it’s for PD.

int argc – the number of arguments the user has entered, following the name of the object.

t_atom *argv – a pointer to the first of these arguments.

You’ll use argc to tell you how many arguments to read, starting from the argv pointer. This allows you to create an object that uses default values if a user doesn’t enter all of the required arguments.

In randomwalk.c, I’m using a switch statement to check the number of arguments provided, and then read the user-provided arguments into their proper variables. The atom_getfloat() function simply takes one of the arguments (of the PD type atom) and returns a C/C++ float, which can be assigned to a variable.

Below that, I reuse the argc count to determine which variables have to be assigned to defaults. Finally, I do some error checking to make sure that the highbound is actually a higher number than the lowbound, and swap if needed. This kind of error checking is very important to avoid crashes when actually using the object.

Finally, we have to assign inlets and outlets. The three calls to floatinlet_new() assign inlets which allow direct assignment of the lower, upper, and step variables from PD. There should probably be some error checking here too, because what would happen if a user input a list or a symbol instead? We also define f_out to be an outlet, using outlet_new() which takes two arguments, a reference to the object itself, and the type of value that will be output.

The return statement simply returns the initialized object to PD, ready for use.

Write your own Pure Data external! (Part 3)

In this part of the tutorial (Part 1, Part 2), I’m going to talk about the first of two functions that PD calls when you ask it to create an instance of your object.

The first is the setup function. In my example file, it’s called:

void randomwalk_setup()

Here, you can see I’m finally defining the randomwalk_class that was declared above. The class_new function provides PD with some important information about the object. The interface is as follows:

t_class *class_new(t_symbol *name,
t_newmethod newmethod, t_method freemethod,
size_t size, int flags,
t_atomtype arg1, ...);

Obviously, I’m defining the name of the object here, with the gensym("randomwalk") code.

Below that, we allocate some memory with sizeof(t_randomwalk) (this returns the size in memory of our struct from above). You’ll probably never have to worry about the int flags argument, it’s mainly for the GUI representation of the object.

Finally, the t_atomtype arg1 stuff lets you define what kinds of arguments the object should expect. Here, the A_GIMME lets you provide a list of atoms of arbitrary length and types. You can check out Johannes’ tutorial for the full list of possible arguments here.

The last thing in the randomwalk_setup() function is class_addbang(randomwalk_class, randomwalk_bang);

This is where you declare the function your object will call when it receives a particular type of message in it’s inlet. The first argument should be the name of your class, and the second should be the name of a function which will be called.

In the next part, I’ll talk about the *randomwalk_new() function, which handles all of the arguments to your object.

Write your own Pure Data External! (Part 2)

So, the first thing you’ll want to do is create a folder for your project. In the folder, you’ll want a copy of the files in this .zip archive. m_pd.h is a header file which you will use in every external you write. It allows your external to use the functions defined for use by PD. The makefile will automate the compilation process. You’ll want to edit it (using a text editor) to make sure the path to your PD.app is correct.

The .zip also contains a file called randomwalk.c that I’ll be using as the example file for these tutorials. Open it in your text editor. Skipping over the comment at the top, you’ll notice that I’m #include-ing m_pd.h. You’ll have to do that for every external, assuming you want it to compile.

Skip down a bit to this chunk of code:

static t_class *randomwalk_class; // declares a pointer to the object

typedef struct _randomwalk
{
t_object x_obj; // the required t_object
t_float current; // the current value
t_float step; // step width
t_float lower, upper; // bounds
t_outlet *f_out; // outlet pointer
} t_randomwalk;

The first line declares a pointer to your object, which will allow PD to reference it. We’ll define it below.

This defines the variables that your object will have access to. Every object needs to have the t_object x_obj; line, this allows the object to store PD-specific information, which we don’t have to worry about right now. You’ll notice that the next three variables are all of t_float type. This is essentially the same as a float variable, but PD defines it’s own atomic types, which are used to facilitate portability cross-platform. Here, I’ve defined three variables for the random-walk procedure. Finally, the t_outlet *f_out; is a pointer to an outlet. The name f_out is just a convention so that we remember that this outlet is going to output float's.

In the next segment, I’ll talk about our setup function, found in the

void randomwalk_setup() function below.

Write your own Pure Data external! (Part 1)

This document will (hopefully) serve as an easy to read and understand introduction to the process of writing an external for Pure Data. Pure Data, or PD, is a visual programming environment designed for real-time computer music applications. PD is open-source software, under the BSD license, and expansion of the software in the form of externals is strongly encouraged.

PD and its externals are written in the C programming language. When PD is running an external, it makes no distinction between the ‘core’ functionality and the external code. There are hundreds of user-written externals freely available for use and study. As you learn to write externals yourself, I strongly encourage studying other people’s code. For example, I learned about timing issues from studying the “pipe” object.

To get started coding an external, you’ll need a text editor. I use Textwrangler, but there are a few good, free editors out there. Get one with syntax highlighting. You’ll also need to install GCC, the Gnu C Compiler, and Make. If you’re on OS X, you can just install Apple’s XCode Developer Tools, and you’ll have both of these programs installed. I’m going to assume some knowledge of using the command line here, so I won’t explain how to use GCC or run Make. (Hint: type “make”.) You’ll also need an installation of PD, so that you can link and run your externals.

In the next post, I’ll talk about the basic concepts and chunks of code that you’ll need to write your external.