Repository navigation
Slice 12 — Beat Grid: detection, nudge, energy (#13) - #32
Merged
Merged
Conversation
) - detectBeatGrid: energy-based onset detection + autocorrelation; detects BPM within ±2% and first-beat offset within ±30ms from synthetic click tracks - nudge: snaps slide target durations to nearest beat; energy multipliers (calm 1.5×, medium 1.0×, punchy 0.67×) produce directionally different average durations (AC4) while energy=medium preserves ≤half-beat deviation (AC2) - planner wired with beatGrid? + beatSync toggle: off returns exact targets (AC3); energy reads through resolved(slide) so per-slide overrides are honoured - BeatGrid type, decodeMono adapter, and beatGridCache in SlideshowJson schema lay the ground for UI integration in the next slice Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #13
Approach
Pure-module Beat Grid implementation in
src/beat-grid/with planner integration.Detection (
detection.ts): energy-based onset detection (RMS per 512-sample hop → positive first-difference) followed by autocorrelation over the 60–200 BPM lag range. Phase accumulation then finds the first-beat offset. All math is parameter-free and tested via synthetic click tracks.Nudge (
nudge.ts): snaps a slide's target duration to the nearest beat multiple. Energy applies a multiplier before snapping (calm 1.5×, medium 1.0×, punchy 0.67×) so average durations differ by energy level while energy=medium always stays within ±½ beat interval of the passed-in target.Planner wiring (
planner.ts): new optionalbeatGrid?parameter;beatSyncActive = !!beatGrid && settings.beatSync !== false;getDurationcallsnudgefor non-title, non-video slides. Energy is read viaresolved(slide).energyso per-slide overrides are honoured correctly.Schema (
schema.ts):beatGridCache?: BeatGridadded toSlideshowJsonfor future persistence.Adapter (
adapter.ts): thindecodeMonowrapper overAudioContext.decodeAudioDatafor use in the next UI-integration slice.Acceptance criteria
detection.test.tsat 90 and 120 BPMplanner.test.ts"beat sync on (AC2)"planner.test.ts"beat sync off (AC3)"nudge.test.tsandplanner.test.ts"beat sync energy effect (AC4)"Code review verdict
APPROVE — one confirmed finding fixed: energy now reads through
resolved(slide)instead ofsettingsdirectly, so per-slide energy overrides inSlideOverridesare honoured. Also addedMath.max(lagMin, ...)guard onlagMaxfor non-standard sample rates.Follow-ups noted (out of scope)
decodeMono+detectBeatGridinto the editor shell (UI integration slice)beatGridCachethroughslidesToJson/ read-back in Project StorebeatSynctoggle and energy selector inGlobalSettingsPanel