5.2 KiB
OpenSpec Change: enterprise-audio-analysis-beat
- Change ID: enterprise-audio-analysis-beat
- Package:
@suaveplan/audio-analysis-beat - Category: universal
- Target path:
packages/media/audio/audio-analysis-beat - Status: PROPOSED
- Date: 2026-05-14
- Design:
./design.md - Spec delta:
./specs/audio-analysis-beat/spec.md
Summary
Deliver @suaveplan/audio-analysis-beat on the genesis branch from scratch at enterprise quality. Beat and tempo detection plugin for the universal audio analysis framework. Detects BPM, beat locations, and onset times from AudioDocument streams using energy-based and spectral-flux algorithms, with optional comb-filter tempo estimation and beat-grid alignment.
Runs identically in browser and server via BlockProcessor or direct stream iteration.
Current-state audit (genesis)
The package does not exist on genesis yet — this is a fresh build. No prior source, no test results, no coverage data. The old enterprise-browser-audio-engine openspec was browser-only and did not include beat detection.
Available workspace deps on genesis
| Package | Role |
|---|---|
@suaveplan/audio-core (workspace:^) |
AudioDocument, BlockProcessor, BlockContext |
@suaveplan/error (workspace:^) |
AudioError base class; AUDIO_ANALYSIS.* codes |
@suaveplan/types (workspace:^) |
LoggerLike |
@suaveplan/opentelemetry (workspace:^) |
OTel spans, counters, histograms |
zod (catalog:forms) |
Zod schemas for option types |
Dev deps: vitest, @vitest/coverage-istanbul, fast-check, mitata (all catalog:testing).
Public API
Core types
interface BeatDetectorOptions {
minBpm?: number // default 60
maxBpm?: number // default 200
algorithm?: 'energy' | 'spectral-flux' | 'comb' // default 'energy'
}
interface BeatResult extends AnalysisResult {
bpm: number
beats: Float64Array // beat timestamps (seconds)
onsets: Float64Array // onset timestamps (seconds)
confidence: number // 0..1
}
class BeatDetector implements AnalysisOp {
readonly name = 'beat-detector'
readonly description = 'Detect tempo and beat locations'
constructor(options?: BeatDetectorOptions)
analyze(doc: AudioDocument, opts?: BeatDetectorOptions): Promise<BeatResult>
analyzeStream(doc: AudioDocument, opts?: BeatDetectorOptions): AsyncGenerator<BeatResult>
analyzeBlock(block: Float32Array[], ctx: BlockContext): BeatResult
}
Error codes
type BEATErrorCode =
| 'AUDIO_ANALYSIS_BEAT.INVALID_OPTIONS'
| 'AUDIO_ANALYSIS_BEAT.EMPTY_DOCUMENT'
| 'AUDIO_ANALYSIS_BEAT.NO_BEATS_DETECTED'
const AUDIO_ANALYSIS_BEAT_ERROR_METADATA: Readonly<Record<BEATErrorCode, CodeMetadata>>
function registerAudioAnalysisErrorCodes(): void
Zod schemas
BeatDetectorOptionsSchema
BeatResultSchema
New additions for genesis
- Three algorithms — energy ODF (fast, from existing block stats), spectral flux (FFT-based, higher precision), comb-filter tempo estimation.
- Beat grid alignment — phase-align detected onsets to a regular grid after tempo is known.
- Streaming refinement —
analyzeStream()yields partial results that refine as more audio is processed. - Block-level real-time —
analyzeBlock()returns instantaneous onset detection for visualization. - OTel instrumentation — span
audio.analysis.beat, counteraudio.analysis.beat.runs_total, histogramaudio.analysis.beat.duration_ms. - Property-based tests — synthetic metronome input yields exact BPM, silence yields no beats with graceful fallback.
- Benchmark suite — analyze 1-minute track, analyze 10-minute track.
File layout
packages/media/audio/audio-analysis-beat/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
error-codes.ts
detector/
beat-detector.ts
beat-detector.md
beat-detector.types.ts
beat-detector.test.ts
index.ts
algorithms/
energy-odf.ts
energy-odf.md
energy-odf.test.ts
spectral-flux.ts
spectral-flux.md
spectral-flux.test.ts
comb-tempo.ts
comb-tempo.md
comb-tempo.test.ts
beat-grid.ts
beat-grid.md
beat-grid.test.ts
index.ts
__benchmarks__/
beat.bench.ts
tests/
integration.test.ts
property.test.ts
Impact
Breaking changes: none — fresh build, package does not yet exist on genesis.
Prerequisites: @suaveplan/audio-core, @suaveplan/error, @suaveplan/types, @suaveplan/opentelemetry published to Verdaccio. All four already exist on genesis.
Affected dependents
No dependents in this batch (verified by bunx turbo ls --filter=...@suaveplan/audio-analysis-beat). @suaveplan/audio-analysis-beat is a leaf Analysis Op plugin — no other package in this 13-change audio batch depends on it. It is consumed at runtime by application/timeline code that registers it as a sidecar analysis op (e.g. auto-mixing in @suaveplan/audio-plugins-fx, visualisation in a future react-audio-player, batch analysis in @suaveplan/audio-cli) — those consumers depend on @suaveplan/audio-core's AnalysisOp interface, not on this package directly, and none are created or modified by this change.