shimga

BPM Detection & Beat-Synced Visuals: A Music Video Maker's Guide

Engineering 📅 May 2026 ⏱ 8 min read

BPM detection is the difference between a music video that looks reactive and one that feels reactive. Frequency-band reactivity (bass → glow, mid → rotation) responds to whatever's playing right now; beat synchronization snaps visual events to the song's underlying grid. The two together — band reactivity for moment-to-moment energy, beat sync for structural punch — are what every great music visualizer does.

This guide explains how automatic BPM detection works, how Shimga uses it, and what to do when the algorithm gets it wrong.

What "BPM Detection" Actually Means

Beats per minute. 120 BPM = one beat every 0.5 seconds. The detector's job is to look at a raw audio file and return:

  1. A BPM number (usually a half-integer like 124.5).
  2. A list of beat timestamps — the actual times where beats fall.

Returning just the BPM isn't enough. If a song is 120 BPM, you still need to know whether beat one is at 0.04 seconds or 0.32 seconds. Different starting offsets produce visibly different beat-snapped visuals.

How the Algorithm Works (the Short Version)

Modern in-browser BPM detection algorithms follow the same recipe:

  1. Downsample audio from 44.1 kHz to ~22 kHz. Halves the work.
  2. Low-pass filter — keep only frequencies below ~200 Hz. Beats live in the bass (kicks, low toms).
  3. Onset detection — break the filtered audio into short frames, measure energy in each, and look for sudden jumps. Each jump is a potential beat.
  4. Autocorrelation — slide the onset-strength signal against itself at various lags (corresponding to 60-200 BPM). The lag that produces the highest correlation is the tempo.
  5. Parabolic interpolation — refine the integer-frame lag to a sub-frame value, giving you a more accurate BPM than the frame rate alone supports.
  6. Find the first beat — within the first ~2 beats of audio, pick the strongest onset. That's beat 1; the rest of the grid follows from BPM.

Total runtime: ~2-5 seconds for a 3-minute song. More on how the FFT side works.

Why It Sometimes Gets It Wrong

BPM detection is solved for "regular" music — drum-driven hip hop, EDM, rock, pop. It struggles on:

How to Fix a Wrong BPM in Shimga

If the studio detects a wrong BPM:

  1. Open the timeline. Look at the beat-grid lines overlaid on the waveform.
  2. If the grid is exactly twice or half what it should be, manually edit the BPM in the timeline header (click the BPM badge). Halving 150 → 75 fixes the most common case.
  3. If the grid is correct in tempo but offset (every beat is 0.2 seconds too early), use the "First Beat Offset" field. Shimga shifts the entire grid by that amount.
  4. If the song genuinely has no steady tempo, turn off Beat Snap in the timeline and place reactive events manually using keyframes.

Using the Beat Grid Creatively

Once Shimga has a correct BPM, you can:

Why Run BPM Detection in a Web Worker

Three minutes of audio is ~7.9 million samples. The autocorrelation loop alone runs ~3 million iterations per BPM lag tested. Doing that on the main thread blocks the UI for several seconds — the user clicks "Upload Audio" and the studio freezes. Shimga runs it in a Web Worker, so the main thread keeps painting at 60fps while detection happens in parallel. The result arrives via postMessage and updates the timeline live.

What "Beat Sync" Looks Like in a Music Video

The cleanest beat sync is usually invisible. Examples:

Avoid: a different visual event on every beat. That's strobing, not sync.

Try beat-synced visuals now

Upload audio, the BPM appears in the timeline, beat-snap is on by default.

Open Shimga Studio →

Related Reading