Skip to content

wobblemidi v1.0.0

Latest

Choose a tag to compare

@JakebGutierrez JakebGutierrez released this 06 Jul 12:58

wobblemidi v1.0.0

First stable release. wobblemidi humanises programmed drum MIDI by sampling
timing and velocity deviations from real drummer performances — the
Groove MIDI Dataset
(341 rock takes, 114,890 hits, Roland TD-11) — instead of adding random jitter.

Highlights

  • Statistical timing & velocity sampled per instrument, grid position,
    beat/fill context, and dynamic tier (per-bucket KDE, six-level fallback for
    sparse buckets, per-bucket outlier clipping).
  • One clock for the kit — an AR(1) groove-drift clock (phi calibrated
    ≈0.37 from the data) correlates timing across the whole kit so it breathes
    as a pocket instead of scattering; kick velocity gets its own drift clock
    (the one instrument where human velocities measure strongly autocorrelated).
  • Flam & chord preservation — same-tick hits and close-spaced ornaments
    (≤12 ms) move as one rigid unit; see demo/flam_beat_*.mid for the A/B.
  • Relative velocity tiering — ghost/accent roles are read from your file's
    own velocity structure, so programmed dynamics survive humanisation.
  • De-biased timing by default — the source drummers' systematic push/drag
    is removed (kept as spread, not lean); --push restores the authentic lean.
  • Controls: --intensity (default 0.35; 0.2–0.5 is the useful range),
    --groove-tightness, --section beat|fill, --seed, --timing-only /
    --velocity-only, --all-channels. Per-lane intensity and lean amount in
    the GUI/API.
  • GUIwobblemidi-gui (pywebview): drag a file in, turn knobs, audition,
    export. macOS .app attached below.

Validation, honestly

The engine gates on a harness that scores it against held-out human takes
(GMD's own train/test split) — per-instrument offset distributions
(Wasserstein/KS/σ/mean), within-position velocity spread, adjacent-jump
distributions, contour preservation, lag-1 autocorrelation, cross-instrument
gap tightness — all two-sided against human, so "more robotic than a drummer"
and "sloppier than a drummer" both fail. Then ear-tested.

Two known misses are accepted and documented, not hidden:

  1. At full intensity, kick/hat/ride velocities carry 2–3× a human's
    within-role spread (unimodal excess; masked at the 0.35 default; the next
    lever — a velocity analogue of the AR timing clock — is identified).
  2. Snare emits slightly too few exactly-repeated velocities compared with
    human ghost runs — structural to continuous KDE sampling, cosmetic.

Engineering

  • Deterministic: one seed, three isolated RNG streams; semantics frozen in
    wobblemidi_determinism.md.
  • 26 golden vectors byte-lock the engine across the full parameter surface,
    verified on every CI run on Linux + macOS (308 tests total).
  • This engine is the reference implementation for a planned JUCE/AU Logic
    plugin; the port gate is defined in wobblemidi_porting_contract.md.

Assets

  • wobblemidi-1.0.0-macos-arm64.zip — the GUI as a macOS app
    (unsigned: right-click → Open on first launch).
  • wobblemidi-1.0.0-demo-midi.zip — the seeded before/after MIDI pairs; see
    demo/README.md for what to listen for in each.
  • wobblemidi-1.0.0-py3-none-any.whl / .tar.gz — pip-installable build.

Install

pip install git+https://github.com/JakebGutierrez/wobblemidi

(or pip install the attached wheel; add the [gui] extra for the GUI).

Licensed MIT. Profile data derived from the Groove MIDI Dataset, © Google LLC,
CC BY 4.0.