2
* Peak metering facilities.
4
* Copyright (C) 2007 Krzysztof Foltman
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, or (at your option)
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., 51 Franklin Street, Fifth Floor, Boston, MA
21
#ifndef __CALF_VUMETER_H
22
#define __CALF_VUMETER_H
31
/// Measured signal level
33
/// Falloff of signal level (b1 coefficient of a 1-pole filter)
35
/// Clip indicator (set to 1 when |value| >= 1, fading otherwise)
37
/// Falloff of clip indicator (b1 coefficient of a 1-pole filter); set to 1 if no falloff is required (manual reset of clip indicator)
43
clip_falloff = 0.999f;
53
/// Set falloff so that the meter falls 20dB in time_20dB seconds, assuming sample rate of sample_rate
54
/// @arg time_20dB time for the meter to move by 20dB (default 300ms if <= 0)
55
void set_falloff(double time_20dB, double sample_rate)
59
// 20dB = 10x +/- --> 0.1 = pow(falloff, sample_rate * time_20dB) = exp(sample_rate * ln(falloff))
60
// ln(0.1) = sample_rate * ln(falloff)
61
falloff = pow(0.1, 1 / (sample_rate * time_20dB));
62
clip_falloff = falloff;
64
/// Copy falloff from another object
65
void copy_falloff(const vumeter &src)
67
falloff = src.falloff;
68
clip_falloff = src.clip_falloff;
71
/// Update peak meter based on input signal
72
inline void update(const float *src, unsigned int len)
74
update_stereo(src, NULL, len);
76
/// Update peak meter based on louder of two input signals
77
inline void update_stereo(const float *src1, const float *src2, unsigned int len)
79
// "Age" the old level by falloff^length
80
level *= pow(falloff, len);
81
// Same for clip level (using different fade constant)
82
clip *= pow(clip_falloff, len);
85
// Process input samples - to get peak value, take a max of all values in the input signal and "aged" old peak
86
// Clip is set to 1 if any sample is out-of-range, if no clip occurs, the "aged" value is assumed
88
run_sample_loop(src1, len);
90
run_sample_loop(src2, len);
92
inline void run_sample_loop(const float *src, unsigned int len)
95
for (unsigned int i = 0; i < len; i++) {
96
float sig = fabs(src[i]);
97
tmp = std::max(tmp, sig);
103
/// Update clip meter as if update was called with all-zero input signal
104
inline void update_zeros(unsigned int len)
106
level *= pow((double)falloff, (double)len);
107
clip *= pow((double)clip_falloff, (double)len);
108
dsp::sanitize(level);
117
inline void update_stereo(const float *src1, const float *src2, unsigned int len)
119
left.update_stereo(src1, NULL, len);
120
right.update_stereo(NULL, src2, len);
122
inline void update_zeros(unsigned int len)
124
left.update_zeros(len);
125
right.update_zeros(len);
132
inline void set_falloff(double time_20dB, double sample_rate)
134
left.set_falloff(time_20dB, sample_rate);
135
right.copy_falloff(left);
137
inline void copy_falloff(const dual_vumeter &src)
139
left.copy_falloff(src.left);
140
right.copy_falloff(src.right);