npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cdp-wasm

v0.6.0

Published

CDP (Composers Desktop Project) audio processing programs compiled to WebAssembly, for Node.js and the browser.

Downloads

2,003

Readme

cdp-wasm

npm CI license

The Composers Desktop Project (CDP) compiled to WebAssembly and wrapped in a small typed API for Node.js and the browser.

npm i cdp-wasm      # the library
npm i -g cdp-wasm   # the `cdp` command line tool

Quick start · Effect catalog · Command line · Agent skills · Install details · FAQ

The published package ships the prebuilt .wasm; you do not need the submodule or a toolchain. The submodule below is only for building from source.

Architecture

CDP programs are individual command-line tools: each reads and writes audio files and takes its parameters as command-line arguments. This package adds a few layers on top so you can drive them with in-memory audio buffers and named parameters, in Node and the browser.

  • WebAssembly modules — each CDP program compiled to a .wasm, sharing one cdp-core (libc + the CDP core libraries). This is the full suite: the same programs, arguments and file formats as native CDP.
  • The CDP runtime (cdp.run / cdp.process) — stages your audio into an in-memory filesystem, runs the program, and returns the result as byte arrays / AudioBuffers. You work with Uint8Arrays rather than files on disk, and $IN/$OUT tokens stand in for paths. Every bundled program is reachable here.
  • Data helpers (decodeWav, extractEnvelope, getPitch, findPeaks, …) — convert CDP's audio and text formats to and from plain JS values: float channel data, [[time, value], …] breakpoint arrays, pitch contours, peak times.
  • The typed catalog (EFFECTS / applyEffect, GENERATORS / applyGenerator) — describes each effect and generator as data (named parameters with ranges and defaults) and runs it for you, taking care of spectral (pvoc) analysis/resynthesis wrapping, per-channel splitting and recombining, two-input effects, breakpoint automation, and multi-step pipelines.
applyEffect(cdp, effect, values, wav)   typed catalog — named params, pvoc + channels
  └─ cdp.process(program, args, bytes)   byte interface — $IN/$OUT, one in / one out
       └─ cdp.run(program, argv)         in-memory FS staging + callMain(argv)
            └─ blur.wasm on cdp-core      a CDP program (same arguments/formats as native)

Each layer is usable on its own: reach for the catalog when you want ready-made effects with named parameters, or drop down to cdp.run for any bundled program the catalog doesn't cover.

Building from source

The CDP C sources are a pinned git submodule (CDP8/) tracking the cdp-wasm-suite/CDP8 fork of upstream ComposersDesktop/CDP8 — upstream plus a small set of bug fixes and portability changes (Emscripten support among them), each maintained as a reviewable topic branch on the fork and proposed upstream. The sources build unmodified; nothing is patched at build time.

git clone --recurse-submodules https://github.com/cdp-wasm-suite/cdp-wasm
cd cdp-wasm
source /path/to/emsdk/emsdk_env.sh   # activate Emscripten
npm run build:wasm                   # builds wasm/
npm test                             # catalog (mono+stereo), helpers, CLI, externals, docs

(If you cloned without --recurse-submodules, run git submodule update --init.)

Build knobs (env vars): CDP_SPECTRAL_O3=0 reverts the core + FFT/spectral programs to -Oz instead of the default -O3 (smaller, ~15% slower spectral; time-domain programs are always -Oz); CDP_WASM_OUT=<dir> writes to an alternate output dir; CDP_SIMD_FFT=0 disables the hand-written SIMD128 FFT that replaces the Singleton FFT in the phase-vocoder path (pvoc/synth) and fastconv — it is on by default and gated by a build-time scalar-vs-SIMD self-test. Engines without SIMD128 are handled at runtime, not build time: each SIMD-bearing program also ships a <program>.scalar.* variant (~250 KB total), and the loader auto-detects the engine's SIMD support and picks the right one — old webviews and pre-16.4 Safari/Node just work, a few percent slower. new CDP({ simd: false }) forces the scalar variants explicitly. npm run bench measures performance against a baseline build.

libc and the CDP core libraries are compiled once into a shared cdp-core.{js,wasm}; each program is a small program-only .wasm side module loaded into that core on demand. The wrapper stages your audio into Emscripten's in-memory filesystem, runs the program, and hands the results back as byte arrays / AudioBuffers — you never touch the virtual filesystem directly. (The loader also transparently supports a legacy self-contained module per program; build with CDP_WASM_LINKING=static for that.)

The package bundles every CDP audio-processing program — 215 program modules plus the shared cdp-core (197 main-suite side modules and 18 self-contained externals), the entire suite that builds to WebAssembly (the only exclusions are 3 internal build-helper utilities and a few programs that don't compile/aren't usable headless). Any of them is callable via cdp.run('<name>', [...args], { inputs, outputs }). The most useful processes are also exposed through a typed effect catalog (below) with named parameters, ranges and defaults — 232 effects across 110 CDP programs: abfpan, blur, bounce, brownian, cantor, cascade, ceracu, clip, combine, constrict, crumble, crystal, distcut, distmark, distmore, distort, distortt, distrep, distshift, dvdwind, envcut, envel, envnu, envspeak, extend, fastconv, filter, flatten, flutter, focus, formants, fractal, fracture, frfractal, gate, glisten, grain, grainex, hilite, housekeep, hover, hover2, isolate, iterfof, iterline, madrid, matrix, mchanpan, mchanrev, mchshred, modify, morph, motor, multimix, newdelay, newmorph, newtex, packet, panorama, partition, phase, phasor, pitch, psow, pulser, quirk, rejoin, repeater, repitch, retime, reverb, rmverb, rotor, scramble, selfsim, sfecho, shifter, shrink, specenv, specfnu, specfold, speclean, specnu, specross, specsphinx, spectstr, spectune, spectwin, spike, spin, splinter, strange, strans, stretch, stutter, submix, subtract, superaccu, suppress, tangent, tesselate, texture, transit, tremenv, tremolo, tunevary, tweet, verges, waveform, wrappage (plus synth/sndinfo/pvoc as utilities). A further 16 synthesis generators (no audio input) are exposed the same way (see below).

Effect catalog

For ready-to-use effects with named parameters, the package ships a curated catalog (EFFECTS) plus a runner (applyEffect) that handles spectral (pvoc) wrapping and multichannel sources automatically:

import { CDP, EFFECTS, applyEffect } from 'cdp-wasm';

const cdp = new CDP();
const effect = EFFECTS.find((e) => e.id === 'blur.blur');
const values = { windows: 20 };               // override any of effect.params
const wavOut = await applyEffect(cdp, effect, values, wavIn);

Each entry is one mode of one CDP program: it names the program, an argument template, and its parameters. If you already know CDP, read The catalog and CDP — it explains what an entry decides on your behalf (the mode it picks, arguments it fixes, why its ranges are narrower than CDP's, how its parameter names map back) and when to drop to cdp.run instead. Every effect page shows the command line its effect really runs, next to CDP's own synopsis.

Each effect lists its category, program, params (with min/max/default for building UI), and whether it is spectral, mono-only, or spatial. The catalog effects span pitch/time, filtering/dynamics, waveset distortion, envelope, granular, spatialisation, extend/segment, delay/reverb, morph/combine, spectral and spectral-pitch processing, mixing, texture and synthesis, and are exercised on mono + stereo by npm test. See the effect reference for the full list; the cdp-web app is a UI built directly from this catalog.

Synthesis generators

Pure generators (no audio input) live in a parallel GENERATORS catalog run by applyGenerator — 16 synthesis generators: synth wave/noise/silence/spectra/chord, clicknew clicktrack, impulse, multiosc, synspline, chirikov, newsynth additive/wave-packet/fractal/Duffing, multisynth (score-driven), and strands (spiralling pitch-stream texture). Same param metadata as effects; entries with a text input (chord notes, click score…) carry a data descriptor:

import { CDP, GENERATORS, applyGenerator } from 'cdp-wasm';

const cdp = new CDP();
const gen = GENERATORS.find((g) => g.id === 'wave');
const wav = await applyGenerator(cdp, gen, { freq: 220, dur: 2 },
                                 { sampleRate: 48000 });   // default 44100

$SR tokens in the generator arg templates resolve to extra.sampleRate, so generated audio matches your session rate. See the generator reference.

Envelope / breakpoint helpers

CDP's envelopes are plain-text breakpoint filestime value pairs. The package can extract a sound's amplitude envelope as editable points, transform them, and feed one back into any time-varying parameter (see the ENVELOPE_PARAMS map for which params accept a breakpoint envelope):

import { CDP, extractEnvelope, warpBreakpoints, formatBreakpoints,
         applyEffect, EFFECTS } from 'cdp-wasm';

const cdp = new CDP();

// 1. extract an amplitude envelope from a sound  ->  [[time, value], …]
let points = await extractEnvelope(cdp, wavIn, { windowMs: 15, dataReduce: 0.05 });

// 2. (optional) transform it — normalise / reverse / invert / gate / …
points = await warpBreakpoints(cdp, points, 'normalise');

// 3. drive a parameter with it (here: gain over time)
const gain = EFFECTS.find((e) => e.id === 'modify.loudness');
const wavOut = await applyEffect(cdp, gain, { gain: 1 }, otherWav,
  { brk: { gain: formatBreakpoints(points.map(([t, v]) => [t, 0.2 + v * 1.8])) } });

parseBreakpoints / formatBreakpoints convert between the [[t, v], …] array (easy to draw and edit) and CDP's text format; REPLOT_MODES lists the warpBreakpoints warp modes. All of these are thin wrappers over the envel program, so they run in Node and the browser.

Analysis helpers (pitch, peaks)

Beyond envelopes, the package can pull other editable data out of a sound — a pitch contour and transient markers — for display, editing, or driving parameters:

import { CDP, getPitch, findPeaks } from 'cdp-wasm';

const cdp = new CDP();
const pitch = await getPitch(cdp, wav);   // [[time, Hz], …]  (empty if unpitched)
const peaks = await findPeaks(cdp, wav, { windowMs: 50 }); // [time, …] peak times
  • getPitch(cdp, wav) — pitch contour via pvoc anal → repitch getpitch (mixed to mono; monophonic). Feed it back through extra.brk to make a sound track its own (or another's) pitch. Needs harmonic material — silence, noise, or a pure sine returns [].
  • findPeaks(cdp, wav, { windowMs, threshold }) — amplitude-peak times for slicing / rhythmic analysis; works on any channel count.

These sit alongside a larger set of bundled data-producing programs (onset, partials, spectral and MIDI analysis) surveyed in docs/data-programs.md.

Tests

  • npm test — runs every catalog effect on a mono and a stereo source (plus every generator on its defaults), checking each yields valid, non-silent audio with the expected channel count; also the AIFF, envelope/analysis-helper, CLI, externals, docs-coverage, agent-plugin and cdp-web patch-builder checks.
  • npm run test:parity — compares WASM output against the native CDP command-line tools for every parity-testable effect (deterministic effects match bit-for-bit; effects using a seeded RNG / platform-dependent edge handling are exempt and only checked for valid audio; multi-step derive/pipeline and external effects are covered by npm test instead). Needs native binaries built with CMake and CDP_NATIVE_BIN pointing at them. Both run in CI (.github/workflows/ci.yml).

Install

npm install cdp-wasm

No registry configuration and no auth — it's a public package on npmjs.org. Releases carry a provenance attestation linking the tarball to the commit and workflow run that built it.

The compiled .wasm modules are built when the package is published (via a prepack step) and shipped in the tarball — they are not committed to the repo. To build them yourself from the CDP sources you need the Emscripten SDK activated, then:

npm run build:wasm

A tagged release publishes automatically: push a tag like v0.3.0 and the Publish workflow builds the WASM, tests, and publishes.

The per-effect reference under docs/ is not shipped in the npm tarball — read it on GitHub. The cdp CLI's own man pages are included: man cdp.

Command line

The package ships a cdp command that runs the original CDP programs against files on disk — invoke it exactly like the native CDP tool, just prefixed with cdp:

cdp modify speed 2 in.wav out.wav -12
cdp pvoc anal 1 in.wav out.ana
cdp sndinfo len in.wav                                        # read-only: prints to stdout

Install it globally to get that bare cdp command — worth it for a tool you run against files over and over:

npm install -g cdp-wasm

Or run it without installing, which is handy for a one-off:

npx cdp-wasm sndinfo len in.wav

…or, from a local checkout of this repo, symlink it onto your PATH:

npm link                             # then `cdp …` runs bin/cdp.js

Any argument with an audio/analysis extension (.wav .aif .aiff .ana .frq .for .brk .txt .dat) or a / is treated as a file — existing ones are read in, files the program writes are saved back to disk — and everything else (numbers, flags) is passed to CDP untouched. Existing outputs are protected unless you pass --force.

Spectral programs (blur, morph, stretch, pitch, …) natively read and write phase-vocoder .ana files. Either bracket them yourself:

cdp pvoc anal 1 in.wav in.ana
cdp blur blur in.ana out.ana 10
cdp pvoc synth out.ana out.wav

…or let --pvoc analyse the WAV input and resynthesise the WAV output for you:

cdp --pvoc blur blur in.wav out.wav 10

Options (before the program name): --pvoc/--spectral, -f/--force, --in <path>, --out <path>. Helpers: cdp help <program> [mode] (native usage plus a link to the online CDP reference; add --catalog for the catalog's named parameters, ranges and defaults), cdp list [--spectral], cdp doctor, cdp --version. Generated man pages ship in the package (man cdp, and cdp-<program>.1 for the cataloged programs).

For multi-step chains from a single JSON spec, see the plugin's render-chain.mjs; for programmatic use, the library API below.

Agent skills and plugins

The repo ships a shared agent plugin for Codex and Claude Code containing three skills:

  • cdp-sound-design orchestrates and renders CDP processing through this library — multi-effect chains, breakpoint automation, analysis, batch jobs, and raw access to every bundled program.
  • build-cdp-web-patches builds and validates editable .cdp graph files, inserts the explicit PVOC nodes cdp-web needs, and produces compressed links that open directly in cdp-web. URL-backed sound Sources travel with those links; their host must permit CORS.
  • drive-cdp-web drives a running cdp-web in Chrome through the app's WebMCP agent tools, using the chrome-devtools MCP as the transport — building and editing a patch live on the canvas, loading sounds, setting parameters, and rendering, instead of authoring files offline.

Codex:

codex plugin marketplace add cdp-wasm-suite/cdp-wasm
codex plugin add cdp-sound-design@cdp-wasm

Claude Code:

/plugin marketplace add cdp-wasm-suite/cdp-wasm
/plugin install cdp-sound-design@cdp-wasm

It can also be installed into Codex, Claude Code, Cursor, and other compatible agents with the open Skills CLI:

npx skills add https://github.com/cdp-wasm-suite/cdp-wasm/tree/main/plugins/cdp-sound-design/skills/cdp-sound-design
npx skills add https://github.com/cdp-wasm-suite/cdp-wasm/tree/main/plugins/cdp-sound-design/skills/build-cdp-web-patches
npx skills add https://github.com/cdp-wasm-suite/cdp-wasm/tree/main/plugins/cdp-sound-design/skills/drive-cdp-web

The plugin also carries a portable Agent Plugins 1.0.0 manifest, so any client implementing that spec can load it directly from plugins/cdp-sound-design.

The integration ships the skills, not the library — they use whichever cdp-wasm they find: a project-local install, a global npm install -g cdp-wasm, or a checkout of this repo, in that order. Install it globally if you want Claude or Codex to work on loose audio files anywhere, not just inside a Node project.

build-cdp-web-patches can serialize Faust nodes for cdp-web, but cdp-wasm itself does not include a Faust compiler and cannot render or verify them. Faust patches must be compiled and auditioned in cdp-web, which supplies its own @grame/faustwasm dependency.

See plugins/cdp-sound-design/README.md.

Quick start (Node)

import { CDP, decodeWav } from 'cdp-wasm';

const cdp = new CDP();

// Generate a 1s 440 Hz tone with CDP `synth`
const { outputs } = await cdp.run(
  'synth', ['wave', '1', '/tone.wav', '44100', '1', '1.0', '440', '-a0.8'],
  { outputs: ['/tone.wav'] }
);
const tone = outputs['/tone.wav'];

// Transpose it down an octave with `modify` ($IN/$OUT are virtual paths)
const { bytes } = await cdp.process('modify', ['speed', '2', '$IN', '$OUT', '-12'], tone);

// Inspect the result
const { sampleRate, numChannels, length } = decodeWav(bytes);
console.log(sampleRate, numChannels, length);

Spectral processing (analysis → transform → resynthesis)

CDP's signature spectral programs operate on phase-vocoder analysis files. Chain them by passing the intermediate .ana bytes between runs:

const ana     = await cdp.process('pvoc', ['anal', '1', '$IN', '$OUT'], wav, { outExt: 'ana' });
const blurred = await cdp.process('blur', ['blur', '$IN', '$OUT', '10'], ana.bytes, { inExt: 'ana', outExt: 'ana' });
const out     = await cdp.process('pvoc', ['synth', '$IN', '$OUT'], blurred.bytes, { inExt: 'ana' });
// out.bytes is a WAV

Multichannel input and mono-only programs

Many classic CDP programs are mono-only (e.g. pvoc analysis, and distort) and reject a multichannel infile, while others (modify) handle multichannel natively. To keep stereo/quad/8-channel width through a mono-only program, run it per channel and recombine:

// single mono-only program: pass channels:'split' (or 'mix' to fold to mono)
const { bytes } = await cdp.process('distort', ['multiply', '$IN', '$OUT', '2'],
                                    stereoWav, { channels: 'split' });

// a multi-step mono chain (analysis → transform → resynthesis), per channel:
const out = await cdp.eachChannel(stereoWav, async (mono) => {
  const ana = await cdp.process('pvoc', ['anal', '1', '$IN', '$OUT'], mono, { outExt: 'ana' });
  const blr = await cdp.process('blur', ['blur', '$IN', '$OUT', '10'], ana.bytes, { inExt: 'ana', outExt: 'ana' });
  return (await cdp.process('pvoc', ['synth', '$IN', '$OUT'], blr.bytes, { inExt: 'ana' })).bytes;
});

eachChannel works for any channel count and returns a recombined WAV with the same number of channels. (Processing channels independently is correct for per-channel effects; for stereo-correlated processing it can affect the image.)

Browser

import { CDP, wavToAudioBuffer, audioBufferToWav } from 'cdp-wasm';

const cdp = new CDP();
const ctx = new AudioContext();

// from a Web Audio AudioBuffer ...
const wavIn = audioBufferToWav(myAudioBuffer);
const { bytes } = await cdp.process('distort', ['multiply', '$IN', '$OUT', '2'], wavIn);
const processed = wavToAudioBuffer(bytes, ctx);     // ... back to an AudioBuffer

const src = ctx.createBufferSource();
src.buffer = processed; src.connect(ctx.destination); src.start();

For heavier jobs run the CDP instance inside a Web Worker so the UI thread stays responsive — the API is identical.

Old engines without WASM SIMD128 (pre-16.4 Safari, aging webview hosts) are handled automatically: the loader detects support and falls back to the bundled no-SIMD .scalar variants of the FFT-bearing modules, a few percent slower but otherwise identical. new CDP({ simd: false }) forces that path if you want to test what such hosts will run.

See cdp-web for a complete, runnable browser app built on this package.

Serving the .wasm modules

new CDP() resolves the modules relative to the package itself (../wasm/), which is right under Node and for bundlers that leave the package on disk. Programs are looked up by name at run time, though, so a bundler that only traces static imports will not emit them — point baseUrl at a copy you serve instead. Copy the whole wasm/ directory: the loader needs manifest.json and cdp-core.js/cdp-core.wasm alongside the per-program files and their .scalar variants.

const cdp = new CDP({ baseUrl: '/wasm/' });

Or host nothing at all — the published tarball is served per file by jsDelivr and unpkg, with CORS:

const cdp = new CDP({
  baseUrl: 'https://cdn.jsdelivr.net/npm/[email protected]/wasm/',
});

Substitute the cdp-wasm version you installed rather than a floating tag — the loader and the modules are built and published together. Only the programs you actually run are fetched, so the directory's total size is not a download cost.

API

  • new CDP({ baseUrl?, simd? })baseUrl points at the folder of .wasm modules (defaults to this package's bundled wasm/); simd: false forces the no-SIMD .scalar module variants (default: auto-detect the engine).
  • cdp.run(program, args, { inputs?, outputs? }){ exitCode, stdout, stderr, outputs } — full control: stage any input files, read any output files.
  • cdp.process(program, args, inputBytes, { inExt?, outExt? }){ bytes, stdout, stderr, exitCode } — one in, one out; $IN/$OUT in args are replaced with virtual paths.
  • cdp.processWav(program, args, inputWav) → decoded float channel data plus the raw wav.
  • EFFECTS + applyEffect(cdp, effect, values, srcWav, extra?) — the typed effect catalog and its runner (spectral wrapping, per-channel processing and two-input effects handled for you).
  • GENERATORS + applyGenerator(cdp, gen, values, extra?) — the synthesis generators (extra.sampleRate sets the output rate, extra.data feeds score/note text inputs).
  • decodeAudio (WAV or AIFF, sniffed), decodeWav, decodeAiff, encodeWav, wavToAudioBuffer, audioBufferToWav — audio ↔ float/AudioBuffer helpers.

Input formats

CDP reads WAV and AIFF/AIFF-C natively, so the package accepts both directly (decodeAudio sniffs the header; AIFF decoding covers PCM 8/16/24/32 and the sowt/fl32/fl64 AIFF-C variants). In the browser, a consuming app typically passes WAV and AIFF straight to CDP and decodes any other container (MP3, FLAC, Ogg…) via the Web Audio API first. CDP output is always 32-bit float WAV.

Typings are in index.d.ts.

How it works

The modules are built with -sMODULARIZE -sEXPORT_ES6 and run via callMain, with INVOKE_RUN=0/EXIT_RUNTIME=0 so the in-memory filesystem stays readable after the program returns. Each run() uses a fresh module instance, so there's no shared state between invocations; the core's wasm is compiled once and cached (a compiled WebAssembly.Module is stateless), and the shared core is linked MAIN_MODULE=2 — dead-code-eliminated against the side modules — so per-run instantiation costs a few milliseconds rather than tens. The loader probes the engine's SIMD128 support once and, per the manifest's simd list, loads either a program's SIMD build or its .scalar fallback. CDP writes 32-bit float WAVs by default, which the Web Audio API reads directly.

File size limits

The modules are 32-bit WebAssembly and stage every file in memory, so a single run() has to hold the input, the output, and CDP's working buffers in one linear address space — capped at 4 GB (the wasm32 limit). There is no streaming; files are read and written whole.

In practice that ceiling is generous. A 32-bit float WAV is roughly 10 MB/min mono (~20 MB/min stereo) at 44.1 kHz, so ~1 GB is about 100 minutes mono / 50 minutes stereo. A modify pass of ~1.5 GB in → ~1.5 GB out (~3 GB peak memory) completes under Node; browsers are more variable (per-engine wasm memory and ArrayBuffer caps), so keep a single file comfortably under ~1 GB and split longer material into chunks. Spectral work (pvoc) is tighter — the analysis file is several times larger than the source audio — so long spectral chains reach the limit sooner.

FAQ

How does this relate to Sound Loom, Soundshaper, Soundthread and the other CDP front-ends? Only in that they all drive the same CDP programs. cdp-wasm is a new WebAssembly port of CDP — an engine, with a JS API and a CLI, no user interface. cdp-web is a graphical front-end built on that engine. Neither shares code or lineage with the existing front-ends, and neither is a replacement for them: they are separate projects that happen to sit in front of the same suite.

Do I need CDP installed, or a CDP licence? No. The compiled programs ship inside the npm package — no native CDP installation, no toolchain, nothing to buy. CDP8 itself is open source (LGPL-2.1-or-later); see License for how that applies if you redistribute the modules.

Is this all of CDP? 215 programs are bundled, which is the suite. The typed catalog gives named, range-checked parameters for 232 effects across 110 of them plus 16 generators; the remainder are reachable raw through cdp.run / the cdp CLI with the same arguments as native CDP.

Does it sound the same as native CDP? That's tested, not assumed: npm run test:parity compares WASM output against the native command-line tools and deterministic effects match bit-for-bit. Effects with a seeded RNG or platform-dependent edge handling are exempt and checked for valid audio instead. See Tests.

Does it run in the browser? Yes — the same API, with AudioBuffer in and out. See Browser.

Is this an official CDP project? No. It's an independent port. The C sources are a pinned submodule tracking a fork of upstream CDP8 that adds bug fixes and portability changes (Emscripten support among them); they build unmodified, and the changes are maintained as reviewable topic branches and proposed upstream.

License

Two licenses, split along the CDP boundary:

  • The wrapper is MIT — the JavaScript API (src/), the CLI (bin/), the type definitions, build scripts, tests and documentation are original work, licensed under the MIT License.
  • The CDP programs are LGPL — the compiled WebAssembly modules (wasm/*.wasm) and the CDP8 sources they're built from (the CDP8/ submodule) are Copyright Trevor Wishart and Composers Desktop Project Ltd, licensed LGPL-2.1-or-later. See wasm/LICENSE.

The wrapper drives the CDP programs at arm's length (argv + an in-memory filesystem), so using this package does not make your application a derivative of CDP — but if you redistribute the .wasm modules (including by bundling this package), the LGPL's terms apply to them: keep the license notice, and users must be able to swap in their own builds of the modules (they're loaded as separate files at runtime, so this is normally already the case). The baseUrl constructor option lets an application host the modules outside its own bundle entirely and load them from a user-controllable location.