mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 06:44:57 +01:00
attempt to fix roll delay logic by moving it into DiskReader (the only place it matters)
This commit is contained in:
parent
cb71d49dc6
commit
48d11000e5
5 changed files with 67 additions and 57 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue