pd-chuck

February 8, 2026 · View on GitHub

Embeds the ChucK audio engine in a puredata external.

The chuck~ external works on MacOS and Linux and uses a bleeding edge ChucK version: 1.5.5.8-dev (chai). It has the following features:

  • Generate and process audio by running chuck files and evaluating chuck code with global parameters controlled and adjusted in realtime by pd messages.

  • Layer sounds from a single instance by running multiple chuck files concurrently.

  • Add, remove, replace audio and audio processes on the fly using chuck messages via pd messages.

  • Interact with pd via MIDI and OSC protocols.

  • Includes support for callbacks and events via the signal and broadcast messages.

see chuck_tilde/help-chuck.pd for a basic overview of current features, and chuck_tilde/test for feature-specific test patches.

Also included are the following:

  • The complete set of current chuck examples

  • All of the CCRMA chugins including WarpBuf, Fauck (Faust) and FluidSynth.

  • PdPatch chugin for loading and running Pure Data patches inside ChucK, with bidirectional messaging, array access, and MIDI support.

  • Optional plugin-hosting chugins: AbletonLink, AudioUnit (macOS), CLAP, and VST3.

  • Many pd patches to test and demonstrate usage.

  • Contributed patchers and code examples.

For the impatient: download the pd-chuck package with pre-compiled externals and chugins from the the project's Releases section and check out the cheatsheat.

Note that pd-chuck has a sibling in the chuck-max project.

Usage

The pd-chuck package consists of the following folders:

pd-chuck
├── chuck_tilde
  ├── examples
  ├── ai
  ├── ...
  ├── chugins
  ├── ...
  ├── data
  ├── ...
  ├── fauck
  ├── faust
  ├── ...
  ├── pd
  ├── ...
  ├── test
  ├── ...
  └── warpbuf
  └── tests
├── docs
├── scripts
└── thirdparty
    ├── chuck
    └── chugins

Start with the help-chuck.pd file in the chuck_tilde folder for an overview of the external's features.

The examples directory in the same folder contains all chuck examples from the chuck repo, and some additional folders: chugins containing chugin binaries, fauck, containing faust.chug examples, faust, containing the faust stdlib, pd chuck files which are used by pd patches. There are also quite a few patches demonstrating one feature or other in the tests folder,

Overview

The chuck~ object supports configurable I/O channels and optional tap outlets for reading global UGen samples:

  • [chuck~] - 2 I/O channels (default), 0 tap outlets
  • [chuck~ 4] - 4 I/O channels, 0 tap outlets
  • [chuck~ 2 4] - 2 I/O channels, 4 tap outlets
  • [chuck~ filename.ck] - 2 I/O channels, runs file on load (backward compatible)
  • [chuck~ 4 2 filename.ck] - 4 I/O channels, 2 tap outlets, runs file on load

If a <filename> argument is given it will be searched for according to the following rules:

  1. Assume it's an absolute path, use it if it exists.

  2. Assume that it's a partial path with the package's examples folder as a prefix. So if stk/flute.ck is given as <filename>, the absolute path of the package examples folder is prepended to it and if the resulting path exists, it is used.

  3. Assume <filename> exists in the parent patcher's directory. Test that this is the case and if it is, use it. This is useful if you want to package patchers and chuck files together.

Core Messages

As of the current version, chuck~ implements the core Chuck vm messages as puredata messages:

ActionPuredata msgPuredata msg (alias)
Add shred from fileadd <file> [arg1 arg2 .. ]+ <filepath> [args]
Run chuck file (save last used)run <file>
Eval code as shredeval <code>
Remove shredremove <shredID>- <shredID>
Remove last shredremove last
Remove all shredsremove all
Remove all shreds (keep VM state)removeall
Replace shredreplace <shredID> <file>= <shredID> <file>
List running shredsstatus
Shred introspectionshreds [subcommand]
Clear vmclear vmreset
Clear globalsclear globals
Reset idreset id
Timetime

It's worth reading the ChucK Language Specification's section on Concurrency and Shreds to get a sense of what the above means. The first paragraph will be quoted here since it's quite informative:

ChucK is able to run many processes concurrently (the process behave as if they are running in parallel). A ChucKian process is called a shred. To spork a shred means creating and adding a new process to the virtual machine. Shreds may be sporked from a variety of places, and may themselves spork new shreds.

Utility Messages

The core set of chuck vm messesages is also extended in pd-chuck with the following utility messages:

ActionPuredata msg
Set file attribute (does not run)file <path>
Set full path to editor attributeeditor <path>
Prevent running shreds when dsp is offrun_needs_audio
Open file in external editoredit <path>
Probe chuginschugins
Get/set loglevel (0-10)loglevel & loglevel <n>
Get state of chuck vmvm
Launch chuck docs in a browserdocs
Get/set adaptive modeadaptive & adaptive <n>
Get/set VM parametersparam [name] [value]
Tap global UGen samplestap [outlet] [ugen_name]

Parameter Messages

Once a shred is running you can change its parameters by sending values from puredata to the chuck~ object. To this end, ChucK makes available three mechanisms: global variables, global events, and callbacks which are triggered by events. chuck~ maps these chuck language elements to corresponding puredata constructs as per the following table:

ActionChucKPuredata msg
Change param value (untyped)global variable<name> <value>
Dump global variables to consoleglobal variableglobals
Trigger named eventglobal eventsig <name>
Trigger named event all shredsglobal eventbroadcast <name>

You change a global variable by sending a <variable-name> <value> message to a chuck~ instance where the value can be an int, float, string, array of ints or floats, etc. You can also trigger events by sending sig or signal messages, broadcast messages as per the above table.

Note: You can't use the ChucK types of dur or time in pd. Also, while in the above case, the pd msg seems untyped, it must match the type of the chuck global variable. So if you connect a pd number or flownum object to a message box, it needs to match the type of the global variable (int/float).

See chuck_tilde/help-chuck.pd and patchers in the tests directory for a demonstration of current features.

Shred Introspection

The shreds message provides detailed information about running shreds:

ActionPuredata msg
List all shredsshreds
List all shred IDsshreds all
List ready shredsshreds ready
List blocked shredsshreds blocked
Get shred countshreds count
Get highest shred IDshreds highest
Get last shred IDshreds last
Get next shred IDshreds next
Get info about specific IDshreds <id>

Tap Outlets

Tap outlets allow you to read samples directly from global UGens in your ChucK code. This is useful for analysis, visualization, or routing specific UGen outputs separately from the main mix.

To use tap outlets, create the object with tap channels: [chuck~ 2 4] creates 2 I/O channels and 4 tap outlets.

ActionPuredata msg
Clear all tap outletstap
Set all outlets to same UGentap <ugen_name>
Clear specific outlet (1-based)tap <outlet>
Set specific outlet to UGentap <outlet> <ugen_name>

Example ChucK code with a global UGen to tap:

SinOsc s => dac;
s => Gain myGain => blackhole;  // myGain is global, can be tapped
440 => s.freq;
while(true) 1::second => now;

Then in Pd: tap 1 myGain routes the output of myGain to tap outlet 1.

Parameter Messages using Callbacks (Advanced Usage)

In addition to the typical way of changing parameters there is also an extensive callback system which includes listening / stop-listening for events associated with callbacks, triggering them via sig and broadcast messages and also setting typed global variables via messages and symmetrically getting their values via typed callbacks:

ActionChucKPuredata msg
Listen to event (one shot)global eventlisten <name> or listen <name> 0
Listen to event (forever)global eventlisten <name> 1
Stop listening to eventglobal eventunlisten <name>
Trigger named callbackglobal eventsig <name>
Trigger named callback all shredsglobal eventbroadcast <name>
Get int variableglobal variableget int <name>
Get float variableglobal variableget float <name>
Get string variableglobal variableget string <name>
Get int arrayglobal variableget int[] <name>
Get float arrayglobal variableget float[] <name>
Get int array indexed valueglobal variableget int[i] <name> <index>
Get float array indexed valueglobal variableget float[i] <name> <index>
Get int associative array valueglobal variableget int[k] <name> <key>
Get float associative array valueglobal variableget float[k] <name> <key>
Set int variableglobal variableset int <name> <value>
Set float variableglobal variableset float <name> <value>
Set string variableglobal variableset string <name> <value>
Set int arrayglobal variableset int[] <name> v1, v2, ..
Set float arrayglobal variableset float[] <name> v1, v2, ..
Set int array indexed valueglobal variableset int[i] <name> <index> <value>
Set float array indexed valueglobal variableset float[i] <name> <index> <value>
Set int associative array valueglobal variableset int[k] <name> <key> <value>
Set float associative array valueglobal variableset float[k] <name> <key> <value>

Building

pd-chuck is currently developed and tested on macOS and Linux. For both of these platforms, it provides a make-based frontend and uses cmake as the backend build system.

This project provides for building two general variants depending on the need of end-user:

  1. The base system consists of the chuck~ external and the base CCRMA chugins. This is already more than sufficient for more than 80% of users. The base system is relatively easy to build and only needs a c++ compiler, cmake, make, bison and flex.

  2. The advanced system consists of the base system above plus chugins which are relatively more challenging to build and use: Faust.chug, WarpBuf.chug, FluidSynth.chug, and PdPatch.chug.

On macOS requirements for the variants can be installed using Homebrew as follows:

brew install cmake bison flex fluidsynth automake autogen libtool rubberband libsamplerate

On Debian Linux, requirements can be installed via:

sudo apt install build-essential cmake bison flex libsndfile1-dev libasound2-dev libpulse-dev libjack-jackd2-dev libmpg123-dev libmp3lame-dev libresample1-dev librubberband-dev libfluidsynth-dev

Each build option has a Makefile target as follows:

Makefile targetaliasfaustwarpbuffluidsynth.wav.mp3.others
fullxxxxx
nomp3xxxx
lightxxx
macos-base-nativemakex
macos-base-universalx
macos-adv-brewmake macosxxxxxx
linux-base-alsamakex
linux-base-pulsex
linux-base-jackx
linux-base-allx
linux-adv-alsamake linuxxxxxx
linux-adv-pulsexxxxx
linux-adv-jackxxxxx
linux-adv-allxxxxx

Note: .others includes support for .flac, .ogg, .opus, and .vorbis formats

To get a sense of build times, the following table (for macOS builds on an M1 Macbook Air) should be illustrative:

build commandbuild time (secs)
make macos-base-native55.074
make macos-adv-brew1:29.24
make macos-base-universal1:44.31
make macos-adv-light2:27.28
make macos-adv-nomp32:50.15
make macos-adv-full3:14.91

If you'd rather use the more verbose cmake build instructions directly, feel free to look at the Makefile which is quite minimal.

A. The Base System

The base chuck-max system consists of a puredata package with the chuck~ external, the base CCRMA chugins and extensive examples, tests and puredata patchers.

If you have installed the prerequisites above, to get up and running on either system with the default build option:

git clone https://github.com/shakfu/pd-chuck.git
cd pd-chuck
make

The complete list of base build options are:

  • make or make macos-base-native: builds the external using your machine's native architecture which is arm64 for Apple Silicon Macs and x86_64 for Intel Macs. This is the default build option on macOS.

  • make macos-base-universal: build the external as a 'universal' binary making it compatible with both Mac architectural variants. This is useful if you want share the external with others in a custom pd package.

  • make or make linux-base-alsa: builds the external on Linux using the default ALSA audio driver. This is the default build base option for Linux.

  • make linux-base-pulse: builds the external on Linux using the PULSE audio driver.

  • make linux-base-jack: builds the external on Linux using the JACK audio driver.

  • make linux-base-all: builds the external on Linux with support for ALSA, PULSE and JACK audio drivers.

B. The Advanced System

The advanced system consists of the base system + two advanced chugins, Faust.chug and WarpBuf.chug:

  1. The Fauck chugin contains the full llvm-based faust engine and dsp platform which makes it quite powerful and also quite large compared to other chugins (at around 45 MB stripped down). It requires at least 2 output channels to work properly. It also uses the libsndfile library.

  2. The WarpBuf chugin makes it possible to time-stretch and independently transpose the pitch of an audio file. It uses the rubberband, libsndfile, and libsamplerate libraries.

  3. The FluidSynth chugin, enables a real-time software synthesizer based on the SoundFont 2 specifications, (see above for requirements).

  4. The PdPatch chugin wraps libpd to load and run Pure Data patches inside ChucK, with stereo audio, bidirectional messaging, array access, and MIDI. Build with make build_pd or -DENABLE_PDPATCH=ON. No external dependencies -- libpd is fetched and built automatically.

If you have installed the prerequisites above, it should be possible the advanced system with one of the following options:

  • make macos-adv-brew or make macos: build the external using the previously installed homebrew dependencies, as well as downloaded faust headers and a downloaded pre-compiled libfaust (libfaustwithllvm) library. This is the newer, faster, recommended way of getting a full chuck-max system up and running.

  • make macos-adv-full: build the external by manually downloading and building all of the dependencies except for libfaust from source. This is the previous way of building an advanced system. It is currently only for advanced developers who want maximum flexibility in their builds.

  • make macos-adv-nomp3: same as make full except without support for the .mp3 format. Try this variant if you are unable to build using make full on Intel Macs or on older macOS versions.

  • make macos-adv-light: Same as make full except for withouth libsndfile multi-file format support. This means that (.mp3, flac, vorbis, opus, ogg) formats are not supported in this build. Only .wav files can be used.

  • make linux-adv-alsa or make linux: builds the external on Linux using the default ALSA audio driver. This is the default advanced option for Linux.

  • make linux-adv-pulse: builds the external on Linux with advanced options using the PULSE audio driver.

  • make linux-adv-jack: builds the external on Linux with advanced options using the JACK audio driver.

  • make linux-adv-all: builds the external on Linux with advanced options and support for ALSA, PULSE and JACK audio drivers.

C. PdPatch Chugin (Optional)

The PdPatch chugin wraps libpd to load and run Pure Data patches inside ChucK. It supports stereo audio I/O, bidirectional messaging, Pd array access, and MIDI send. libpd is automatically fetched and statically linked via CMake FetchContent -- no external dependencies required.

make build_pd

Or manually: cmake .. -DENABLE_PDPATCH=ON && cmake --build . --config Release

To run the PdPatch test suite: make test-pdpatch

See thirdparty/chugins/PdPatch/README.md for the full API reference.

D. Plugin-Hosting Chugins (Optional)

pd-chuck includes optional chugins for hosting audio plugins within ChucK. These require additional CMake flags to enable:

ChuginPlatformCMake FlagSDK Source
AbletonLinkAll-DENABLE_ABLETONLINK=ONAuto-fetched from GitHub
AudioUnitmacOS only(built automatically)macOS frameworks
CLAPAll-DENABLE_CLAP=ONHeaders included
PdPatchAll-DENABLE_PDPATCH=ONAuto-fetched from GitHub
VST3All-DENABLE_VST3=ONAuto-fetched from GitHub

To build with all plugin-hosting chugins enabled:

cd build
cmake .. -DENABLE_ABLETONLINK=ON -DENABLE_CLAP=ON -DENABLE_VST3=ON -DENABLE_PDPATCH=ON
cmake --build . --config Release

The AbletonLink, VST3, and libpd SDKs are automatically cloned from GitHub during configuration if not already present. This may take additional time on the first build.

Credits

This project thanks the following:

  • Professors GE Wang and Perry Cook and all chuck and chuggin contributors for creating the amazing ChucK language and chuggin ecosystem!

  • Professor Perry Cook for co-authoring Chuck and creating the Synthesis Toolkit which is integrated with chuck.

  • Professor Brad Garton for creating the original chuck~ external for Max 5. My failure to build it and run it on Max 8 motivated me to start this project.

  • David Braun, the author of the very cool and excellent DawDreamer project, for creating the excellent ChucKDesigner project which embeds chuck in a Touch Designer plugin. His project provided a super-clear blueprint on how to embed libchuck in another host or plugin system and was essential to this project.