2 Copyright (C) 2006 Paul Davis
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)
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
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.
19 #include "ardour/meter.h"
22 #include "ardour/buffer_set.h"
23 #include "ardour/peak.h"
24 #include "ardour/dB.h"
25 #include "ardour/session.h"
26 #include "ardour/midi_buffer.h"
27 #include "ardour/audio_buffer.h"
28 #include "ardour/runtime_functions.h"
32 using namespace ARDOUR
;
34 PBD::Signal0
<void> Metering::Meter
;
36 /** Get peaks from @a bufs
37 * Input acceptance is lenient - the first n buffers from @a bufs will
38 * be metered, where n was set by the last call to setup(), excess meters will
42 PeakMeter::run (BufferSet
& bufs
, framepos_t
/*start_frame*/, framepos_t
/*end_frame*/, pframes_t nframes
, bool)
44 if (!_active
&& !_pending_active
) {
48 // cerr << "meter " << name() << " runs with " << bufs.available() << " inputs\n";
50 const uint32_t n_audio
= min (current_meters
.n_audio(), bufs
.count().n_audio());
51 const uint32_t n_midi
= min (current_meters
.n_midi(), bufs
.count().n_midi());
55 // Meter MIDI in to the first n_midi peaks
56 for (uint32_t i
= 0; i
< n_midi
; ++i
, ++n
) {
58 for (MidiBuffer::iterator e
= bufs
.get_midi(i
).begin(); e
!= bufs
.get_midi(i
).end(); ++e
) {
59 const Evoral::MIDIEvent
<framepos_t
> ev(*e
, false);
60 if (ev
.is_note_on()) {
61 const float this_vel
= log(ev
.buffer()[2] / 127.0 * (M_E
*M_E
-M_E
) + M_E
) - 1.0;
66 val
+= 1.0 / bufs
.get_midi(n
).capacity();
72 _peak_power
[n
] = max (val
, _peak_power
[n
]);
75 // Meter audio in to the rest of the peaks
76 for (uint32_t i
= 0; i
< n_audio
; ++i
, ++n
) {
77 _peak_power
[n
] = compute_peak (bufs
.get_audio(i
).data(), nframes
, _peak_power
[n
]);
80 // Zero any excess peaks
81 for (uint32_t i
= n
; i
< _peak_power
.size(); ++i
) {
82 _peak_power
[i
] = 0.0f
;
85 _active
= _pending_active
;
91 for (size_t i
= 0; i
< _peak_power
.size(); ++i
) {
92 _peak_power
[i
] = 0.0f
;
97 PeakMeter::reset_max ()
99 for (size_t i
= 0; i
< _max_peak_power
.size(); ++i
) {
100 _max_peak_power
[i
] = -INFINITY
;
105 PeakMeter::can_support_io_configuration (const ChanCount
& in
, ChanCount
& out
) const
112 PeakMeter::configure_io (ChanCount in
, ChanCount out
)
114 if (out
!= in
) { // always 1:1
120 reset_max_channels (in
);
122 return Processor::configure_io (in
, out
);
126 PeakMeter::reflect_inputs (const ChanCount
& in
)
132 PeakMeter::reset_max_channels (const ChanCount
& chn
)
134 uint32_t const limit
= chn
.n_total();
136 while (_peak_power
.size() > limit
) {
137 _peak_power
.pop_back();
138 _visible_peak_power
.pop_back();
139 _max_peak_power
.pop_back();
142 while (_peak_power
.size() < limit
) {
143 _peak_power
.push_back(0);
144 _visible_peak_power
.push_back(minus_infinity());
145 _max_peak_power
.push_back(minus_infinity());
148 assert(_peak_power
.size() == limit
);
149 assert(_visible_peak_power
.size() == limit
);
150 assert(_max_peak_power
.size() == limit
);
153 /** To be driven by the Meter signal from IO.
154 * Caller MUST hold its own processor_lock to prevent reconfiguration
155 * of meter size during this call.
165 assert(_visible_peak_power
.size() == _peak_power
.size());
167 const size_t limit
= min (_peak_power
.size(), (size_t) current_meters
.n_total ());
169 for (size_t n
= 0; n
< limit
; ++n
) {
171 /* grab peak since last read */
173 float new_peak
= _peak_power
[n
]; /* XXX we should use atomic exchange from here ... */
174 _peak_power
[n
] = 0; /* ... to here */
176 /* compute new visible value using falloff */
178 if (new_peak
> 0.0) {
179 new_peak
= fast_coefficient_to_dB (new_peak
);
181 new_peak
= minus_infinity();
184 /* update max peak */
186 _max_peak_power
[n
] = std::max (new_peak
, _max_peak_power
[n
]);
188 if (Config
->get_meter_falloff() == 0.0f
|| new_peak
> _visible_peak_power
[n
]) {
189 _visible_peak_power
[n
] = new_peak
;
192 new_peak
= _visible_peak_power
[n
] - (Config
->get_meter_falloff() * 0.01f
);
193 _visible_peak_power
[n
] = std::max (new_peak
, -INFINITY
);
199 PeakMeter::state (bool full_state
)
201 XMLNode
& node (Processor::state (full_state
));
202 node
.add_property("type", "meter");