# Metering and spectral processing

> Measure pitch, levels and loudness, and build FFT, vocoder and pitch-shifting paths.

Canonical: https://maru.audio/docs/dsp-metering-and-spectral
Documentation index: https://maru.audio/llms.txt

Analysis extracts information from sound; spectral processing changes its
frequency or pitch content. Keep those roles clear: a pitch detector reports a
period/frequency, while a pitch shifter needs a processing path and suitable
timing. A meter reports levels; a loudness matcher also changes gain.

## Choose the measurement

| Question | Start with | Interpret the result |
| --- | --- | --- |
| Is there a pitched monophonic note? | `analysis/pitch-detector`, `analysis/voice-pitch-detector` | Frequency/period, confidence and voiced state, updated at a hop. |
| What note should an input trigger? | `analysis/pitch-tracking` | Adds gating and continuous-pitch decisions. |
| How loud is this short window? | `analysis/loudness-meter` | Rolling stereo K-weighted/RMS power; not integrated LUFS. |
| What is programme loudness? | `analysis/programme-meter` | Gated integrated LUFS, momentary/short-term values, LRA and history. |
| What inter-sample peak is estimated? | `analysis/true-peak` | Four-phase BS.1770-5 detector; distinct from sample peak. |
| How do two paths compare? | `analysis/loudness-match` | Learn/hold/continuous compensation from paired inputs. |

```ts
import { initTruePeak, truePeakTick, resetTruePeak } from "maruaudio/dsp/analysis/true-peak"
const meter = initTruePeak() // one state per measured channel
let peak = 0
function observe(sample: number): void {
  peak = Math.max(peak, truePeakTick(meter, sample))
}
// At an explicit measurement restart:
function restart(): void { resetTruePeak(meter); peak = 0 }
```

Tick the true-peak detector for every contiguous sample. At Stop, flush twelve
zeros to observe its FIR tail, without counting those zeros as programme audio.

Meters need enough history before their reading is ready. Retain their readiness
and reset/segment semantics in the module; publish telemetry through the host
rather than updating React or the DOM from DSP. A loudness matcher belongs
before the manual master stage and needs the actual pre-compensation candidate.
It is separate from a limiter.

## Choose the transformation

Frequency shifting adds an offset in Hz, so harmonic spacing changes. Pitch
shifting multiplies frequencies, preserving musical interval ratios. The
single-sideband frequency shifter, delay-based pitch shifter and TD-PSOLA
shifters therefore solve different problems.

`pitch-shifter` requires an explicit input period. `voice-shifter` adds the
control/voicing path for a monophonic voice and has declared fixed latency;
align its dry path. The dual-delay shifter uses caller-owned rings and offers
stereo detuning, without formant preservation. A vocoder needs an analysis
signal and the selected carrier; it is a band-envelope system.

`real-fft` supplies transforms over prepared twiddle/bit-reversal tables with
split real/imaginary output. Design the window, overlap, hop, reconstruction
and latency around it. A transform alone is not a complete spectral effect.

## Toolkit reference

Import paths below are suffixes of `maruaudio/dsp/`. Use the exported types
and setters in your installed version for complete signatures and defaults.

### Analysis and meters

| Import suffix | Purpose | Selected API |
| --- | --- | --- |
| `analysis/pitch-detector` | Streaming bounded YIN-lite monophonic pitch detector exposing frequency, period, confidence and voiced state per fixed hop. | `initPitchDetectorNode`, `pitchDetectorNodeTick` |
| `analysis/pitch-tracking` | Causal monophonic note gating, continuous pitch and experimental circular tuning compensation. | `initPitchTracking`, `configurePitchTracking` |
| `analysis/voice-pitch-detector` | Voice YIN pitch detector with decimated analysis, full-rate refinement, voicing hysteresis and configurable 50–1600 Hz range and hop. | `initVoicePitchDetector`, `voicePitchDetectorTick` |
| `analysis/k-weighting` | Shared BS.1770 K filter coefficient and sample operations for offline/streaming consumers. | `initKWeighting`, `kWeightingTick` |
| `analysis/loudness-match` | Bounded paired stereo window matching, fresh learn/hold and continuous correction. | `initLoudnessMatch`, `loudnessMatchTick` |
| `analysis/loudness-meter` | Bounded live summed-stereo K/RMS window meter independent of matching, signal gating, or gain control. | `initLoudnessMeter`, `loudnessMeterTick` |
| `analysis/true-peak` | BS.1770-5 four-phase true-peak detector with a twelve-tap phase kernel. | `initTruePeak`, `truePeakTick` |
| `analysis/programme-meter` | Continuous stereo gated integrated LUFS, momentary/short-term loudness, LRA, true peak and sample-timed dynamics/stereo history. | `initProgrammeMeter`, `programmeMeterTick` |

### Spectral processing

| Import suffix | Purpose | Selected API |
| --- | --- | --- |
| `spectral/frequency-shifter` | Single-sideband frequency shifter: two fixed four-section Niemitalo allpass banks and phase-locked quadrature carriers. | `initFrequencyShifterNode`, `frequencyShifterAllpassTick` |
| `spectral/pitch-shifter` | Bounded monophonic TD-PSOLA pitch shifter over a fixed ring, with the input period as an explicit control input. | `initPitchShifterNode`, `pitchShifterNodeTick` |
| `spectral/vocoder` | Channel vocoder with logarithmic filter bands, envelope followers, carrier noise and dry/wet. | `initVocoderNode`, `vocoderNodeTick` |
| `spectral/voice-shifter` | Monophonic TD-PSOLA voice pitch shifter for pitch correction: smoothed continuous ratio, independent formant factor, mark-spacing pitch, fixed declared latency and a voiced/unvoiced crossfade to an aligned dry path. | `initVoiceShifter`, `voiceShifterTick` |
| `spectral/real-fft` | Prepared real forward/inverse FFT with split real/imaginary bins, power-of-two sizes up to 2^19 and caller-owned tables. | `initRealFft`, `realFftLog2` |
| `spectral/delay-pitch-shifter` | Dual sweeping-delay pitch shifter over caller-owned prepared stereo rings. | `initDelayPitchShifter`, `delayPitchShifterTick` |

Return to [DSP fundamentals](https://maru.audio/docs/dsp-fundamentals.md) for I/O, lifecycle,
units and the category map.
