carl's wondrous DnD VBox patch - processor boxes are now vboxes and not listviews...
[ardour.git] / libs / ardour / send.cc
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
25 #include "ardour/amp.h"
26 #include "ardour/send.h"
27 #include "ardour/session.h"
28 #include "ardour/port.h"
29 #include "ardour/audio_port.h"
30 #include "ardour/buffer_set.h"
31 #include "ardour/meter.h"
32 #include "ardour/panner.h"
33 #include "ardour/io.h"
34
35 #include "i18n.h"
36
37 using namespace ARDOUR;
38 using namespace PBD;
39 using namespace std;
40
41 Send::Send (Session& s, boost::shared_ptr<MuteMaster> mm, Role r)
42         : Delivery (s, mm, string_compose (_("send %1"), (_bitslot = s.next_send_id()) + 1), r)
43         , _metering (false)
44 {
45         _amp.reset (new Amp (_session, _mute_master));
46         _meter.reset (new PeakMeter (_session));
47
48         ProcessorCreated (this); /* EMIT SIGNAL */
49 }
50
51 Send::Send (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode& node, int version, Role r)
52         : Delivery (s, mm, "send", r)
53         , _metering (false)
54 {
55         _amp.reset (new Amp (_session, _mute_master));
56         _meter.reset (new PeakMeter (_session));
57
58         if (set_state (node, version)) {
59                 throw failed_constructor();
60         }
61
62         ProcessorCreated (this); /* EMIT SIGNAL */
63 }
64
65 Send::~Send ()
66 {
67         GoingAway ();
68 }
69
70 void
71 Send::activate ()
72 {
73         _amp->activate ();
74         _meter->activate ();
75
76         Processor::activate ();
77 }
78
79 void
80 Send::deactivate ()
81 {
82         _amp->deactivate ();
83         _meter->deactivate ();
84         _meter->reset ();
85         
86         Processor::deactivate ();
87 }
88
89 void
90 Send::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes)
91 {
92         if (_output->n_ports() == ChanCount::ZERO) {
93                 _meter->reset ();
94                 _active = _pending_active;
95                 return;
96         }
97
98         if (!_active && !_pending_active) {
99                 _meter->reset ();
100                 _output->silence (nframes);
101                 _active = _pending_active;
102                 return;
103         }
104
105         // we have to copy the input, because deliver_output() may alter the buffers
106         // in-place, which a send must never do.
107
108         BufferSet& sendbufs = _session.get_mix_buffers (bufs.count());
109         sendbufs.read_from (bufs, nframes);
110         assert(sendbufs.count() == bufs.count());
111
112         /* gain control */
113
114         // Can't automate gain for sends or returns yet because we need different buffers
115         // so that we don't overwrite the main automation data for the route amp
116         // _amp->setup_gain_automation (start_frame, end_frame, nframes);
117         _amp->run (sendbufs, start_frame, end_frame, nframes);
118
119         /* deliver to outputs */
120
121         Delivery::run (sendbufs, start_frame, end_frame, nframes);
122
123         /* consider metering */
124
125         if (_metering) {
126                 if (_amp->gain_control()->get_value() == 0) {
127                         _meter->reset();
128                 } else {
129                         _meter->run (*_output_buffers, start_frame, end_frame, nframes);
130                 }
131         }
132
133         /* _active was set to _pending_active by Delivery::run() */
134 }
135
136 XMLNode&
137 Send::get_state(void)
138 {
139         return state (true);
140 }
141
142 XMLNode&
143 Send::state(bool full)
144 {
145         XMLNode& node = Delivery::state(full);
146         char buf[32];
147
148         node.add_property ("type", "send");
149         snprintf (buf, sizeof (buf), "%" PRIu32, _bitslot);
150         node.add_property ("bitslot", buf);
151
152         return node;
153 }
154
155 int
156 Send::set_state (const XMLNode& node, int version)
157 {
158         XMLNodeList nlist = node.children();
159         XMLNodeIterator niter;
160         const XMLProperty* prop;
161
162         if ((prop = node.property ("bitslot")) == 0) {
163                 _bitslot = _session.next_send_id();
164         } else {
165                 sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
166                 cerr << this << " scanned " << prop->value() << " to get " << _bitslot << endl;
167                 _session.mark_send_id (_bitslot);
168         }
169
170         const XMLNode* insert_node = &node;
171
172         /* XXX need to load automation state & data for amp */
173
174         Delivery::set_state (*insert_node, version);
175
176         return 0;
177 }
178
179 bool
180 Send::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
181 {
182         /* sends have no impact at all on the channel configuration of the
183            streams passing through the route. so, out == in.
184         */
185
186         out = in;
187         return true;
188 }
189
190 bool
191 Send::configure_io (ChanCount in, ChanCount out)
192 {
193         if (!_amp->configure_io (in, out) || !_meter->configure_io (in, out)) {
194                 return false;
195         }
196
197         if (!Processor::configure_io (in, out)) {
198                 return false;
199         }
200
201         reset_panner ();
202
203         return true;
204 }
205
206 /** Set up the XML description of a send so that its name is unique.
207  *  @param state XML send state.
208  *  @param session Session.
209  */
210 void
211 Send::make_unique (XMLNode &state, Session &session)
212 {
213         uint32_t const bitslot = session.next_send_id() + 1;
214
215         char buf[32];
216         snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
217         state.property("bitslot")->set_value (buf);
218
219         string const name = string_compose (_("send %1"), bitslot);
220
221         state.property("name")->set_value (name);
222
223         XMLNode* io = state.child ("IO");
224
225         if (io) {
226                 io->property("name")->set_value (name);
227         }
228 }
229
230 bool
231 Send::set_name (const string& new_name)
232 {
233         string unique_name;
234
235         if (_role == Delivery::Send) {
236                 char buf[32];
237
238                 /* rip any existing numeric part of the name, and append the bitslot
239                  */
240
241                 string::size_type last_letter = new_name.find_last_not_of ("0123456789");
242
243                 if (last_letter != string::npos) {
244                         unique_name = new_name.substr (0, last_letter + 1);
245                 } else {
246                         unique_name = new_name;
247                 }
248
249                 snprintf (buf, sizeof (buf), "%u", (_bitslot + 1));
250                 unique_name += buf;
251
252         } else {
253                 unique_name = new_name;
254         }
255
256         return Delivery::set_name (unique_name);
257 }
258
259 bool
260 Send::display_to_user () const
261 {
262         /* we ignore Deliver::_display_to_user */
263
264         if (_role == Listen) {
265                 return false;
266         }
267
268         return true;
269 }