ardour
send.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2000 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #include <iostream>
21 #include <algorithm>
22 
23 #include "pbd/xml++.h"
24 #include "pbd/boost_debug.h"
25 
26 #include "ardour/amp.h"
27 #include "ardour/buffer_set.h"
28 #include "ardour/debug.h"
29 #include "ardour/io.h"
30 #include "ardour/meter.h"
31 #include "ardour/panner_shell.h"
32 #include "ardour/send.h"
33 #include "ardour/session.h"
34 
35 #include "i18n.h"
36 
37 namespace ARDOUR {
38 class AutomationControl;
39 class MuteMaster;
40 class Pannable;
41 }
42 
43 using namespace ARDOUR;
44 using namespace PBD;
45 using namespace std;
46 
47 string
48 Send::name_and_id_new_send (Session& s, Role r, uint32_t& bitslot, bool ignore_bitslot)
49 {
50  if (ignore_bitslot) {
51  /* this happens during initial construction of sends from XML,
52  before they get ::set_state() called. lets not worry about
53  it.
54  */
55  bitslot = 0;
56  return string ();
57  }
58 
59  switch (r) {
60  case Delivery::Aux:
61  return string_compose (_("aux %1"), (bitslot = s.next_aux_send_id ()) + 1);
62  case Delivery::Listen:
63  return _("listen"); // no ports, no need for numbering
64  case Delivery::Send:
65  return string_compose (_("send %1"), (bitslot = s.next_send_id ()) + 1);
66  default:
67  fatal << string_compose (_("programming error: send created using role %1"), enum_2_string (r)) << endmsg;
68  abort(); /*NOTREACHED*/
69  return string();
70  }
71 
72 }
73 
75  : Delivery (s, p, mm, name_and_id_new_send (s, r, _bitslot, ignore_bitslot), r)
76  , _metering (false)
77  , _delay_in (0)
78  , _delay_out (0)
79 {
80  if (_role == Listen) {
81  /* we don't need to do this but it keeps things looking clean
82  in a debugger. _bitslot is not used by listen sends.
83  */
84  _bitslot = 0;
85  }
86 
87  //boost_debug_shared_ptr_mark_interesting (this, "send");
88 
89  _amp.reset (new Amp (_session));
90  _meter.reset (new PeakMeter (_session, name()));
91 
92  _delayline.reset (new DelayLine (_session, name()));
93 
94  add_control (_amp->gain_control ());
95 
96  if (panner_shell()) {
97  panner_shell()->Changed.connect_same_thread (*this, boost::bind (&Send::panshell_changed, this));
98  }
99 }
100 
102 {
104 }
105 
106 void
108 {
109  _amp->activate ();
110  _meter->activate ();
111 
113 }
114 
115 void
117 {
118  _amp->deactivate ();
119  _meter->deactivate ();
120  _meter->reset ();
121 
123 }
124 
125 void
127 {
128  if (!_delayline) return;
129  if (_delay_in == delay) {
130  return;
131  }
132  _delay_in = delay;
133 
135  string_compose ("Send::set_delay_in(%1) + %2 = %3\n",
136  delay, _delay_out, _delay_out + _delay_in));
137  _delayline.get()->set_delay(_delay_out + _delay_in);
138 }
139 
140 void
142 {
143  if (!_delayline) return;
144  if (_delay_out == delay) {
145  return;
146  }
147  _delay_out = delay;
149  string_compose ("Send::set_delay_out(%1) + %2 = %3\n",
150  delay, _delay_in, _delay_out + _delay_in));
151  _delayline.get()->set_delay(_delay_out + _delay_in);
152 }
153 
154 void
155 Send::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
156 {
157  if (_output->n_ports() == ChanCount::ZERO) {
158  _meter->reset ();
160  return;
161  }
162 
163  if (!_active && !_pending_active) {
164  _meter->reset ();
165  _output->silence (nframes);
167  return;
168  }
169 
170  // we have to copy the input, because deliver_output() may alter the buffers
171  // in-place, which a send must never do.
172 
173  BufferSet& sendbufs = _session.get_mix_buffers (bufs.count());
174  sendbufs.read_from (bufs, nframes);
175  assert(sendbufs.count() == bufs.count());
176 
177  /* gain control */
178 
179  _amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
180  _amp->setup_gain_automation (start_frame, end_frame, nframes);
181  _amp->run (sendbufs, start_frame, end_frame, nframes, true);
182 
183  _delayline->run (sendbufs, start_frame, end_frame, nframes, true);
184 
185  /* deliver to outputs */
186 
187  Delivery::run (sendbufs, start_frame, end_frame, nframes, true);
188 
189  /* consider metering */
190 
191  if (_metering) {
192  if (_amp->gain_control()->get_value() == 0) {
193  _meter->reset();
194  } else {
195  _meter->run (*_output_buffers, start_frame, end_frame, nframes, true);
196  }
197  }
198 
199  /* _active was set to _pending_active by Delivery::run() */
200 }
201 
202 XMLNode&
204 {
205  return state (true);
206 }
207 
208 XMLNode&
209 Send::state (bool full)
210 {
211  XMLNode& node = Delivery::state(full);
212  char buf[32];
213 
214  node.add_property ("type", "send");
215  snprintf (buf, sizeof (buf), "%" PRIu32, _bitslot);
216 
217  if (_role != Listen) {
218  node.add_property ("bitslot", buf);
219  }
220 
221  node.add_child_nocopy (_amp->state (full));
222 
223  return node;
224 }
225 
226 int
227 Send::set_state (const XMLNode& node, int version)
228 {
229  if (version < 3000) {
230  return set_state_2X (node, version);
231  }
232 
233  const XMLProperty* prop;
234 
235  Delivery::set_state (node, version);
236 
237  if (node.property ("ignore-bitslot") == 0) {
238 
239  /* don't try to reset bitslot if there is a node for it already: this can cause
240  issues with the session's accounting of send ID's
241  */
242 
243  if ((prop = node.property ("bitslot")) == 0) {
244  if (_role == Delivery::Aux) {
246  } else if (_role == Delivery::Send) {
248  } else {
249  // bitslot doesn't matter but make it zero anyway
250  _bitslot = 0;
251  }
252  } else {
253  if (_role == Delivery::Aux) {
255  sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
257  } else if (_role == Delivery::Send) {
259  sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
261  } else {
262  // bitslot doesn't matter but make it zero anyway
263  _bitslot = 0;
264  }
265  }
266  }
267 
268  XMLNodeList nlist = node.children();
269  for (XMLNodeIterator i = nlist.begin(); i != nlist.end(); ++i) {
270  if ((*i)->name() == X_("Processor")) {
271  _amp->set_state (**i, version);
272  }
273  }
274 
275  return 0;
276 }
277 
278 int
279 Send::set_state_2X (const XMLNode& node, int /* version */)
280 {
281  /* use the IO's name for the name of the send */
282  XMLNodeList const & children = node.children ();
283 
284  XMLNodeList::const_iterator i = children.begin();
285  while (i != children.end() && (*i)->name() != X_("Redirect")) {
286  ++i;
287  }
288 
289  if (i == children.end()) {
290  return -1;
291  }
292 
293  XMLNodeList const & grand_children = (*i)->children ();
294  XMLNodeList::const_iterator j = grand_children.begin ();
295  while (j != grand_children.end() && (*j)->name() != X_("IO")) {
296  ++j;
297  }
298 
299  if (j == grand_children.end()) {
300  return -1;
301  }
302 
303  XMLProperty const * prop = (*j)->property (X_("name"));
304  if (!prop) {
305  return -1;
306  }
307 
308  set_name (prop->value ());
309 
310  return 0;
311 }
312 
313 bool
315 {
316  /* sends have no impact at all on the channel configuration of the
317  streams passing through the route. so, out == in.
318  */
319 
320  out = in;
321  return true;
322 }
323 
325 bool
327 {
328  if (!_amp->configure_io (in, out)) {
329  return false;
330  }
331 
332  if (!Processor::configure_io (in, out)) {
333  return false;
334  }
335 
336  if (!_meter->configure_io (ChanCount (DataType::AUDIO, pan_outs()), ChanCount (DataType::AUDIO, pan_outs()))) {
337  return false;
338  }
339 
340  if (_delayline && !_delayline->configure_io(in, out)) {
341  cerr << "send delayline config failed\n";
342  return false;
343  }
344 
345  reset_panner ();
346 
347  return true;
348 }
349 
350 void
352 {
354 }
355 
356 bool
357 Send::set_name (const string& new_name)
358 {
359  string unique_name;
360 
361  if (_role == Delivery::Send) {
362  char buf[32];
363 
364  /* rip any existing numeric part of the name, and append the bitslot
365  */
366 
367  string::size_type last_letter = new_name.find_last_not_of ("0123456789");
368 
369  if (last_letter != string::npos) {
370  unique_name = new_name.substr (0, last_letter + 1);
371  } else {
372  unique_name = new_name;
373  }
374 
375  snprintf (buf, sizeof (buf), "%u", (_bitslot + 1));
376  unique_name += buf;
377 
378  } else {
379  unique_name = new_name;
380  }
381 
382  return Delivery::set_name (unique_name);
383 }
384 
385 bool
387 {
388  /* we ignore Deliver::_display_to_user */
389 
390  if (_role == Listen) {
391  /* don't make the monitor/control/listen send visible */
392  return false;
393  }
394 
395  return true;
396 }
397 
398 string
400 {
401  return _amp->value_as_string (ac);
402 }
403 
404 
uint32_t next_send_id()
Definition: session.cc:4381
int set_state(const XMLNode &, int version)
Definition: delivery.cc:345
XMLNodeList::iterator XMLNodeIterator
Definition: xml++.h:48
ARDOUR::Session & _session
LIBPBD_API Transmitter fatal
bool display_to_user() const
Definition: send.cc:386
void set_delay_out(framecnt_t)
Definition: send.cc:141
void run(BufferSet &bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
Definition: delivery.cc:232
void activate()
Definition: send.cc:107
void unmark_aux_send_id(uint32_t)
Definition: session.cc:4497
const std::string & value() const
Definition: xml++.h:159
XMLNode & get_state()
Definition: send.cc:203
#define enum_2_string(e)
Definition: enumwriter.h:97
XMLNode & state(bool full)
Definition: delivery.cc:320
void reset_panner()
Definition: delivery.cc:395
boost::shared_ptr< PeakMeter > _meter
Definition: send.h:82
XMLNode & state(bool full)
Definition: send.cc:209
framecnt_t _delay_in
Definition: send.h:94
int set_state(const XMLNode &, int version)
Definition: send.cc:227
uint32_t pframes_t
Definition: types.h:61
Definition: Beats.hpp:239
void run(BufferSet &bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
Definition: send.cc:155
const XMLNodeList & children(const std::string &str=std::string()) const
Definition: xml++.cc:329
uint32_t _bitslot
Definition: send.h:92
bool _metering
Definition: send.h:80
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
void read_from(const BufferSet &in, framecnt_t nframes)
Definition: buffer_set.cc:434
void deactivate()
Definition: send.cc:116
boost::shared_ptr< IO > _output
Definition: io_processor.h:84
virtual void add_control(boost::shared_ptr< Evoral::Control >)
Definition: automatable.cc:138
std::list< XMLNode * > XMLNodeList
Definition: xml++.h:44
#define _(Text)
Definition: i18n.h:11
void unmark_send_id(uint32_t)
Definition: session.cc:4489
virtual void deactivate()
Definition: processor.h:80
bool configure_io(ChanCount in, ChanCount out)
Definition: send.cc:326
virtual ~Send()
Definition: send.cc:101
virtual uint32_t pan_outs() const
Definition: delivery.cc:385
static std::string name_and_id_new_send(Session &, Delivery::Role r, uint32_t &, bool)
Definition: send.cc:48
#define X_(Text)
Definition: i18n.h:13
int64_t framecnt_t
Definition: types.h:76
XMLProperty * property(const char *)
Definition: xml++.cc:413
uint32_t next_aux_send_id()
Definition: session.cc:4401
Definition: amp.h:29
gain_t * send_gain_automation_buffer() const
Definition: session.cc:4833
bool set_name(const std::string &str)
Definition: send.cc:357
framecnt_t _delay_out
Definition: send.h:95
virtual bool configure_io(ChanCount in, ChanCount out)
Definition: processor.cc:246
void mark_send_id(uint32_t)
Definition: session.cc:4441
boost::shared_ptr< Amp > _amp
Definition: send.h:81
#define DEBUG_TRACE(bits, str)
Definition: debug.h:55
int64_t framepos_t
Definition: types.h:66
bool set_name(const std::string &name)
Definition: delivery.cc:555
boost::shared_ptr< DelayLine > _delayline
Definition: send.h:83
XMLProperty * add_property(const char *name, const std::string &value)
void set_delay_in(framecnt_t)
Definition: send.cc:126
void add_child_nocopy(XMLNode &)
Definition: xml++.cc:357
Send(Session &, boost::shared_ptr< Pannable > pannable, boost::shared_ptr< MuteMaster >, Delivery::Role r=Delivery::Send, bool ignore_bitslot=false)
Definition: send.cc:74
BufferSet * _output_buffers
Definition: delivery.h:108
Definition: xml++.h:95
int set_state_2X(XMLNode const &, int)
Definition: send.cc:279
std::string name() const
const ChanCount & count() const
Definition: buffer_set.h:87
Definition: debug.h:30
virtual void activate()
Definition: processor.h:79
LIBARDOUR_API uint64_t LatencyCompensation
Definition: debug.cc:33
std::string value_as_string(boost::shared_ptr< AutomationControl >) const
Definition: send.cc:399
void panshell_changed()
Definition: send.cc:351
static const ChanCount ZERO
Definition: chan_count.h:149
boost::shared_ptr< PannerShell > panner_shell() const
Definition: delivery.h:95
BufferSet & get_mix_buffers(ChanCount count=ChanCount::ZERO)
Definition: session.cc:4864
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
void mark_aux_send_id(uint32_t)
Definition: session.cc:4453
bool can_support_io_configuration(const ChanCount &in, ChanCount &out)
Definition: send.cc:314