4.6 KiB
OpenSpec Change: enterprise-audio-analysis-loudness
- Change ID: enterprise-audio-analysis-loudness
- Package:
@suaveplan/audio-analysis-loudness - Category: universal
- Target path:
packages/media/audio/audio-analysis-loudness - Status: PROPOSED
- Date: 2026-05-14
- Design:
./design.md - Spec delta:
./specs/audio-analysis-loudness/spec.md
Summary
Deliver @suaveplan/audio-analysis-loudness on the genesis branch from scratch at enterprise quality. Loudness metering plugin for the universal audio analysis framework. Measures integrated loudness (LUFS), loudness range, true peak, RMS, and DC offset per ITU-R BS.1770-4. Essential for broadcast compliance, mastering, and auto-normalization pipelines.
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.
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 LoudnessMeterOptions {
blockSize?: number // default 400ms (BS.1770)
overlap?: number // default 75%
targetLufs?: number // default -14.0 (streaming) or -23.0 (broadcast)
}
interface LoudnessResult extends AnalysisResult {
lufs: number // integrated loudness
loudnessRange: number // LRA in LU
truePeak: number // dBTP
rms: number // dB
peak: number // dB
dcOffset: number[] // per-channel
}
class LoudnessMeter implements AnalysisOp {
readonly name = 'loudness-meter'
readonly description = 'ITU-R BS.1770-4 loudness measurement'
constructor(options?: LoudnessMeterOptions)
analyze(doc: AudioDocument, opts?: LoudnessMeterOptions): Promise<LoudnessResult>
analyzeStream(doc: AudioDocument, opts?: LoudnessMeterOptions): AsyncGenerator<LoudnessResult>
analyzeBlock(block: Float32Array[], ctx: BlockContext): Partial<LoudnessResult>
}
New additions for genesis
- BS.1770-4 compliance — K-weighting filter, relative gate at -70 LUFS, integrated gate.
- True peak — 4x oversampled peak detection using polyphase interpolation.
- Loudness range — statistical loudness range (LU) per EBU Tech 3342.
- Streaming meters —
analyzeStream()yields running integrated loudness as blocks arrive. - Block-level metering —
analyzeBlock()returns momentary loudness for real-time meters. - OTel instrumentation — span
audio.analysis.loudness, counter, histogram. - Property-based tests — sine wave at 0 dBFS → known LUFS, silence → -∞ LUFS handled gracefully.
- Benchmark suite — meter 1-minute track, meter 10-minute track.
File layout
packages/media/audio/audio-analysis-loudness/
package.json
tsconfig.json
vitest.config.ts
src/
index.ts
error-codes.ts
meter/
loudness-meter.ts
loudness-meter.md
loudness-meter.types.ts
loudness-meter.test.ts
index.ts
algorithms/
lufs.ts
lufs.md
lufs.test.ts
true-peak.ts
true-peak.md
true-peak.test.ts
loudness-range.ts
loudness-range.md
loudness-range.test.ts
index.ts
filters/
k-weighting.ts
k-weighting.md
k-weighting.test.ts
index.ts
__benchmarks__/
loudness.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 already on genesis).
Affected dependents
No dependents in this batch (verified by bunx turbo ls --filter=...@suaveplan/audio-analysis-loudness). @suaveplan/audio-analysis-loudness is a leaf analysis plugin — no batch package depends on it. It is consumed at runtime by application/timeline code and by normalize's LUFS mode, both of which are created against this package's spec delta, not retrofitted.