Files
suaveplan/openspec/archive/2026-05-23-enterprise-audio-analysis-loudness/proposal.md
2026-05-27 23:29:53 +01:00

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

  1. BS.1770-4 compliance — K-weighting filter, relative gate at -70 LUFS, integrated gate.
  2. True peak — 4x oversampled peak detection using polyphase interpolation.
  3. Loudness range — statistical loudness range (LU) per EBU Tech 3342.
  4. Streaming meters — analyzeStream() yields running integrated loudness as blocks arrive.
  5. Block-level metering — analyzeBlock() returns momentary loudness for real-time meters.
  6. OTel instrumentation — span audio.analysis.loudness, counter, histogram.
  7. Property-based tests — sine wave at 0 dBFS → known LUFS, silence → -∞ LUFS handled gracefully.
  8. 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.