IEEE Lunch & Learn
2026

trail mix: DSP analysis with a compact transformer key reranker

Pardis Noorzad djpardis.com trailmix.tools
Abstract illustration of nuts, seeds, dried fruit, and chocolate
Cueport

Cueport

Cueport is a multi-device workstation for DJs that can import Serato libraries or construct local libraries directly from audio files.

Pardis DJing with headphones and a laptop
Pardis DJing a live set at The New Parish in Oakland
Cueport

Local pairing

The desktop and mobile applications exchange selected library data over a local network or hotspot after QR-based pairing.
The QR code carries connection details; data moves both ways after pairing.

Desktop app canonical library
LAN or hotspot
scan QR to pair
Phone app selected replica
→ Desktop to phone selected crates, tracks, analysis, cues
← Phone to desktop edits return for desktop review
Cueport

Serato integration

Cueport v1 reads tempo, key, cues, and beat-grid metadata from an existing Serato library on disk.
The desktop database imports audio and metadata from Serato.
The mobile database is a cached replica.

Serato library source of truth
Desktop SQLite canonical working copy
Mobile SQLite cached replica
→ Import from Serato library metadata and existing analysis
→ Sync to mobile selected library copy
← Mobile edits return reviewed on desktop before publishing
← Write back to Serato restore point first, then approved library update
One desktop review queue desktop edits enter directly; synced edits join the same queue
Cueport Direct

Cueport Direct

Cueport Direct constructs a working music library from local folders without depending on an external DJ database.

  • Pick one or more local music folders
  • Cueport builds a cueport-direct.db working library
  • Browse, prep, play, and edit without a Serato library
  • trail mix analyzes audio locally for BPM, key, beats, and waveforms
trail mix

trail mix

trail mix is a Rust toolkit that decodes audio into mono samples and runs three analyzers behind one versioned JSON output.

trail mix facade calling beat-salad, key-lime, and sampler-platter crates

Signal input and normalization

Audio decoding normalizes supported file formats into a mono sample buffer and sample rate.

  • Decoding: an audio file becomes evenly spaced amplitude values
  • Downmixing: sample buffers combine into one mono signal
  • f32: a 32-bit floating-point number for storing those amplitudes
  • u32: a non-negative 32-bit integer for storing the sample rate
Input file
MP3 · FLAC · WAV · AIFF · MP4
→
Decode to samples
left/right sample buffers
→
Downmix
(left + right) / 2 = one mono buffer
→
Analyzer input
samples: &[f32] sample_rate: u32
trail mix

Why build a local analyzer?

Cueport Direct imports ordinary folders on a user's machine. Analysis has to run in process, finish during library import, produce reproducible metadata, and avoid requiring a server.

Option License Integration issue
stratum-dsp MIT OR Apache-2.0 closest Rust reference; reports global tempo and key, not the local sections Cueport needs
S-KEY MIT accurate learned reference, but needs a model runtime rather than a small native Rust crate
libKeyFinder GPL-3.0 license does not fit a permissive app integration
Essentia AGPLv3 or paid license cost and terms did not fit this product integration
Tempo estimator

beat salad

Tempo and beat positions

Abstract illustration of beet salad ingredients

Onset detection

Onset detection measures frame-to-frame increases in band energy and uses peaks in the resulting onset-strength curve as beat candidates.

Audio on top with two loud bursts where new sounds start, and the onset-strength curve below spiking into a peak under each burst

Onset detection formula

Spectral flux turns band-energy rises into one onset-strength value per frame.

\[\operatorname{flux}(t) = \sum_{b=1}^{24} \max\!\bigl(0,\; E_b(t) - E_b(t-1)\bigr)\]

  • E_b(t): energy in band b at frame t
  • max(0, change): count rises and ignore decays
  • sum over b: combine all 24 band changes into the onset-strength curve

Tempo estimation

Tempo estimation finds the repeated spacing between onset peaks and converts that spacing into BPM. Beat tracking is the next step.

Match-strength curve with three equal peaks at half time, the true pulse, and double time, a dashed preference bell over the middle of the tempo range, and the true pulse chosen

Beat tracking with dynamic programming (DP)

Tempo gives the beat spacing. DP chooses the beat grid offset, skips loud off-beat peaks, and keeps the grid regular when a beat is weak.

Onset-strength curve with regular beat intervals: dots sit on strong peaks, one beat is kept on a weak spot for timing, and an off-beat peak is skipped

Beat tracking optimization

DP chooses the beat sequence with the best total score: strong onset peaks plus regular spacing near the estimated BPM.

\[ \hat{b}_{1:m}=\arg\max_{b_{1:m}} \left[ \sum_t O(b_t) + \lambda\sum_{t>1} R(b_t-b_{t-1}, P) \right] \]

  • b_t: candidate beat time t
  • O(b_t): onset strength at that beat time
  • P: target beat spacing from the estimated BPM
  • R(gap, P): spacing reward; highest when the gap is close to P
  • DP job: find the full beat sequence with the highest total score

Beat switches

beat salad reports a dominant BPM and an alternate tempo when a secondary tempo covers at least 25% of the track.

Field What it contains Example
global_bpm Dominant tempo for the whole file 120 BPM
multi_tempo Boolean: another tempo covers at least 25% true
alternate_bpm Secondary tempo + coverage fraction 90 BPM, 45%
tempo_segments Timeline of local BPM ranges 120 BPM, then 90 BPM

Beat-switch decision rule

Multi-tempo detection reruns tempo estimation in rolling windows and reports a secondary tempo only when it covers enough of the track.

\[ \begin{aligned} \widehat{b}_w &= \operatorname{tempo}(w) \\ b_r &= \operatorname*{mode}_{w \in r}\,\widehat{b}_w \\ q_r &= \frac{\operatorname{duration}(r)}{\operatorname{duration}(\mathrm{track})} \end{aligned} \]

  • w: a 12-second analysis window, advanced every 6 seconds
  • r: a contiguous run made by grouping neighboring windows whose local BPM estimates agree
  • b_r: representative BPM for that run of windows
  • Decision rule: report multi_tempo when \(|b_r - b_{\mathrm{global}}| > \delta\) and \(q_r \ge 0.25\)
Multi-tempo

Beat-switch demo

A 60-second demo: 120 BPM for the first half, then 90 BPM. The output below is beat salad's result.

120 BPM0:00-0:30
90 BPM0:30-1:00
0:00 / 1:00
global_bpm120.08
multi_tempotrue
alternate_bpm90.03
switch detected~33 s

beat salad pipeline

beat salad turns samples into onset evidence, estimates tempo, places beats, and checks for local tempo changes.

Samples mono audio values
Onset detection energy rises
Tempo estimation periodicity score
Beat tracking beat timestamps
Beat-switch detection local tempo runs
BeatAnalysis global_bpm beats multi_tempo alternate_bpm tempo_segments

Tempo evaluation metrics

Tempo uses Acc1 and Acc2. The next slide reports both on GiantSteps Tempo.

Acc1
Global BPM is correct when it is within 4% of the reference tempo.
Acc2
Also counts half-time and double-time as correct, because they represent the same pulse counted differently.

Tempo diagnostic results

On GiantSteps Tempo, beat salad leads the DSP systems on exact-tempo Acc1 and trails stratum-dsp by 0.02 on Acc2, which accepts half-time and double-time matches. Beat This learns beat activations instead of using a fixed spectral-flux onset curve.

System Class Acc1 Acc2
beat salad DSP 0.68 0.83
stratum-dsp DSP 0.60 0.85
Essentia DSP 0.61 0.80
librosa DSP 0.37 0.52
Beat This Learned 0.86 0.94
Waveform summarizer

sampler platter

Compact waveform overview

Abstract illustration of a sampler platter
sampler platter

Waveform summarization

Decoded samples reduced to display columns, each storing min, max, and RMS
Column: one display column contains samples x_1...x_n.
Min: min = min(x_i), the lowest sample.
Max: max = max(x_i), the highest sample.
RMS: RMS = sqrt((x_1^2 + ... + x_n^2) / n), average energy.
Peak: peak = max(|min|, |max|), the largest absolute sample.
Drawn height: r = sqrt(peak * RMS); h is the final bar height after the app rescales r.
Band: b = 1...8 names the frequency band; E_b is energy in band b.
Band scale: p_b = (b - 1) / 7, so p_b runs from 0 for the lowest band to 1 for the highest.
Color: c = sum_b(p_b E_b) / sum_b(E_b), then hue = 10 + 200c.
sampler platter

App-style waveform sample

Orange/red bars mean lower spectral balance: less high-frequency brightness in that column. Green/blue bars mean brighter high-frequency content, such as hi-hats, cymbals, or sharp attacks.

0:00 / 1:00
segment60 s
bars200
Key estimator

key lime

Musical key from chroma and a compact reranker

Abstract illustration of a sliced lime
Vocabulary

Key vocabulary

These terms define the musical object that key lime predicts.

Pitch class
The note name without octave. One C key and the next C key up are an octave apart, and both are pitch class C.
Chroma
A 12-value summary of how much audio energy belongs to each pitch class: C, C#, D, ... B.
Tonic
The pitch class that feels like home or resolution in a specific song or section.
Mode
A scale type, such as major or minor.
Key
A contextual label for a song or section, written as tonic plus mode.
Global key
The one key label selected for the full track.

Key estimation as 24-way classification

Chroma measures energy in 12 pitch classes. The classifier predicts which pitch class is the tonic and whether the mode is major or minor.

Relative major/minor
A minor and C major share a key signature, so their chroma can be similar.
Parallel major/minor
A major and A minor share a tonic but differ in mode.
Perfect fifth
A and E are close in tonal function. Keys a fifth apart share many stable notes.
Unrelated key
Outside those relationships. Usually means the tonal center was missed entirely.

DSP key-estimation pipeline

Outputs by stage: windowed audio frames → pitch-class evidence → averaged 12-bin chroma → 24 key scores → global key with optional local segments.

Audio samples feed chroma extraction, 24 key-template scores, and key-lime output fields

Framing audio for key estimation

key lime analyzes short overlapping slices of audio. A Hann window fades each slice at the edges before frequency analysis.

Mono audio split into overlapping frames, then tapered by a Hann window
  • Frame: a short slice of the audio signal
  • H: hop size between frames
  • Hann window: fades the frame edges so boundaries contribute less energy
  • Output: windowed audio frames for Goertzel and CQT pitch analysis

Measuring pitch energy in each frame

Goal: turn each windowed audio frame into note-energy estimates. The next step folds those estimates into 12 chroma values.

Windowed audio frame measured by Goertzel target checks and CQT note-spaced bins, producing pitch-frequency energy
  • Goertzel: ask a few chosen questions, such as "how much A is in this frame?"
  • CQT: build a broader note-spaced energy map across the pitch range
  • Output: note energy estimates for the next chroma-folding step

Output: 12-value chroma

This is the step where the pipeline first creates chroma: 12 values, one for each pitch class.

Pitch energy from different octaves folding into 12 pitch-class bins
  • Input: pitch-frequency energy from Goertzel and CQT
  • Fold octaves: C2, C3, and C4 all add to the C pitch-class bin
  • Output: 12 chroma values, one for each pitch class
  • Next step: compare the chroma pattern with 24 key templates

Key templates and scoring

A key template is a 12-value chroma pattern for one key. Compare the song chroma with 24 templates and pick the highest score.

Song chroma compared with 24 key templates, then the highest-scoring template becomes the predicted key
  • c: the song chroma, 12 values for pitch-class energy
  • T_k: the key template for candidate key k, 12 expected chroma values
  • corr: Pearson correlation, high when the two 12-value shapes match
  • Selection: the highest of 24 template scores becomes the predicted key
Multi-key

A key change

A 60-second demo: A major for the first half, then C minor. This is key lime's DSP-only local segmentation; the reranker selects only the global key.

A major0:00-0:30
C minor0:30-1:00
0:00 / 1:00
keyC minor
multi_keytrue
alternate_keyA major
change detected~33 s

Key evaluation metric

For each track, MIREX gives credit based on how close the predicted key is to the reference key, then averages those credits from 0 to 100.

Prediction relation Example if reference is C major Credit
Exact C major 100
Perfect fifth G major or F major 50
Relative major/minor A minor 30
Parallel major/minor C minor 20
Unrelated Any other key 0

\[s_i=\text{credit for track }i\text{ from the table},\qquad \text{MIREX}=\frac{s_1+s_2+\cdots+s_N}{N}\]

Reranker data splits

KL means key lime. FMAK means FMA Key, a key-labeled Free Music Archive benchmark; FMAKv2 is the version-2 evaluation set.

Set Tracks Used for Not used for
Training 4,040 FMAK Update reranker weights Final reported score
Validation 449 FMAK Choose the saved model version and when to stop training Weight updates or final score
Sealed holdout 1,000 FMAKv2 Report KL-DSP, KL-FMAK, and local madmom Training or checkpoint selection
Published full FMAKv2 5,489 FMAKv2 full dataset Cite MIREX scores from earlier papers Reranker training, validation, or same-holdout comparison
Key focus

Why add a reranker?

On the 1,000-track FMAKv2 holdout, the DSP key baseline scores 61.08 MIREX. Local madmom scores 74.16 MIREX on the same files.

Key baseline Value
KL-DSP MIREX 61.08
Local madmom MIREX 74.16
MIREX gap to local madmom 13.08 points
Available evidence 24 DSP scores + chroma frames

DSP-guided transformer reranker

Reranking means the DSP scorer proposes 24 key scores, then the learned model adjusts those scores using chroma-frame context.

Audio produces chroma frames and DSP key scores, which feed a compact transformer reranker that outputs the selected key
  • 1. DSP ranks candidates: produce 24 scores, one for each tonic-mode label
  • 2. Chroma gives context: show how pitch-class energy changes across the first 256 frames
  • 3. Learned model adjusts scores: add a learned correction to the DSP ranking
  • 4. Highest adjusted score wins: choose the global key; local key segments remain DSP-based

Reranker architecture and parameter budget

The chroma branch makes 24 learned score corrections. The DSP branch carries the 24 DSP scores. Add them, then choose the largest score.

Simplified KL-FMAK architecture with chroma frames and DSP scores feeding two branches, added into 24 adjusted key scores, then selecting the largest score

How the reranker is trained

Training teaches the reranker when chroma context should change the DSP ranking.

Step What happens
1. Read inputs first 256 chroma frames (about 32 s) plus 24 DSP scores
2. Learn the answer predict the FMAKv2 key label; related keys get small partial credit
3. Update weights AdamW updates model weights; validation decides when to stop
4. Test variants transpose examples, try easy-to-hard ordering, and test teacher distillation

FMAKv2 key-estimation results

Only compare rows with the same run type. The sealed-holdout rows are fair comparisons; published full-FMAKv2 rows are context, not win/loss claims.

System Run type Tracks MIREX score
KL-DSP local sealed holdout 1,000 61.08
KL-FMAK local sealed holdout 1,000 73.55 ± 0.46
madmom (local run) local sealed holdout 1,000 74.16
S-KEY 60k published full FMAKv2 5,489 72.10
S-KEY 1M published full FMAKv2 5,489 73.20
madmom (published) published full FMAKv2 5,489 73.10

Which input features help?

This asks whether the gain comes from reranking alone or from giving the reranker chroma-frame evidence.

Takeaway: DSP-score-only reranking does not help. DSP plus chroma-frame reranking produces the MIREX gain.
Variant Parameters MIREX score
KL-DSP baseline 0 learned 61.08
Only 24 DSP key scores (no chroma frames) 576 60.25 ± 0.45
DSP-score + chroma-frame features 21,528 73.55 ± 0.46
DSP-score + chroma-frame features + teacher distillation 21,528 72.50 ± 0.58
No DSP-margin curriculum 21,528 73.16 ± 0.62
Linear chroma input projection 21,984 72.50 ± 0.47

New model footprint

This table breaks installed size into analyzer code, model weights, and runtime so the total shows what an app ships.

System Analyzer/lib (MB) Model (MB) Runtime (MB) Total installed (MB)
KL-DSP (baseline) 2.0 0 0 2.0
KL-FMAK (+ ONNX) 2.0 0.115 74.6 76.7
KL-FMAK (native) 2.0 0.115 0 2.1
stratum-dsp 1.4 0 0 1.4
libKeyFinder 0.8 0 0 0.8
Essentia EDMM 48.4 0 0 48.4
madmom KeyCNN 0 2.5 171 174
S-KEY 0 0.75 435 436

Accuracy versus installed footprint

The paper footprint figure uses the ONNX package measurement; the Cueport release uses the same weights in native Rust.

FMAKv2 MIREX score against installed footprint for KL-DSP, libKeyFinder, stratum-dsp, KL-FMAK, local madmom, and S-KEY 1M

Key runtime measurements

KL-FMAK uses the same full DSP analysis as KL-DSP, then adds a sub-millisecond reranker pass.

System Time Corpus
KL-DSP 486 ms FMAKv2
KL-FMAK 486 ms + 0.32 ms FMAKv2
stratum-dsp 684.5 ms FMAKv2
Essentia EDMM 407.1 ms GiantSteps Key
libKeyFinder 591.6 ms GiantSteps Key
S-KEY 884.9 ms GiantSteps Key
madmom KeyCNN 2842.7 ms GiantSteps Key
What's next

trail mix next steps

Next work should cover beat analysis, stronger key benchmarks, stronger beat benchmarks, and compact model experiments.

1
Beat analysis
Improve beat positions, tempo-change boundaries, and grid stability
2
Key benchmarks
Add disjoint key datasets and rerun baselines when artifacts are available
3
Beat benchmarks
Evaluate beat tracking and beat grids beyond global-BPM metrics
4
Model experiments
Try small learned components for confidence, local key, and beat uncertainty
Cueport

Cueport next steps

Follow Cueport development at usecueport.com.

1
Cueport Direct libraries
Choose local music folders, scan files, and keep a working library without a DJ database
2
Local analysis
Key, tempo, beat positions, waveform overviews, confidence, and analyzer provenance
3
Desktop and iPhone workflow
Cache selected tracks, review metadata, edit on mobile, and sync changes back
4
Podcast and conversations
Talk with DJs, engineers, and music analysis experts about music ownership, metadata, analysis, mobile prep, and open tools

Selected bibliography

A short reference map for the methods, learned key baselines, tempo baselines, and datasets used in the talk.

Key estimation

Reranker and baselines

  • Noorzad. Key lime: a 115 KB DSP-guided transformer for key estimation. arXiv preprint, 2026.
  • Vaswani et al. Attention is all you need. NeurIPS, 2017.
  • Kong et al. S-KEY. ICASSP, 2025.

Tempo method

  • Bello et al. A tutorial on onset detection. IEEE TASLP, 2005.
  • Ellis. Beat tracking by dynamic programming. Journal of New Music Research, 2007.
  • Foscarin et al. Beat This!. ISMIR, 2024.
  • GiantSteps Tempo and Key, plus FMAKv2.

IEEE Lunch & Learn
2026

Thank you