X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fardour%2Fardour%2Fplaylist.h;h=754e48cc25d1fbf71a2956c9e1250295b62bd71b;hb=99fb7346f07be28f548855b3e9c1ff2a174d994f;hp=7635d004bcbd6883322131d4fa967e11f5021424;hpb=16c280e40582209e151f54ea7b9d0e9b67048b68;p=ardour.git diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h index 7635d004bc..754e48cc25 100644 --- a/libs/ardour/ardour/playlist.h +++ b/libs/ardour/ardour/playlist.h @@ -32,11 +32,11 @@ #include - #include "pbd/undo.h" #include "pbd/stateful.h" #include "pbd/statefuldestructible.h" #include "pbd/sequence_property.h" +#include "pbd/stacktrace.h" #include "evoral/types.hpp" @@ -49,19 +49,19 @@ namespace ARDOUR { class Session; class Region; class Playlist; -class Crossfade; +class Crossfade; namespace Properties { - /* fake the type, since regions are handled by SequenceProperty which doesn't - care about such things. - */ - extern PBD::PropertyDescriptor regions; + /* fake the type, since regions are handled by SequenceProperty which doesn't + care about such things. + */ + extern PBD::PropertyDescriptor regions; } class RegionListProperty : public PBD::SequenceProperty > > { public: - RegionListProperty (Playlist&); + RegionListProperty (Playlist&); RegionListProperty* clone () const; void get_content_as_xml (boost::shared_ptr, XMLNode &) const; @@ -73,16 +73,15 @@ class RegionListProperty : public PBD::SequenceProperty { public: - typedef std::list > RegionList; - static void make_property_quarks (); + static void make_property_quarks (); Playlist (Session&, const XMLNode&, DataType type, bool hidden = false); Playlist (Session&, std::string name, DataType type, bool hidden = false); @@ -91,9 +90,9 @@ public: virtual ~Playlist (); - void update (const RegionListProperty::ChangeRecord&); - void clear_owned_changes (); - void rdiff (std::vector&) const; + void update (const RegionListProperty::ChangeRecord&); + void clear_owned_changes (); + void rdiff (std::vector&) const; boost::shared_ptr region_by_id (const PBD::ID&) const; @@ -109,7 +108,7 @@ public: bool used () const { return _refcnt != 0; } bool set_name (const std::string& str); - int sort_id() { return _sort_id; } + int sort_id() { return _sort_id; } const DataType& data_type() const { return _type; } @@ -119,6 +118,7 @@ public: bool hidden() const { return _hidden; } bool empty() const; uint32_t n_regions() const; + bool all_regions_empty() const; std::pair get_extent () const; layer_t top_layer() const; @@ -132,6 +132,7 @@ public: void remove_region_by_source (boost::shared_ptr); void get_equivalent_regions (boost::shared_ptr, std::vector >&); void get_region_list_equivalent_regions (boost::shared_ptr, std::vector >&); + void get_source_equivalent_regions (boost::shared_ptr, std::vector >&); void replace_region (boost::shared_ptr old, boost::shared_ptr newr, framepos_t pos); void split_region (boost::shared_ptr, framepos_t position); void split (framepos_t at); @@ -151,11 +152,11 @@ public: const RegionListProperty& region_list () const { return regions; } - RegionList* regions_at (framepos_t frame); - uint32_t count_regions_at (framepos_t) const; - uint32_t count_joined_regions () const; - RegionList* regions_touched (framepos_t start, framepos_t end); - RegionList* regions_to_read (framepos_t start, framepos_t end); + boost::shared_ptr regions_at (framepos_t frame); + uint32_t count_regions_at (framepos_t) const; + boost::shared_ptr regions_touched (framepos_t start, framepos_t end); + boost::shared_ptr regions_with_start_within (Evoral::Range); + boost::shared_ptr regions_with_end_within (Evoral::Range); uint32_t region_use_count (boost::shared_ptr) const; boost::shared_ptr find_region (const PBD::ID&) const; boost::shared_ptr top_region_at (framepos_t frame); @@ -165,14 +166,14 @@ public: bool region_is_shuffle_constrained (boost::shared_ptr); bool has_region_at (framepos_t const) const; - bool uses_source (boost::shared_ptr src) const; + bool uses_source (boost::shared_ptr src) const; framepos_t find_next_transient (framepos_t position, int dir); void foreach_region (boost::function)>); XMLNode& get_state (); - int set_state (const XMLNode&, int version); + virtual int set_state (const XMLNode&, int version); XMLNode& get_template (); PBD::Signal1 InUse; @@ -180,7 +181,6 @@ public: PBD::Signal1 > RegionAdded; PBD::Signal1 > RegionRemoved; PBD::Signal0 NameChanged; - PBD::Signal0 LengthChanged; PBD::Signal0 LayeringChanged; /** Emitted when regions have moved (not when regions have only been trimmed) */ @@ -201,17 +201,14 @@ public: void raise_region_to_top (boost::shared_ptr); void lower_region_to_bottom (boost::shared_ptr); - uint32_t read_data_count() const { return _read_data_count; } - - /* XXX: use of diskstream here is a little unfortunate */ - const PBD::ID& get_orig_diskstream_id () const { return _orig_diskstream_id; } - void set_orig_diskstream_id (const PBD::ID& did) { _orig_diskstream_id = did; } + const PBD::ID& get_orig_track_id () const { return _orig_track_id; } + void set_orig_track_id (const PBD::ID& did); /* destructive editing */ virtual bool destroy_region (boost::shared_ptr) = 0; - void sync_all_regions_with_regions (); + void sync_all_regions_with_regions (); /* special case function used by UI selection objects, which have playlists that actually own the regions within them. @@ -219,56 +216,60 @@ public: void drop_regions (); - bool explicit_relayering () const { - return _explicit_relayering; - } - - void set_explicit_relayering (bool e); - virtual boost::shared_ptr find_crossfade (const PBD::ID &) const { return boost::shared_ptr (); } - framepos_t find_next_top_layer_position (framepos_t) const; + framepos_t find_next_top_layer_position (framepos_t) const; uint32_t combine_ops() const { return _combine_ops; } + void set_layer (boost::shared_ptr, double); + + void set_capture_insertion_in_progress (bool yn); + protected: friend class Session; protected: - struct RegionLock { - RegionLock (Playlist *pl, bool do_block_notify = true) : playlist (pl), block_notify (do_block_notify) { - playlist->region_lock.lock(); - if (block_notify) { - playlist->delay_notifications(); - } - } - ~RegionLock() { - playlist->region_lock.unlock(); - if (block_notify) { - playlist->release_notifications (); - } - } - Playlist *playlist; - bool block_notify; - }; - - friend class RegionLock; - - RegionListProperty regions; /* the current list of regions in the playlist */ + class RegionReadLock : public Glib::Threads::RWLock::ReaderLock { + public: + RegionReadLock (Playlist *pl) : Glib::Threads::RWLock::ReaderLock (pl->region_lock) {} + ~RegionReadLock() {} + }; + + class RegionWriteLock : public Glib::Threads::RWLock::WriterLock { + public: + RegionWriteLock (Playlist *pl, bool do_block_notify = true) + : Glib::Threads::RWLock::WriterLock (pl->region_lock) + , playlist (pl) + , block_notify (do_block_notify) { + if (block_notify) { + playlist->delay_notifications(); + } + } + + ~RegionWriteLock() { + Glib::Threads::RWLock::WriterLock::release (); + if (block_notify) { + playlist->release_notifications (); + } + } + Playlist *playlist; + bool block_notify; + }; + + RegionListProperty regions; /* the current list of regions in the playlist */ std::set > all_regions; /* all regions ever added to this playlist */ PBD::ScopedConnectionList region_state_changed_connections; DataType _type; - int _sort_id; + int _sort_id; mutable gint block_notifications; mutable gint ignore_state_changes; - mutable Glib::RecMutex region_lock; std::set > pending_adds; std::set > pending_removes; RegionList pending_bounds; bool pending_contents_change; bool pending_layering; - bool pending_length; /** Movements of time ranges caused by region moves; note that * region trims are not included in this list; it is used to @@ -277,10 +278,8 @@ public: std::list< Evoral::RangeMove > pending_range_moves; /** Extra sections added to regions during trims */ std::list< Evoral::Range > pending_region_extensions; - bool save_on_thaw; - std::string last_save_reason; uint32_t in_set_state; - bool in_update; + bool in_undo; bool first_set_state; bool _hidden; bool _splicing; @@ -291,20 +290,11 @@ public: bool in_flush; bool in_partition; bool _frozen; + bool _capture_insertion_underway; uint32_t subcnt; - uint32_t _read_data_count; - PBD::ID _orig_diskstream_id; - uint64_t layer_op_counter; - framecnt_t freeze_length; - bool auto_partition; + PBD::ID _orig_track_id; uint32_t _combine_ops; - /** true if relayering should be done using region's current layers and their `pending explicit relayer' - * flags; otherwise false if relayering should be done using the layer-model (most recently moved etc.) - * Explicit relayering is used by tracks in stacked regionview mode. - */ - bool _explicit_relayering; - void init (bool hide); bool holding_state () const { @@ -317,11 +307,12 @@ public: virtual void flush_notifications (bool from_undo = false); void clear_pending (); - void _set_sort_id (); + void _set_sort_id (); + + boost::shared_ptr regions_touched_locked (framepos_t start, framepos_t end); void notify_region_removed (boost::shared_ptr); void notify_region_added (boost::shared_ptr); - void notify_length_changed (); void notify_layering_changed (); void notify_contents_changed (); void notify_state_changed (const PBD::PropertyChange&); @@ -346,10 +337,6 @@ public: void splice_locked (framepos_t at, framecnt_t distance, boost::shared_ptr exclude); void splice_unlocked (framepos_t at, framecnt_t distance, boost::shared_ptr exclude); - virtual void finalize_split_region (boost::shared_ptr /*original*/, boost::shared_ptr /*left*/, boost::shared_ptr /*right*/) {} - - virtual void check_dependents (boost::shared_ptr /*region*/, bool /*norefresh*/) {} - virtual void refresh_dependents (boost::shared_ptr /*region*/) {} virtual void remove_dependents (boost::shared_ptr /*region*/) {} virtual XMLNode& state (bool); @@ -357,7 +344,6 @@ public: bool add_region_internal (boost::shared_ptr, framepos_t position); int remove_region_internal (boost::shared_ptr); - RegionList *find_regions_at (framepos_t); void copy_regions (RegionList&) const; void partition_internal (framepos_t start, framepos_t end, bool cutting, RegionList& thawlist); @@ -368,27 +354,14 @@ public: boost::shared_ptr cut (framepos_t start, framecnt_t cnt, bool result_is_hidden); boost::shared_ptr copy (framepos_t start, framecnt_t cnt, bool result_is_hidden); - int move_region_to_layer (layer_t, boost::shared_ptr r, int dir); void relayer (); void begin_undo (); void end_undo (); - void unset_freeze_parent (Playlist*); - void unset_freeze_child (Playlist*); - - void timestamp_layer_op (boost::shared_ptr); void _split_region (boost::shared_ptr, framepos_t position); typedef std::pair, boost::shared_ptr > TwoRegions; - virtual void copy_dependents (const std::vector&, boost::shared_ptr) { } - - struct RegionInfo { - boost::shared_ptr region; - framepos_t position; - framecnt_t length; - framepos_t start; - }; /* this is called before we create a new compound region */ virtual void pre_combine (std::vector >&) {} @@ -398,6 +371,16 @@ public: with its constituent regions */ virtual void pre_uncombine (std::vector >&, boost::shared_ptr) {} + + private: + friend class RegionReadLock; + friend class RegionWriteLock; + mutable Glib::Threads::RWLock region_lock; + + private: + void setup_layering_indices (RegionList const &); + void coalesce_and_check_crossfades (std::list >); + boost::shared_ptr find_regions_at (framepos_t); }; } /* namespace ARDOUR */