ardour
kmeterdsp.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008-2011 Fons Adriaensen <fons@linuxaudio.org>
3  Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 
20 #include <math.h>
21 #include "ardour/kmeterdsp.h"
22 
23 
24 float Kmeterdsp::_omega;
25 
26 
28  _z1 (0),
29  _z2 (0),
30  _rms (0),
31  _flag (false)
32 {
33 }
34 
35 
37 {
38 }
39 
40 void Kmeterdsp::init (int fsamp)
41 {
42  _omega = 9.72f / fsamp; // ballistic filter coefficient
43 }
44 
45 void Kmeterdsp::process (float const *p, int n)
46 {
47  // Called by JACK's process callback.
48  //
49  // p : pointer to sample buffer
50  // n : number of samples to process
51 
52  float s, z1, z2;
53 
54  // Get filter state.
55  z1 = _z1 > 50 ? 50 : (_z1 < 0 ? 0 : _z1);
56  z2 = _z2 > 50 ? 50 : (_z2 < 0 ? 0 : _z2);
57 
58  // Perform filtering. The second filter is evaluated
59  // only every 4th sample - this is just an optimisation.
60  n /= 4; // Loop is unrolled by 4.
61  while (n--)
62  {
63  s = *p++;
64  s *= s;
65  z1 += _omega * (s - z1); // Update first filter.
66  s = *p++;
67  s *= s;
68  z1 += _omega * (s - z1); // Update first filter.
69  s = *p++;
70  s *= s;
71  z1 += _omega * (s - z1); // Update first filter.
72  s = *p++;
73  s *= s;
74  z1 += _omega * (s - z1); // Update first filter.
75  z2 += 4 * _omega * (z1 - z2); // Update second filter.
76  }
77 
78  if (isnan(z1)) z1 = 0;
79  if (isnan(z2)) z2 = 0;
80  // Save filter state. The added constants avoid denormals.
81  _z1 = z1 + 1e-20f;
82  _z2 = z2 + 1e-20f;
83 
84  s = sqrtf (2.0f * z2);
85 
86  if (_flag) // Display thread has read the rms value.
87  {
88  _rms = s;
89  _flag = false;
90  }
91  else
92  {
93  // Adjust RMS value and update maximum since last read().
94  if (s > _rms) _rms = s;
95  }
96 }
97 
98 /* Returns highest _rms value since last call */
100 {
101  float rv= _rms;
102  _flag = true; // Resets _rms in next process().
103  return rv;
104 }
105 
107 {
108  _z1 = _z2 = _rms = .0f;
109  _flag = false;
110 }
111 
112 /* vi:set ts=8 sts=8 sw=4: */
~Kmeterdsp(void)
Definition: kmeterdsp.cc:36
void process(float const *p, int n)
Definition: kmeterdsp.cc:45
float _z1
Definition: kmeterdsp.h:40
tuple f
Definition: signals.py:35
float _rms
Definition: kmeterdsp.h:42
static void init(int fsamp)
Definition: kmeterdsp.cc:40
static float _omega
Definition: kmeterdsp.h:45
float _z2
Definition: kmeterdsp.h:41
void reset()
Definition: kmeterdsp.cc:106
bool _flag
Definition: kmeterdsp.h:43
float read()
Definition: kmeterdsp.cc:99
Kmeterdsp(void)
Definition: kmeterdsp.cc:27