2 Copyright (C) 2006 Paul Davis
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.
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.
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.
18 #include "pbd/error.h"
19 #include <sigc++/retype.h>
20 #include <sigc++/retype_return.h>
21 #include <sigc++/bind.h>
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"
42 using namespace ARDOUR;
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))
50 _freeze_record.state = NoFreeze;
51 _saved_meter_point = _meter_point;
55 Track::Track (Session& sess, const XMLNode& node, DataType default_type)
56 : Route (sess, node, default_type)
57 , _rec_enable_control (new RecEnableControllable(*this))
59 _freeze_record.state = NoFreeze;
61 _saved_meter_point = _meter_point;
66 DEBUG_TRACE (DEBUG::Destruction, string_compose ("track %1 destructor\n", _name));
70 Track::set_meter_point (MeterPoint p, void *src)
72 Route::set_meter_point (p, src);
82 Track::get_template ()
88 Track::toggle_monitor_input ()
90 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
91 i->ensure_monitor_input(!i->monitoring_input());
96 Track::update_total_latency ()
98 nframes_t old = _output->effective_latency();
99 nframes_t own_latency = _output->user_latency();
101 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
102 if ((*i)->active ()) {
103 own_latency += (*i)->signal_latency ();
109 cerr << _name << ": internal redirect (final) latency = " << own_latency << endl;
112 _output->set_port_latency (own_latency);
114 if (old != own_latency) {
115 _output->set_latency_delay (own_latency);
116 signal_latency_changed (); /* EMIT SIGNAL */
119 return _output->effective_latency();
122 Track::FreezeRecord::~FreezeRecord ()
124 for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
130 Track::freeze_state() const
132 return _freeze_record.state;
135 Track::RecEnableControllable::RecEnableControllable (Track& s)
136 : Controllable (X_("recenable")), track (s)
141 Track::RecEnableControllable::set_value (float val)
143 bool bval = ((val >= 0.5f) ? true: false);
144 track.set_record_enable (bval, this);
148 Track::RecEnableControllable::get_value (void) const
150 if (track.record_enabled()) { return 1.0f; }
155 Track::record_enabled () const
157 return _diskstream && _diskstream->record_enabled ();
163 bool will_record = true;
164 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
173 Track::set_record_enable (bool yn, void *src)
175 if (!_session.writable()) {
179 if (_freeze_record.state == Frozen) {
183 if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::RecEnable)) {
184 _route_group->apply (&Track::set_record_enable, yn, _route_group);
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;
193 _diskstream->set_record_enabled (yn);
196 if (_diskstream->record_enabled()) {
197 set_meter_point (MeterInput, this);
199 set_meter_point (_saved_meter_point, this);
204 _rec_enable_control->Changed ();
210 Track::set_name (const string& str)
214 if (record_enabled() && _session.actively_recording()) {
215 /* this messes things up if done while recording */
219 if (_diskstream->set_name (str)) {
223 /* save state so that the statefile fully reflects any filename changes */
225 if ((ret = Route::set_name (str)) == 0) {
226 _session.save_state ("");
233 Track::set_latency_delay (nframes_t longest_session_latency)
235 Route::set_latency_delay (longest_session_latency);
236 _diskstream->set_roll_delay (_roll_delay);
240 Track::zero_diskstream_id_in_xml (XMLNode& node)
242 if (node.property ("diskstream-id")) {
243 node.add_property ("diskstream-id", "0");
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*/)
251 if (n_outputs().n_total() == 0) {
260 if (session_state_changing) {
262 /* XXX is this safe to do against transport state changes? */
264 passthru_silence (start_frame, end_frame, nframes, 0);
268 diskstream()->check_record_status (start_frame, nframes, can_record);
272 if (_have_internal_generator) {
273 /* since the instrument has no input streams,
274 there is no reason to send any signal
279 if (!Config->get_tape_machine_mode()) {
281 ADATs work in a strange way..
282 they monitor input always when stopped.and auto-input is engaged.
284 if ((Config->get_monitoring_model() == SoftwareMonitoring)
285 && (_session.config.get_auto_input () || _diskstream->record_enabled())) {
286 send_silence = false;
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)
296 if ((Config->get_monitoring_model() == SoftwareMonitoring)
297 && _diskstream->record_enabled()) {
298 send_silence = false;
305 _amp->apply_gain_automation(false);
309 /* if we're sending silence, but we want the meters to show levels for the signal,
313 if (_have_internal_generator) {
314 passthru_silence (start_frame, end_frame, nframes, 0);
316 if (_meter_point == MeterInput) {
317 _input->process_input (_meter, start_frame, end_frame, nframes);
319 passthru_silence (start_frame, end_frame, nframes, 0);
324 /* we're sending signal, but we may still want to meter the input.
327 passthru (start_frame, end_frame, nframes, false);
330 _main_outs->flush (nframes, end_frame - start_frame - 1);
336 Track::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/,
337 bool can_record, bool rec_monitors_input)
339 if (n_outputs().n_total() == 0 && _processors.empty()) {
349 _amp->apply_gain_automation(false);
353 return diskstream()->process (_session.transport_frame(), nframes, can_record, rec_monitors_input);