Skip to content
06Client-side music analysis

ChordLab

Music analysis tools want your audio on their servers. Everything needed to do the analysis already exists in the browser.

Chord states
145
Key profiles
24
Frame size
8192
Runtime deps
0

Context

ChordLab analyses a song — or a live microphone — entirely client-side: chord recognition, key detection, guitar tablature, MIDI export and Roman-numeral analysis, with no upload and no server.

The whole signal chain is written from scratch in TypeScript with zero runtime dependencies: FFT, chromagram, onset detection, pitch estimation, Viterbi decoding and a MIDI writer.

How it works

01Chromagram

Audio is decoded and resampled to 22.05 kHz, then analysed in Hann-windowed 8192-sample frames. Spectral peaks are refined with parabolic interpolation and a global tuning offset is estimated from the circular mean of cent deviations, so a recording that sits between concert pitches still resolves. Peaks map onto a 12-bin pitch-class profile with square-root magnitude compression.

02Chords, smoothed rather than filtered

Each frame is scored against harmonic-aware chord templates — instrument overtones are modelled in the template, which keeps the chromagram itself sharp instead of blurring it to compensate. A Viterbi pass with sharpened emissions removes flicker while still catching quick changes, and segments under 300 ms are absorbed. The result reads like a chart rather than a per-frame argument: 145 states, 12 qualities × 12 roots plus no-chord.

03Key and transcription

Key comes from correlating the energy-weighted aggregate chroma against the 24 rotated Krumhansl-Kessler major and minor profiles, reported with a certainty and the correct flat or sharp spelling. Onsets come from spectral flux with an adaptive threshold and a global significance gate; tempo from autocorrelation of the flux envelope. Each inter-onset segment goes through iterative harmonic-salience pitch estimation with spectral subtraction, up to six simultaneous notes, with sub-octave ghost suppression.

04Tabs a hand can actually play

Notes are grouped into columns, with strums chain-grouped automatically, then assigned string and fret positions by exhaustive search minimising hand position, stretch and movement between shapes. Measures follow the estimated tempo and the chord analysis labels the staff; the tab is downloadable as plain text and the transcription exports as format-1 MIDI with tempo, time-signature and key-signature metadata.

Architecture

src/lib/dsp
FFT, windowing, chromagram, tuning estimation.
src/lib/chords
Templates, Viterbi decoding, segmentation.
src/lib/theory
Key profiles, spelling, Roman-numeral analysis.
src/lib/tab
Fingering search and text tab rendering.
Web Worker
The entire engine, off the main thread.

Decisions

The choices worth defending, and what they cost.

Zero runtime dependencies

Every stage is understood and tunable. A DSP library would have made the tuning-offset estimation and the harmonic-aware templates someone else's parameters.

Model overtones in the templates, not the chroma

Smearing the chromagram to account for harmonics costs resolution everywhere. Putting the harmonic model in the template keeps the observation sharp and the correction local.

Viterbi over per-frame argmax

Frame-by-frame classification flickers between relative chords. A decoder with transition costs produces a timeline a musician can read.

Everything in a Web Worker

The main thread stays responsive during analysis, and the audio never leaves the machine — which is the whole premise.

Verification

A Vitest suite covers the DSP and music-theory layers — the parts where a subtle error produces plausible-looking output rather than an obvious failure.

  • TypeScript
  • Next.js
  • Web Audio API
  • Web Workers
  • DSP
  • Vitest

Next case study

Kasane

Self-hosted live JA→EN translator