Skip to content

analysis: produce neutral core.Analysis + lock the waveform encoders (modular-backends step 2)#2

Merged
vynulldev merged 4 commits into
mainfrom
analysis-split
Jul 7, 2026
Merged

analysis: produce neutral core.Analysis + lock the waveform encoders (modular-backends step 2)#2
vynulldev merged 4 commits into
mainfrom
analysis-split

Conversation

@vynulldev

Copy link
Copy Markdown
Owner

Summary

Step 2 of the modular-backends refactor: the DSP → neutral half. analysis
now produces the brand-agnostic core.Analysis (tempo, beat grid, key, phrases,
and per-band waveforms), so a future backend can consume analysis without any
Pioneer types. It also lands golden-hash tests over all four colour-waveform
encoders as the safety net for the byte-sensitive encoder relocation still to
come (step 2, part 3).

Additive and byte-safe. No encoder logic or serving-path code changes — the
PWV4/5/6/7 outputs are byte-for-byte identical (proven by the golden tests), so
CDJs render exactly as before.

What's in it

Part 1 — Result.Core() (analysis/tocore.go): projects the Pioneer-flavoured
analysis.Result onto core.Analysis — BPM, beat grid (with downbeat flags
derived from DownbeatIndex), key (both notations), and phrases (reusing the
API's phrase-name mapping). analysis now depends on core.

Part 2 — band-waveform extraction (analysis/bandwaveform.go):
BandWaveformDetail / BandWaveformOverview turn samples into the neutral
bass/mid/treble amplitude envelope (0..1, inter-band energy preserved), reusing
GenerateDetail's own band split (splitBandsAndPeaks) so the neutral data
agrees with the PWV5 output. Result.CoreWithBands(samples, sr) assembles the
full core.Analysis; samples are passed in rather than cached, keeping the large
float arrays off disk.

Golden safety net (analysis/waveform_golden_test.go): new byte-for-byte
tests for PWV4 (GenerateColorPreview), PWV6 (GeneratePreview3Band),
and PWV7 (GenerateDetail3Band), and the existing PWV5 test moved in
beside them to share the goldenSignal() / checkGolden() helpers (its hash is
unchanged). All four colour waveforms are now locked.

Why now (and what's deliberately not here)

The remaining half of step 2 — relocating the PWV/ANLZ/PQT/PVB/PSSI encoders
into link/prolink/anlz to consume core.Analysis, then repointing
dbserver/api/proto
— changes the wire-serving path and is best done as
its own PR. The golden tests in this PR are the guardrail for that move: a
single changed byte will fail them. (PWV5 has always been guarded; this adds
PWV4/6/7.) Even so, that later PR should get a real-CDJ smoke test, since the
golden tests lock the current bytes but can't confirm a deck renders them
end-to-end.

Verification

  • go build ./... ✅ · go vet ./analysis/ ✅ · gofmt clean ✅
  • New tests pass: TestResultCore, TestBandWaveformDetail/Overview,
    TestCoreWithBands, TestPWV4/5/6/7GoldenHash (deterministic, -count=2) ✅
  • TestPWV5GoldenHash unchanged → encoders byte-identical, additive ✅

Where to look

analysis/tocore.go and analysis/bandwaveform.go are the whole production
surface; analysis/waveform_golden_test.go shows the encoder guardrails. Nothing
in the serving path (dbserver, api, proto) is touched.

vynulldev added 4 commits July 7, 2026 20:07
Add Result.Core(), mapping the DSP facts (BPM, beat grid with downbeat
flags, key, phrases) onto core.Analysis so backends can consume analysis
without Pioneer types. analysis now depends on core.

Additive and byte-safe: the encoders and the Result fields the serving
path reads (WaveDetail, BeatGridPQT2, …) are untouched — the golden-hash
test still passes. The waveform band data and the encoder relocation
(PWV/ANLZ packers → link/prolink/anlz, consuming core.Analysis) are the
next, byte-sensitive commits.
… 2, part 2)

Add BandWaveformDetail / BandWaveformOverview, turning samples into the
brand-agnostic per-band (bass/mid/treble) amplitude envelope every backend
re-encodes into its own colour waveform. They reuse GenerateDetail's band
split (splitBandsAndPeaks) so the neutral data agrees with the PWV5 output.
Result.CoreWithBands assembles the full core.Analysis (DSP facts + bands);
samples are passed in rather than cached, keeping the band arrays off disk.

Additive: no encoder or serving-path change — the golden-hash test still passes.
Lock GenerateColorPreview (PWV4), GeneratePreview3Band (PWV6), and
GenerateDetail3Band (PWV7) byte-for-byte against a deterministic tone,
matching the existing PWV5 golden test. This is the safety net for the
upcoming encoder relocation (step 2, part 3): a byte change in any of
these now fails the tests instead of silently altering what a CDJ renders.

Test-only — no production code changed.
Move TestPWV5GoldenHash next to the PWV4/6/7 tests and reuse the shared
goldenSignal() + checkGolden() helpers, dropping the duplicated signal and
the now-unused sha256/hex imports from waveform_test.go. PWV5's hash is
unchanged (goldenSignal() produces the identical samples), so the guard is
byte-for-byte equivalent — all four colour-waveform golden tests now live
in one file.
@vynulldev vynulldev merged commit 1197935 into main Jul 7, 2026
1 check passed
@vynulldev vynulldev deleted the analysis-split branch July 7, 2026 20:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant