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/delivery.h"
28 #include "ardour/diskstream.h"
29 #include "ardour/io_processor.h"
30 #include "ardour/meter.h"
31 #include "ardour/port.h"
32 #include "ardour/processor.h"
33 #include "ardour/route_group_specialized.h"
34 #include "ardour/session.h"
35 #include "ardour/track.h"
36 #include "ardour/utils.h"
41 using namespace ARDOUR;
44 Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type)
45 : Route (sess, name, flag, default_type)
46 , _rec_enable_control (new RecEnableControllable(*this))
49 _freeze_record.state = NoFreeze;
50 _saved_meter_point = _meter_point;
54 Track::Track (Session& sess, const XMLNode& node, DataType default_type)
55 : Route (sess, node, default_type)
56 , _rec_enable_control (new RecEnableControllable(*this))
58 _freeze_record.state = NoFreeze;
60 _saved_meter_point = _meter_point;
68 Track::set_meter_point (MeterPoint p, void *src)
70 Route::set_meter_point (p, src);
80 Track::get_template ()
86 Track::toggle_monitor_input ()
88 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end(); ++i) {
89 i->ensure_monitor_input(!i->monitoring_input());
94 Track::update_total_latency ()
96 nframes_t old = _output->effective_latency();
97 nframes_t own_latency = _output->user_latency();
99 for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
100 if ((*i)->active ()) {
101 own_latency += (*i)->signal_latency ();
107 cerr << _name << ": internal redirect (final) latency = " << own_latency << endl;
110 _output->set_port_latency (own_latency);
112 if (old != own_latency) {
113 _output->set_latency_delay (own_latency);
114 signal_latency_changed (); /* EMIT SIGNAL */
117 return _output->effective_latency();
120 Track::FreezeRecord::~FreezeRecord ()
122 for (vector<FreezeRecordProcessorInfo*>::iterator i = processor_info.begin(); i != processor_info.end(); ++i) {
128 Track::freeze_state() const
130 return _freeze_record.state;
133 Track::RecEnableControllable::RecEnableControllable (Track& s)
134 : Controllable (X_("recenable")), track (s)
139 Track::RecEnableControllable::set_value (float val)
141 bool bval = ((val >= 0.5f) ? true: false);
142 track.set_record_enable (bval, this);
146 Track::RecEnableControllable::get_value (void) const
148 if (track.record_enabled()) { return 1.0f; }
153 Track::record_enabled () const
155 return _diskstream && _diskstream->record_enabled ();
161 bool will_record = true;
162 for (PortSet::iterator i = _input->ports().begin(); i != _input->ports().end() && will_record; ++i) {
171 Track::set_record_enable (bool yn, void *src)
173 if (!_session.writable()) {
177 if (_freeze_record.state == Frozen) {
181 if (_route_group && src != _route_group && _route_group->active_property (RouteGroup::RecEnable)) {
182 _route_group->apply (&Track::set_record_enable, yn, _route_group);
186 /* keep track of the meter point as it was before we rec-enabled */
187 if (!_diskstream->record_enabled()) {
188 _saved_meter_point = _meter_point;
191 _diskstream->set_record_enabled (yn);
193 if (_diskstream->record_enabled()) {
194 set_meter_point (MeterInput, this);
196 set_meter_point (_saved_meter_point, this);
199 _rec_enable_control->Changed ();
204 Track::set_name (const string& str)
208 if (record_enabled() && _session.actively_recording()) {
209 /* this messes things up if done while recording */
213 if (_diskstream->set_name (str)) {
217 /* save state so that the statefile fully reflects any filename changes */
219 if ((ret = Route::set_name (str)) == 0) {
220 _session.save_state ("");
227 Track::set_latency_delay (nframes_t longest_session_latency)
229 Route::set_latency_delay (longest_session_latency);
230 _diskstream->set_roll_delay (_roll_delay);
234 Track::zero_diskstream_id_in_xml (XMLNode& node)
236 if (node.property ("diskstream-id")) {
237 node.add_property ("diskstream-id", "0");
242 Track::no_roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
243 bool session_state_changing, bool can_record, bool /*rec_monitors_input*/)
245 if (n_outputs().n_total() == 0) {
254 if (session_state_changing) {
256 /* XXX is this safe to do against transport state changes? */
258 passthru_silence (start_frame, end_frame, nframes, 0);
262 diskstream()->check_record_status (start_frame, nframes, can_record);
266 if (_have_internal_generator) {
267 /* since the instrument has no input streams,
268 there is no reason to send any signal
273 if (!Config->get_tape_machine_mode()) {
275 ADATs work in a strange way..
276 they monitor input always when stopped.and auto-input is engaged.
278 if ((Config->get_monitoring_model() == SoftwareMonitoring)
279 && (_session.config.get_auto_input () || _diskstream->record_enabled())) {
280 send_silence = false;
286 Other machines switch to input on stop if the track is record enabled,
287 regardless of the auto input setting (auto input only changes the
288 monitoring state when the transport is rolling)
290 if ((Config->get_monitoring_model() == SoftwareMonitoring)
291 && _diskstream->record_enabled()) {
292 send_silence = false;
299 _amp->apply_gain_automation(false);
303 /* if we're sending silence, but we want the meters to show levels for the signal,
307 if (_have_internal_generator) {
308 passthru_silence (start_frame, end_frame, nframes, 0);
310 if (_meter_point == MeterInput) {
311 _input->process_input (_meter, start_frame, end_frame, nframes);
313 passthru_silence (start_frame, end_frame, nframes, 0);
318 /* we're sending signal, but we may still want to meter the input.
321 passthru (start_frame, end_frame, nframes, false);
324 _main_outs->flush (nframes, end_frame - start_frame - 1);
330 Track::silent_roll (nframes_t nframes, sframes_t /*start_frame*/, sframes_t /*end_frame*/,
331 bool can_record, bool rec_monitors_input)
333 if (n_outputs().n_total() == 0 && _processors.empty()) {
343 _amp->apply_gain_automation(false);
347 return diskstream()->process (_session.transport_frame(), nframes, can_record, rec_monitors_input);