Fix underruns when looping/locating and changing region content
Previously loop-wrap around asked the butler to perform a unnecessary seek operation next time it is summoned. If the butler is then summoned for a PostTransportOverWrite event, the seek causes a DR::Underrun.
This commit is contained in:
parent
5af023c70b
commit
18e0cba1cb
@ -560,6 +560,7 @@ DiskReader::pending_overwrite () const
|
|||||||
void
|
void
|
||||||
DiskReader::set_pending_overwrite (OverwriteReason why)
|
DiskReader::set_pending_overwrite (OverwriteReason why)
|
||||||
{
|
{
|
||||||
|
DEBUG_TRACE (DEBUG::DiskIO, string_compose ("%1 set_pending_overwrite because %3%4%5\n", owner ()->name (), std::hex, why, std::dec));
|
||||||
std::shared_ptr<ChannelList const> c = channels.reader ();
|
std::shared_ptr<ChannelList const> c = channels.reader ();
|
||||||
|
|
||||||
/* called from audio thread, so we can use the read ptr and playback sample as we wish */
|
/* called from audio thread, so we can use the read ptr and playback sample as we wish */
|
||||||
@ -862,9 +863,10 @@ DiskReader::seek (samplepos_t sample, bool complete_refill)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_pending_overwrite.store (OverwriteReason (0));
|
DEBUG_TRACE (DEBUG::DiskIO, string_compose ("DiskReader::seek %1 %2 -> %3 refill=%4 pending_overwrite = %5\n",
|
||||||
|
owner ()->name (), playback_sample, sample, complete_refill, _pending_overwrite.load ()));
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::DiskIO, string_compose ("DiskReader::seek %1 %2 -> %3 refill=%4\n", owner ()->name ().c_str (), playback_sample, sample, complete_refill));
|
_pending_overwrite.store (OverwriteReason (0));
|
||||||
|
|
||||||
const samplecnt_t distance = sample - playback_sample;
|
const samplecnt_t distance = sample - playback_sample;
|
||||||
if (!complete_refill && can_internal_playback_seek (distance)) {
|
if (!complete_refill && can_internal_playback_seek (distance)) {
|
||||||
|
@ -202,9 +202,12 @@ Session::locate (samplepos_t target_sample, bool for_loop_end, bool force, bool
|
|||||||
// Update Timecode time
|
// Update Timecode time
|
||||||
_transport_sample = target_sample;
|
_transport_sample = target_sample;
|
||||||
_nominal_jack_transport_sample = boost::none;
|
_nominal_jack_transport_sample = boost::none;
|
||||||
// Bump seek counter so that any in-process locate in the butler
|
|
||||||
// thread(s?) can restart.
|
/* Note that loop wrap-around locates do not need to call "seek" */
|
||||||
_seek_counter.fetch_add (1);
|
if (force || !for_loop_end) {
|
||||||
|
/* Bump seek counter so that any in-process locate in the butler can restart */
|
||||||
|
_seek_counter.fetch_add (1);
|
||||||
|
}
|
||||||
_last_roll_or_reversal_location = target_sample;
|
_last_roll_or_reversal_location = target_sample;
|
||||||
if (!for_loop_end && !_exporting) {
|
if (!for_loop_end && !_exporting) {
|
||||||
_remaining_latency_preroll = worst_latency_preroll_buffer_size_ceil ();
|
_remaining_latency_preroll = worst_latency_preroll_buffer_size_ceil ();
|
||||||
@ -1206,7 +1209,10 @@ Session::butler_transport_work (bool have_process_lock)
|
|||||||
non_realtime_locate ();
|
non_realtime_locate ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptw & PostTransportOverWrite) {
|
/* if we just performed a locate, buffers have been refilled.
|
||||||
|
* This effectively has done the work of "PostTransportOverWrite" already.
|
||||||
|
*/
|
||||||
|
else if (ptw & PostTransportOverWrite) {
|
||||||
non_realtime_overwrite (on_entry, finished, (ptw & PostTransportLoopChanged));
|
non_realtime_overwrite (on_entry, finished, (ptw & PostTransportLoopChanged));
|
||||||
if (!finished) {
|
if (!finished) {
|
||||||
(void) PBD::atomic_dec_and_test (_butler->should_do_transport_work);
|
(void) PBD::atomic_dec_and_test (_butler->should_do_transport_work);
|
||||||
|
Loading…
Reference in New Issue
Block a user