part one of hiding Diskstreams and making them a private object of a Track
[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
20 #include "ardour/amp.h"
21 #include "ardour/audioplaylist.h"
22 #include "ardour/audioregion.h"
23 #include "ardour/audiosource.h"
24 #include "ardour/debug.h"
25 #include "ardour/delivery.h"
26 #include "ardour/diskstream.h"
27 #include "ardour/io_processor.h"
28 #include "ardour/meter.h"
29 #include "ardour/port.h"
30 #include "ardour/processor.h"
31 #include "ardour/route_group_specialized.h"
32 #include "ardour/session.h"
33 #include "ardour/track.h"
34 #include "ardour/utils.h"
35
36 #include "i18n.h"
37
38 using namespace std;
39 using namespace ARDOUR;
40 using namespace PBD;
41
42 Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type)
43         : Route (sess, name, flag, default_type)
44         , _saved_meter_point (_meter_point)
45         , _mode (mode)
46         , _rec_enable_control (new RecEnableControllable(*this))
47 {
48         _freeze_record.state = NoFreeze;
49         _declickable = true;
50 }
51
52 Track::~Track ()
53 {
54         DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
55 }
56
57 int
58 Track::init ()
59 {
60         if (Route::init ()) {
61                 return -1;
62         }
63
64         return 0;
65 }
66 XMLNode&
67 Track::get_state ()
68 {
69         return state (true);
70 }
71
72 XMLNode&
73 Track::get_template ()
74 {
75         return state (false);
76 }
77
78 void
79 Track::toggle_monitor_input ()
80 {
81         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
82                 i->ensure_monitor_input(!i->monitoring_input());
83         }
84 }
85
86 ARDOUR::nframes_t
87 Track::update_total_latency ()
88 {
89         nframes_t old = _output->effective_latency();
90         nframes_t own_latency = _output->user_latency();
91
92         for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
93                 if ((*i)->active ()) {
94                         own_latency += (*i)->signal_latency ();
95                 }
96         }
97
98 #undef DEBUG_LATENCY
99 #ifdef DEBUG_LATENCY
100         cerr << _name << ": internal redirect (final) latency = " << own_latency << endl;
101 #endif
102
103         _output->set_port_latency (own_latency);
104
105         if (old != own_latency) {
106                 _output->set_latency_delay (own_latency);
107                 signal_latency_changed (); /* EMIT SIGNAL */
108         }
109
110         return _output->effective_latency();
111 }
112
113 Track::FreezeRecord::~FreezeRecord ()
114 {
115         for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
116                 delete *i;
117         }
118 }
119
120 Track::FreezeState
121 Track::freeze_state() const
122 {
123         return _freeze_record.state;
124 }
125
126 Track::RecEnableControllable::RecEnableControllable (Track& s)
127         : Controllable (X_("recenable")), track (s)
128 {
129 }
130
131 void
132 Track::RecEnableControllable::set_value (float val)
133 {
134         bool bval = ((val >= 0.5f) ? true: false);
135         track.set_record_enable (bval, this);
136 }
137
138 float
139 Track::RecEnableControllable::get_value (void) const
140 {
141         if (track.record_enabled()) { return 1.0f; }
142         return 0.0f;
143 }
144
145 bool
146 Track::record_enabled () const
147 {
148         return _diskstream && _diskstream->record_enabled ();
149 }
150
151 bool
152 Track::can_record()
153 {
154         bool will_record = true;
155         for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
156                 if (!i->connected())
157                         will_record = false;
158         }
159
160         return will_record;
161 }
162
163 void
164 Track::set_record_enable (bool yn, void *src)
165 {
166         if (!_session.writable()) {
167                 return;
168         }
169
170         if (_freeze_record.state == Frozen) {
171                 return;
172         }
173
174         if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) {
175                 _route_group->apply (&Track::set_record_enable, yn, _route_group);
176                 return;
177         }
178
179         /* keep track of the meter point as it was before we rec-enabled */
180         if (!_diskstream->record_enabled()) {
181                 _saved_meter_point = _meter_point;
182         }
183
184         _diskstream->set_record_enabled (yn);
185
186         if (_diskstream->record_enabled()) {
187                 if (_meter_point != MeterCustom) {
188                         set_meter_point (MeterInput, this);
189                 }
190         } else {
191                 set_meter_point (_saved_meter_point, this);
192         }
193
194         _rec_enable_control->Changed ();
195 }
196
197
198 bool
199 Track::set_name (const string& str)
200 {
201         bool ret;
202
203         if (record_enabled() && _session.actively_recording()) {
204                 /* this messes things up if done while recording */
205                 return false;
206         }
207
208         if (_diskstream->set_name (str)) {
209                 return false;
210         }
211
212         /* save state so that the statefile fully reflects any filename changes */
213
214         if ((ret = Route::set_name (str)) == 0) {
215                 _session.save_state ("");
216         }
217
218         return ret;
219 }
220
221 void
222 Track::set_latency_delay (nframes_t longest_session_latency)
223 {
224         Route::set_latency_delay (longest_session_latency);
225         _diskstream->set_roll_delay (_roll_delay);
226 }
227
228 void
229 Track::zero_diskstream_id_in_xml (XMLNode& node)
230 {
231         if (node.property ("diskstream-id")) {
232                 node.add_property ("diskstream-id", "0");
233         }
234 }
235
236 int
237 Track::no_roll (nframes_t nframes, framepos_t start_frame, framepos_t end_frame,
238                 bool session_state_changing, bool can_record, bool /*rec_monitors_input*/)
239 {
240         if (n_outputs().n_total() == 0) {
241                 return 0;
242         }
243
244         if (!_active) {
245                 silence (nframes);
246                 return 0;
247         }
248
249         if (session_state_changing) {
250                 if (_session.transport_speed() != 0.0f) {
251                         /* we're rolling but some state is changing (e.g. our diskstream contents)
252                            so we cannot use them. Be silent till this is over. Don't declick.
253
254                            XXX note the absurdity of ::no_roll() being called when we ARE rolling!
255                         */
256                         passthru_silence (start_frame, end_frame, nframes, 0);
257                         return 0;
258                 }
259                 /* we're really not rolling, so we're either delivery silence or actually
260                    monitoring, both of which are safe to do while session_state_changing is true.
261                 */
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, framepos_t /*start_frame*/, framepos_t /*end_frame*/,
333                     bool can_record, bool rec_monitors_input, bool& need_butler)
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, need_butler);
350 }
351
352 ChanCount
353 Track::input_streams () const
354 {
355         ChanCount cc = _input->n_ports ();
356
357         if (cc.n_total() == 0 && _diskstream) {
358                 return cc = _diskstream->n_channels();
359         }
360
361         return cc;
362 }
363