This document summarises the mathematical steps the original C implementation (src/leqm-nrt.c) performs to derive the Leq(M) value defined in ISO 21727. It tracks the code path taken by the default non–real‑time run (worker_function) and indicates where optional features (gating, Dolby DI, etc.) hook into the pipeline.
sf_read_double / avcodec_receive_frame).inputcalib, chconf). Per-channel gain coefficients (normally unity) can be supplied to emulate cinema B-chain alignment. They scale the sample amplitudes before further processing (see worker_function, around lines 4500–4540).buffersizems milliseconds (default 850 ms, cf. lines 638 and 1263). Each worker thread receives nsamples = samplerate * buffersizems / 1000 * nch interleaved samples.M_filter for the commonly used 48 kHz rate.M_filter)The ISO 21727 M-weighting curve is implemented as a cascade of recursive biquads. The C code stores pre-computed denominator (a) and numerator (b) coefficients for 44.1 kHz and 48 kHz sampling rates (see table starting at line ~7330). For a sample sequence (x[n]) the filter output (y[n]) is computed by
The difference equation is realised inside M_filter, with explicit case handling for the first few samples until enough history is populated (lines 7350–7460). This gives a weighted pressure signal (p_M[n]) that mimics the standard’s equal-loudness curve.
When --convpoints is enabled the program instead convolves each block with the published 21-tap impulse response (functions convolv_buff and loadIR), but both branches ultimately produce the weighted signal convolvedbuffer used in the subsequent energy computation.
Within each worker block, the code performs three accumulations (lines 4518–4550):
rectify) and accumulated per channel (accumulatech) into chsumaccumulator_conv.chsumaccumulator_norm (used for the “Leq(noW)” diagnostic value).sumsamples adds the channel sums into a shared Sum struct (totsum). The struct stores:
sum – cumulative unweighted energy (\sum x^2)csum – cumulative weighted energy (\sum p_M^2)nsamples – total number of mono samples accumulated (frames × channels)These arrays are protected by a mutex when multiple threads run in parallel.
Once all samples are processed, meanoverduration (lines 5856–5871) performs the ISO integration:
The same routine also produces the unweighted RMS level from sum. The constant 108.010299957 is derived from the reference sound pressure (20 µPa) and the nominal calibration tone level (–20 dBFS), as documented in the inline comments around lines 5838–5869.
Because the accumulation is linear over sample squares, the discrete formulation faithfully approximates the continuous integral used by the standard:
\[L_{eq(M)} = 10 \log_{10}\left( \frac{1}{T} \int_0^T \frac{p_M(t)^2}{p_0^2}\, dt \right)\]where (T) is the total observation time and (p_0 = 20\,\mu\text{Pa}). In the implementation (p_M(t)) is represented by the filtered discrete sequence and the integral is replaced by the sample mean of squared values.
The alternative worker worker_function_gated2 adds loudness gating similar to ITU-R BS.1770:
calcSampleStepLG derives the hop size ops from the configured overlap (default 75 %), yielding a 400 ms gating block as required by the standard (lines 1853–1895).K_filter_stage1/2 and rectified (lines 4573–4632).chgateconf, levelgate, and dolbydi settings. If a block energy falls below threshold it is discarded before the final mean is computed (see lkfs_finalcomputation and dolbydifinalcomputation2).These gated sums feed either an LKFS measurement or a dialogue-specific variant, but the core Leq(M) channel is unaffected unless a level gate is explicitly enabled.
The program finally reports:
Leq(M) – weighted level as described above.Leq(noW) – unweighted level derived from sum.True Peak (optional) – computed by the oversampling routine truepeakcheck which upsamples each channel (default ×4) and tracks the maximum squared sample.Leq(M,10m) and time-varying loudness when the respective switches are set (see logleqm and logleqm10).The essential Leq(M) calculation in leqm-nrt can therefore be summarised as:
Every step maps directly to well-documented functions in src/leqm-nrt.c, so the mathematical intent is visible and aligns with ISO 21727’s formal definition of Leq(M).