Tuesday 2013.06.18

FRACT Audio Tech: Identifying Patches

Last week I discussed how we can use remote messages to receive messages sent from code, and have them delivered to the right parts of our patch. But there’s a problem: we don’t just want to have one instance of our synth patch, we want to have multiple voices playing alongside each other. If we just make multiple instances, they’ll end up all taking remote messages with the same name, and we’ll be left with no way to differentiate between them. This is what that looks like:

1

(yeah, in this case the sound isn’t actually going anywhere, but bear with me)

To solve this, we’re going to give each instance of our synth a name. The convention I use is that every patch in FRACT OSC that corresponds to a unique emitter takes a special first argument, which it will use as its name. Inside the patch, we then prefix each message with $1-, which splices the patch’s first argument into the beginning of the message’s name, like so:

2

This way there’s no ambiguity; when we send the message, we prefix the message name with the name of the object we want to send the message to, and only that object will receive it.

At this point I should mention a special patch argument which Pure Data creates automatically, $0. For any abstraction (i.e. a patch saved in its own file), $0 is a unique name Pure Data generates for that instance of the patch. In fact, $0 is conventionally used to prefix internal patch messages similarly to our use of $1. Why don’t we use $0 instead?

The main reason is that we have no good way of predicting what value $0 will have external to the patch. Within the patch, you can send a message into a [send $0-message-name] object and then just receive it at a [receive $0-message-name] and know that they will automatically match up, but when we create a new patch there isn’t an easy way to tell what $0 is. Another reason is that by choosing our own object name we can use something that’s human-readable, or that corresponds to something in the game engine. For example, you could decide to name the patches after their voice IDs. This way if you get errors telling you that Pure Data couldn’t find the receiver for a message, you can tell just by the name which object it was supposed to go to, and often which object in your engine the message originated from.

Another advantage is that you can further give $1 as arguments to sub-patches that add their own functionality. For example, in FRACT OSC most patches take the same types of messages for managing their position in the world, for panning purposes. The panning functionality is common and implemented in a shared sub-patch. Using this scheme means I can have the panning sub-patch accept the messages itself, rather than doing something messy like having the outer patch receive the messages and pass them inwards.

$0 is still useful for internal messages, though. In my own patches, I typically use a $1- prefix for public messages received from other patches and from the game, and $0- for private ones that a patch sends to itself.

- Henk

More in our audio tech series:
Part 1: Getting Started
Part 2: Connecting to Pure Data
Part 3: Wrapping Pure Data
Part 4: Message Basics
Part 5: Identifying Patches