Detect BPM: golden fixture diverges from ~136 reference (Δ up to ~25 BPM)
- Dominant language
- JavaScript
- Stars
- 2
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Problem
**Detect BPM** on the committed golden audio fixture is far from the nominal manual reference, so MVP acceptance cannot use a tight ±2 BPM gate.
| Source | Value |
|--------|--------|
| **Fixture** | `tests/fixtures/audio/vco-berlin-deathbycuriosity-remix.mp3` |
| **Manual / nominal reference** | ~**136** BPM |
| **Detect BPM (browser, 2026-07-02)** | **161.5** BPM (Δ **25.5**) |
| **Prior note (librosa, commit `e9f9f203`)** | ~**120** vs 136 on same material |
Repro (server on `:6066`):
```bash
uv run pulsehz-server
uv run python scripts/mvp_acceptance_check.py # WARN on Δ > ±2
```
Or in the app: load the golden MP3 → set manual BPM to 136 → **Detect BPM** after tempo map is ready.
## Context
- Detect path: segment median when `bpmSegmentsStatus === "ready"`, else full-buffer `estimateBpmFromAudioBuffer` (`public/bpm-analysis.js`, `public/app.js`).
- Acceptance docs record this as **plausible but not ideal**: [docs/delivery/mvp-acceptance.md](docs/delivery/mvp-acceptance.md).
- Related (implemented): [docs/delivery/task-adaptive-bpm-detection.md](docs/delivery/task-adaptive-bpm-detection.md).
- **Not a merge blocker** for PR #1; tracked so accuracy can improve without losing the fixture.
## Goal
Bring **Detect BPM** on the golden fixture within a **documented tolerance** of the reference (target: **±2 BPM** for acceptance, or revise reference if the track’s true tempo is disputed).
## Acceptance criteria
- [ ] Document **authoritative reference BPM** for the golden MP3 (measured + rationale) in fixture docs or `tests/support/audio_fixtures.py` comment.
- [ ] **Detect BPM** on that file in headless Chromium (`scripts/mvp_acceptance_check.py`) within agreed tolerance **or** acceptance script/doc updated with an honest band + explanation.
- [ ] Add a **regression test** (pytest and/or Playwright) that fails if detect drifts outside the agreed band on the golden file.
- [ ] No regression on existing `tests/test_audio_fixtures.py` plausibility band (85–175).
## Investigation hints
- Compare **segment median** vs **full-buffer** estimate on the fixture.
- Check **double/half tempo** ambiguity (161.5 ≈ 1.19×136; 120 ≈ 0.88×136).
- Onset NMS / median interval tuning in `estimateBpmFromAudioBuffer`.
- Optional: second fixture with unambiguous tempo for tight ±2 CI.
## Links
- PR #1 (MVP): https://github.com/funkatron/PulseHZ/pull/1
- Scripts: `scripts/mvp_acceptance_check.py`, `scripts/mvp_manual_remaining.py`
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with public/bpm-analysis.js and public/app.js, then run uv run python scripts/mvp_acceptance_check.py against tests/fixtures/audio/vco-berlin-deathbycuriosity-remix.mp3. Compare the segment-median and full-buffer estimates and document the authoritative BPM and rationale. Done means the agreed tolerance is enforced by a regression test, with any revised acceptance band explained and existing fixture plausibility tests still passing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, playwright, python
- Domain
- testing, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100