Overview
The pd::Instance class wraps libpd and provides a C++ interface for managing Pure Data instances. It handles DSP processing, MIDI events, message passing, patch loading, and communication between the GUI and the Pure Data audio engine.
Location: Source/Pd/Instance.h
Class Declaration
namespace pd {
class Instance : public AsyncUpdater {
// ...
};
}
Constructor and Initialization
Creates a new Pure Data instance. Each instance is isolated from others.
void initialisePd(String& pdlua_version);
Initialize Pure Data and load required libraries. Call this before using the instance.
DSP Control
void prepareDSP(int nins, int nouts, double samplerate);
Prepare DSP processing with specified channel counts and sample rate.Parameters:
nins - Number of input channels
nouts - Number of output channels
samplerate - Sample rate in Hz
void startDSP();
void releaseDSP();
Start or stop DSP processing.
void performDSP(float const* inputs, float* outputs);
Process one block of audio. Call this from your audio callback.Parameters:
inputs - Interleaved input audio buffer
outputs - Interleaved output audio buffer
Buffer size is determined by getBlockSize().
static int getBlockSize();
Get Pure Data’s block size (typically 64 samples).
Sending MIDI to Pure Data
void sendNoteOn(int channel, int pitch, int velocity) const;
Send MIDI note on message.
void sendControlChange(int channel, int controller, int value) const;
Send MIDI control change message.
void sendProgramChange(int channel, int value) const;
Send MIDI program change message.
void sendPitchBend(int channel, int value) const;
Send MIDI pitch bend message (value range: 0-16383).
void sendAfterTouch(int channel, int value) const;
Send MIDI channel aftertouch message.
void sendPolyAfterTouch(int channel, int pitch, int value) const;
Send MIDI polyphonic aftertouch message.
void sendMidiByte(int port, int byte) const;
void sendSysEx(int port, int byte) const;
void sendSysRealTime(int port, int byte) const;
Send raw MIDI bytes, SysEx, or real-time messages.
Receiving MIDI from Pure Data
These are pure virtual methods that must be implemented by subclasses:
virtual void receiveNoteOn(int channel, int pitch, int velocity) = 0;
virtual void receiveControlChange(int channel, int controller, int value) = 0;
virtual void receiveProgramChange(int channel, int value) = 0;
virtual void receivePitchBend(int channel, int value) = 0;
virtual void receiveAftertouch(int channel, int value) = 0;
virtual void receivePolyAftertouch(int channel, int pitch, int value) = 0;
virtual void receiveMidiByte(int port, int byte) = 0;
Callbacks for MIDI messages coming from Pure Data (e.g., from [noteout], [ctlout], etc.).
Sending Messages to Pure Data
void sendBang(char const* receiver) const;
Send bang to a receiver.Example:instance->sendBang("trigger-event");
void sendFloat(char const* receiver, float value) const;
Send float value to a receiver.Example:instance->sendFloat("frequency", 440.0f);
void sendSymbol(char const* receiver, char const* symbol) const;
Send symbol to a receiver.Example:instance->sendSymbol("mode", "lowpass");
void sendList(char const* receiver, SmallArray<pd::Atom> const& list) const;
Send list of atoms to a receiver.Example:SmallArray<pd::Atom> list = {1.0f, 2.0f, 3.0f};
instance->sendList("data-receiver", list);
void sendMessage(char const* receiver, char const* msg, SmallArray<pd::Atom> const& list) const;
Send named message with arguments to a receiver.Example:SmallArray<pd::Atom> args = {100.0f, 200.0f};
instance->sendMessage("osc", "range", args);
void sendDirectMessage(void* object, SmallString const& msg, SmallArray<Atom>&& list);
void sendDirectMessage(void* object, SmallArray<pd::Atom>&& list);
void sendDirectMessage(void* object, SmallString const& msg);
void sendDirectMessage(void* object, float msg);
Send message directly to a specific Pure Data object (not by name).
Patch Management
Patch::Ptr openPatch(File const& toOpen);
Open a Pure Data patch file. Returns a smart pointer to the loaded patch.Example:auto patch = instance->openPatch(File("/path/to/synth.pd"));
if (patch) {
DBG("Patch loaded successfully");
}
patches
SmallArray<pd::Patch::Ptr>
SmallArray<pd::Patch::Ptr, 16> patches;
Array of all currently opened patches.
Message Listeners
void registerMessageListener(void* object, MessageListener* messageListener);
void unregisterMessageListener(MessageListener* messageListener);
Register/unregister listeners for messages from specific Pure Data objects.
Thread Safety
void lockAudioThread();
void unlockAudioThread();
Lock/unlock the audio thread mutex. Use this when accessing Pure Data from the GUI thread.Example:instance->lockAudioThread();
// Safe to modify Pure Data state here
instance->sendFloat("param", value);
instance->unlockAudioThread();
void enqueueFunctionAsync(std::function<void()> const& fn);
template<typename T>
void enqueueFunctionAsync(WeakReference& ref, std::function<void(T*)> const& fn);
Enqueue a function to be executed safely from the message thread.Example:instance->enqueueFunctionAsync([this]() {
// This runs on the message thread
updateGUI();
});
Symbol Generation
t_symbol* generateSymbol(String const& symbol) const;
t_symbol* generateSymbol(SmallString const& symbol) const;
t_symbol* generateSymbol(char const* symbol) const;
Generate a Pure Data symbol from a string. Symbols are interned (unique).
Console and Logging
void logMessage(String const& message);
void logError(String const& message);
void logWarning(String const& message);
Log messages to the plugdata console.
std::deque<std::tuple<void*, String, int, int, int>>& getConsoleMessages() const;
std::deque<std::tuple<void*, String, int, int, int>>& getConsoleHistory() const;
Access console message queues.
Virtual Methods (Must Implement)
virtual void receiveSysMessage(SmallString const& selector, SmallArray<pd::Atom> const& list) = 0;
Receive system messages from Pure Data.
virtual void updateConsole(int numMessages, bool newWarning) = 0;
Called when console needs updating.
virtual void titleChanged() = 0;
Called when patch title changes.
Properties
Pointer to the underlying libpd instance.
Pure Data receiver for system messages.
Pure Data receiver for parameter messages.
Mutex for thread-safe audio operations.
Usage Example
// Create and initialize instance
class MyPdInstance : public pd::Instance {
public:
void receiveNoteOn(int ch, int pitch, int vel) override {
DBG("Note: " + String(pitch));
}
void receiveSysMessage(SmallString const& sel, SmallArray<pd::Atom> const& list) override {
// Handle system messages
}
void updateConsole(int num, bool warn) override { }
void titleChanged() override { }
// ... implement other virtual methods
};
MyPdInstance instance;
String pdluaVer;
instance.initialisePd(pdluaVer);
instance.prepareDSP(2, 2, 48000.0);
instance.startDSP();
// Load and use a patch
auto patch = instance.openPatch(File("synth.pd"));
instance.sendFloat("frequency", 440.0f);
instance.sendBang("trigger");
// In audio callback
instance.performDSP(inputs, outputs);
See Also
PluginProcessor - Inherits from pd::Instance
pd::Patch - Patch management
pd::Atom - Pure Data atom wrapper
MessageListener - Message listening interface