logic rearrangement to avoid unnecessary call to Route::monitoring_state() in instrum...
[ardour.git] / libs / ardour / meter.cc
1 /*
2     Copyright (C) 2006 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify it
5     under the terms of the GNU General Public License as published by the Free
6     Software Foundation; either version 2 of the License, or (at your option)
7     any later version.
8
9     This program is distributed in the hope that it will be useful, but WITHOUT
10     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12     for more details.
13
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <algorithm>
20 #include <cmath>
21 #include <limits>
22
23 #include "pbd/compose.h"
24
25 #include "ardour/audio_buffer.h"
26 #include "ardour/buffer_set.h"
27 #include "ardour/dB.h"
28 #include "ardour/meter.h"
29 #include "ardour/midi_buffer.h"
30 #include "ardour/session.h"
31 #include "ardour/rc_configuration.h"
32 #include "ardour/runtime_functions.h"
33
34 using namespace std;
35
36 using namespace ARDOUR;
37
38 PeakMeter::PeakMeter (Session& s, const std::string& name)
39     : Processor (s, string_compose ("meter-%1", name))
40 {
41         Kmeterdsp::init(s.nominal_frame_rate());
42         Iec1ppmdsp::init(s.nominal_frame_rate());
43         Iec2ppmdsp::init(s.nominal_frame_rate());
44         Vumeterdsp::init(s.nominal_frame_rate());
45         _pending_active = true;
46         _meter_type = MeterPeak;
47         _reset_dpm = true;
48         _reset_max = true;
49         _bufcnt = 0;
50 }
51
52 PeakMeter::~PeakMeter ()
53 {
54         while (_kmeter.size() > 0) {
55                 delete (_kmeter.back());
56                 delete (_iec1meter.back());
57                 delete (_iec2meter.back());
58                 delete (_vumeter.back());
59                 _kmeter.pop_back();
60                 _iec1meter.pop_back();
61                 _iec2meter.pop_back();
62                 _vumeter.pop_back();
63         }
64         while (_peak_power.size() > 0) {
65                 _peak_buffer.pop_back();
66                 _peak_power.pop_back();
67                 _max_peak_signal.pop_back();
68         }
69 }
70
71
72 /** Get peaks from @a bufs
73  * Input acceptance is lenient - the first n buffers from @a bufs will
74  * be metered, where n was set by the last call to setup(), excess meters will
75  * be set to 0.
76  *
77  * (runs in jack realtime context)
78  */
79 void
80 PeakMeter::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t nframes, bool)
81 {
82         if (!_active && !_pending_active) {
83                 return;
84         }
85         const bool do_reset_max = _reset_max;
86         const bool do_reset_dpm = _reset_dpm;
87         _reset_max = false;
88         _reset_dpm = false;
89
90         // cerr << "meter " << name() << " runs with " << bufs.available() << " inputs\n";
91
92         const uint32_t n_audio = min (current_meters.n_audio(), bufs.count().n_audio());
93         const uint32_t n_midi  = min (current_meters.n_midi(), bufs.count().n_midi());
94
95         uint32_t n = 0;
96
97         const float falloff_dB = Config->get_meter_falloff() * nframes / _session.nominal_frame_rate();
98         const uint32_t zoh = _session.nominal_frame_rate() * .021;
99         _bufcnt += nframes;
100
101         // Meter MIDI in to the first n_midi peaks
102         for (uint32_t i = 0; i < n_midi; ++i, ++n) {
103                 float val = 0.0f;
104                 const MidiBuffer& buf (bufs.get_midi(i));
105                 
106                 for (MidiBuffer::const_iterator e = buf.begin(); e != buf.end(); ++e) {
107                         const Evoral::MIDIEvent<framepos_t> ev(*e, false);
108                         if (ev.is_note_on()) {
109                                 const float this_vel = ev.buffer()[2] / 127.0;
110                                 if (this_vel > val) {
111                                         val = this_vel;
112                                 }
113                         } else {
114                                 val += 1.0 / bufs.get_midi(n).capacity();
115                                 if (val > 1.0) {
116                                         val = 1.0;
117                                 }
118                         }
119                 }
120                 if (_peak_power[n] < (1.0 / 512.0)) {
121                         _peak_power[n] = 0;
122                 } else {
123                         /* empirical algorithm WRT to audio falloff times */
124                         _peak_power[n] -= sqrtf (_peak_power[n]) * falloff_dB * 0.045f;
125                 }
126                 _peak_power[n] = max(_peak_power[n], val);
127                 _max_peak_signal[n] = 0;
128         }
129
130         // Meter audio in to the rest of the peaks
131         for (uint32_t i = 0; i < n_audio; ++i, ++n) {
132                 if (bufs.get_audio(i).silent()) {
133                         ;
134                 } else {
135                         _peak_buffer[n] = compute_peak (bufs.get_audio(i).data(), nframes, _peak_buffer[n]);
136                         _max_peak_signal[n] = std::max(_peak_buffer[n], _max_peak_signal[n]); // todo sync reset
137                 }
138
139                 if (do_reset_max) {
140                         _max_peak_signal[n] = 0;
141                 }
142
143                 if (do_reset_dpm) {
144                         _peak_buffer[n] = 0;
145                         _peak_power[n] = -std::numeric_limits<float>::infinity();
146                 } else {
147                         // falloff
148                         if (_peak_power[n] >  -318.8f) {
149                                 _peak_power[n] -= falloff_dB;
150                         } else {
151                                 _peak_power[n] = -std::numeric_limits<float>::infinity();
152                         }
153                         _peak_power[n] = max(_peak_power[n], accurate_coefficient_to_dB(_peak_buffer[n]));
154                         // integration buffer, retain peaks > 49Hz
155                         if (_bufcnt > zoh) {
156                                 _peak_buffer[n] = 0;
157                         }
158                 }
159
160                 if (_meter_type & (MeterKrms | MeterK20 | MeterK14 | MeterK12)) {
161                         _kmeter[i]->process(bufs.get_audio(i).data(), nframes);
162                 }
163                 if (_meter_type & (MeterIEC1DIN | MeterIEC1NOR)) {
164                         _iec1meter[i]->process(bufs.get_audio(i).data(), nframes);
165                 }
166                 if (_meter_type & (MeterIEC2BBC | MeterIEC2EBU)) {
167                         _iec2meter[i]->process(bufs.get_audio(i).data(), nframes);
168                 }
169                 if (_meter_type & MeterVU) {
170                         _vumeter[i]->process(bufs.get_audio(i).data(), nframes);
171                 }
172         }
173
174         // Zero any excess peaks
175         for (uint32_t i = n; i < _peak_power.size(); ++i) {
176                 _peak_power[i] = -std::numeric_limits<float>::infinity();
177                 _max_peak_signal[n] = 0;
178         }
179
180         if (_bufcnt > zoh) {
181                 _bufcnt = 0;
182         }
183
184         _active = _pending_active;
185 }
186
187 void
188 PeakMeter::reset ()
189 {
190         if (_active || _pending_active) {
191                 _reset_dpm = true;
192         } else {
193                 for (size_t i = 0; i < _peak_power.size(); ++i) {
194                         _peak_power[i] = -std::numeric_limits<float>::infinity();
195                         _peak_buffer[i] = 0;
196                 }
197         }
198
199         // these are handled async just fine.
200         for (size_t n = 0; n < _kmeter.size(); ++n) {
201                 _kmeter[n]->reset();
202                 _iec1meter[n]->reset();
203                 _iec2meter[n]->reset();
204                 _vumeter[n]->reset();
205         }
206 }
207
208 void
209 PeakMeter::reset_max ()
210 {
211         if (_active || _pending_active) {
212                 _reset_max = true;
213                 return;
214         }
215         for (size_t i = 0; i < _max_peak_signal.size(); ++i) {
216                 _max_peak_signal[i] = 0;
217                 _peak_buffer[i] = 0;
218         }
219 }
220
221 bool
222 PeakMeter::can_support_io_configuration (const ChanCount& in, ChanCount& out)
223 {
224         out = in;
225         return true;
226 }
227
228 bool
229 PeakMeter::configure_io (ChanCount in, ChanCount out)
230 {
231         if (out != in) { // always 1:1
232                 return false;
233         }
234
235         current_meters = in;
236
237         set_max_channels (in);
238
239         return Processor::configure_io (in, out);
240 }
241
242 void
243 PeakMeter::reflect_inputs (const ChanCount& in)
244 {
245         reset();
246         current_meters = in;
247         reset_max();
248         // ConfigurationChanged() postponed
249 }
250
251 void
252 PeakMeter::emit_configuration_changed () {
253         ConfigurationChanged (current_meters, current_meters); /* EMIT SIGNAL */
254 }
255
256 void
257 PeakMeter::set_max_channels (const ChanCount& chn)
258 {
259         uint32_t const limit = chn.n_total();
260         const size_t n_audio = chn.n_audio();
261
262         while (_peak_power.size() > limit) {
263                 _peak_buffer.pop_back();
264                 _peak_power.pop_back();
265                 _max_peak_signal.pop_back();
266         }
267
268         while (_peak_power.size() < limit) {
269                 _peak_buffer.push_back(0);
270                 _peak_power.push_back(-std::numeric_limits<float>::infinity());
271                 _max_peak_signal.push_back(0);
272         }
273
274         assert(_peak_buffer.size() == limit);
275         assert(_peak_power.size() == limit);
276         assert(_max_peak_signal.size() == limit);
277
278         /* alloc/free other audio-only meter types. */
279         while (_kmeter.size() > n_audio) {
280                 delete (_kmeter.back());
281                 delete (_iec1meter.back());
282                 delete (_iec2meter.back());
283                 delete (_vumeter.back());
284                 _kmeter.pop_back();
285                 _iec1meter.pop_back();
286                 _iec2meter.pop_back();
287                 _vumeter.pop_back();
288         }
289         while (_kmeter.size() < n_audio) {
290                 _kmeter.push_back(new Kmeterdsp());
291                 _iec1meter.push_back(new Iec1ppmdsp());
292                 _iec2meter.push_back(new Iec2ppmdsp());
293                 _vumeter.push_back(new Vumeterdsp());
294         }
295         assert(_kmeter.size() == n_audio);
296         assert(_iec1meter.size() == n_audio);
297         assert(_iec2meter.size() == n_audio);
298         assert(_vumeter.size() == n_audio);
299
300         reset();
301         reset_max();
302 }
303
304 /** To be driven by the Meter signal from IO.
305  * Caller MUST hold its own processor_lock to prevent reconfiguration
306  * of meter size during this call.
307  */
308
309 #define CHECKSIZE(MTR) (n < MTR.size() + n_midi && n >= n_midi)
310
311 float
312 PeakMeter::meter_level(uint32_t n, MeterType type) {
313         switch (type) {
314                 case MeterKrms:
315                 case MeterK20:
316                 case MeterK14:
317                 case MeterK12:
318                         {
319                                 const uint32_t n_midi = current_meters.n_midi();
320                                 if (CHECKSIZE(_kmeter)) {
321                                         return accurate_coefficient_to_dB (_kmeter[n - n_midi]->read());
322                                 }
323                         }
324                         break;
325                 case MeterIEC1DIN:
326                 case MeterIEC1NOR:
327                         {
328                                 const uint32_t n_midi = current_meters.n_midi();
329                                 if (CHECKSIZE(_iec1meter)) {
330                                         return accurate_coefficient_to_dB (_iec1meter[n - n_midi]->read());
331                                 }
332                         }
333                         break;
334                 case MeterIEC2BBC:
335                 case MeterIEC2EBU:
336                         {
337                                 const uint32_t n_midi = current_meters.n_midi();
338                                 if (CHECKSIZE(_iec2meter)) {
339                                         return accurate_coefficient_to_dB (_iec2meter[n - n_midi]->read());
340                                 }
341                         }
342                         break;
343                 case MeterVU:
344                         {
345                                 const uint32_t n_midi = current_meters.n_midi();
346                                 if (CHECKSIZE(_vumeter)) {
347                                         return accurate_coefficient_to_dB (_vumeter[n - n_midi]->read());
348                                 }
349                         }
350                         break;
351                 case MeterPeak:
352                 case MeterPeak0dB:
353                         if (n < _peak_power.size()) {
354                                 return _peak_power[n];
355                         }
356                         break;
357                 case MeterMaxSignal:
358                         assert(0);
359                         break;
360                 default:
361                 case MeterMaxPeak:
362                         if (n < _max_peak_signal.size()) {
363                                 return accurate_coefficient_to_dB(_max_peak_signal[n]);
364                         }
365                         break;
366         }
367         return minus_infinity();
368 }
369
370 void
371 PeakMeter::set_type(MeterType t)
372 {
373         if (t == _meter_type) {
374                 return;
375         }
376
377         _meter_type = t;
378
379         if (t & (MeterKrms | MeterK20 | MeterK14 | MeterK12)) {
380                 const size_t n_audio = current_meters.n_audio();
381                 for (size_t n = 0; n < n_audio; ++n) {
382                         _kmeter[n]->reset();
383                 }
384         }
385         if (t & (MeterIEC1DIN | MeterIEC1NOR)) {
386                 const size_t n_audio = current_meters.n_audio();
387                 for (size_t n = 0; n < n_audio; ++n) {
388                         _iec1meter[n]->reset();
389                 }
390         }
391         if (t & (MeterIEC2BBC | MeterIEC2EBU)) {
392                 const size_t n_audio = current_meters.n_audio();
393                 for (size_t n = 0; n < n_audio; ++n) {
394                         _iec2meter[n]->reset();
395                 }
396         }
397         if (t & MeterVU) {
398                 const size_t n_audio = current_meters.n_audio();
399                 for (size_t n = 0; n < n_audio; ++n) {
400                         _vumeter[n]->reset();
401                 }
402         }
403
404         TypeChanged(t);
405 }
406
407 XMLNode&
408 PeakMeter::state (bool full_state)
409 {
410         XMLNode& node (Processor::state (full_state));
411         node.add_property("type", "meter");
412         return node;
413 }