Fix artifacts with concurrent region read / shared playlists

This commit is contained in:
Robin Gareus 2025-11-30 16:55:49 +01:00 committed by Nicolas Koch
parent 1b5c231d01
commit d13f02e65a
2 changed files with 22 additions and 0 deletions

View file

@ -274,6 +274,7 @@ class LIBARDOUR_API AudioRegion : public Region, public AudioReadable
pframes_t _fx_block_size;
mutable bool _fx_latent_read;
mutable Glib::Threads::Mutex _read_lock;
mutable Glib::Threads::Mutex _cache_lock;
mutable BufferSet _readcache;
mutable samplepos_t _cache_start;

View file

@ -725,6 +725,25 @@ AudioRegion::read_at (Sample* buf,
}
}
/* Prevent concurrent reads for the same region
* which can happen with shared playlists, or
* after unfreeze of a copied playlist.
*
* Concurrent calls will cause issues when
* * evaluating gain/fade curves (ControlList lookup_cache)
* * evaulating regionFX
*
* This lock is not usually contended, since usually
* regions are unique.
*
* Note that AudioSource::read is also exclusive
* since libsndfile is not thread-safe either.
* So a more fine-grained lock strategy below
* (envelope/fades/regionFX) will not make a
* significant difference.
*/
Glib::Threads::Mutex::Lock crl (_read_lock);
Glib::Threads::Mutex::Lock cl (_cache_lock);
if (chan_n == 0 && _invalidated.exchange (false)) {
_cache_start = _cache_end = -1;
@ -1039,6 +1058,8 @@ endread:
}
}
crl.release ();
/* MIX OR COPY THE REGION BODY FROM mixdown_buffer INTO buf */
samplecnt_t const N = to_read - fade_in_limit - fade_out_limit;