tracing and small fixes to improve object destruction pathways
[ardour.git] / libs / ardour / track.cc
1 /*
2     Copyright (C) 2006 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 #include "pbd/error.h"
19 #include <sigc++/retype.h>
20 #include <sigc++/retype_return.h>
21 #include <sigc++/bind.h>
22
23 #include "ardour/amp.h"
24 #include "ardour/audioplaylist.h"
25 #include "ardour/audioregion.h"
26 #include "ardour/audiosource.h"
27 #include "ardour/debug.h"
28 #include "ardour/delivery.h"
29 #include "ardour/diskstream.h"
30 #include "ardour/io_processor.h"
31 #include "ardour/meter.h"
32 #include "ardour/port.h"
33 #include "ardour/processor.h"
34 #include "ardour/route_group_specialized.h"
35 #include "ardour/session.h"
36 #include "ardour/track.h"
37 #include "ardour/utils.h"
38
39 #include "i18n.h"
40
41 using namespace std;
42 using namespace ARDOUR;
43 using namespace PBD;
44
45 Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type)
46         : Route (sess, name, flag, default_type)
47         , _rec_enable_control (new RecEnableControllable(*this))
48 {
49         _declickable = true;
50         _freeze_record.state = NoFreeze;
51         _saved_meter_point = _meter_point;
52         _mode = mode;
53 }
54
55 Track::Track (Session& sess, const XMLNode& node, DataType default_type)
56         : Route (sess, node, default_type)
57         , _rec_enable_control (new RecEnableControllable(*this))
58 {
59         _freeze_record.state = NoFreeze;
60         _declickable = true;
61         _saved_meter_point = _meter_point;
62 }
63
64 Track::~Track ()
65 {
66         DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
67 }
68
69 void
70 Track::set_meter_point (MeterPoint p, void *src)
71 {
72         Route::set_meter_point (p, src);
73 }
74
75 XMLNode&
76 Track::get_state ()
77 {
78         return state (true);
79 }
80
81 XMLNode&
82 Track::get_template ()
83 {
84         return state (false);
85 }
86
87 void
88 Track::toggle_monitor_input ()
89 {
90         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
91                 i->ensure_monitor_input(!i->monitoring_input());
92         }
93 }
94
95 ARDOUR::nframes_t
96 Track::update_total_latency ()
97 {
98         nframes_t old = _output->effective_latency();
99         nframes_t own_latency = _output->user_latency();
100
101         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
102                 if ((*i)->active ()) {
103                         own_latency += (*i)->signal_latency ();
104                 }
105         }
106
107 #undef DEBUG_LATENCY
108 #ifdef DEBUG_LATENCY
109         cerr << _name << ": internal redirect (final) latency = " << own_latency << endl;
110 #endif
111
112         _output->set_port_latency (own_latency);
113
114         if (old != own_latency) {
115                 _output->set_latency_delay (own_latency);
116                 signal_latency_changed (); /* EMIT SIGNAL */
117         }
118
119         return _output->effective_latency();
120 }
121
122 Track::FreezeRecord::~FreezeRecord ()
123 {
124         for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
125                 delete *i;
126         }
127 }
128
129 Track::FreezeState
130 Track::freeze_state() const
131 {
132         return _freeze_record.state;
133 }
134
135 Track::RecEnableControllable::RecEnableControllable (Track& s)
136         : Controllable (X_("recenable")), track (s)
137 {
138 }
139
140 void
141 Track::RecEnableControllable::set_value (float val)
142 {
143         bool bval = ((val >= 0.5f) ? true: false);
144         track.set_record_enable (bval, this);
145 }
146
147 float
148 Track::RecEnableControllable::get_value (void) const
149 {
150         if (track.record_enabled()) { return 1.0f; }
151         return 0.0f;
152 }
153
154 bool
155 Track::record_enabled () const
156 {
157         return _diskstream && _diskstream->record_enabled ();
158 }
159
160 bool
161 Track::can_record()
162 {
163         bool will_record = true;
164         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
165                 if (!i->connected())
166                         will_record = false;
167         }
168
169         return will_record;
170 }
171
172 void
173 Track::set_record_enable (bool yn, void *src)
174 {
175         if (!_session.writable()) {
176                 return;
177         }
178
179         if (_freeze_record.state == Frozen) {
180                 return;
181         }
182
183         if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::RecEnable)) {
184                 _route_group->apply (&Track::set_record_enable, yn, _route_group);
185                 return;
186         }
187
188         /* keep track of the meter point as it was before we rec-enabled */
189         if (!_diskstream->record_enabled()) {
190                 _saved_meter_point = _meter_point;
191         }
192
193         _diskstream->set_record_enabled (yn);
194
195         if (_diskstream->record_enabled()) {
196                 set_meter_point (MeterInput, this);
197         } else {
198                 set_meter_point (_saved_meter_point, this);
199         }
200
201         _rec_enable_control->Changed ();
202 }
203
204
205 bool
206 Track::set_name (const string& str)
207 {
208         bool ret;
209
210         if (record_enabled() && _session.actively_recording()) {
211                 /* this messes things up if done while recording */
212                 return false;
213         }
214
215         if (_diskstream->set_name (str)) {
216                 return false;
217         }
218
219         /* save state so that the statefile fully reflects any filename changes */
220
221         if ((ret = Route::set_name (str)) == 0) {
222                 _session.save_state ("");
223         }
224
225         return ret;
226 }
227
228 void
229 Track::set_latency_delay (nframes_t longest_session_latency)
230 {
231         Route::set_latency_delay (longest_session_latency);
232         _diskstream->set_roll_delay (_roll_delay);
233 }
234
235 void
236 Track::zero_diskstream_id_in_xml (XMLNode& node)
237 {
238         if (node.property ("diskstream-id")) {
239                 node.add_property ("diskstream-id", "0");
240         }
241 }
242
243 int
244 Track::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
245                 bool session_state_changing, bool can_record, bool /*rec_monitors_input*/)
246 {
247         if (n_outputs().n_total() == 0) {
248                 return 0;
249         }
250
251         if (!_active) {
252                 silence (nframes);
253                 return 0;
254         }
255
256         if (session_state_changing) {
257
258                 /* XXX is this safe to do against transport state changes? */
259
260                 passthru_silence (start_frame, end_frame, nframes, 0);
261                 return 0;
262         }
263
264         diskstream()->check_record_status (start_frame, nframes, can_record);
265
266         bool send_silence;
267
268         if (_have_internal_generator) {
269                 /* since the instrument has no input streams,
270                    there is no reason to send any signal
271                    into the route.
272                 */
273                 send_silence = true;
274         } else {
275                 if (!Config->get_tape_machine_mode()) {
276                         /*
277                            ADATs work in a strange way..
278                            they monitor input always when stopped.and auto-input is engaged.
279                         */
280                         if ((Config->get_monitoring_model() == SoftwareMonitoring)
281                                         && (_session.config.get_auto_input () || _diskstream->record_enabled())) {
282                                 send_silence = false;
283                         } else {
284                                 send_silence = true;
285                         }
286                 } else {
287                         /*
288                            Other machines switch to input on stop if the track is record enabled,
289                            regardless of the auto input setting (auto input only changes the
290                            monitoring state when the transport is rolling)
291                         */
292                         if ((Config->get_monitoring_model() == SoftwareMonitoring)
293                                         && _diskstream->record_enabled()) {
294                                 send_silence = false;
295                         } else {
296                                 send_silence = true;
297                         }
298                 }
299         }
300
301         _amp->apply_gain_automation(false);
302
303         if (send_silence) {
304
305                 /* if we're sending silence, but we want the meters to show levels for the signal,
306                    meter right here.
307                 */
308
309                 if (_have_internal_generator) {
310                         passthru_silence (start_frame, end_frame, nframes, 0);
311                 } else {
312                         if (_meter_point == MeterInput) {
313                                 _input->process_input (_meter, start_frame, end_frame, nframes);
314                         }
315                         passthru_silence (start_frame, end_frame, nframes, 0);
316                 }
317
318         } else {
319
320                 /* we're sending signal, but we may still want to meter the input.
321                  */
322
323                 passthru (start_frame, end_frame, nframes, false);
324         }
325
326         _main_outs->flush (nframes, end_frame - start_frame - 1);
327
328         return 0;
329 }
330
331 int
332 Track::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/,
333                     bool can_record, bool rec_monitors_input)
334 {
335         if (n_outputs().n_total() == 0 && _processors.empty()) {
336                 return 0;
337         }
338
339         if (!_active) {
340                 silence (nframes);
341                 return 0;
342         }
343
344         _silent = true;
345         _amp->apply_gain_automation(false);
346
347         silence (nframes);
348
349         return diskstream()->process (_session.transport_frame(), nframes, can_record, rec_monitors_input);
350 }