bpplay is a minimalist, bit-perfect music player for macOS. One C file, about two thousand lines, no external dependencies. It has a single job: deliver the samples of a music file to your DAC untouched — no resampling, no software volume, no mixing.
On an ordinary macOS app, audio doesn't reach the DAC directly — it passes through CoreAudio's system mixer, where resampling, floating-point mixing and software volume can all quietly change the signal.
Everything that could touch the signal happens before the DAC is running. During playback there is exactly one operation left.
hog mode — bpplay becomes the sole owner of the DAC. No other app can interfere; the system mixer is disabled.
bpplay asks the hardware for an integer physical format. If the device only offers float32, it takes that instead — and tells you which route it took.
The whole file is read into memory. If a lossless format conversion is needed, it happens once here, on a non-real-time thread.
mlockThe decoded buffer is pinned in RAM. The operating system cannot page it out mid-playback.
IOProc does exactly one thing: memcpy. No float math, no allocation, no file reads, no locks — the callback that feeds your DAC never does anything a real-time thread shouldn't.
No on-the-fly buffering, no disk reads during playback. The track sits in RAM, locked there, and reaches the DAC with a single memory copy.
This also has an electrical rationale, not just a signal-path one. A conventional player continuously reads, decodes and re-buffers — each operation is a brief, spiky load on the machine's power supply. A modern NVMe SSD's read spike can jump from 15 mA to 2 A in microseconds, a di/dt of nearly two million amps per second, a real source of high-frequency EMI. Once the track is fully in RAM, none of that happens during playback — there's nothing left to spike.
Neither step is lossy. The float32 mantissa is 24 bits, so the 16/24-bit integer range fits inside it exactly — the extra memory is the honest cost of two lossless conversions, not waste.
DSD256 stores the signal as 1-bit samples at 11.2896 MHz per channel — too dense for USB audio to carry directly. bpplay packs it into PCM using the DoP (DSD over PCM v1.1) protocol.
The alternating marker is a self-checking handshake: a DAC that understands DoP unpacks the bits into its own DSD decoder; one that doesn't just plays it as plain PCM and stays passive. Either way, the DoP frame is only the transport — never the content. Validated up to DSD256, architecture scales to DSD512.
| Format | Details |
|---|---|
| WAV | 16 / 24 / 32-bit integer and 32-bit float |
| FLAC | 16 / 24-bit, Vorbis metadata, MQA detection (not decoding) |
| ALAC (M4A) | 16 / 24-bit — what iTunes / Music.app produce |
| AIFF / AIFC | 16 / 24 / 32-bit, uncompressed only |
| DSF (DSD) | DSD64–DSD256 via DoP |
bpplay plays files — from local storage, a NAS, or a Google Drive / Dropbox folder, as long as it's mounted on the Mac. It is not a streaming client: no built-in connection to Spotify, Tidal, Qobuz or similar services.
Library management, a graphical interface, network streaming, signal processing, volume control. None are oversights — each would be a place where the signal could change, or noise could arise, between the file and the DAC.
A short, unedited screen recording of installing bpplay and playing an album — start to finish.
Bit-perfect behaviour was identical across every topology and cable tried — the bit path is independent of how you connect it.
The DMG bundles the CLI binary plus two zero-configuration launchers — a drag-and-drop app and a Finder Quick Action. Both are Developer ID signed and notarised.
"bpplay forgoes a polished interface and convenience features, and in return gives a reference — a fixed point to measure against."From the project's design philosophy