Skip to content

fix(mix): show the speeds a ridden pitch fader went between - #327

Merged
botandbang merged 4 commits into
mainfrom
bnb/pitch-rides
Oct 31, 2026
Merged

botandbang merged 4 commits into
mainfrom
bnb/pitch-rides

Conversation

@botandbang

Copy link
Copy Markdown
Contributor

What and why

Riding the pitch fader from +0% to +4% during a track gave one speed everywhere a mix is shown. The track stays in one chain, because each 4 s slice drifts well within a chain's 0.75 s tolerance of the last, and the chain's one line averaged both speeds. In a test the play read +0.0%: the averaged slope was 2% off the speed searched, so the matcher fell back to that speed. Its presence curve was traced at the average, which neither half played at, and it dipped to 0.18.

This takes option a from triage, which is a provisional choice that hasn't been confirmed: split a chain's fit where its speed changes. The other options were (b) report the range of speeds searched, quantised, and (c) keep one averaged speed and document it. Undoing it means removing lines/split/Bend in the matcher and the speed_range field.

Added in loclib-mixid:

  • split tries two lines meeting at a knot, searched on a 0.5 s grid at least 24 s from either end. It keeps them when their speeds differ by 0.3% (RIDE) or more, each is within 2% of the speeds its slices voted for, and the Bayesian information criterion prefers them (k = 2 against 4). It recurses on each side. Strays are dropped relative to the bend, so the end of a short second speed isn't cut off.
  • Found::speed_range() gives the slowest and fastest measured lines.
  • BIC alone isn't enough: whole-frame rounding runs in sawtooth stretches and passes it. Rounding can tip two lines of 24 s or more apart by up to 0.29%, so the 0.3% check rules it out.

Changed in loclib-mixid:

  • Found.fits has a line per speed.
  • tempo is weighted by votes and line length, so a play at one speed is unchanged.
  • trace listens near each line's own speed.
  • least_squares, drop_strays, edges and chain_pairs are pulled out of fit to share with the new code.

Added in locallibrary and the website:

  • Play.speed_range and the export's speedRange. Both are optional, so the export keeps version 2, and the RPC contract is regenerated.
  • The range ("+0.0% to +4.0%") is shown in the HTML report (track list and both tooltips), the terminal tracklist, the player's Mixes view (tracklist column and details) and the website's mix report (tracklist and tempo chart).

Not included: the player's playhead and the tempo charts still follow one speed per play, since Play carries the range and not the lines.

Fixes LOC-122

How it was tested

  • A matcher end-to-end test (45 s at +0%, then +4%) that gave one fit before the fix and now gives two lines meeting at 45 s, with presence at 0.4 or more throughout. Hegel properties that a play at one speed is never split and that a 1 to 4% step is found where it happened (150 cases each).
  • A locallibrary end-to-end test through Identifier with WAVs, and a test per surface: the report page, the export (hegel), the tracklist, the TUI and the website's helper and schema.
  • Broken once each, and failed: the per-line trace (presence back to 0.18), both split checks removed and RIDE removed alone, the export, the report page field, the TUI's fastest speed, and the website schema field.
  • cargo fmt -- --check, and cargo clippy -p loclib-mixid -p locallibrary -p locallibrary-cli --all-targets -- -D warnings.
  • cargo nextest run: loclib-mixid 75/75, locallibrary's mix, sets, mixes and sessions tests 106/106, and locallibrary-cli's mix, TUI mix, rpc and mix command tests 138/138 (the_contract_in_docs_is_current included).
  • apps/web pnpm check, pnpm lint, oxfmt --check and pnpm test (800 pass).
  • Not run: the full Rust suites, Windows clippy, web test:storybook and test:build, and screenshots.

Checklist

  • Tests cover the change
  • For locallibrary: apps/locallibrary/CHANGELOG.md has a line under Unreleased, if people using it will notice
  • The READMEs, docs/ and --help still say what the code does (apps/locallibrary/docs/rpc/ too, for a sidecar change)

@botandbang
botandbang requested a review from bnb as a code owner October 30, 2026 16:19
@linear-code

linear-code Bot commented Oct 30, 2026

Copy link
Copy Markdown

LOC-122

bnb
bnb previously approved these changes Oct 30, 2026
@github-actions github-actions Bot added documentation Improvements or additions to documentation web The Local Network website (apps/web) locallibrary locallibrary and the loclib-* crates web: mixes Mixes, their tracklists and mix reports web: ui Shared components, design tokens, layout and the static pages locallibrary: cli The locallibrary command line locallibrary: player The terminal player and its waveforms locallibrary: sidecar The JSON-RPC sidecar and the api module it serves locallibrary: core The core crate, the data model and rekordbox's formats locallibrary: mixes Finding the tracks a recorded mix plays, and mix reports locallibrary: publishing The Atmosphere account, and the sets and profile published to it tests Tests, fixtures and test harnesses labels Oct 30, 2026
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Coverage Report for apps/web

Status Category Percentage Covered / Total
🟢 Lines 95.46% (🎯 93%)
🟰 ±0 pp
7750 / 8118
🟢 Statements 94.11% (🎯 91%)
🟰 ±0 pp
11857 / 12598
🟢 Functions 94.26% (🎯 92%)
🟰 ±0 pp
3075 / 3262
🟢 Branches 84.75% (🎯 80%)
⬆️ +0.01 pp
5541 / 6538
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
apps/web/src/lib/components/mix/MixTracklist.svelte 92.74%
🟰 ±0 pp
65.34%
🟰 ±0 pp
93.47%
🟰 ±0 pp
94.82%
🟰 ±0 pp
8, 58, 58, 78, 78, 51-53
apps/web/src/lib/components/mix/TempoChart.svelte 88.7%
🟰 ±0 pp
57.14%
🟰 ±0 pp
95.91%
🟰 ±0 pp
79.24%
🟰 ±0 pp
45-59, 70-101, 63
apps/web/src/lib/mix/report.ts 93.25%
⬆️ +0.07 pp
82.75%
⬆️ +0.61 pp
97.36%
⬆️ +0.07 pp
97.14%
⬆️ +0.04 pp
132-134, 179, 190
apps/web/src/lib/mix/schema.ts 100%
🟰 ±0 pp
92.59%
🟰 ±0 pp
100%
🟰 ±0 pp
100%
🟰 ±0 pp
Generated in workflow #653 for commit 61a662d by the Vitest Coverage Report Action

Size

Compared with main. KiB are 1,024 bytes.

This pull request main Change
Client JavaScript 679.4 KiB 676.3 KiB +3.2 KiB (+0.5%)
Client JavaScript, brotli 225.6 KiB 224.9 KiB +813 B (+0.4%)
Client CSS 89.6 KiB 89.6 KiB 0 B (0%)
Client CSS, brotli 12.9 KiB 12.9 KiB 0 B (0%)

@botandbang

Copy link
Copy Markdown
Contributor Author

Closing and reopening so CI reruns with the destinations test fix (#344) now on main. Branch unchanged.

@botandbang botandbang closed this Oct 31, 2026
auto-merge was automatically disabled October 31, 2026 00:29

Pull request was closed

@botandbang botandbang reopened this Oct 31, 2026
@botandbang
botandbang enabled auto-merge October 31, 2026 00:30
@botandbang botandbang closed this Oct 31, 2026
auto-merge was automatically disabled October 31, 2026 01:01

Pull request was closed

@botandbang botandbang reopened this Oct 31, 2026
@botandbang
botandbang enabled auto-merge October 31, 2026 01:01
@github-actions

Copy link
Copy Markdown

Rust coverage

From run 641. Both are held to the thresholds in .cargo/config.toml.

Tests Lines Functions Regions
All 97.45% (83016/85189) 96.53% (13243/13719) 95.71% (182618/190804)
Hegel property tests alone 95.56% (81406/85189) 94.25% (12930/13719) 93.65% (178689/190804)

@botandbang
botandbang merged commit 476432d into main Oct 31, 2026
182 of 190 checks passed
@botandbang
botandbang deleted the bnb/pitch-rides branch October 31, 2026 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation locallibrary: cli The locallibrary command line locallibrary: core The core crate, the data model and rekordbox's formats locallibrary: mixes Finding the tracks a recorded mix plays, and mix reports locallibrary: player The terminal player and its waveforms locallibrary: publishing The Atmosphere account, and the sets and profile published to it locallibrary: sidecar The JSON-RPC sidecar and the api module it serves locallibrary locallibrary and the loclib-* crates tests Tests, fixtures and test harnesses web: mixes Mixes, their tracklists and mix reports web: ui Shared components, design tokens, layout and the static pages web The Local Network website (apps/web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants