Only show user-presets in favorite sidebar
[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_sample_rate());
42         Iec1ppmdsp::init(s.nominal_sample_rate());
43         Iec2ppmdsp::init(s.nominal_sample_rate());
44         Vumeterdsp::init(s.nominal_sample_rate());
45         _pending_active = true;
46         _meter_type = MeterPeak;
47         _reset_dpm = true;
48         _reset_max = true;
49         _bufcnt = 0;
50         _combined_peak = 0;
51 }
52
53 PeakMeter::~PeakMeter ()
54 {
55         while (_kmeter.size() > 0) {
56                 delete (_kmeter.back());
57                 delete (_iec1meter.back());
58                 delete (_iec2meter.back());
59                 delete (_vumeter.back());
60                 _kmeter.pop_back();
61                 _iec1meter.pop_back();
62                 _iec2meter.pop_back();
63                 _vumeter.pop_back();
64         }
65         while (_peak_power.size() > 0) {
66                 _peak_buffer.pop_back();
67                 _peak_power.pop_back();
68                 _max_peak_signal.pop_back();
69         }
70 }
71
72
73 /** Get peaks from @a bufs
74  * Input acceptance is lenient - the first n buffers from @a bufs will
75  * be metered, where n was set by the last call to setup(), excess meters will
76  * be set to 0.
77  *
78  * (runs in jack realtime context)
79  */
80 void
81 PeakMeter::run (BufferSet& bufs, samplepos_t /*start_sample*/, samplepos_t /*end_sample*/, double /*speed*/, pframes_t nframes, bool)
82 {
83         if (!_active && !_pending_active) {
84                 return;
85         }
86         const bool do_reset_max = _reset_max;
87         const bool do_reset_dpm = _reset_dpm;
88         _reset_max = false;
89         _reset_dpm = false;
90         _combined_peak = 0;
91
92         // cerr << "meter " << name() << " runs with " << bufs.available() << " inputs\n";
93
94         const uint32_t n_audio = min (current_meters.n_audio(), bufs.count().n_audio());
95         const uint32_t n_midi  = min (current_meters.n_midi(), bufs.count().n_midi());
96
97         uint32_t n = 0;
98
99         const float falloff_dB = Config->get_meter_falloff() * nframes / _session.nominal_sample_rate();
100         const uint32_t zoh = _session.nominal_sample_rate() * .021;
101         _bufcnt += nframes;
102
103         // Meter MIDI in to the first n_midi peaks
104         for (uint32_t i = 0; i < n_midi; ++i, ++n) {
105                 float val = 0.0f;
106                 if (do_reset_dpm) {
107                         _peak_power[n] = 0;
108                 }
109                 const MidiBuffer& buf (bufs.get_midi(i));
110
111                 for (MidiBuffer::const_iterator e = buf.begin(); e != buf.end(); ++e) {
112                         const Evoral::Event<samplepos_t> ev(*e, false);
113                         if (ev.is_note_on()) {
114                                 const float this_vel = ev.buffer()[2] / 127.0;
115                                 if (this_vel > val) {
116                                         val = this_vel;
117                                 }
118                                 if (val > 0.01) {
119                                         if (_combined_peak < 0.01) {
120                                                 _combined_peak = 0.01;
121                                         }
122                                 }
123                         } else {
124                                 val += 1.0 / bufs.get_midi(n).capacity();
125                                 if (val > 1.0) {
126                                         val = 1.0;
127                                 }
128                         }
129                 }
130                 if (_peak_power[n] < (1.0 / 512.0)) {
131                         _peak_power[n] = 0;
132                 } else {
133                         /* empirical algorithm WRT to audio falloff times */
134                         _peak_power[n] -= sqrtf (_peak_power[n]) * falloff_dB * 0.045f;
135                 }
136                 _peak_power[n] = max(_peak_power[n], val);
137                 _max_peak_signal[n] = 0;
138         }
139
140         // Meter audio in to the rest of the peaks
141         for (uint32_t i = 0; i < n_audio; ++i, ++n) {
142                 if (bufs.get_audio(i).silent()) {
143                         _peak_buffer[n] = 0;
144                 } else {
145                         _peak_buffer[n] = compute_peak (bufs.get_audio(i).data(), nframes, _peak_buffer[n]);
146                         _peak_buffer[n] = std::min (_peak_buffer[n], 100.f); // cut off at +40dBFS for falloff.
147                         _max_peak_signal[n] = std::max(_peak_buffer[n], _max_peak_signal[n]); // todo sync reset
148                         _combined_peak = std::max(_peak_buffer[n], _combined_peak);
149                 }
150
151                 if (do_reset_max) {
152                         _max_peak_signal[n] = 0;
153                 }
154
155                 if (do_reset_dpm) {
156                         _peak_buffer[n] = 0;
157                         _peak_power[n] = -std::numeric_limits<float>::infinity();
158                 } else {
159                         // falloff
160                         if (_peak_power[n] >  -318.8f) {
161                                 _peak_power[n] -= falloff_dB;
162                         } else {
163                                 _peak_power[n] = -std::numeric_limits<float>::infinity();
164                         }
165                         _peak_power[n] = max(_peak_power[n], accurate_coefficient_to_dB(_peak_buffer[n]));
166                         // integration buffer, retain peaks > 49Hz
167                         if (_bufcnt > zoh) {
168                                 _peak_buffer[n] = 0;
169                         }
170                 }
171
172                 if (_meter_type & (MeterKrms | MeterK20 | MeterK14 | MeterK12)) {
173                         _kmeter[i]->process(bufs.get_audio(i).data(), nframes);
174                 }
175                 if (_meter_type & (MeterIEC1DIN | MeterIEC1NOR)) {
176                         _iec1meter[i]->process(bufs.get_audio(i).data(), nframes);
177                 }
178                 if (_meter_type & (MeterIEC2BBC | MeterIEC2EBU)) {
179                         _iec2meter[i]->process(bufs.get_audio(i).data(), nframes);
180                 }
181                 if (_meter_type & MeterVU) {
182                         _vumeter[i]->process(bufs.get_audio(i).data(), nframes);
183                 }
184         }
185
186         // Zero any excess peaks
187         for (uint32_t i = n; i < _peak_power.size(); ++i) {
188                 _peak_power[i] = -std::numeric_limits<float>::infinity();
189                 _max_peak_signal[n] = 0;
190         }
191
192         if (_bufcnt > zoh) {
193                 _bufcnt = 0;
194         }
195
196         _active = _pending_active;
197 }
198
199 void
200 PeakMeter::reset ()
201 {
202         if (_active || _pending_active) {
203                 _reset_dpm = true;
204         } else {
205                 for (size_t i = 0; i < _peak_power.size(); ++i) {
206                         _peak_power[i] = -std::numeric_limits<float>::infinity();
207                         _peak_buffer[i] = 0;
208                 }
209                 const uint32_t n_midi = min (current_meters.n_midi(), (uint32_t)_peak_power.size());
210                 for (size_t i = 0; i < n_midi; ++i) {
211                         _peak_power[i] = 0;
212                 }
213         }
214
215         // these are handled async just fine.
216         for (size_t n = 0; n < _kmeter.size(); ++n) {
217                 _kmeter[n]->reset();
218                 _iec1meter[n]->reset();
219                 _iec2meter[n]->reset();
220                 _vumeter[n]->reset();
221         }
222 }
223
224 void
225 PeakMeter::reset_max ()
226 {
227         if (_active || _pending_active) {
228                 _reset_max = true;
229                 return;
230         }
231         for (size_t i = 0; i < _max_peak_signal.size(); ++i) {
232                 _max_peak_signal[i] = 0;
233                 _peak_buffer[i] = 0;
234         }
235 }
236
237 bool
238 PeakMeter::can_support_io_configuration (const ChanCount& in, ChanCount& out)
239 {
240         out = in;
241         return true;
242 }
243
244 bool
245 PeakMeter::configure_io (ChanCount in, ChanCount out)
246 {
247         bool changed = false;
248         if (out != in) { // always 1:1
249                 return false;
250         }
251
252         if (current_meters != in) {
253                 changed = true;
254         }
255
256         current_meters = in;
257
258         set_max_channels (in);
259
260         if (changed) {
261                 reset_max();
262         }
263
264         return Processor::configure_io (in, out);
265 }
266
267 void
268 PeakMeter::reflect_inputs (const ChanCount& in)
269 {
270         reset();
271         current_meters = in;
272         reset_max();
273         // ConfigurationChanged() postponed
274 }
275
276 void
277 PeakMeter::emit_configuration_changed () {
278         ConfigurationChanged (current_meters, current_meters); /* EMIT SIGNAL */
279 }
280
281 void
282 PeakMeter::set_max_channels (const ChanCount& chn)
283 {
284         uint32_t const limit = chn.n_total();
285         const size_t n_audio = chn.n_audio();
286
287         while (_peak_power.size() > limit) {
288                 _peak_buffer.pop_back();
289                 _peak_power.pop_back();
290                 _max_peak_signal.pop_back();
291         }
292
293         while (_peak_power.size() < limit) {
294                 _peak_buffer.push_back(0);
295                 if (_peak_power.size() < current_meters.n_midi()) {
296                         _peak_power.push_back(0);
297                 } else {
298                         _peak_power.push_back(-std::numeric_limits<float>::infinity());
299                 }
300                 _max_peak_signal.push_back(0);
301         }
302
303         assert(_peak_buffer.size() == limit);
304         assert(_peak_power.size() == limit);
305         assert(_max_peak_signal.size() == limit);
306
307         /* alloc/free other audio-only meter types. */
308         while (_kmeter.size() > n_audio) {
309                 delete (_kmeter.back());
310                 delete (_iec1meter.back());
311                 delete (_iec2meter.back());
312                 delete (_vumeter.back());
313                 _kmeter.pop_back();
314                 _iec1meter.pop_back();
315                 _iec2meter.pop_back();
316                 _vumeter.pop_back();
317         }
318         while (_kmeter.size() < n_audio) {
319                 _kmeter.push_back(new Kmeterdsp());
320                 _iec1meter.push_back(new Iec1ppmdsp());
321                 _iec2meter.push_back(new Iec2ppmdsp());
322                 _vumeter.push_back(new Vumeterdsp());
323         }
324         assert(_kmeter.size() == n_audio);
325         assert(_iec1meter.size() == n_audio);
326         assert(_iec2meter.size() == n_audio);
327         assert(_vumeter.size() == n_audio);
328
329         reset();
330         reset_max();
331 }
332
333 /** To be driven by the Meter signal from IO.
334  * Caller MUST hold its own processor_lock to prevent reconfiguration
335  * of meter size during this call.
336  */
337
338 #define CHECKSIZE(MTR) (n < MTR.size() + n_midi && n >= n_midi)
339
340 float
341 PeakMeter::meter_level(uint32_t n, MeterType type) {
342         float mcptmp;
343         switch (type) {
344                 case MeterKrms:
345                 case MeterK20:
346                 case MeterK14:
347                 case MeterK12:
348                         {
349                                 const uint32_t n_midi = current_meters.n_midi();
350                                 if (CHECKSIZE(_kmeter)) {
351                                         return accurate_coefficient_to_dB (_kmeter[n - n_midi]->read());
352                                 }
353                         }
354                         break;
355                 case MeterIEC1DIN:
356                 case MeterIEC1NOR:
357                         {
358                                 const uint32_t n_midi = current_meters.n_midi();
359                                 if (CHECKSIZE(_iec1meter)) {
360                                         return accurate_coefficient_to_dB (_iec1meter[n - n_midi]->read());
361                                 }
362                         }
363                         break;
364                 case MeterIEC2BBC:
365                 case MeterIEC2EBU:
366                         {
367                                 const uint32_t n_midi = current_meters.n_midi();
368                                 if (CHECKSIZE(_iec2meter)) {
369                                         return accurate_coefficient_to_dB (_iec2meter[n - n_midi]->read());
370                                 }
371                         }
372                         break;
373                 case MeterVU:
374                         {
375                                 const uint32_t n_midi = current_meters.n_midi();
376                                 if (CHECKSIZE(_vumeter)) {
377                                         return accurate_coefficient_to_dB (_vumeter[n - n_midi]->read());
378                                 }
379                         }
380                         break;
381                 case MeterPeak:
382                 case MeterPeak0dB:
383                         if (n < _peak_power.size()) {
384                                 return _peak_power[n];
385                         }
386                         break;
387                 case MeterMCP:
388                         mcptmp = _combined_peak;
389                         return accurate_coefficient_to_dB(mcptmp);
390                 case MeterMaxSignal:
391                         assert(0);
392                         break;
393                 default:
394                 case MeterMaxPeak:
395                         if (n < _max_peak_signal.size()) {
396                                 return accurate_coefficient_to_dB(_max_peak_signal[n]);
397                         }
398                         break;
399         }
400         return minus_infinity();
401 }
402
403 void
404 PeakMeter::set_type(MeterType t)
405 {
406         if (t == _meter_type) {
407                 return;
408         }
409
410         _meter_type = t;
411
412         if (t & (MeterKrms | MeterK20 | MeterK14 | MeterK12)) {
413                 const size_t n_audio = current_meters.n_audio();
414                 for (size_t n = 0; n < n_audio; ++n) {
415                         _kmeter[n]->reset();
416                 }
417         }
418         if (t & (MeterIEC1DIN | MeterIEC1NOR)) {
419                 const size_t n_audio = current_meters.n_audio();
420                 for (size_t n = 0; n < n_audio; ++n) {
421                         _iec1meter[n]->reset();
422                 }
423         }
424         if (t & (MeterIEC2BBC | MeterIEC2EBU)) {
425                 const size_t n_audio = current_meters.n_audio();
426                 for (size_t n = 0; n < n_audio; ++n) {
427                         _iec2meter[n]->reset();
428                 }
429         }
430         if (t & MeterVU) {
431                 const size_t n_audio = current_meters.n_audio();
432                 for (size_t n = 0; n < n_audio; ++n) {
433                         _vumeter[n]->reset();
434                 }
435         }
436
437         TypeChanged(t);
438 }
439
440 XMLNode&
441 PeakMeter::state ()
442 {
443         XMLNode& node (Processor::state ());
444         node.set_property("type", "meter");
445         return node;
446 }