MusicPack is an open, self-hosted music ecosystem built around a simple idea: an album should be a first-class digital object — not merely a folder full of loosely related files.
A specific CD, vinyl pressing, remaster or digital edition is more than a set of tracks: it is a particular release with its own identity, artwork, mastering, catalogue information and provenance. MusicPack keeps that identity inside the album object itself, so a digital collection can feel like a digital record shelf — intentional, curated, and collectible again. Two editions of the same album are meaningful rather than redundant, because the library understands why they are different.
The project deliberately gives Musepack a starring role. Musepack is a mature, open and exceptionally efficient lossy codec — still one of the best ever designed for transparent music playback — and it is the audio foundation everything here is built on:
Musepack SV8 = the codec / bitstream format (unchanged)
mpcenc 1.32.0 --stable-- = MusicPack-maintained encoder implementation version
libmusepack 7.0.1 / API 1 = decoder library/API version
MusicPack 0.1.0 = the ecosystem (.mpack packages, server, tools)
Version namespaces are intentionally separate, following historical Musepack
practice. mpcenc 1.32.0 does not mean SV32 or a new format: the codec is and
stays Musepack SV8 (magic MPCK, stream version 8). Even encoder minors
are stable (--stable--), odd minors are development (--unstable--).
The guiding rule of this repository:
Modernize the ecosystem aggressively; change the codec conservatively.
- The Musepack codec (foundation) — the decoder (
libmpcdec), the encoder core (libmpcenc,libmpcpsy), a WAV helper (libwavformat), and the CLI codec tools. The decoder supports SV7/SV8; the encoder produces SV8. - The
.mpackalbum model —libmusicpackowns the package format: a release-group → release/edition → media → track hierarchy, assets, SHA-256 integrity, BS.1770-5 loudness, and optional precomputed waveform envelopes; themusicpackCLI authors, imports and verifies packages. The format is codec-aware rather than Musepack-only — Musepack is the foundation codec, but FLAC-backed packages are valid v1. Packages are directory bundles by default and may be packed into a single-file MPAK v1 container (specs/mpak-v1.md);.mpakcontainers are acquirable over HTTP Range from the nativempakhttpadapter or the browser/WASM transport (design:specs/mpak-http-range-design.md). - The server —
musicpack-serverindexes an.mpackcollection into a SQLite collector library and serves it over a read-only HTTP API v1 with direct streaming (the original audio bytes, never transcoded). - The web client —
web/is the first-party "digital record shelf": browse your collection by album and edition, then play it with Musepack demand-driven WASM decoding, BS.1770 album normalization, gapless album playback and Media Session integration. - The desktop authoring GUI —
author/is MusicPack Author, a Tauri 2 desktop app (macOS/Apple Silicon is the current packaged target) that turns a tagged lossless album into a curated, validated.mpackrelease through a real authoring pipeline: inspect → metadata review → Musepack q6 encoding (bundled staticmpcenc; FLAC/WAV sources decoded natively bylibmusicpack— no FFmpeg and no other external tool) →.mpackassembly → validation. It generates a deterministic per-track waveform envelope from source PCM by default. The.appships everything the authoring workflow needs. It drives the existingmusicpackimplementation through the CLI's JSON draft modes (inspect,validate-draft,encode-draft,build-draft,identify-draft) behind a clean service, solibmusicpackstays the only authority on package semantics. Source files are never modified; package finalization is transactional and verified before it is reported successful. It can also export the package as a deterministic single-file.mpakcontainer (via the CLIpackcommand), either when creating a new package or by converting an opened.mpack. - WASM + demo — the decoder builds to WebAssembly (Emscripten);
demo/is a low-level playback proof-of-concept kept as a development/test artifact.
Project status: Musepack encoder optimization is complete (2026-08-27); the codec foundation is no longer the primary active engineering area. The project is now in real-world MusicPack validation and dogfooding — see
docs/ROADMAP.md.
web/ is the first genuinely usable MusicPack client. It is
deliberately a digital record shelf, not a streaming catalogue:
- sign in once with a server token (exchanged for an HttpOnly session cookie; the token is never stored in the browser)
- an artwork-first album shelf with infinite scrolling, search and "recently added"
- an album page that shows which exact release/edition you are looking at (edition chips, disc-grouped track lists, an expandable release-information panel with identity, provenance, codec and BS.1770 details)
- playback through one controller over two backends: the Musepack
demand-driven engine (SharedArrayBuffer reader → decoder workers → an
AudioWorklet ring) for
.mpc, and the browser's native media stack for FLAC and other supported codecs — with a user-facing audio-quality preference (automatic / lossless / codec family) and format labels on what is playing - BS.1770 album/track normalization (default −16 LUFS, true-peak capped), gapless album transitions, a queue, Media Session, responsive waveform seek controls when the package provides envelopes, complete-release downloads for offline listening (integrity-checked, local-first), a settings surface for audio-quality preference and storage management, and a responsive mobile/desktop UI
The client is a static Svelte 5 + Vite + TypeScript build served by
musicpack-server --static-dir web/app/dist. See web/README.md for the
stack decision, the npm run dev / npm run build workflow, and the
Vitest/Playwright suites.
libmusicpack owns MusicPack package semantics: the .mpack v1 manifest,
album/release-group → release/edition → media → track model, assets, SHA-256
integrity, BS.1770-5 loudness (measured per track and as an album program),
and the versioned per-track waveform envelope format
and directory-bundle storage. It depends on libmusepack (for the Musepack
track handoff) but never the reverse. It builds as libmusicpack, exported
as MusicPack::Package:
find_package(MusicPack CONFIG REQUIRED)
target_link_libraries(app PRIVATE MusicPack::Package)#include <musicpack/musicpack.h>
musicpack_package *pkg = musicpack_package_open_dir("Album.mpack", 0);
const musicpack_manifest *m = musicpack_package_manifest(pkg);
musicpack_report rep;
musicpack_package_verify(pkg, &rep, 0, 0);
/* Musepack handoff: expose a track's .mpc to the codec layer */
mpc_reader reader;
musicpack_package_track_open_reader(pkg, 0, 0, &reader);
musepack_decoder *d = musepack_decoder_open(&reader, 0);The musicpack CLI (musicpack info|verify|identify|create|import|update-metadata,
plus the authoring draft commands inspect/validate-draft/encode-draft/
waveform-draft/build-draft/identify-draft) builds, inspects and validates directory-form
packages. info shows collector identity (release type, edition, release/
original dates, country, label, catalogue number, medium, barcode);
create/import accept release options.
import reads embedded metadata (Vorbis Comments from FLAC, APEv2 from
.mpc) to fill album/track/release/identifier/source fields — explicit flags
override tags, and it never invents edition/country/label/catalogue/type from
filenames. identify applies a local MusicBrainz release document via
--mb-json and enriches empty fields with honest identity.confidence
(exact/confirmed/probable/none) — importing never requires a network.
update-metadata reconciles the manifest from the tracks' tags and, with
--sync-tags, writes the manifest back into .mpc APEv2 tags and refreshes
checksums (unknown top-level manifest fields preserved). The normative spec and
machine-readable schema live in specs/musicpack-v1.md and
specs/musicpack-v1.schema.json; committed reference packages (a Musepack
album and a FLAC album) are under tests/reference/.
The v1 contract is strictly enforced by the parser: a manifest must be a
single strict JSON document (duplicate keys and malformed nested objects are
rejected, numbers are parsed finitely and range-safely), every
manifest-referenced file requires a SHA-256, referenced paths must be unique
and stay contained within the package root, and unknown root-level fields are
documented to survive a round-trip. A committed conformance corpus (3 valid
manifests, 49 invalid manifests, 9 invalid asset cases) gates the contract
across platforms. See docs/mpack-v1-contract-hardening.md for the enforced
rules.
MusicPack sonic analysis stores a versioned audio embedding per track (and a
deterministic album embedding) in the package, so a server can later offer
content-based similarity and radio without a centralized recommendation
service. The container format is frozen and model-independent
(specs/musicpack-sonic-v1.md): analysis/sonic.json, referenced from the
manifest's optional analysis[], with model-scoped profiles
(musicpack-sonic-openl3-v1 = default permissive profile, not normative;
musicpack-sonic-discogs-v1 = research-only quality reference;
musicpack-sonic-clap-v1 = rejected). libmusicpack owns all Sonic parsing,
validation and profile-compatibility semantics (musicpack/sonic.h); the
musicpack CLI reports it in info/verify and attaches a completed
document in build-draft. The musicpack-sonic analyzer (in sonic/, ONNX
Runtime, single-threaded) computes embeddings at authoring time with a
SHA-256-pinned model; MusicPack Author exposes it as a model-independent
"Sonic Analysis" panel and downloads the ~18 MB pinned ONNX artifact on first
use (never a Python/ONNX-conversion step for end users). The standalone
.app bundles ONNX Runtime; the model lives in the app data directory. See
author/README.md for the acquisition, offline and packaging details.
Server-side recommendations are deliberately not implemented yet.
musicpack-server (in server/) indexes a real .mpack collection into a
SQLite collector library and serves it over a read-only HTTP API v1. It
consumes libmusicpack for all package parsing, validation and path
security; it never parses manifests itself.
musicpack-server scan --library ~/Music [--database library.db] [--verify]
musicpack-server serve --library ~/Music [--listen 127.0.0.1] [--port 8080]
musicpack-server verify --library ~/Music
musicpack-server token create --name "Web" | token list | token revoke <id>- Scanner — deterministic and idempotent; finds
.mpackbundles (recursion stops at a package root), validates through libmusicpack, and ingests each package in its own transaction. A package's manifest sha256 gives cheap change detection; a content fingerprint keeps a moved package the same album. Removed packages becomeunavailable; malformed packages are recordedinvalidwithout touching the index. Scanning is fail-closed: an incomplete traversal (enumeration, metadata or database-write failure) fails the scan and the unavailable sweep does not run, so prior library state is preserved. A lightweight scan records package verification state;--verifyruns full SHA-256 verification. - Verified-only visibility — a newly discovered package is not servable
merely because its manifest parses. It becomes visible/servable only after
full SHA-256 verification succeeds (
--verifyor the live verify endpoint); an unverified, checksum-failed or quarantined package is never served. - Package ownership — releases can share logical identity (editions, mirror duplicates), but servable content is owned by exactly one package per release: one package owns the content graph, and a package claiming the same release identity cannot overwrite another package's tracks/assets. Streaming and API content enumeration resolve through the owning package only.
- Conflict quarantine — a package claiming an already-owned release
identity with different content is quarantined as
conflictrather than silently merged. Verification can never clear a conflict; quarantine ends only through explicit ownership re-arbitration (the owner becomes unavailable/invalid, or the conflicting content comes to match the owner). - Collector library — SQLite (vendored amalgamation) preserving the release-group → release/edition → media → track hierarchy, with artists, assets, package status, and schema migrations.
- Authentication —
/api/v1/*is protected by opaque bearer tokens (256-bit secrets; only their SHA-256 is stored), exceptGET /api/v1/health. Tokens are created/listed/revoked via the CLI. CORS is deny-by-default (--allow-origin URL, repeatable). The first-party web client exchanges a token once for an HttpOnly session cookie (POST /api/v1/session). - Live maintenance —
POST /api/v1/library/scanandPOST /api/v1/library/verifyrun on single background workers (SQLite WAL), so playback and API reads continue and new state appears after each commit;GET /api/v1/library/statusreports current/last scan + verify state. - HTTP API v1 —
GET /api/v1/health|albums|albums/{id}|releases/{id}| tracks/{id}|tracks/{id}/audio|artists|artists/{id}|assets/{id}|session, with pagination, strict numeric ids, a JSON error envelope, and deterministic ordering. Editions are never collapsed: an album lists its distinct releases. - Direct streaming — audio/assets are served as the original stored
bytes (no decode/remux/rewrite) with full RFC 9110 single-range support
(
206/416,Content-Range,Accept-Ranges,HEAD), streamed from a file descriptor — never buffered. Only verified package content is servable, and every referenced object is type-checked (a regular file) and read through hardened opened-descriptor handling. Manifest hashes are validated during verification; a strongETag(the manifest hash) enablesIf-None-Match→304. After verification, the package must remain in non-mutable, server-controlled storage for this trust guarantee to hold; post-verification mutation is detected on the next scan/verify. MIME and codec (musepack-sv8, …) are reported separately and derived server-side. - Package-object serving — package-controlled web content is served
defensively. Inline serving is restricted to verified raster image types
(JPEG, PNG, GIF, WebP, BMP) and audio streams; HTML, SVG, JavaScript, XML,
text and PDF-like assets are forced to
Content-Disposition: attachmentwith a sanitized filename. Every package-object response carriesX-Content-Type-Options: nosniffplus a sandboxingContent-Security-Policyon200/206/304/416. - Browser streaming —
--static-dir DIRserves static files with cross-origin isolation (COOP/COEP). Point it at the built web client (web/app/dist) to get the first-party record shelf at the server root; the client streams Musepack through a demand-driven reader (SharedArrayBuffer + Atomics + a network worker with a block cache), fetching only the compressed ranges the decoder needs, so playback starts before the file downloads and seeking never fetches the whole file.
MusicPack serves collections that may contain untrusted, externally placed
.mpack directories, and the server is hardened accordingly: verified-only
visibility, package-owned content, identity-conflict quarantine, regular-file
checks bound to the object actually read or hashed (POSIX opens with
O_NONBLOCK|O_NOFOLLOW and fstats the opened descriptor), hard-link
rejection on POSIX, symlink/reparse-point containment, the attachment/nosniff/
sandbox-CSP serving policy above, fail-closed scanning and verification, and
resource budgets bounding object counts, aggregate referenced bytes, traversal
depth and manifest/Sonic parse sizes. A hostile-package regression suite
exercises special files, hard links, symlink escapes and oversized objects.
Documented operational restrictions remain: verified bytes are not copied
into immutable server-owned storage, so package directories must not be
concurrently mutable after verification; path containment is pathname-based
rather than descriptor-relative (openat-style); Windows cannot reliably
detect hard links (that rejection is POSIX-only); scans are not scoped to a
persisted library-root id (one database per root); and sanitizer testing is
local, not hosted. See docs/server-untrusted-package-hardening.md for the
exact limits and threat model.
Defaults are safe: loopback binding, no remote access implied. The API spec
is specs/musicpack-api-v1.md.
For a real end-to-end setup — MusicPack Author on macOS, musicpack-server
and the web client on a Linux server, browser clients — see
docs/deployment.md (build/install steps, filesystem layout, transfer
workflow, first-run procedure, systemd service, reverse proxy, upgrade,
backup and troubleshooting). The server also has its own concise README at
server/README.md, and a production systemd unit plus optional environment
template ship under packaging/systemd/.
Musepack is the audio foundation: a mature, open lossy codec whose SV7/SV8 streams the rest of the ecosystem plays and produces. The codec parts are preserved and modernized conservatively — they are stable, well-tested, and guarded by byte-identity regression tests.
CMake 3.16+ is required. Everything builds out of the box:
cmake -S . -B build
cmake --build build -jUseful options:
| Option | Default | Description |
|---|---|---|
MPC_BUILD_SHARED |
ON (non-Windows) |
Build libmusepack as a shared library |
MPC_BUILD_TESTS |
OFF |
Register the regression suites (ctest) |
MPC_BUILD_MPCGAIN |
ON |
Build mpcgain (needs libreplaygain) |
MPC_BUILD_MPCCHAP |
ON |
Build mpcchap (needs libcuefile) |
MPC_BUILD_SERVER |
ON |
Build musicpack-server (needs libmicrohttpd) |
mpcgain and mpcchap are skipped automatically if their optional
dependencies (libreplaygain, libcuefile) are not found.
musicpack-server is skipped when libmicrohttpd is unavailable (Windows is
not supported for the server executable; the server core still builds there).
Install (headers, libraries, pkg-config files, and tools):
cmake --install buildInstalled consumers can use the packaged CMake targets:
find_package(Musepack CONFIG REQUIRED) # the codec library
target_link_libraries(app PRIVATE Musepack::Decoder)libmusepack is the stable decoder-facing library (SV7/SV8). It exposes an
opaque, single-threaded session API over a pluggable reader abstraction
(files, memory buffers, or custom callbacks):
#include <musepack/musepack.h>
mpc_reader reader;
mpc_reader_init_stdio(&reader, "song.mpc");
musepack_decoder *d = musepack_decoder_open(&reader, 0);
float pcm[MUSEPACK_FRAME_MAX * 2];
uint64_t n;
while (musepack_decoder_read(d, pcm, MUSEPACK_FRAME_MAX, &n) == MUSEPACK_OK) {
/* play n sample-frames of interleaved float PCM */
}
musepack_decoder_close(d);
mpc_reader_exit_stdio(&reader);See docs/api.md for the full API, ownership rules, error codes, and the
reader design. The decoder also builds to WebAssembly (Emscripten) and powers
the two browser front-ends above:
emcmake cmake -S . -B build-wasm && cmake --build build-wasm- The MusicPack web client (
web/) decodes.mpcover HTTP Range with a demand-driven reader; seeweb/README.md. - The low-level WASM demo (
demo/) is a development/test artifact kept for the demand-reader plumbing.
| Tool | Purpose |
|---|---|
mpcdec |
Decode MPC to WAV; -i prints stream info, -c checks a file |
mpcenc |
Encode WAV (or other formats via external decoders) to MPC |
mpc2sv8 |
Convert SV7 files to SV8 |
mpccut |
Cut a range of samples out of an SV8 file |
mpcgain |
Compute ReplayGain (requires libreplaygain) |
mpcchap |
Read/write SV8 chapters (requires libcuefile) |
wavcmp |
Compare two WAV files |
musicpack |
Author and verify .mpack albums (info, verify, create, import, identify, update-metadata, plus the authoring draft commands inspect/validate-draft/encode-draft/build-draft/identify-draft) |
musicpack-server |
Index a .mpack library and serve it over HTTP API v1 (requires libmicrohttpd) |
See tests/README.md. With -DMPC_BUILD_TESTS=ON, ctest runs the full suite,
organized by category rather than a single count:
- unit / API / codec — crc32, bitstream and table internals; the stable
libmusepackAPI surface; a fixture regression pinning decode output for bit-exactness; end-to-end toolchain integration; and decoder robustness on malformed input; - decoder SIMD A/B — scalar-vs-SIMD synthesis differential and direct
decoder-state differential (
synth_ab,synth_state_ab), each fail-closed when the SIMD kernel is unavailable; - encoder / psy A/B — analysis-filter and psychoacoustic scalar-vs-SIMD
differentials (
enc_ab,psy_ab), also fail-closed; .mpackpackage — manifest, paths, checksums, loudness meter, handoff, integration and fuzz-lite; the MPAK v1 container (mpak) and the HTTP Range transports (mpakhttp,mpakrange_smoke);- v1 conformance corpus — 3 valid manifests, 42 invalid manifests, 8
invalid asset cases, required to pass
info/verifyper case; - hostile-package regression — special files (FIFO/directory/symlink escape), hard links and oversized objects must fail quickly;
- Sonic — container parsing/validation units and WAV robustness;
- Author — backend draft-command tests, the FLAC→MPC / WAV→MPC q6 encode
stage, native source decoding (
audio_decode), and an ffmpeg-free negative workflow; no external tool is required; - server — a core suite (range parser, migrations, tokens, package identity, ownership/conflict, verify, scanner behaviors) that runs on all platforms, plus an HTTP integration suite (auth matrix, CORS, live scan/verify/status, streaming, HTTP Range, ETag/304, concurrency, security headers — UNIX);
- compatibility — a check that pins the encoder to bit-identical output
with the pristine reference encoder, and
enc_compatfor the extended q5/q6/q7 corpus (live against a same-toolchain reference build on CI, with a committed manifest as the local fallback); - Wasm / web — Emscripten
wasm_smokeandmpak_wasm_smoke(demand-driven range-reader path and MPAK-range open/verify/decode/seek: PCM identity, seek fetch-accounting, network-failure injection), aweb_wasm_gaplessNode suite (gapless two-track continuity, exact track-end frames, demand-reader seek accounting), anmpakrangeNode suite pinning the browser HTTP Range transport against a deterministic loopback server, and the web client's own Vitest/Playwright suites.
Hosted CI covers Linux GCC, Linux Clang, macOS ARM64, Windows MSVC, a Linux SIMD-off build, Emscripten/Wasm, and the web client (Playwright). Sanitizer coverage (ASan/UBSan) is a targeted local exercise of the package, server, integration and fuzz suites — not a hosted job.
The web client adds its own suites (web/): Vitest units for the controller,
queue, ring buffer, loudness math, API client and session; a Playwright
browser suite (authenticate → shelf → album → edition switch → Musepack and
native playback → seek → gapless → queue → Media Session → 401 re-auth) run
in the CI web-client job; and a performance report script. See
web/README.md.
cmake -S . -B build -DMPC_BUILD_TESTS=ON
cmake --build build
ctest --test-dir buildcodec/— Musepack codec domain:codec/libmpcdec/— SV7/SV8 decoder +musepack_decoderfacade (the codec)codec/libmpcenc/— SV8 encoder corecodec/libmpcpsy/— psychoacoustic modelcodec/libwavformat/— WAV read/write helpercodec/include/musepack/— stablelibmusepackpublic APIcodec/include/mpc/— historical public headers (installed for compatibility)codec/common/— shared sources (crc32, fast-math tables, tag handling)codec/mpcdec/,codec/mpcenc/,codec/mpc2sv8/,codec/mpccut/,codec/mpcgain/,codec/mpcchap/,codec/wavcmp/— CLI tools
core/— MusicPack format domain:core/libmusicpack/—.mpackpackage library (libmusicpack)core/musicpack/—musicpackCLI (info/verify/create/import/update-metadata + the authoring draft commandsinspect/validate-draft/encode-draft/build-draft/identify-draft)core/sonic/— Sonic analysis
author/— MusicPack Author: the Tauri 2 + Svelte 5 desktop authoring GUI (author/README.md)server/—musicpack-server: scanner, SQLite collector library, HTTP API v1, direct streaming (vendored SQLite inserver/vendor/)web/— the web client (Svelte 5 + Vite + TS): the digital record shelfplatform/— platform-specific code:platform/win32/— Windows compatibility shimsplatform/packaging/— systemd service unit + optional environment template (seedocs/deployment.md)
wasm/— Emscripten build of the decoder + WASM wrapper + MPAK-range wrapper + smoke testsdemo/— low-level browser playback proof-of-concept, plus the browser MPAK HTTP Range transport (demo/mpakrange.js)mpakhttp/— optional embedding-layer HTTP Range adapter for.mpakcontainers (libcurl; gated like the server's libmicrohttpd)specs/—.mpackv1 spec + JSON Schema, the MPAK v1 container spec (mpak-v1.md), the MPAK-over-HTTP-Range design (mpak-http-range-design.md), and the server API spec (musicpack-api-v1.md)tests/— fixture generator, corpus generator, and regression harnesseslegacy/— retired autotools and Visual Studio 2005 build files
MusicPack is a mixed-license repository. The historical Musepack notices are preserved verbatim in the files they apply to; individual files carry their own copyright and SPDX license identifier.
- LGPL-2.1-or-later — the Musepack encoder core and its derivatives:
libmpcenc,libmpcpsy,mpcenc, the encoder-side SIMD kernels (libmpcenc/analy_filter_simd.c,libmpcpsy/fft4g_simd.c,libmpcpsy/fft_routines_simd.c),libmpcpsy/psy_profile.*, and the encoder-sidecommon/sources (fastmath.c,tags.c). Musepack files modified by the MusicPack project carry a "Modified by the MusicPack Development Team" notice per LGPL 2.1 §2. - BSD-3-Clause — the Musepack decoder and its tools:
libmpcdec,libwavformat,mpcdec,mpccut,mpc2sv8,mpcgain,mpcchap,wavcmp, and theinclude/mpc/decoder headers. The MusicPack ecosystem is also BSD-3-Clause:libmusicpack, themusicpackCLI,musicpack-server,sonic,wasm,web,author,demo,tests, andbench. - MIT — vendored
cJSON,libebur128, andmpcchap'siniparser. - Public domain — vendored
SQLite,dr_flac, AT&T'sgetopt, and the PNG-spec CRC-32 reference incommon/crc32.c.
Full license texts live in LICENSES/; libmpcdec/COPYING carries the
decoder's BSD notice. The top-level LICENSE is the GNU Lesser General
Public License version 2.1.