~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to libs/ardour/send.cc

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/send.h"
 
28
#include "ardour/session.h"
 
29
#include "ardour/buffer_set.h"
 
30
#include "ardour/meter.h"
 
31
#include "ardour/io.h"
 
32
 
 
33
#include "i18n.h"
 
34
 
 
35
namespace ARDOUR {
 
36
class AutomationControl;
 
37
class MuteMaster;
 
38
class Pannable;
 
39
}
 
40
 
 
41
using namespace ARDOUR;
 
42
using namespace PBD;
 
43
using namespace std;
 
44
 
 
45
string
 
46
Send::name_and_id_new_send (Session& s, Role r, uint32_t& bitslot)
 
47
{
 
48
        if (r == Role (0)) {
 
49
                /* this happens during initial construction of sends from XML, 
 
50
                   before they get ::set_state() called. lets not worry about
 
51
                   it.
 
52
                */
 
53
                bitslot = 0;
 
54
                return string ();
 
55
        }
 
56
 
 
57
        switch (r) {
 
58
        case Delivery::Aux:
 
59
                return string_compose (_("aux %1"), (bitslot = s.next_aux_send_id ()) + 1);
 
60
        case Delivery::Listen:
 
61
                return _("listen"); // no ports, no need for numbering
 
62
        case Delivery::Send:
 
63
                return string_compose (_("send %1"), (bitslot = s.next_send_id ()) + 1);
 
64
        default:
 
65
                fatal << string_compose (_("programming error: send created using role %1"), enum_2_string (r)) << endmsg;
 
66
                /*NOTREACHED*/
 
67
                return string();
 
68
        }
 
69
        
 
70
}
 
71
 
 
72
Send::Send (Session& s, boost::shared_ptr<Pannable> p, boost::shared_ptr<MuteMaster> mm, Role r)
 
73
        : Delivery (s, p, mm, name_and_id_new_send (s, r, _bitslot), r)
 
74
        , _metering (false)
 
75
{
 
76
        if (_role == Listen) {
 
77
                /* we don't need to do this but it keeps things looking clean
 
78
                   in a debugger. _bitslot is not used by listen sends.
 
79
                */
 
80
                _bitslot = 0;
 
81
        }
 
82
 
 
83
        boost_debug_shared_ptr_mark_interesting (this, "send");
 
84
 
 
85
        _amp.reset (new Amp (_session));
 
86
        _meter.reset (new PeakMeter (_session, name()));
 
87
 
 
88
        add_control (_amp->gain_control ());
 
89
}
 
90
 
 
91
Send::~Send ()
 
92
{
 
93
        _session.unmark_send_id (_bitslot);
 
94
}
 
95
 
 
96
void
 
97
Send::activate ()
 
98
{
 
99
        _amp->activate ();
 
100
        _meter->activate ();
 
101
 
 
102
        Processor::activate ();
 
103
}
 
104
 
 
105
void
 
106
Send::deactivate ()
 
107
{
 
108
        _amp->deactivate ();
 
109
        _meter->deactivate ();
 
110
        _meter->reset ();
 
111
 
 
112
        Processor::deactivate ();
 
113
}
 
114
 
 
115
void
 
116
Send::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
 
117
{
 
118
        if (_output->n_ports() == ChanCount::ZERO) {
 
119
                _meter->reset ();
 
120
                _active = _pending_active;
 
121
                return;
 
122
        }
 
123
 
 
124
        if (!_active && !_pending_active) {
 
125
                _meter->reset ();
 
126
                _output->silence (nframes);
 
127
                _active = _pending_active;
 
128
                return;
 
129
        }
 
130
 
 
131
        // we have to copy the input, because deliver_output() may alter the buffers
 
132
        // in-place, which a send must never do.
 
133
 
 
134
        BufferSet& sendbufs = _session.get_mix_buffers (bufs.count());
 
135
        sendbufs.read_from (bufs, nframes);
 
136
        assert(sendbufs.count() == bufs.count());
 
137
 
 
138
        /* gain control */
 
139
 
 
140
        _amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
 
141
        _amp->setup_gain_automation (start_frame, end_frame, nframes);
 
142
        _amp->run (sendbufs, start_frame, end_frame, nframes, true);
 
143
 
 
144
        /* deliver to outputs */
 
145
 
 
146
        Delivery::run (sendbufs, start_frame, end_frame, nframes, true);
 
147
 
 
148
        /* consider metering */
 
149
 
 
150
        if (_metering) {
 
151
                if (_amp->gain_control()->get_value() == 0) {
 
152
                        _meter->reset();
 
153
                } else {
 
154
                        _meter->run (*_output_buffers, start_frame, end_frame, nframes, true);
 
155
                }
 
156
        }
 
157
 
 
158
        /* _active was set to _pending_active by Delivery::run() */
 
159
}
 
160
 
 
161
XMLNode&
 
162
Send::get_state(void)
 
163
{
 
164
        return state (true);
 
165
}
 
166
 
 
167
XMLNode&
 
168
Send::state (bool full)
 
169
{
 
170
        XMLNode& node = Delivery::state(full);
 
171
        char buf[32];
 
172
 
 
173
        node.add_property ("type", "send");
 
174
        snprintf (buf, sizeof (buf), "%" PRIu32, _bitslot);
 
175
 
 
176
        if (_role != Listen) {
 
177
                node.add_property ("bitslot", buf);
 
178
        }
 
179
 
 
180
        node.add_child_nocopy (_amp->state (full));
 
181
 
 
182
        return node;
 
183
}
 
184
 
 
185
int
 
186
Send::set_state (const XMLNode& node, int version)
 
187
{
 
188
        if (version < 3000) {
 
189
                return set_state_2X (node, version);
 
190
        }
 
191
 
 
192
        const XMLProperty* prop;
 
193
 
 
194
        Delivery::set_state (node, version);
 
195
 
 
196
        if (node.property ("ignore-bitslot") == 0) {
 
197
 
 
198
                /* don't try to reset bitslot if there is a node for it already: this can cause
 
199
                   issues with the session's accounting of send ID's
 
200
                */
 
201
                
 
202
                if ((prop = node.property ("bitslot")) == 0) {
 
203
                        if (_role == Delivery::Aux) {
 
204
                                _bitslot = _session.next_aux_send_id ();
 
205
                        } else if (_role == Delivery::Send) {
 
206
                                _bitslot = _session.next_send_id ();
 
207
                        } else {
 
208
                                // bitslot doesn't matter but make it zero anyway
 
209
                                _bitslot = 0;
 
210
                        }
 
211
                } else {
 
212
                        if (_role == Delivery::Aux) {
 
213
                                _session.unmark_aux_send_id (_bitslot);
 
214
                                sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
 
215
                                _session.mark_aux_send_id (_bitslot);
 
216
                        } else if (_role == Delivery::Send) {
 
217
                                _session.unmark_send_id (_bitslot);
 
218
                                sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
 
219
                                _session.mark_send_id (_bitslot);
 
220
                        } else {
 
221
                                // bitslot doesn't matter but make it zero anyway
 
222
                                _bitslot = 0;
 
223
                        }
 
224
                }
 
225
        }
 
226
        
 
227
        XMLNodeList nlist = node.children();
 
228
        for (XMLNodeIterator i = nlist.begin(); i != nlist.end(); ++i) {
 
229
                if ((*i)->name() == X_("Processor")) {
 
230
                        _amp->set_state (**i, version);
 
231
                }
 
232
        }
 
233
 
 
234
        return 0;
 
235
}
 
236
 
 
237
int
 
238
Send::set_state_2X (const XMLNode& node, int /* version */)
 
239
{
 
240
        /* use the IO's name for the name of the send */
 
241
        XMLNodeList const & children = node.children ();
 
242
 
 
243
        XMLNodeList::const_iterator i = children.begin();
 
244
        while (i != children.end() && (*i)->name() != X_("Redirect")) {
 
245
                ++i;
 
246
        }
 
247
 
 
248
        if (i == children.end()) {
 
249
                return -1;
 
250
        }
 
251
 
 
252
        XMLNodeList const & grand_children = (*i)->children ();
 
253
        XMLNodeList::const_iterator j = grand_children.begin ();
 
254
        while (j != grand_children.end() && (*j)->name() != X_("IO")) {
 
255
                ++j;
 
256
        }
 
257
 
 
258
        if (j == grand_children.end()) {
 
259
                return -1;
 
260
        }
 
261
 
 
262
        XMLProperty const * prop = (*j)->property (X_("name"));
 
263
        if (!prop) {
 
264
                return -1;
 
265
        }
 
266
 
 
267
        set_name (prop->value ());
 
268
 
 
269
        return 0;
 
270
}
 
271
 
 
272
bool
 
273
Send::can_support_io_configuration (const ChanCount& in, ChanCount& out)
 
274
{
 
275
        /* sends have no impact at all on the channel configuration of the
 
276
           streams passing through the route. so, out == in.
 
277
        */
 
278
 
 
279
        out = in;
 
280
        return true;
 
281
}
 
282
 
 
283
/** Caller must hold process lock */
 
284
bool
 
285
Send::configure_io (ChanCount in, ChanCount out)
 
286
{
 
287
        if (!_amp->configure_io (in, out) || !_meter->configure_io (in, out)) {
 
288
                return false;
 
289
        }
 
290
 
 
291
        if (!Processor::configure_io (in, out)) {
 
292
                return false;
 
293
        }
 
294
 
 
295
        reset_panner ();
 
296
 
 
297
        return true;
 
298
}
 
299
 
 
300
bool
 
301
Send::set_name (const string& new_name)
 
302
{
 
303
        string unique_name;
 
304
 
 
305
        if (_role == Delivery::Send) {
 
306
                char buf[32];
 
307
 
 
308
                /* rip any existing numeric part of the name, and append the bitslot
 
309
                 */
 
310
 
 
311
                string::size_type last_letter = new_name.find_last_not_of ("0123456789");
 
312
 
 
313
                if (last_letter != string::npos) {
 
314
                        unique_name = new_name.substr (0, last_letter + 1);
 
315
                } else {
 
316
                        unique_name = new_name;
 
317
                }
 
318
 
 
319
                snprintf (buf, sizeof (buf), "%u", (_bitslot + 1));
 
320
                unique_name += buf;
 
321
 
 
322
        } else {
 
323
                unique_name = new_name;
 
324
        }
 
325
 
 
326
        return Delivery::set_name (unique_name);
 
327
}
 
328
 
 
329
bool
 
330
Send::display_to_user () const
 
331
{
 
332
        /* we ignore Deliver::_display_to_user */
 
333
 
 
334
        if (_role == Listen) {
 
335
                /* don't make the monitor/control/listen send visible */
 
336
                return false;
 
337
        }
 
338
 
 
339
        return true;
 
340
}
 
341
 
 
342
string
 
343
Send::value_as_string (boost::shared_ptr<AutomationControl> ac) const
 
344
{
 
345
        return _amp->value_as_string (ac);
 
346
}
 
347
 
 
348