1 // ------------------------------------------------------------------------
3 // Copyright (C) 2010-2011 Fons Adriaensen <fons@linuxaudio.org>
4 // Copyright (C) 2015 Robin Gareus <robin@gareus.org>
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 // ------------------------------------------------------------------------
25 #include "ebu_r128_proc.h"
29 // C99 'isfinite()' is not available in MSVC.
30 #define isfinite_local(val) (bool)_finite((double)val)
32 #define isfinite_local isfinite
37 float Ebu_r128_hist::_bin_power [100] = { 0.0f };
38 float Ebu_r128_proc::_chan_gain [5] = { 1.0f, 1.0f, 1.0f, 1.41f, 1.41f };
41 Ebu_r128_hist::Ebu_r128_hist (void)
43 _histc = new int [751];
49 Ebu_r128_hist::~Ebu_r128_hist (void)
55 void Ebu_r128_hist::reset (void)
57 memset (_histc, 0, 751 * sizeof (float));
63 void Ebu_r128_hist::initstat (void)
67 if (_bin_power [0]) return;
68 for (i = 0; i < 100; i++)
70 _bin_power [i] = powf (10.0f, i / 100.0f);
75 void Ebu_r128_hist::addpoint (float v)
79 k = (int) floorf (10 * v + 700.5f);
91 float Ebu_r128_hist::integrate (int i)
103 s += k * _bin_power [j++];
114 void Ebu_r128_hist::calc_integ (float *vi, float *th)
125 // Original threshold was -8 dB below result of first integration
126 // if (th) *th = 10 * log10f (s) - 8.0f;
127 // k = (int)(floorf (100 * log10f (s) + 0.5f)) + 620;
128 // Threshold redefined to -10 dB below result of first integration
129 if (th) *th = 10 * log10f (s) - 10.0f;
130 k = (int)(floorf (100 * log10f (s) + 0.5f)) + 600;
133 *vi = 10 * log10f (s);
137 void Ebu_r128_hist::calc_range (float *v0, float *v1, float *th)
149 if (th) *th = 10 * log10f (s) - 20.0f;
150 k = (int)(floorf (100 * log10f (s) + 0.5)) + 500;
152 for (i = k, n = 0; i <= 750; i++) n += _histc [i];
155 for (i = k, s = 0; s < a; i++) s += _histc [i];
156 for (j = 750, s = n; s > b; j--) s -= _histc [j];
157 *v0 = (i - 701) / 10.0f;
158 *v1 = (j - 699) / 10.0f;
164 Ebu_r128_proc::Ebu_r128_proc (void)
170 Ebu_r128_proc::~Ebu_r128_proc (void)
175 void Ebu_r128_proc::init (int nchan, float fsamp)
179 _fragm = (int) fsamp / 20;
180 detect_init (_fsamp);
185 void Ebu_r128_proc::reset (void)
193 _loudness_M = -200.0f;
194 _loudness_S = -200.0f;
195 memset (_power, 0, 64 * sizeof (float));
201 void Ebu_r128_proc::integr_reset (void)
205 _maxloudn_M = -200.0f;
206 _maxloudn_S = -200.0f;
207 _integrated = -200.0f;
208 _integ_thr = -200.0f;
209 _range_min = -200.0f;
210 _range_max = -200.0f;
211 _range_thr = -200.0f;
216 void Ebu_r128_proc::process (int nfram, const float *const *input)
220 for (i = 0; i < _nchan; i++) _ipp [i] = input [i];
223 k = (_frcnt < nfram) ? _frcnt : nfram;
224 _frpwr += detect_process (k);
228 _power [_wrind++] = _frpwr / _fragm;
232 _loudness_M = addfrags (8);
233 _loudness_S = addfrags (60);
234 if (!isfinite_local(_loudness_M) || _loudness_M < -200.f) _loudness_M = -200.0f;
235 if (!isfinite_local(_loudness_S) || _loudness_S < -200.f) _loudness_S = -200.0f;
236 if (_loudness_M > _maxloudn_M) _maxloudn_M = _loudness_M;
237 if (_loudness_S > _maxloudn_S) _maxloudn_S = _loudness_S;
242 _hist_M.addpoint (_loudness_M);
247 _hist_S.addpoint (_loudness_S);
249 _hist_M.calc_integ (&_integrated, &_integ_thr);
250 _hist_S.calc_range (&_range_min, &_range_max, &_range_thr);
254 for (i = 0; i < _nchan; i++) _ipp [i] += k;
260 float Ebu_r128_proc::addfrags (int nfrag)
266 k = (_wrind - nfrag) & 63;
267 for (i = 0; i < nfrag; i++) s += _power [(i + k) & 63];
268 return -0.6976f + 10 * log10f (s / nfrag);
272 void Ebu_r128_proc::detect_init (float fsamp)
274 float a, b, c, d, r, u1, u2, w1, w2;
276 r = 1 / tan (4712.3890f / fsamp);
279 u1 = u2 = 1.4085f + 210.0f / fsamp;
285 _a0 = (1 + c + d) / r;
286 _a1 = (2 - 2 * d) / r;
287 _a2 = (1 - c + d) / r;
288 _b1 = (2 - 2 * b) / r;
289 _b2 = (1 - a + b) / r;
292 b = 6.2298014f * r * r;
305 void Ebu_r128_proc::detect_reset (void)
307 for (int i = 0; i < MAXCH; i++) _fst [i].reset ();
311 float Ebu_r128_proc::detect_process (int nfram)
315 float x, y, z1, z2, z3, z4;
320 for (i = 0, S = _fst; i < _nchan; i++, S++)
328 for (j = 0; j < nfram; j++)
330 x = p [j] - _b1 * z1 - _b2 * z2 + 1e-15f;
331 y = _a0 * x + _a1 * z1 + _a2 * z2 - _c3 * z3 - _c4 * z4;
338 if (_nchan == 1) si = 2 * sj;
339 else si += _chan_gain [i] * sj;
340 S->_z1 = !isfinite_local(z1) ? 0 : z1;
341 S->_z2 = !isfinite_local(z2) ? 0 : z2;
342 S->_z3 = !isfinite_local(z3) ? 0 : z3;
343 S->_z4 = !isfinite_local(z4) ? 0 : z4;