summaryrefslogtreecommitdiff
path: root/libs/ardour/kmeterdsp.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2013-07-07 02:00:43 +0200
committerRobin Gareus <robin@gareus.org>2013-07-10 15:27:12 +0200
commit6e1781e5e33d6d97233a2e46aa98fd570d09e31f (patch)
tree92d236a8a82c9ba33687e2abc3988f2d7f5c7720 /libs/ardour/kmeterdsp.cc
parenta181009caefd5fe9efb73fff7c0c663dc8415e0a (diff)
experimental RMS-meter and peak-signal (vs peak-power) query
Diffstat (limited to 'libs/ardour/kmeterdsp.cc')
-rw-r--r--libs/ardour/kmeterdsp.cc116
1 files changed, 116 insertions, 0 deletions
diff --git a/libs/ardour/kmeterdsp.cc b/libs/ardour/kmeterdsp.cc
new file mode 100644
index 0000000000..77d1a87a81
--- /dev/null
+++ b/libs/ardour/kmeterdsp.cc
@@ -0,0 +1,116 @@
+/*
+ Copyright (C) 2008-2011 Fons Adriaensen <fons@linuxaudio.org>
+ Adopted for Ardour 2013 by Robin Gareus <robin@gareus.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <math.h>
+#include "kmeterdsp.h"
+
+float Kmeterdsp::_omega;
+
+Kmeterdsp::Kmeterdsp (void) :
+ _z1 (0),
+ _z2 (0),
+ _rms (0),
+ _flag (false)
+{
+}
+
+
+Kmeterdsp::~Kmeterdsp (void)
+{
+}
+
+
+void Kmeterdsp::process (float *p, int n)
+{
+ // Called by JACK's process callback.
+ //
+ // p : pointer to sample buffer
+ // n : number of samples to process
+
+ float s, t, z1, z2;
+
+ if (_flag) // Display thread has read the rms value.
+ {
+ _rms = 0;
+ _flag = false;
+ }
+
+ // Get filter state.
+ z1 = _z1;
+ z2 = _z2;
+
+ // Process n samples. Find digital peak value for this
+ // period and perform filtering. The second filter is
+ // evaluated only every 4th sample - this is just an
+ // optimisation.
+ t = 0;
+ n /= 4; // Loop is unrolled by 4.
+ while (n--)
+ {
+ s = *p++;
+ s *= s;
+ if (t < s) t = s; // Update digital peak.
+ z1 += _omega * (s - z1); // Update first filter.
+ s = *p++;
+ s *= s;
+ if (t < s) t = s; // Update digital peak.
+ z1 += _omega * (s - z1); // Update first filter.
+ s = *p++;
+ s *= s;
+ if (t < s) t = s; // Update digital peak.
+ z1 += _omega * (s - z1); // Update first filter.
+ s = *p++;
+ s *= s;
+ if (t < s) t = s; // Update digital peak.
+ z1 += _omega * (s - z1); // Update first filter.
+ z2 += 4 * _omega * (z1 - z2); // Update second filter.
+ }
+ t = sqrtf (t);
+
+ // Save filter state. The added constants avoid denormals.
+ _z1 = z1 + 1e-20f;
+ _z2 = z2 + 1e-20f;
+
+ // Adjust RMS value and update maximum since last read().
+ s = sqrtf (2 * z2);
+ if (s > _rms) _rms = s;
+}
+
+
+/* Returns highest _rms value since last call */
+float Kmeterdsp::read ()
+{
+ float rv= _rms;
+ _flag = true; // Resets _rms in next process().
+ return rv;
+}
+
+void Kmeterdsp::init (int fsamp)
+{
+ _omega = 9.72f / fsamp; // ballistic filter coefficient
+}
+
+void Kmeterdsp::reset ()
+{
+ _z1 = _z2 = _rms = 0.0;
+ _flag=false;
+}
+
+/* vi:set ts=8 sts=8 sw=8: */