Passion Audio Player

Developers

Build plugins, skins, and tools with the Passion Audio Player API.

Passion Audio Player exposes a stable C-compatible plugin API, a skinning format, and a set of header files that let you build input decoders, output drivers, DSP processors, visualisations, and full UI skins. All API documentation is provided free of charge. The codebase is developed in Free Pascal / Lazarus but plugins can be written in any language that can produce a Windows DLL.

Developer Resources

DSP Plugins SDK

George Boudouris365 KB20-09-2007

The official Passion Audio Player DSP Plugin SDK. Contains headers, reference structs, and build instructions. The authoritative starting point for writing any DSP plugin.

Download SDK →

Sonique Visuals Delphi Template

George Boudouris26 KB29-04-2009

Delphi/Pascal template for Sonique Visualization plugins. Covers the full vis API: init, render loop, PCM/FFT data consumption, and shutdown.

Download Template →

Sonique Visuals with Text Template

George Boudouris72 KB01-05-2009

Extended Delphi template for Sonique vis plugins that render on-screen text overlays. Demonstrates GDI text drawing within the Sonique vis window lifecycle.

Download Template →

Psycho JM-DG with source

JM-DG76 KB02-05-2009

A complete Sonique visualisation plugin with full source code. Reacts to the audio waveform with colour-driven graphics — a real-world example to study and extend.

Download →

Plugin API Reference

All plugin types

Complete documentation for all plugin types: input, output, DSP, visualisation, and general. Covers structs, callbacks, version negotiation, and thread safety.

Read Docs →

Plugin Types

IN

Input Plugin

Decode audio from a file format or stream. The player calls your plugin when it encounters a file extension you've registered. Return PCM frames on demand.

DLL export PCM output Tag reading
OUT

Output Plugin

Write decoded PCM to an audio device, network stream, or file. You control buffering, volume, pause/resume, and device enumeration.

Device control Buffering Volume API
DSP

DSP Plugin

Process PCM in real time: EQ, reverb, compressor, crossfeed, sample-rate conversion, or any other effect. Multiple DSP plugins can be chained.

In-place PCM Chainable Config UI
VIS

Visualisation Plugin

Render a real-time visual driven by PCM or FFT data in a child window provided by the player. Compatible with the Sonique visualisation API.

FFT data Window render Sonique API
GEN

General Plugin

Everything else: scrobblers, file taggers, hotkey managers, library scanners, Discord presence, remote control apps. Loaded at startup, runs for the session.

Startup load Event hooks Player API
SKIN

Skin

Full UI replacement via XML layout + bitmap assets. Every control, animation, and colour is under your control. Ships as a ZIP-based .pap-skin package.

XML layout PNG/BMP assets .pap-skin pkg

Quick Start

The minimal boilerplate for a C input plugin. Export the PAP_GetPluginInfo function and the player will load your DLL automatically on startup.

C my_input_plugin.c
// Passion Audio Player — Minimal Input Plugin
// Compile as a 32 or 64-bit Windows DLL
#include "pap_plugin.h"

static PAP_InputPlugin plugin = {
    .version     = PAP_PLUGIN_VERSION,
    .description = "My Format Decoder",
    .extensions  = "myfmt;mf2",
    .Open        = MyFormat_Open,
    .GetPCM      = MyFormat_GetPCM,
    .Seek        = MyFormat_Seek,
    .Close       = MyFormat_Close,
    .GetTags     = MyFormat_GetTags,
};

__declspec(dllexport) PAP_InputPlugin* PAP_GetPluginInfo(void) {
    return &plugin;
}
Full examples with build scripts for MSVC, MinGW, and Free Pascal are included in the SDK download. The Pascal units ship with the same interface, wrapped for idiomatic Object Pascal.

Developer FAQ

Any language that can produce a Windows DLL and export C-compatible symbols. C, C++, Free Pascal, Delphi, Rust (with cdecl exports), and Go have all been used successfully by community members.
Yes. The 64-bit player can only load 64-bit DLLs, and the 32-bit player only loads 32-bit DLLs. If you want to support both, compile and distribute two separate DLLs. The API itself is identical; only pointer widths and calling conventions change.
The player calls CoInitialize(NULL) on the main thread. If your plugin uses COM on a worker thread, you must call CoInitializeEx yourself on that thread and balance it with CoUninitialize before the thread exits. Never call CoUninitialize on the main thread from a plugin.
Yes, but you must signal the format change through the PAP_DSP_FormatChange callback before returning modified PCM. The player will re-negotiate with the output plugin. Changing both rate and channels simultaneously in a single block is supported from API version 4 onwards.
The Developer Talk section of the community forum is the primary channel. For confirmed API bugs, you can also contact George directly. Feature requests are tracked in the forum and considered for the next major API version.