[FFmpeg-devel] [PATCH] avfilter/f_ebur128: add all sample rates support

Clément Bœsch u at pkh.me
Fri Mar 5 15:36:57 EET 2021


On Thu, Mar 04, 2021 at 04:05:53PM +0100, Paul B Mahol wrote:
[...]
> +    double f0 = 1681.974450955533;
> +    double G = 3.999843853973347;
> +    double Q = 0.7071752369554196;
> +
> +    double K = tan(M_PI * f0 / (double)inlink->sample_rate);
> +    double Vh = pow(10.0, G / 20.0);
> +    double Vb = pow(Vh, 0.4996667741545416);

Not a fan of these constants coming out of nowhere. Please add the
following comment in the code: "Unofficial reversed parametrization of pre
and RLB from 48kHz".

And in the commit description, please include the following:

    The magic constants come from the unofficial "ITU-R BS.1770-1 filter
    specifications"¹ by Raiden (libebur128) which relies on "Parameter
    Quantization in Direct-Form Recursive Audio Filters"² by Brian
    Neunaber.

    The constants seem to include a quantization bias, for example:
    - Vb is supposed to be exactly √Vh in a high shelf filter
    - the Pre-filter Gain should likely be 4dB
    - Pre Q and RLB Q are respectively very close to √½ and ½

    Those are not adjusted to prevent the values from drifting away from
    the official specifications.

    An alternative to this approach would be to requantize on the fly as
    proposed by pbelkner³, where the 48kHz code path would use the exact
    specifications constants while derivating constants for other
    frequencies.

    [1]: https://www.scribd.com/document/49991813/ITU-R-BS-1770-1-filters
    [2]: https://www.scribd.com/document/6531763/Direct-Form-Filter-Parameter-Quantization
    [3]: https://hydrogenaud.io/index.php?topic=86116.msg740092#msg740092

Feel free to add more information if you have any. This will likely save a
lot of time for anyone looking into understanding and improving that code
in the future.

> +
> +    double a0 = 1.0 + K / Q + K * K;
> +
> +    ebur128->pre_b[0] = (Vh + Vb * K / Q + K * K) / a0;
> +    ebur128->pre_b[1] = 2.0 * (K * K - Vh) / a0;
> +    ebur128->pre_b[2] = (Vh - Vb * K / Q + K * K) / a0;
> +    ebur128->pre_a[1] = 2.0 * (K * K - 1.0) / a0;
> +    ebur128->pre_a[2] = (1.0 - K / Q + K * K) / a0;
> +
> +    f0 = 38.13547087602444;
> +    Q = 0.5003270373238773;
> +    K = tan(M_PI * f0 / (double)inlink->sample_rate);
> +
> +    ebur128->rlb_b[0] = 1.0;
> +    ebur128->rlb_b[1] = -2.0;
> +    ebur128->rlb_b[2] = 1.0;

> +    ebur128->rlb_a[1] = 2.0 * (K * K - 1.0) / (1.0 + K / Q + K * K);
> +    ebur128->rlb_a[2] = (1.0 - K / Q + K * K) / (1.0 + K / Q + K * K);

You can redefine a0 like with the pre filter and use it in these 2
expressions.

[...]

Regards,

-- 
Clément B.


More information about the ffmpeg-devel mailing list