X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Ftrack.cc;h=4f682085b2b19a82630213d9d88fac5a8130a9eb;hb=8f46b0dc4bbc54d0b6072376712654f69b36c4fa;hp=46517e1752bf17de1e108548ec95609b71946494;hpb=fff03c103dd899e14891c827f0a52eafb6f6eadb;p=ardour.git diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 46517e1752..4f682085b2 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -69,6 +69,8 @@ Track::get_state () return state (true); } + + XMLNode& Track::get_template () { @@ -83,33 +85,6 @@ Track::toggle_monitor_input () } } -ARDOUR::nframes_t -Track::update_total_latency () -{ - nframes_t old = _output->effective_latency(); - nframes_t own_latency = _output->user_latency(); - - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - if ((*i)->active ()) { - own_latency += (*i)->signal_latency (); - } - } - -#undef DEBUG_LATENCY -#ifdef DEBUG_LATENCY - cerr << _name << ": internal redirect (final) latency = " << own_latency << endl; -#endif - - _output->set_port_latency (own_latency); - - if (old != own_latency) { - _output->set_latency_delay (own_latency); - signal_latency_changed (); /* EMIT SIGNAL */ - } - - return _output->effective_latency(); -} - Track::FreezeRecord::~FreezeRecord () { for (vector::iterator i = processor_info.begin(); i != processor_info.end(); ++i) { @@ -205,9 +180,7 @@ Track::set_name (const string& str) return false; } - if (_diskstream->set_name (str)) { - return false; - } + _diskstream->set_name (str); /* save state so that the statefile fully reflects any filename changes */ @@ -219,9 +192,9 @@ Track::set_name (const string& str) } void -Track::set_latency_delay (nframes_t longest_session_latency) +Track::set_latency_compensation (framecnt_t longest_session_latency) { - Route::set_latency_delay (longest_session_latency); + Route::set_latency_compensation (longest_session_latency); _diskstream->set_roll_delay (_roll_delay); } @@ -234,8 +207,8 @@ Track::zero_diskstream_id_in_xml (XMLNode& node) } int -Track::no_roll (nframes_t nframes, framepos_t start_frame, framepos_t end_frame, - bool session_state_changing, bool can_record, bool /*rec_monitors_input*/) +Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, + bool session_state_changing, bool can_record) { Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); if (!lm.locked()) { @@ -268,44 +241,21 @@ Track::no_roll (nframes_t nframes, framepos_t start_frame, framepos_t end_frame, _diskstream->check_record_status (start_frame, can_record); - bool send_silence; + bool be_silent; if (_have_internal_generator) { /* since the instrument has no input streams, there is no reason to send any signal into the route. */ - send_silence = true; + be_silent = true; } else { - if (!Config->get_tape_machine_mode()) { - /* - ADATs work in a strange way.. - they monitor input always when stopped.and auto-input is engaged. - */ - if ((Config->get_monitoring_model() == SoftwareMonitoring) - && (_session.config.get_auto_input () || _diskstream->record_enabled())) { - send_silence = false; - } else { - send_silence = true; - } - } else { - /* - Other machines switch to input on stop if the track is record enabled, - regardless of the auto input setting (auto input only changes the - monitoring state when the transport is rolling) - */ - if ((Config->get_monitoring_model() == SoftwareMonitoring) - && _diskstream->record_enabled()) { - send_silence = false; - } else { - send_silence = true; - } - } + be_silent = send_silence (); } _amp->apply_gain_automation(false); - if (send_silence) { + if (be_silent) { /* if we're sending silence, but we want the meters to show levels for the signal, meter right here. @@ -334,8 +284,8 @@ Track::no_roll (nframes_t nframes, framepos_t start_frame, framepos_t end_frame, } int -Track::silent_roll (nframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/, - bool can_record, bool rec_monitors_input, bool& need_butler) +Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /*end_frame*/, + bool can_record, bool& need_butler) { Glib::RWLock::ReaderLock lm (_processor_lock, Glib::TRY_LOCK); if (!lm.locked()) { @@ -356,26 +306,14 @@ Track::silent_roll (nframes_t nframes, framepos_t /*start_frame*/, framepos_t /* silence (nframes); - return _diskstream->process (_session.transport_frame(), nframes, can_record, rec_monitors_input, need_butler); -} - -ChanCount -Track::input_streams () const -{ - ChanCount cc = _input->n_ports (); - - if (cc.n_total() == 0 && _diskstream) { - return cc = _diskstream->n_channels(); - } - - return cc; + return _diskstream->process (_session.transport_frame(), nframes, can_record, need_butler); } void Track::set_diskstream (boost::shared_ptr ds) { _diskstream = ds; - + ds->PlaylistChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_playlist_changed, this)); diskstream_playlist_changed (); ds->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_enable_changed, this)); @@ -437,7 +375,7 @@ Track::set_capture_offset () _diskstream->set_capture_offset (); } -list > +list > Track::steal_write_sources() { return _diskstream->steal_write_sources (); @@ -528,7 +466,7 @@ Track::overwrite_existing_buffers () } framecnt_t -Track::get_captured_frames (uint32_t n) +Track::get_captured_frames (uint32_t n) const { return _diskstream->get_captured_frames (n); } @@ -588,7 +526,7 @@ Track::n_channels () } framepos_t -Track::get_capture_start_frame (uint32_t n) +Track::get_capture_start_frame (uint32_t n) const { return _diskstream->get_capture_start_frame (n); } @@ -599,6 +537,12 @@ Track::alignment_style () const return _diskstream->alignment_style (); } +AlignChoice +Track::alignment_choice () const +{ + return _diskstream->alignment_choice (); +} + framepos_t Track::current_capture_start () const { @@ -642,9 +586,15 @@ Track::read_data_count () const } void -Track::set_align_style (AlignStyle s) +Track::set_align_style (AlignStyle s, bool force) +{ + _diskstream->set_align_style (s, force); +} + +void +Track::set_align_choice (AlignChoice s, bool force) { - _diskstream->set_align_style (s); + _diskstream->set_align_choice (s, force); } uint32_t @@ -660,13 +610,13 @@ Track::diskstream_id () const } void -Track::set_block_size (nframes_t n) +Track::set_block_size (pframes_t n) { Route::set_block_size (n); _diskstream->set_block_size (n); } -void +void Track::adjust_playback_buffering () { if (_diskstream) { @@ -674,10 +624,109 @@ Track::adjust_playback_buffering () } } -void +void Track::adjust_capture_buffering () { if (_diskstream) { _diskstream->adjust_capture_buffering (); } } + +bool +Track::send_silence () const +{ + /* + ADATs work in a strange way.. + they monitor input always when stopped.and auto-input is engaged. + + Other machines switch to input on stop if the track is record enabled, + regardless of the auto input setting (auto input only changes the + monitoring state when the transport is rolling) + */ + + bool send_silence; + + if (!Config->get_tape_machine_mode()) { + /* + ADATs work in a strange way.. + they monitor input always when stopped.and auto-input is engaged. + */ + if ((Config->get_monitoring_model() == SoftwareMonitoring) + && (_session.config.get_auto_input () || _diskstream->record_enabled())) { + send_silence = false; + } else { + send_silence = true; + } + } else { + /* + Other machines switch to input on stop if the track is record enabled, + regardless of the auto input setting (auto input only changes the + monitoring state when the transport is rolling) + */ + if ((Config->get_monitoring_model() == SoftwareMonitoring) + && _diskstream->record_enabled()) { + send_silence = false; + } else { + send_silence = true; + } + } + + return send_silence; +} + +void +Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick) +{ + /* never declick if there is an internal generator - we just want it to + keep generating sound without interruption. + */ + + if (_have_internal_generator) { + return; + } + + if (!declick) { + declick = _pending_declick; + } + + if (declick != 0) { + Amp::declick (bufs, nframes, declick); + } +} + +framecnt_t +Track::check_initial_delay (framecnt_t nframes, framecnt_t& transport_frame) +{ + if (_roll_delay > nframes) { + + _roll_delay -= nframes; + silence_unlocked (nframes); + /* transport frame is not legal for caller to use */ + return 0; + + } else if (_roll_delay > 0) { + + nframes -= _roll_delay; + silence_unlocked (_roll_delay); + transport_frame += _roll_delay; + + /* shuffle all the port buffers for things that lead "out" of this Route + to reflect that we just wrote _roll_delay frames of silence. + */ + + Glib::RWLock::ReaderLock lm (_processor_lock); + for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { + boost::shared_ptr iop = boost::dynamic_pointer_cast (*i); + if (iop) { + iop->increment_port_buffer_offset (_roll_delay); + } + } + _output->increment_port_buffer_offset (_roll_delay); + + _roll_delay = 0; + + } + + return nframes; +} +