The core runtime library for OpenSampler — a Rust sampler engine with a stable
C ABI, built to load and play .osmp bundles with stream-on-disk hybrid playback
and optional AES-256 protection for commercial libraries.
Status: pre-alpha / specification. This repository currently contains the v0.1–v0.5 technical design. See docs/ROADMAP.md for the implementation plan.
libOsmp is the shared runtime powering the OpenSampler family:
- OpenSampler — the sampler application
- OpenSampler Rack — the host/rack environment
- OpenSampler Plugin — plugin builds (VST/AU/etc.)
- Futureboard — hardware integration
It is written in Rust for a realtime-safe core, and exposes a C ABI so C/C++, plugin SDKs, and hardware can integrate against a stable boundary.
.osmp = OpenSampler Package Bundle. It is not a raw sample file — it is a
chunk-based binary container that can hold a complete instrument/library in a
single file:
- package + vendor metadata
- one or more instruments (mapping + sound-design base)
- one or more presets (parameter/macro/FX/mix state)
- a shared sample pool
- zone maps + articulation / round-robin metadata
- a stream index and cache hints
- an optional license block
- signature + hash tables for integrity/trust
- optional UI metadata
The container supports random access: read metadata, a single sample block, the stream index, or an encrypted block without touching the rest of the file.
Full spec: docs/FORMAT.md.
| Area | State |
|---|---|
| Format spec | Drafted |
| Metadata schema | Drafted |
| Streaming design | Drafted |
| Crypto design | Drafted |
| C ABI | Drafted |
| Rust API | Drafted |
| Implementation | Not started (see roadmap) |
- Rust
rlib(native Rust consumers) cdylib/staticlibexposing the C ABI (libosmp.{so,dylib,dll}/.a/.lib)- C header at
include/osmp.h - CLI binaries (
osmp-pack,osmp-cli) — planned for v0.5
Planned toolchain: stable Rust, no GPL/LGPL dependencies in the core.
libosmp/
├── crates/
│ ├── osmp-core # Package/instrument/preset model, orchestration
│ ├── osmp-container # Binary container: header, directory, chunks, footer
│ ├── osmp-metadata # CBOR/MessagePack/JSON metadata (de)serialization
│ ├── osmp-stream # Stream-on-disk, IO workers, ring buffers, SIDX
│ ├── osmp-cache # Hot-block RAM cache + optional .osmpcache
│ ├── osmp-crypto # BLAKE3/SHA-256, Ed25519, AES-256-GCM, key provider
│ ├── osmp-engine # Realtime voice engine, mapping, envelopes, render
│ ├── osmp-pack # Bundle authoring / packing
│ ├── osmp-cli # osmp-pack / osmp-inspect / osmp-verify front-ends
│ └── osmp-capi # C ABI (cdylib/staticlib) over the Rust core
├── include/
│ └── osmp.h # Public C header
├── docs/
│ ├── FORMAT.md
│ ├── METADATA.md
│ ├── STREAMING.md
│ ├── CRYPTO.md
│ ├── C_API.md
│ ├── RUST_API.md
│ └── ROADMAP.md
└── examples/
├── c_player/ # Minimal C player using osmp.h
├── rust_player/ # Minimal Rust player using the osmp crate
└── pack_basic/ # Folder -> .osmp packing exampleHandle-based, stable, UTF-8 strings owned by the library. Full reference: docs/C_API.md.
#include "osmp.h"
osmp_package_t* pkg = NULL;
osmp_open_package("OpenGrand.osmp", &pkg);
osmp_instrument_t* inst = NULL;
osmp_load_instrument(pkg, "concert_grand", OSMP_LOAD_HYBRID, &inst);
osmp_engine_config_t cfg = {0};
cfg.struct_size = sizeof(cfg);
cfg.sample_rate = 48000; cfg.block_size = 128; cfg.channels = 2;
cfg.max_voices = 256; cfg.ram_cache_mb = 512; cfg.stream_block_kb = 64;
osmp_engine_t* eng = NULL;
osmp_create_engine(&cfg, &eng);
osmp_engine_set_instrument(eng, inst);
osmp_engine_note_on(eng, 0, 60, 100);
/* render into planar float buffers ... */Idiomatic, Result-based. Full reference: docs/RUST_API.md.
use osmp::{Package, Engine, EngineConfig};
let pkg = Package::open("OpenGrand.osmp")?;
println!("{:#?}", pkg.metadata());
let instrument = pkg.load_instrument("concert_grand")?;
let mut engine = Engine::new(EngineConfig {
sample_rate: 48_000, block_size: 128, channels: 2,
max_voices: 256, ram_cache_mb: 512, ..Default::default()
})?;
engine.set_instrument(instrument)?;
engine.note_on(0, 60, 100);| Tool | Purpose |
|---|---|
osmp-pack |
Pack a sample folder into a .osmp bundle. |
osmp-inspect |
Dump header, chunk directory, and metadata. |
osmp-verify |
Verify hashes, signature, and metadata schema. |
The audio render path must not:
- allocate or free memory,
- perform file IO,
- block on a mutex,
- perform heavy decrypt/decompress.
Background IO workers prepare data ahead of time; streaming underflow is handled gracefully. See docs/STREAMING.md.
- Core license: intended permissive (MIT/BSD/Apache-style). No GPL/LGPL in the core runtime.
- Prefer MIT/BSD/Apache dependencies only.
- No FFmpeg in the core sampler runtime.
- No hard dependency on any GUI framework or plugin SDK in the core.
Recommended crates (all permissively licensed):
| Concern | Crate(s) |
|---|---|
| Serialization | serde, ciborium or rmp-serde |
| Hashing | blake3, sha2 (compat) |
| Encryption | aes-gcm |
| Signing | ed25519-dalek |
| Compression | zstd |
| Errors | thiserror |
| Bitflags | bitflags |
| Worker comms | crossbeam / ringbuf (non-audio side; audio-thread safety documented per call site) |
Note:
zstdbindings wrap the zstd C library, which is BSD/GPL dual-licensed; use it under the BSD option to stay GPL-free. Verify the chosen crate's license option before shipping.