EBU R128 / ITU-R BS.1770-4 loudness metering, K-weighting, gating, true peak, LRA, and streaming targets for REVITHION STUDIO.
EBU R128 defines four measurements: Integrated (entire programme, LUFS), Short-term (3 s window, LUFS), Momentary (400 ms window, LUFS), and True Peak (4× oversampled, dBTP). The ITU-R BS.1770-4 algorithm flows: K-weighting filter → mean square per channel → channel-weighted sum (L = -0.691 + 10·log10(Σ Gi·zi), surround Ls/Rs weighted +1.5 dB) → two-stage gating.
Two cascaded biquads. Stage 1: high-shelf pre-filter (+4 dB above ~1.5 kHz). Stage 2: RLB high-pass (−3 dB at ~38 Hz). Recompute via bilinear transform for other sample rates.
void prepareKWeighting (double sampleRate) {
// Stage 1 high-shelf — b:{1.53512485958697,-2.69169618940638,1.19839281085285} a:{1,-1.69065929318241,0.73248077421585}
auto shelf = juce::dsp::IIR::Coefficients<float>::Ptr (new juce::dsp::IIR::Coefficients<float> (
1.53512485958697f, -2.69169618940638f, 1.19839281085285f, 1.0f, -1.69065929318241f, 0.73248077421585f));
// Stage 2 RLB high-pass — b:{1,-2,1} a:{1,-1.99004745483398,0.99007225036621}
auto rlb = juce::dsp::IIR::Coefficients<float>::Ptr (new juce::dsp::IIR::Coefficients<float> (
1.0f, -2.0f, 1.0f, 1.0f, -1.99004745483398f, 0.99007225036621f));
kWeightShelf.coefficients = shelf; kWeightHighPass.coefficients = rlb;
}
400 ms blocks, 75% overlap (100 ms step). Absolute gate at −70 LUFS discards silence, then relative gate at −10 LU below ungated loudness.
float computeGatedLoudness (const std::vector<float>& blockLUFS) {
std::vector<float> gated;
for (auto l : blockLUFS) if (l > -70.0f) gated.push_back (l);
if (gated.empty()) return -INFINITY;
float sum = 0.0f;
for (auto l : gated) sum += std::pow (10.0f, l / 10.0f);
float threshold = 10.0f * std::log10 (sum / (float) gated.size()) - 10.0f;
float finalSum = 0.0f; int n = 0;
for (auto l : gated) if (l > threshold) { finalSum += std::pow (10.0f, l / 10.0f); ++n; }
return n > 0 ? -0.691f + 10.0f * std::log10 (finalSum / (float) n) : -INFINITY;
}
Statistical spread of gated short-term (3 s) loudness: LRA = P95 − P10 in LU (absolute gate −70 LUFS, relative gate −20 LU). Low (< 5 LU) = compressed. Medium (5–15 LU) = broadcast. High (> 15 LU) = classical/film.
Sample peaks miss inter-sample overs — 4× oversampling reconstructs peaks between samples. Ceiling: −1.0 dBTP (EBU R128).
class TruePeakMeter {
juce::dsp::Oversampling<float> oversampler { 1, 2, juce::dsp::Oversampling<float>::filterHalfBandPolyphaseIIR };
std::atomic<float> truePeakDB { -100.0f };