From e62f1093ea8851289278aba36470811b7a282cef Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 9 Sep 2022 17:30:32 +0200 Subject: [PATCH] Add playlist APIs to find audible regions This traverses the layered region stack at a given time, taking both mute and transparency into account. --- libs/ardour/ardour/playlist.h | 2 ++ libs/ardour/playlist.cc | 60 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index a71d921025..59d86b6e80 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -225,6 +225,7 @@ public: boost::shared_ptr regions_touched (timepos_t const & start, timepos_t const & end); boost::shared_ptr regions_with_start_within (Temporal::TimeRange); boost::shared_ptr regions_with_end_within (Temporal::TimeRange); + boost::shared_ptr audible_regions_at (timepos_t const &); uint32_t region_use_count (boost::shared_ptr) const; boost::shared_ptr find_region (const PBD::ID&) const; boost::shared_ptr top_region_at (timepos_t const &); @@ -233,6 +234,7 @@ public: timepos_t find_next_region_boundary (timepos_t const &, int dir); bool region_is_shuffle_constrained (boost::shared_ptr); bool has_region_at (timepos_t const &) const; + bool region_is_audible_at (boost::shared_ptr, timepos_t const&); timepos_t find_prev_region_start (timepos_t const & sample); diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index f5052cffd0..dff0ffa5db 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -1838,6 +1838,66 @@ Playlist::top_unmuted_region_at (timepos_t const & pos) return region; } +boost::shared_ptr +Playlist::audible_regions_at (timepos_t const& pos) +{ + boost::shared_ptr rv (new RegionList); + boost::shared_ptr rlist; + { + RegionReadLock rlock (this); + rlist = find_regions_at (pos); + } + + if (!rlist->size ()) { + return rv; + } + + RegionSortByLayer cmp; + rlist->sort (cmp); + + for (auto i = rlist->rbegin (); i != rlist->rend (); ++i) { + if ((*i)->muted ()) { + continue; + } + rv->push_back (*i); + if ((*i)->opaque ()) { + break; + } + } + + return rv; +} + +bool +Playlist::region_is_audible_at (boost::shared_ptr r, timepos_t const& pos) +{ + boost::shared_ptr rlist; + { + RegionReadLock rlock (this); + rlist = find_regions_at (pos); + } + + if (!rlist->size ()) { + return false; + } + + RegionSortByLayer cmp; + rlist->sort (cmp); + + for (auto i = rlist->rbegin (); i != rlist->rend (); ++i) { + if ((*i)->muted ()) { + continue; + } + if (r == *i) { + return true; + } + if ((*i)->opaque ()) { + break; + } + } + return false; +} + boost::shared_ptr Playlist::find_regions_at (timepos_t const & pos) {