force AFL monitor/listen send to be at the very end of the Route processor list;...
[ardour.git] / libs / ardour / monitor_processor.cc
1 #include "pbd/convert.h"
2 #include "pbd/error.h"
3 #include "pbd/xml++.h"
4
5 #include "ardour/amp.h"
6 #include "ardour/dB.h"
7 #include "ardour/debug.h"
8 #include "ardour/audio_buffer.h"
9 #include "ardour/monitor_processor.h"
10 #include "ardour/session.h"
11
12 #include "i18n.h"
13
14 using namespace ARDOUR;
15 using namespace PBD;
16 using namespace std;
17
18 MonitorProcessor::MonitorProcessor (Session& s)
19         : Processor (s, X_("MonitorOut"))
20 {
21         solo_cnt = 0;
22         _cut_all = false;
23         _dim_all = false;
24         _dim_level = 0.2;
25         _solo_boost_level = 1.0;
26 }
27
28 MonitorProcessor::MonitorProcessor (Session& s, const XMLNode& node)
29         : Processor (s, node)
30 {
31         set_state (node, Stateful::loading_state_version);
32 }
33
34 void
35 MonitorProcessor::allocate_channels (uint32_t size)
36 {
37         while (_channels.size() > size) {
38                 if (_channels.back().soloed) {
39                         if (solo_cnt > 0) {
40                                 --solo_cnt;
41                         }
42                 }
43                 _channels.pop_back();
44         }
45
46         while (_channels.size() < size) {
47                 _channels.push_back (ChannelRecord());
48         }
49 }
50
51 int
52 MonitorProcessor::set_state (const XMLNode& node, int version)
53 {
54         int ret = Processor::set_state (node, version);
55
56         if (ret != 0) {
57                 return ret;
58         }
59
60         const XMLProperty* prop;
61
62         if ((prop = node.property (X_("type"))) == 0) {
63                 error << string_compose (X_("programming error: %1"), X_("MonitorProcessor XML settings have no type information"))
64                       << endmsg;
65                 return -1;
66         }
67
68         if (prop->value() != X_("monitor")) {
69                 error << string_compose (X_("programming error: %1"), X_("MonitorProcessor given unknown XML settings"))
70                       << endmsg;
71                 return -1;
72         }
73
74         if ((prop = node.property (X_("channels"))) == 0) {
75                 error << string_compose (X_("programming error: %1"), X_("MonitorProcessor XML settings are missing a channel cnt"))
76                       << endmsg;
77                 return -1;
78         }
79         
80         allocate_channels (atoi (prop->value()));
81
82         if ((prop = node.property (X_("dim-level"))) != 0) {
83                 double val = atof (prop->value());
84                 _dim_level = val;
85         }
86
87         if ((prop = node.property (X_("solo-boost-level"))) != 0) {
88                 double val = atof (prop->value());
89                 _solo_boost_level = val;
90         }
91
92         if ((prop = node.property (X_("cut-all"))) != 0) {
93                 bool val = string_is_affirmative (prop->value());
94                 _cut_all = val;
95         }
96         if ((prop = node.property (X_("dim-all"))) != 0) {
97                 bool val = string_is_affirmative (prop->value());
98                 _dim_all = val;
99         }
100         if ((prop = node.property (X_("mono"))) != 0) {
101                 bool val = string_is_affirmative (prop->value());
102                 _mono = val;
103         }
104
105         for (XMLNodeList::const_iterator i = node.children().begin(); i != node.children().end(); ++i) {
106
107                 if ((*i)->name() == X_("Channel")) {
108                         if ((prop = (*i)->property (X_("id"))) == 0) {
109                                 error << string_compose (X_("programming error: %1"), X_("MonitorProcessor XML settings are missing an ID"))
110                                       << endmsg;
111                                 return -1;
112                         }
113
114                         uint32_t chn;
115
116                         if (sscanf (prop->value().c_str(), "%u", &chn) != 1) {
117                                 error << string_compose (X_("programming error: %1"), X_("MonitorProcessor XML settings has an unreadable channel ID"))
118                                       << endmsg;
119                                 return -1;
120                         }
121                         
122                         if (chn >= _channels.size()) {
123                                 error << string_compose (X_("programming error: %1"), X_("MonitorProcessor XML settings has an illegal channel count"))
124                                       << endmsg;
125                                 return -1;
126                         }
127                         ChannelRecord& cr (_channels[chn]);
128
129                         if ((prop = (*i)->property ("cut")) != 0) {
130                                 if (string_is_affirmative (prop->value())){
131                                         cr.cut = 0.0f;
132                                 } else {
133                                         cr.cut = 1.0f;
134                                 }
135                         }
136
137                         if ((prop = (*i)->property ("dim")) != 0) {
138                                 bool val = string_is_affirmative (prop->value());
139                                 cr.dim = val;
140                         }
141
142                         if ((prop = (*i)->property ("invert")) != 0) {
143                                 if (string_is_affirmative (prop->value())) {
144                                         cr.polarity = -1.0f;
145                                 } else {
146                                         cr.polarity = 1.0f;
147                                 }
148                         }
149
150                         if ((prop = (*i)->property ("solo")) != 0) {
151                                 bool val = string_is_affirmative (prop->value());
152                                 cr.soloed = val;
153                         }
154                 }
155         }
156         
157         /* reset solo cnt */
158
159         solo_cnt = 0;
160
161         for (vector<ChannelRecord>::const_iterator x = _channels.begin(); x != _channels.end(); ++x) {
162                 if (x->soloed) {
163                         solo_cnt++;
164                 }
165         }
166         
167         return 0;
168 }
169
170 XMLNode&
171 MonitorProcessor::state (bool full)
172 {
173         XMLNode& node (Processor::state (full));
174         char buf[64];
175
176         /* this replaces any existing "type" property */
177
178         node.add_property (X_("type"), X_("monitor"));
179         
180         snprintf (buf, sizeof(buf), "%.12g", _dim_level);
181         node.add_property (X_("dim-level"), buf);
182
183         snprintf (buf, sizeof(buf), "%.12g", _solo_boost_level);
184         node.add_property (X_("solo-boost-level"), buf);
185
186         node.add_property (X_("cut-all"), (_cut_all ? "yes" : "no"));
187         node.add_property (X_("dim-all"), (_dim_all ? "yes" : "no"));
188         node.add_property (X_("mono"), (_mono ? "yes" : "no"));
189         
190         uint32_t limit = _channels.size();
191
192         snprintf (buf, sizeof (buf), "%u", limit);
193         node.add_property (X_("channels"), buf);
194
195         XMLNode* chn_node;
196         uint32_t chn = 0;
197
198         for (vector<ChannelRecord>::const_iterator x = _channels.begin(); x != _channels.end(); ++x, ++chn) {
199                 chn_node = new XMLNode (X_("Channel"));
200
201                 snprintf (buf, sizeof (buf), "%u", chn);
202                 chn_node->add_property ("id", buf);
203
204                 chn_node->add_property (X_("cut"), x->cut == 1.0 ? "no" : "yes");
205                 chn_node->add_property (X_("invert"), x->polarity == 1.0 ? "no" : "yes");
206                 chn_node->add_property (X_("dim"), x->dim ? "yes" : "no");
207                 chn_node->add_property (X_("solo"), x->soloed ? "yes" : "no");
208                 
209                 node.add_child_nocopy (*chn_node);
210         }
211
212         return node;
213 }
214
215 void
216 MonitorProcessor::run (BufferSet& bufs, sframes_t /*start_frame*/, sframes_t /*end_frame*/, nframes_t nframes, bool /*result_required*/)
217 {
218         uint32_t chn = 0;
219         gain_t target_gain;
220         gain_t dim_level_this_time = _dim_level;
221         gain_t global_cut = (_cut_all ? 0.0f : 1.0f);
222         gain_t global_dim = (_dim_all ? dim_level_this_time : 1.0f);
223         gain_t solo_boost;
224
225         if (_session.listening() || _session.soloing()) {
226                 solo_boost = _solo_boost_level;
227         } else {
228                 solo_boost = 1.0;
229         }
230
231         for (BufferSet::audio_iterator b = bufs.audio_begin(); b != bufs.audio_end(); ++b) {
232
233                 /* don't double-scale by both track dim and global dim coefficients */
234
235                 gain_t dim_level = (global_dim == 1.0 ? (_channels[chn].dim ? dim_level_this_time : 1.0) : 1.0);
236
237                 if (_channels[chn].soloed) {
238                         target_gain = _channels[chn].polarity * _channels[chn].cut * dim_level * global_cut * global_dim * solo_boost;
239                 } else {
240                         if (solo_cnt == 0) {
241                                 target_gain = _channels[chn].polarity * _channels[chn].cut * dim_level * global_cut * global_dim * solo_boost;
242                         } else {
243                                 target_gain = 0.0;
244                         }
245                 }
246
247                 DEBUG_TRACE (DEBUG::Monitor, 
248                              string_compose("channel %1 sb %2 gc %3 gd %4 cd %5 dl %6 cp %7 cc %8 cs %9 sc %10 TG %11\n", 
249                                             chn, 
250                                             solo_boost,
251                                             global_cut,
252                                             global_dim,
253                                             _channels[chn].dim,
254                                             dim_level,
255                                             _channels[chn].polarity,
256                                             _channels[chn].cut,
257                                             _channels[chn].soloed,
258                                             solo_cnt,
259                                             target_gain));
260                 
261                 if (target_gain != _channels[chn].current_gain || target_gain != 1.0f) {
262
263                         Amp::apply_gain (*b, nframes, _channels[chn].current_gain, target_gain);
264                         _channels[chn].current_gain = target_gain;
265                 }
266
267                 ++chn;
268         }
269
270         if (_mono) {
271                 DEBUG_TRACE (DEBUG::Monitor, "mono-izing\n");
272
273                 /* chn is now the number of channels, use as a scaling factor when mixing
274                  */
275                 gain_t scale = 1.0/chn;
276                 BufferSet::audio_iterator b = bufs.audio_begin();
277                 AudioBuffer& ab (*b);
278                 Sample* buf = ab.data();
279
280                 /* scale the first channel */
281
282                 for (nframes_t n = 0; n < nframes; ++n) {
283                         buf[n] *= scale;
284                 }
285
286                 /* add every other channel into the first channel's buffer */
287
288                 ++b;
289                 for (; b != bufs.audio_end(); ++b) {
290                         AudioBuffer& ob (*b);
291                         Sample* obuf = ob.data ();
292                         for (nframes_t n = 0; n < nframes; ++n) {
293                                 buf[n] += obuf[n] * scale;
294                         }
295                 }
296
297                 /* copy the first channel to every other channel's buffer */
298
299                 b = bufs.audio_begin();
300                 ++b;
301                 for (; b != bufs.audio_end(); ++b) {
302                         AudioBuffer& ob (*b);
303                         Sample* obuf = ob.data ();
304                         memcpy (obuf, buf, sizeof (Sample) * nframes);
305                 }
306         }
307 }
308
309 bool
310 MonitorProcessor::configure_io (ChanCount in, ChanCount out)
311 {
312         allocate_channels (in.n_audio());
313         return Processor::configure_io (in, out);
314 }
315
316 bool 
317 MonitorProcessor::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
318 {
319         return in == out;
320 }
321
322 void
323 MonitorProcessor::set_polarity (uint32_t chn, bool invert)
324 {
325         if (invert) {
326                 _channels[chn].polarity = -1.0f;
327         } else {
328                 _channels[chn].polarity = 1.0f;
329         }
330 }       
331
332 void
333 MonitorProcessor::set_dim (uint32_t chn, bool yn)
334 {
335         _channels[chn].dim = yn;
336 }
337
338 void
339 MonitorProcessor::set_cut (uint32_t chn, bool yn)
340 {
341         if (yn) {
342                 _channels[chn].cut = 0.0f;
343         } else {
344                 _channels[chn].cut = 1.0f;
345         }
346 }
347
348 void
349 MonitorProcessor::set_solo (uint32_t chn, bool solo)
350 {
351         if (solo != _channels[chn].soloed) {
352                 _channels[chn].soloed = solo;
353                 
354                 if (solo) {
355                         solo_cnt++;
356                 } else {
357                         if (solo_cnt > 0) {
358                                 solo_cnt--;
359                         }
360                 }
361         }
362 }
363
364 void
365 MonitorProcessor::set_mono (bool yn)
366 {
367         _mono = yn;
368 }
369
370 void
371 MonitorProcessor::set_cut_all (bool yn)
372 {
373         _cut_all = yn;
374 }
375
376 void
377 MonitorProcessor::set_dim_all (bool yn)
378 {
379         _dim_all = yn;
380 }
381
382 bool
383 MonitorProcessor::display_to_user () const
384 {
385         return false;
386 }
387
388 void
389 MonitorProcessor::set_dim_level (gain_t val)
390 {
391         _dim_level = val;
392 }
393
394 void
395 MonitorProcessor::set_solo_boost_level (gain_t val)
396 {
397         _solo_boost_level = val;
398 }
399
400 bool 
401 MonitorProcessor::soloed (uint32_t chn) const
402 {
403         return _channels[chn].soloed;
404 }
405
406
407 bool 
408 MonitorProcessor::inverted (uint32_t chn) const
409 {
410         return _channels[chn].polarity < 0.0f;
411 }
412
413
414 bool 
415 MonitorProcessor::cut (uint32_t chn) const
416 {
417         return _channels[chn].cut == 0.0f;
418 }
419
420 bool 
421 MonitorProcessor::dimmed (uint32_t chn) const
422 {
423         return _channels[chn].dim;
424 }
425
426 bool
427 MonitorProcessor::mono () const
428 {
429         return _mono;
430 }
431
432 bool
433 MonitorProcessor::dim_all () const
434 {
435         return _dim_all;
436 }
437
438 bool
439 MonitorProcessor::cut_all () const
440 {
441         return _cut_all;
442 }