move Session::Event into SessionEvent class; add SessionEventManager (Session IS...
[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 0
196         if (_diskstream->record_enabled()) {
197                 set_meter_point (MeterInput, this);
198         } else {
199                 set_meter_point (_saved_meter_point, this);
200         }
201 #endif
202
203         cerr << "4\n";
204         _rec_enable_control->Changed ();
205         cerr << "5\n";
206 }
207
208
209 bool
210 Track::set_name (const string& str)
211 {
212         bool ret;
213
214         if (record_enabled() && _session.actively_recording()) {
215                 /* this messes things up if done while recording */
216                 return false;
217         }
218
219         if (_diskstream->set_name (str)) {
220                 return false;
221         }
222
223         /* save state so that the statefile fully reflects any filename changes */
224
225         if ((ret = Route::set_name (str)) == 0) {
226                 _session.save_state ("");
227         }
228
229         return ret;
230 }
231
232 void
233 Track::set_latency_delay (nframes_t longest_session_latency)
234 {
235         Route::set_latency_delay (longest_session_latency);
236         _diskstream->set_roll_delay (_roll_delay);
237 }
238
239 void
240 Track::zero_diskstream_id_in_xml (XMLNode& node)
241 {
242         if (node.property ("diskstream-id")) {
243                 node.add_property ("diskstream-id", "0");
244         }
245 }
246
247 int
248 Track::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
249                 bool session_state_changing, bool can_record, bool /*rec_monitors_input*/)
250 {
251         if (n_outputs().n_total() == 0) {
252                 return 0;
253         }
254
255         if (!_active) {
256                 silence (nframes);
257                 return 0;
258         }
259
260         if (session_state_changing) {
261
262                 /* XXX is this safe to do against transport state changes? */
263
264                 passthru_silence (start_frame, end_frame, nframes, 0);
265                 return 0;
266         }
267
268         diskstream()->check_record_status (start_frame, nframes, can_record);
269
270         bool send_silence;
271
272         if (_have_internal_generator) {
273                 /* since the instrument has no input streams,
274                    there is no reason to send any signal
275                    into the route.
276                 */
277                 send_silence = true;
278         } else {
279                 if (!Config->get_tape_machine_mode()) {
280                         /*
281                            ADATs work in a strange way..
282                            they monitor input always when stopped.and auto-input is engaged.
283                         */
284                         if ((Config->get_monitoring_model() == SoftwareMonitoring)
285                                         && (_session.config.get_auto_input () || _diskstream->record_enabled())) {
286                                 send_silence = false;
287                         } else {
288                                 send_silence = true;
289                         }
290                 } else {
291                         /*
292                            Other machines switch to input on stop if the track is record enabled,
293                            regardless of the auto input setting (auto input only changes the
294                            monitoring state when the transport is rolling)
295                         */
296                         if ((Config->get_monitoring_model() == SoftwareMonitoring)
297                                         && _diskstream->record_enabled()) {
298                                 send_silence = false;
299                         } else {
300                                 send_silence = true;
301                         }
302                 }
303         }
304
305         _amp->apply_gain_automation(false);
306
307         if (send_silence) {
308
309                 /* if we're sending silence, but we want the meters to show levels for the signal,
310                    meter right here.
311                 */
312
313                 if (_have_internal_generator) {
314                         passthru_silence (start_frame, end_frame, nframes, 0);
315                 } else {
316                         if (_meter_point == MeterInput) {
317                                 _input->process_input (_meter, start_frame, end_frame, nframes);
318                         }
319                         passthru_silence (start_frame, end_frame, nframes, 0);
320                 }
321
322         } else {
323
324                 /* we're sending signal, but we may still want to meter the input.
325                  */
326
327                 passthru (start_frame, end_frame, nframes, false);
328         }
329
330         _main_outs->flush (nframes, end_frame - start_frame - 1);
331
332         return 0;
333 }
334
335 int
336 Track::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/,
337                     bool can_record, bool rec_monitors_input)
338 {
339         if (n_outputs().n_total() == 0 && _processors.empty()) {
340                 return 0;
341         }
342
343         if (!_active) {
344                 silence (nframes);
345                 return 0;
346         }
347
348         _silent = true;
349         _amp->apply_gain_automation(false);
350
351         silence (nframes);
352
353         return diskstream()->process (_session.transport_frame(), nframes, can_record, rec_monitors_input);
354 }