Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BeatTrackerJS

Live beat tracker that runs entirely in the browser: it listens to audio, locks onto the tempo, shows which beat of the bar you are on and how hard it was accented — and a little robot dances to it.

No backend, no WASM, no dependencies. madmom's neural model is ported to plain JavaScript and produces exactly the same beats as the original, down to float32 rounding noise.

Try it — hit "Listen to input" (microphone or system monitor) or "Tab audio" to pick up whatever is playing in another tab.


What it does

  • Tempo and phase from madmom's online tracker (BLSTM + HMM), 1.9 ms per 10 ms hop: 19% of a core.
  • Automatic meter among 3, 4 and 6, or pinned by hand from 2 to 6. It is built to survive a playlist: the meter is re-decided as tracks change instead of latching onto the first one it saw.
  • Position inside the bar, with the 1 located by the downbeat model.
  • Per-hit accent: each beat lights up in proportion to the energy that actually sounded there, so the accent pattern becomes visible.
  • A dancing robot with twelve moves, or auto-rotation every 4 bars. A move separates its look from its timing, so the same step runs at half time, on the beat or on eighths — the arms can be on eighths while the hips follow the bar, which is what makes the meter readable at a glance. Some moves are continuous instead of stepped: the hips roll across a whole bar, or the body walks away for one bar and back the next.
  • Silence gate, so it does not invent a tempo when there is no music.

How it works

audio ─▶ AudioWorklet ─▶ features ─▶ 8x LSTM ensemble ─▶ HMM ─▶ beats
   │      (441 hops)     (FFT +       (with peepholes)  (forward)   │
   │                      filterbank                                ▼
   │                      + log + diff)                          grid
   │                                                       (tempo, meter)
   └─▶ rolling 6 s window ─▶ bidirectional BLSTM ─▶ phase vote ─▶ the "1"
             (in a Web Worker)     (downbeat model)

The beat tracker is causal and runs in real time. The downbeat model is bidirectional — it cannot run in streaming — so it lives in a Web Worker over a 6 s window, and every beat votes for its position in the bar.

Run locally

python3 serve.py 8090      # serves web/, no caching

It has to be over HTTP: ES modules and AudioWorklet do not work from file://. In production HTTPS is required (the microphone demands it); Netlify handles that for you.

Tests

npm test                   # parity against madmom, stage by stage
node test/silence.mjs      # the gate: noise vs music
node test/gapfill.mjs      # filling in skipped beats
node test/meter.mjs a.f32  # meter on songs of known meter
node test/playlist.mjs a.f32   # meter recovery when the track changes
node test/dance.mjs        # dance subdivisions, without a browser

The parity tests need fixtures that are not versioned (~11 MB). Regenerate them with the exporters:

AUDIO_E2E=/path/to/a/song.mp3 python tools/export_madmom.py
python tools/export_downbeats.py 3

That needs madmom==0.16.1 in Python (see docs/MIGRATION.md).

Deploy

Static site, no build. netlify.toml already sets publish = "web".

netlify deploy --prod

Or connect the repo from the Netlify dashboard: it picks up netlify.toml and there is nothing to configure.

Read more

  • docs/MIGRATION.md — how madmom was ported to JavaScript: what was exported as data instead of translated, how it was verified stage by stage, and the three times the test failed while being right.
  • docs/EXPERIMENTS.md — which other trackers were tried before settling on madmom (BeatNet, BeatNet+, BEAST, a classic tracker with no ML), what metrics they were compared with, and what came out.

Layout

web/                 what gets published
├── index.html, app.js, styles.css
├── worklet.js       collects 441-sample hops
├── downbeat-worker.js
├── src/             the port: features, network, HMM, grid, accent, meter, dance
└── public/models/   exported weights (2.7 MB)
tools/               exporters from madmom (Python)
test/                parity and behaviour (Node)
docs/                the two long documents
serve.py             development server with caching disabled

Credits

The model is madmom's (Böck et al.), BSD. This repo only ports it.

MIT.

About

Live beat tracking in the browser: madmom's neural model ported to plain JavaScript. No backend, no WASM, no ONNX.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages