livechord-bar-arbitrator

Post-processor that fixes bar / downbeat phase drift, beats-per-bar confusion, and doubletime/halftime mistakes in beat-tracker output, without re-running expensive audio models. Reads chords[] + beats[] + downbeats[] + bpm from a chord JSON and emits a corrected grid.

🎹 Try it live

This is the same arbitrator that fixes the bar grid before LiveChord's chord ribbon and 88-key piano waterfall lay out their cards. Try the full app at livechord.org.

Quickstart

pip install livechord-bar-arbitrator onnxruntime
from livechord_bar_arbitrator import arbitrate, apply_to_chord_json

chord_data = {
    "chords":    [{"time": 0.0, "end": 4.5, "chord": "Cm7"}, ...],
    "beats":     [0.0, 0.5, 1.0, ...],
    "downbeats": [0.0, 2.0, 4.0, ...],
    "bpm":       120.0,
}

result = arbitrate(chord_data)
if result["applied"]:
    chord_data = apply_to_chord_json(chord_data, result)

The ONNX checkpoint is downloaded from this Hub repo on first call (cached under ~/.cache/huggingface/hub). To use a local file, pass arbitrate(chord_data, model_path="path/to/bar_arbitrator_v1.onnx").

What it does

The arbitrator operates on already-detected chords + beats β€” it does not re-analyze audio. Three families of error get caught:

  1. Phase drift β€” gaps in downbeats[] like 1.4s, 3.3s, 0.7s, ... when the bar should be 2.8s.
  2. Bar-doubling β€” every other bar marked, gaps = 2 Γ— bar duration.
  3. Beat-vs-bar confusion β€” every beat marked as a downbeat, gaps == beat_dur.

It chooses between a deterministic rule-based path (Phase 0, zero ML deps, ships always) and an optional ONNX Transformer (Phase 1, ~750 KB, downloaded from HF Hub) that uses chord-quality features to recover bar phase even when local beats are unreliable.

Architecture

Two-tier:

            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
chord_data───  arbitrate(chord_data)  β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚                     β”‚
            β–Ό                     β–Ό
    [ rule-based ]         [ ONNX Transformer ]   ← Phase 1, optional
    (Phase 0)              (~750 KB, CPU only)
       β€’                          β”‚
       β€’                          β–Ό
       β€’                   [ confidence gate ]
       β€’                          β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β–Ό
        ArbitrationResult dict
        (downbeats_before/after, score_before/after,
         beats_per_bar, applied, reason)

The Phase 1 model is a per-beat Transformer with a 28-dim feature input (chord root pitch class, quality bucket, distance-to-chord-change, beat regularity, ...). It outputs per-beat downbeat probability and beats-per-bar logits, then phase + bpb are decoded to a final grid.

Phase 0 is conservative by design β€” it only acts when the candidate grid scores above an internal F1 threshold against chord changes. This avoids replacing raw downbeats with a worse grid when the underlying beat tracking is broken.

Files in this repo

File What Required
bar_arbitrator_v1.onnx Phase 1 ONNX-exported Transformer (~750 KB) Optional
Source code in livechord-bar-arbitrator on GitHub Arbitration pipeline via pip install

Combining with livechord-beat-refiner

For full audio-level refinement (re-pick beats given audio context) + bar arbitration in one call:

pip install livechord-bar-arbitrator livechord-beat-refiner
from livechord_bar_arbitrator import phase1_refine

result = phase1_refine(chord_data, audio_path="song.flac")

This pipes the audio through the Compact Transformer beat refiner first, then runs the bar arbitrator on the refined output. Recommended when you have access to the source audio file.

Limitations

  • Phase 1 ONNX model is small and conservative. It refuses to act when its candidate grid scores below an internal F1 threshold against chord changes. So bad inputs sometimes pass through unchanged.
  • No reggae / ska / 6/8 specialization. Phase 1 v1 was trained primarily on 4/4 pop and rock. Compound time is OK but rarely re-corrected.
  • No real-time mode. Designed for offline / batch use after chord detection finishes.

Citation

@misc{livechord-bar-arbitrator,
  title  = {livechord-bar-arbitrator: rule-based + Transformer
            post-processor for bar / downbeat grid arbitration},
  author = {LiveChord Project},
  year   = {2026},
  url    = {https://huggingface.co/livechord-music/livechord-bar-arbitrator},
}

License

Apache License 2.0 β€” code AND weights.

Related

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support