Skip to content

libraz/libsonare

Repository files navigation

libsonare

CI npm PyPI codecov License C++17 Platform Docs

libsonare turns audio into data and data back into audio. Load a song and get its BPM, key, chords, and structure; master and mix it to broadcast loudness; turn MIDI into sound with built-in instruments; or build a whole DAW on top — the same engine in C++, Python, Node.js, and the browser, with zero runtime dependencies, no Python at runtime, and no GPL/AGPL or model weights.

Reach for it when you need to:

  • Analyze audio — BPM, key, chords, sections, loudness — without pulling in a heavy Python/ML stack.
  • Master or mix to spec — broadcast-grade loudness and true-peak control, in-process or fully in the browser.
  • Turn MIDI into sound — built-in instruments cover all 128 GM programs + drums, no SoundFont required.
  • Ship one audio engine — the same C++ DSP runs natively and in the browser (WASM + AudioWorklet), with identical results.

📖 Documentation  ·  🎧 Browser-local demos  ·  Getting started

What can you build with it?

sonare studio is a full browser-based DAW built entirely on the libsonare WASM engine — multi-track sequencing, a piano roll, score engraving, a mixer, mastering, and WAV/MP3/MIDI/MusicXML export, all running client-side. It shows how far one Apache-2.0 engine reaches, from analysis to a playable, exportable arrangement.

It's a hosted live demo that drives the whole engine end-to-end as an integration test bed, not a production product (source not public). Try it in the browser to see what libsonare can power.

What's inside

  • Analysis — BPM, key, chords (HMM smoothing, inversions, key-context), beat/downbeat, time signature, sections, timbre, dynamics, pitch (YIN/pYIN), tempogram/PLP, NNLS chroma, EBU R128 loudness, and room acoustics (blind or IR-based RT60/EDT/C50/C80/D50). Where it overlaps librosa, defaults match and are validated against librosa reference values in CI — so results port over without surprises.
  • Mastering — 76 named DSP processors (EQ, dynamics, multiband, stereo, saturation, repair, maximizer, reference matching) built against published references: ITU-R BS.1770-4 loudness and true-peak limiting, Linkwitz-Riley crossovers, Vicanek matched-Z biquads, ADAA-antialiased clippers, a Dempwolf 12AX7 tube model, and polyphase FIR oversampling. Repair is classical DSP, not DNN separation.
  • Mixing & routing — a real-time-safe channel-strip / bus model (denormal-guarded, lock-free parameter changes, plugin-delay compensation) with pan modes, sends, FX buses, metering, scene presets, and offline rendering.
  • Editing & creative FX — time stretch / pitch shift, pitch correction, note stretch, voice change, five reverb engines, modulation effects, stereo delay, guitar amp sim, and ducking.
  • Room acoustics — synthesize a room impulse response from shoebox geometry, blindly estimate an equivalent room from a recording, or morph a recording's reverberation toward a target room. Dependency-free and deterministic.
  • Built-in instruments — a patch-driven NativeSynth with 15 synthesis engines (subtractive, FM, additive plus physically-modeled piano, bowed strings, reeds, brass, flute, pipe organ, plucked strings, voice, free reed, and percussion), a mod matrix, and named presets, backed by a data-free GM fallback covering all 128 programs + drums, so MIDI never renders silent. Add a host-supplied SoundFont and the GS-compatible 16-part SF2 player takes over, falling back per program. The physical-model voices are usable today and being refined over time as tuning continues.
  • Headless DAW runtime — author projects with audio & MIDI tracks/clips (split/trim/move with undo/redo), takes and comp lanes, per-clip warp, MIDI 1.0/2.0 sequencing, SMF and MIDI 2.0 Clip File I/O, deterministic byte-stable JSON, and offline bounce through the built-in instruments.
  • Realtime engine — a sample-accurate, allocation-free playback engine: transport, clip playback with warp, paged streaming for huge clips, live MIDI input, lock-free automation, and capture/recording. The same engine runs in the browser through an AudioWorklet.

See the documentation for the full API of every feature, runtime, and processor.

Installation

npm install @libraz/libsonare   # JavaScript / TypeScript (WASM, takes Float32Array)
pip install libsonare            # Python (WAV/MP3 — see "Audio formats" for M4A/AAC etc.)

For Node.js with native file decoding, build @libraz/libsonare-native from source (it auto-detects FFmpeg via pkg-config). See the installation guide for native builds and FFmpeg options.

Quick start

The snippets below cover the headline capabilities; the docs site has the full, per-runtime API.

Which runtime, and does it decode files for you? WASM takes Float32Array; Python and the Node native addon read files directly. → Choose your runtime

JavaScript / TypeScript (WASM)

@libraz/libsonare accepts decoded Float32Array samples (use the Web Audio API or a JS decoder to obtain them).

import { init, analyze, detectKey, masterAudio } from '@libraz/libsonare';

await init();

const result = analyze(samples, sampleRate);   // BPM, key, chords, sections, ...
const key = detectKey(samples, sampleRate);     // { name: "C major", confidence: 0.95 }

// One-shot mastering with a named preset.
const mastered = masterAudio(samples, sampleRate, 'aiMusic', { 'loudness.targetLufs': -13 });

JavaScript API · Browser / WASM

Python

pip install libsonare ships a WAV/MP3-only wheel. For other formats, pre-convert with ffmpeg or rebuild with FFmpeg linked (see Audio formats).

import libsonare

audio = libsonare.Audio.from_file("song.mp3")
print(f"BPM: {audio.detect_bpm()}, Key: {audio.detect_key()}")

result = audio.mastering(target_lufs=-14.0, ceiling_db=-1.0)
print(f"{result.input_lufs:.1f} LUFS → {result.output_lufs:.1f} LUFS")

Python API · CLI

The sonare command-line tool ships with the Python package (sonare analyze song.mp3, sonare mastering …, sonare project …).

C++

#include "sonare.h"            // analysis + features + effects
#include "mastering/master.h"  // mastering chain & processors

auto audio = sonare::Audio::from_file("music.mp3");
auto result = sonare::MusicAnalyzer(audio).analyze();
std::cout << "BPM: " << result.bpm
          << ", Key: " << result.key.to_string() << std::endl;

C++ API

Instruments & MIDI

Turn a MIDI arrangement into audio with the built-in instruments — no SoundFont required. Build a Project, add notes, and bounce it through a NativeSynth preset.

import libsonare

with libsonare.Project() as project:
    project.set_sample_rate(48000)
    _, clip_id = project.add_midi_clip(0.0, 4.0)             # start, length (quarter notes)
    project.set_midi_events(clip_id, [
        libsonare.Project.midi_note_on(0.0, 0, 0, 60, 100),  # ppq, group, channel, note, velocity
        libsonare.Project.midi_note_off(2.0, 0, 0, 60),
    ])
    audio = project.bounce_with_synth_instrument("e-piano", num_channels=2)  # → float32 audio

The same Project / bounce API is available in every runtime; add a host-supplied SoundFont to render through the GS-compatible SF2 player instead.

Python API · Documentation

Audio formats

Format Default¹ With FFmpeg² WASM (@libraz/libsonare)
WAV (PCM 16/24/32, float32) n/a (samples in)
MP3 n/a
M4A / AAC / FLAC / OGG / Opus / WMA / … ❌ (clear error) n/a (use Web Audio API)

¹ Default: the PyPI wheel and source builds without FFmpeg dev libs. Wheels are pinned to this mode so installation never depends on your libavformat.

² With FFmpeg: a source build with FFmpeg linked — CMake auto-detects via pkg-config (-DSONARE_WITH_FFMPEG=AUTO). Python: SONARE_FFMPEG=1 pip install libsonare --no-binary libsonare; Node native: SONARE_FFMPEG=1 yarn build.

WASM bundles no file decoder by design — pass Float32Array samples from the Web Audio API or another JS decoder.

Build from source

make build && make test   # native; auto-detects FFmpeg, mastering + mixing on by default
make wasm                  # WebAssembly
make release               # optimized native build

Trim the binary with -DBUILD_MASTERING=OFF / -DBUILD_MIXING=OFF for analysis-only builds. Optional, experimental, off-by-default macOS host backends (CoreAudio / CoreMIDI / AU host) cover device I/O and AU hosting for source builds; they ship in no published package. See the architecture docs for build options.

Documentation

Full docs and browser-local demos live at libsonare.libraz.net (demos).

Non-goals

libsonare is the headless engine, not an application. It intentionally does not include a UI or DAW workflow, third-party plugin hosting (VST/CLAP), a cross-platform real-time I/O abstraction, bundled sample data, or deep-learning models. Callers own the audio callback and the UI; the experimental macOS backends are the only (opt-in, unpublished) exception to the I/O boundary. These limits keep the library dependency-free and Apache-2.0 pure. See Non-goals for the rationale.

License

Apache-2.0