funkatron / funkatron/PulseHZ

Detect BPM: golden fixture diverges from ~136 reference (Δ up to ~25 BPM)

Open
#2 0 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.