diff options
-rw-r--r-- | libs/ardour/ardour/route.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/track.h | 2 | ||||
-rw-r--r-- | libs/ardour/disk_reader.cc | 64 | ||||
-rw-r--r-- | libs/ardour/route.cc | 14 | ||||
-rw-r--r-- | libs/ardour/track.cc | 43 |
5 files changed, 67 insertions, 57 deletions
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 0e1d0b65e1..bf8d05dd12 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -627,7 +627,6 @@ public: bool _active; samplecnt_t _signal_latency; samplecnt_t _initial_delay; - samplecnt_t _roll_delay; ProcessorList _processors; mutable Glib::Threads::RWLock _processor_lock; diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index ec81e92939..865b9c0619 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -72,7 +72,6 @@ class LIBARDOUR_API Track : public Route, public Recordable bool can_record(); - void set_latency_compensation (samplecnt_t); void update_latency_information (); enum FreezeState { NoFreeze, @@ -228,7 +227,6 @@ class LIBARDOUR_API Track : public Route, public Recordable virtual void record_enable_changed (bool, PBD::Controllable::GroupControlDisposition); virtual void record_safe_changed (bool, PBD::Controllable::GroupControlDisposition); - samplecnt_t check_initial_delay (samplecnt_t nframes, samplepos_t&); virtual void monitoring_changed (bool, PBD::Controllable::GroupControlDisposition); AlignChoice _alignment_choice; diff --git a/libs/ardour/disk_reader.cc b/libs/ardour/disk_reader.cc index 6f559b6167..5194b6ca2a 100644 --- a/libs/ardour/disk_reader.cc +++ b/libs/ardour/disk_reader.cc @@ -129,6 +129,7 @@ DiskReader::set_name (string const & str) void DiskReader::set_roll_delay (ARDOUR::samplecnt_t nframes) { + /* Must be called from process context or with process lock held */ _roll_delay = nframes; } @@ -278,14 +279,38 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp disk_samples_to_consume = nframes; } + bool roll_delayed = false; + samplecnt_t roll_delay_offset = 0; + + if (speed != 0.0) { + if (_roll_delay > disk_samples_to_consume) { + /* still waiting for _roll_delay to end */ + _roll_delay -= disk_samples_to_consume; + /* we could set disk_samples_to_consume to zero here, but it + won't be used anyway. + */ + roll_delayed = true; + + } else if (_roll_delay > 0) { + /* roll delay will end during this call to ::run(), but + * there's some silence needed in the signal-from-disk first + */ + roll_delay_offset = _roll_delay; + bufs.silence (_roll_delay, 0); + disk_samples_to_consume -= _roll_delay; + start_sample += _roll_delay; + _roll_delay = 0; + } + } + BufferSet& scratch_bufs (_session.get_scratch_buffers (bufs.count())); const bool still_locating = _session.global_locate_pending(); - if (!result_required || ((ms & MonitoringDisk) == 0) || still_locating || _no_disk_output) { + if (!result_required || ((ms & MonitoringDisk) == 0) || still_locating || _no_disk_output || roll_delayed) { /* no need for actual disk data, just advance read pointer and return */ - if (!still_locating || _no_disk_output) { + if (!roll_delayed && (!still_locating || _no_disk_output)) { for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { (*chan)->buf->increment_read_ptr (disk_samples_to_consume); } @@ -293,7 +318,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp /* if monitoring disk but locating put silence in the buffers */ - if ((_no_disk_output || still_locating) && (ms == MonitoringDisk)) { + if ((roll_delayed || _no_disk_output || still_locating) && (ms == MonitoringDisk)) { bufs.silence (nframes, 0); } @@ -325,13 +350,35 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp disk_signal = output.data (); } + /* if we skipped some number of samples at the start + because of the _roll_delay being non-zero but small + enough that we will process some data from disk, + advance where we're going to write that data to, + thus skipping over the silence that was written + there. + */ + disk_signal += roll_delay_offset; + + assert (start_sample >= playback_sample); + + if (start_sample != playback_sample) { + cerr << owner()->name() << " playback not aligned, jump ahead " << (start_sample - playback_sample) << endl; + + if (can_internal_playback_seek (start_sample - playback_sample)) { + internal_playback_seek (start_sample - playback_sample); + } else { + cerr << owner()->name() << " playback not possible: ss = " << start_sample << " ps = " << playback_sample << endl; + goto midi; + } + } + chaninfo->buf->get_read_vector (&(*chan)->rw_vector); if (disk_samples_to_consume <= (samplecnt_t) chaninfo->rw_vector.len[0]) { if (fabsf (speed) != 1.0f) { (void) interpolation.interpolate ( - n, nframes, + n, disk_samples_to_consume, chaninfo->rw_vector.buf[0], disk_signal); } else if (speed != 0.0) { @@ -377,20 +424,23 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp } if (scaling != 1.0f && speed != 0.0) { - apply_gain_to_buffer (disk_signal, nframes, scaling); + apply_gain_to_buffer (disk_signal, disk_samples_to_consume, scaling); } chaninfo->buf->increment_read_ptr (disk_samples_to_consume); - if ((speed != 0.0) && (ms & MonitoringInput)) { + monitor_mix: + + if (ms & MonitoringInput) { /* mix the disk signal into the input signal (already in bufs) */ - mix_buffers_no_gain (output.data(), disk_signal, speed == 0.0 ? nframes : disk_samples_to_consume); + mix_buffers_no_gain (output.data(), disk_signal, disk_samples_to_consume); } } } /* MIDI data handling */ + midi: if (!_session.declick_out_pending() && bufs.count().n_midi()) { MidiBuffer* dst; diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 041640a973..4d473eb740 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -96,7 +96,6 @@ Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType , _active (true) , _signal_latency (0) , _initial_delay (0) - , _roll_delay (0) , _disk_io_point (DiskIOPreFader) , _pending_process_reorder (0) , _pending_signals (0) @@ -3353,7 +3352,9 @@ Route::non_realtime_transport_stop (samplepos_t now, bool flush) } } - _roll_delay = _initial_delay; + if (_disk_reader) { + _disk_reader->set_roll_delay (_initial_delay); + } } void @@ -3941,7 +3942,9 @@ Route::set_latency_compensation (samplecnt_t longest_session_latency) } if (_session.transport_stopped()) { - _roll_delay = _initial_delay; + if (_disk_reader) { + _disk_reader->set_roll_delay (_initial_delay); + } } } @@ -4885,7 +4888,10 @@ Route::non_realtime_locate (samplepos_t pos) (*i)->non_realtime_locate (pos); } } - _roll_delay = _initial_delay; + + if (_disk_reader) { + _disk_reader->set_roll_delay (_initial_delay); + } } void diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 57891968b6..f451a3ed51 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -414,13 +414,6 @@ Track::set_name (const string& str) return ret; } -void -Track::set_latency_compensation (samplecnt_t longest_session_latency) -{ - Route::set_latency_compensation (longest_session_latency); - _disk_reader->set_roll_delay (_roll_delay); -} - int Track::no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool session_state_changing) { @@ -1001,42 +994,6 @@ Track::maybe_declick (BufferSet& bufs, samplecnt_t nframes, int declick) } } -samplecnt_t -Track::check_initial_delay (samplecnt_t nframes, samplepos_t& transport_sample) -{ - if (_roll_delay > nframes) { - - _roll_delay -= nframes; - silence_unlocked (nframes); - /* transport sample is not legal for caller to use */ - return 0; - - } else if (_roll_delay > 0) { - - nframes -= _roll_delay; - silence_unlocked (_roll_delay); - transport_sample += _roll_delay; - - /* shuffle all the port buffers for things that lead "out" of this Route - to reflect that we just wrote _roll_delay samples of silence. - */ - - Glib::Threads::RWLock::ReaderLock lm (_processor_lock); - for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { - boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i); - if (iop) { - iop->increment_port_buffer_offset (_roll_delay); - } - } - _output->increment_port_buffer_offset (_roll_delay); - - _roll_delay = 0; - - } - - return nframes; -} - void Track::monitoring_changed (bool, Controllable::GroupControlDisposition) { |