X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Fregion.h;h=a695d9e5ed5305b1c123b05a0d40d21cf894a629;hb=a855119bdd94aad90f4cfec3066a367b0675a8e9;hp=866f489037eaf7a22a5c1ca2181555f1ff87a406;hpb=dca96d8b5d6737ec811cf5a46548d39a7912bec8;p=ardour.git diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index 866f489037..a695d9e5ed 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -1,21 +1,25 @@ /* - Copyright (C) 2000-2001 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ + * Copyright (C) 2000-2017 Paul Davis + * Copyright (C) 2006-2014 David Robillard + * Copyright (C) 2007-2012 Carl Hetherington + * Copyright (C) 2013-2019 Robin Gareus + * Copyright (C) 2015-2017 Nick Mainsbridge + * Copyright (C) 2018 Ben Loftis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #ifndef __ardour_region_h__ #define __ardour_region_h__ @@ -34,6 +38,7 @@ #include "ardour/readable.h" #include "ardour/session_object.h" #include "ardour/trimmable.h" +#include "ardour/types_convert.h" class XMLNode; @@ -54,18 +59,20 @@ namespace Properties { LIBARDOUR_API extern PBD::PropertyDescriptor hidden; LIBARDOUR_API extern PBD::PropertyDescriptor position_locked; LIBARDOUR_API extern PBD::PropertyDescriptor valid_transients; - LIBARDOUR_API extern PBD::PropertyDescriptor start; - LIBARDOUR_API extern PBD::PropertyDescriptor length; - LIBARDOUR_API extern PBD::PropertyDescriptor position; + LIBARDOUR_API extern PBD::PropertyDescriptor start; + LIBARDOUR_API extern PBD::PropertyDescriptor length; + LIBARDOUR_API extern PBD::PropertyDescriptor position; LIBARDOUR_API extern PBD::PropertyDescriptor beat; - LIBARDOUR_API extern PBD::PropertyDescriptor sync_position; + LIBARDOUR_API extern PBD::PropertyDescriptor sync_position; LIBARDOUR_API extern PBD::PropertyDescriptor layer; - LIBARDOUR_API extern PBD::PropertyDescriptor ancestral_start; - LIBARDOUR_API extern PBD::PropertyDescriptor ancestral_length; + LIBARDOUR_API extern PBD::PropertyDescriptor ancestral_start; + LIBARDOUR_API extern PBD::PropertyDescriptor ancestral_length; LIBARDOUR_API extern PBD::PropertyDescriptor stretch; LIBARDOUR_API extern PBD::PropertyDescriptor shift; LIBARDOUR_API extern PBD::PropertyDescriptor position_lock_style; LIBARDOUR_API extern PBD::PropertyDescriptor layering_index; + LIBARDOUR_API extern PBD::PropertyDescriptor tags; + LIBARDOUR_API extern PBD::PropertyDescriptor contents; // type doesn't matter here }; class Playlist; @@ -87,7 +94,7 @@ class LIBARDOUR_API Region , public Trimmable , public Movable { - public: +public: typedef std::vector > SourceList; static void make_property_quarks (); @@ -103,56 +110,58 @@ class LIBARDOUR_API Region /** How the region parameters play together: * - * POSITION: first frame of the region along the timeline - * START: first frame of the region within its source(s) - * LENGTH: number of frames the region represents + * POSITION: first sample of the region along the timeline + * START: first sample of the region within its source(s) + * LENGTH: number of samples the region represents */ - framepos_t position () const { return _position; } - framepos_t start () const { return _start; } - framecnt_t length () const { return _length; } + samplepos_t position () const { return _position; } + samplepos_t start () const { return _start; } + samplecnt_t length () const { return _length; } layer_t layer () const { return _layer; } - framecnt_t source_length(uint32_t n) const; + void set_selected_for_solo(bool yn); + + samplecnt_t source_length (uint32_t n) const; uint32_t max_source_level () const; /* these two are valid ONLY during a StateChanged signal handler */ - framepos_t last_position () const { return _last_position; } - framecnt_t last_length () const { return _last_length; } + samplepos_t last_position () const { return _last_position; } + samplecnt_t last_length () const { return _last_length; } - framepos_t ancestral_start () const { return _ancestral_start; } - framecnt_t ancestral_length () const { return _ancestral_length; } + samplepos_t ancestral_start () const { return _ancestral_start; } + samplecnt_t ancestral_length () const { return _ancestral_length; } float stretch () const { return _stretch; } float shift () const { return _shift; } - void set_ancestral_data (framepos_t start, framecnt_t length, float stretch, float shift); + void set_ancestral_data (samplepos_t start, samplecnt_t length, float stretch, float shift); - frameoffset_t sync_offset (int& dir) const; - framepos_t sync_position () const; + sampleoffset_t sync_offset (int& dir) const; + samplepos_t sync_position () const; - framepos_t adjust_to_sync (framepos_t) const; + samplepos_t adjust_to_sync (samplepos_t) const; - /* first_frame() is an alias; last_frame() just hides some math */ + /* first_sample() is an alias; last_sample() just hides some math */ - framepos_t first_frame () const { return _position; } - framepos_t last_frame () const { return _position + _length - 1; } + samplepos_t first_sample () const { return _position; } + samplepos_t last_sample () const { return _position + _length - 1; } /** Return the earliest possible value of _position given the * value of _start within the region's sources */ - framepos_t earliest_possible_position () const; - /** Return the last possible value of _last_frame given the + samplepos_t earliest_possible_position () const; + /** Return the last possible value of _last_sample given the * value of _startin the regions's sources */ - framepos_t latest_possible_frame () const; + samplepos_t latest_possible_sample () const; - Evoral::Range last_range () const { - return Evoral::Range (_last_position, _last_position + _last_length - 1); + Evoral::Range last_range () const { + return Evoral::Range (_last_position, _last_position + _last_length - 1); } - Evoral::Range range () const { - return Evoral::Range (first_frame(), last_frame()); + Evoral::Range range () const { + return Evoral::Range (first_sample(), last_sample()); } bool hidden () const { return _hidden; } @@ -178,14 +187,14 @@ class LIBARDOUR_API Region /* meter-based beat at the region position */ double beat () const { return _beat; } void set_beat (double beat) { _beat = beat; } - /* quarter-note beats at the region position (for use with Evoral::Beats) */ - double pos_beats () const { return _pos_beats; } - void set_pos_beats (double pb) { _pos_beats = pb; } + /* quarter-note at the region position */ + double quarter_note () const { return _quarter_note; } + void set_quarter_note (double qn) { _quarter_note = qn; } void suspend_property_changes (); - bool covers (framepos_t frame) const { - return first_frame() <= frame && frame <= last_frame(); + bool covers (samplepos_t sample) const { + return first_sample() <= sample && sample <= last_sample(); } /** @return coverage of this region with the given range; @@ -194,13 +203,15 @@ class LIBARDOUR_API Region * OverlapEnd: the range overlaps the end of this region. * OverlapExternal: the range overlaps all of this region. */ - Evoral::OverlapType coverage (framepos_t start, framepos_t end) const { - return Evoral::coverage (first_frame(), last_frame(), start, end); + Evoral::OverlapType coverage (samplepos_t start, samplepos_t end) const { + return Evoral::coverage (first_sample(), last_sample(), start, end); } - bool equivalent (boost::shared_ptr) const; + bool exact_equivalent (boost::shared_ptr) const; bool size_equivalent (boost::shared_ptr) const; bool overlap_equivalent (boost::shared_ptr) const; + bool enclosed_equivalent (boost::shared_ptr) const; + bool layer_and_time_equivalent (boost::shared_ptr) const; bool region_list_equivalent (boost::shared_ptr) const; bool source_equivalent (boost::shared_ptr) const; bool any_source_equivalent (boost::shared_ptr) const; @@ -212,26 +223,27 @@ class LIBARDOUR_API Region /* EDITING OPERATIONS */ - void set_length (framecnt_t, const int32_t sub_num); - void set_start (framepos_t); - void set_position (framepos_t, int32_t sub_num = 0); - void set_initial_position (framepos_t); - void special_set_position (framepos_t); + void set_length (samplecnt_t, const int32_t sub_num); + void set_start (samplepos_t); + void set_position (samplepos_t, int32_t sub_num = 0); + void set_position_music (double qn); + void set_initial_position (samplepos_t); + void special_set_position (samplepos_t); virtual void update_after_tempo_map_change (bool send_change = true); - void nudge_position (frameoffset_t); + void nudge_position (sampleoffset_t); bool at_natural_position () const; void move_to_natural_position (); - void move_start (frameoffset_t distance, const int32_t sub_num = 0); - void trim_front (framepos_t new_position, const int32_t sub_num = 0); - void trim_end (framepos_t new_position, const int32_t sub_num = 0); - void trim_to (framepos_t position, framecnt_t length, const int32_t sub_num = 0); + void move_start (sampleoffset_t distance, const int32_t sub_num = 0); + void trim_front (samplepos_t new_position, const int32_t sub_num = 0); + void trim_end (samplepos_t new_position, const int32_t sub_num = 0); + void trim_to (samplepos_t position, samplecnt_t length, const int32_t sub_num = 0); - virtual void fade_range (framepos_t, framepos_t) {} + virtual void fade_range (samplepos_t, samplepos_t) {} - void cut_front (framepos_t new_position, const int32_t sub_num = 0); - void cut_end (framepos_t new_position, const int32_t sub_num = 0); + void cut_front (samplepos_t new_position, const int32_t sub_num = 0); + void cut_end (samplepos_t new_position, const int32_t sub_num = 0); void set_layer (layer_t l); /* ONLY Playlist can call this */ void raise (); @@ -239,7 +251,7 @@ class LIBARDOUR_API Region void raise_to_top (); void lower_to_bottom (); - void set_sync_position (framepos_t n); + void set_sync_position (samplepos_t n); void clear_sync_position (); void set_hidden (bool yn); void set_muted (bool yn); @@ -276,10 +288,20 @@ class LIBARDOUR_API Region virtual boost::shared_ptr control (const Evoral::Parameter& id) const = 0; + /* tags */ + + std::string tags() const { return _tags; } + virtual bool set_tags (const std::string& str) { + if (_tags != str) { + _tags = str; + PropertyChanged (PBD::PropertyChange (Properties::tags)); + } + return true; + } + /* serialization */ XMLNode& get_state (); - virtual XMLNode& state (); virtual int set_state (const XMLNode&, int version); virtual boost::shared_ptr get_parent() const; @@ -290,7 +312,7 @@ class LIBARDOUR_API Region virtual bool is_dependent() const { return false; } virtual bool depends_on (boost::shared_ptr /*other*/) const { return false; } - virtual void add_transient (framepos_t) { + virtual void add_transient (samplepos_t) { // no transients, but its OK } @@ -298,11 +320,11 @@ class LIBARDOUR_API Region // no transients, but its OK } - virtual void update_transient (framepos_t /* old_position */, framepos_t /* new_position */) { + virtual void update_transient (samplepos_t /* old_position */, samplepos_t /* new_position */) { // no transients, but its OK } - virtual void remove_transient (framepos_t /* where */) { + virtual void remove_transient (samplepos_t /* where */) { // no transients, but its OK } @@ -325,18 +347,26 @@ class LIBARDOUR_API Region // no transients, but its OK } + /* wrapper to the above for easy access throug Lua */ + AnalysisFeatureList transients () { + AnalysisFeatureList rv; + get_transients (rv); + return rv; + } + bool has_transients () const; - virtual int separate_by_channel (ARDOUR::Session&, - std::vector< boost::shared_ptr >&) const { - return 0; + virtual int separate_by_channel (std::vector< boost::shared_ptr >&) const { + return -1; } void maybe_invalidate_transients (); void drop_sources (); - protected: +protected: + virtual XMLNode& state (); + friend class RegionFactory; /** Construct a region from multiple sources*/ @@ -346,27 +376,28 @@ class LIBARDOUR_API Region Region (boost::shared_ptr); /** Construct a region from another region, at an offset within that region */ - Region (boost::shared_ptr, frameoffset_t start_offset, const int32_t sub_num); + Region (boost::shared_ptr, ARDOUR::MusicSample start_offset); /** Construct a region as a copy of another region, but with different sources */ Region (boost::shared_ptr, const SourceList&); /** Constructor for derived types only */ - Region (Session& s, framepos_t start, framecnt_t length, const std::string& name, DataType); + Region (Session& s, samplepos_t start, samplecnt_t length, const std::string& name, DataType); virtual bool can_trim_start_before_source_start () const { return false; } - protected: +protected: void send_change (const PBD::PropertyChange&); virtual int _set_state (const XMLNode&, int version, PBD::PropertyChange& what_changed, bool send_signal); void post_set (const PBD::PropertyChange&); - virtual void set_position_internal (framepos_t pos, bool allow_bbt_recompute, const int32_t sub_num); - virtual void set_length_internal (framecnt_t, const int32_t sub_num); - virtual void set_start_internal (framecnt_t, const int32_t sub_num = 0); - bool verify_start_and_length (framepos_t, framecnt_t&); + virtual void set_position_internal (samplepos_t pos, bool allow_bbt_recompute, const int32_t sub_num); + virtual void set_position_music_internal (double qn); + virtual void set_length_internal (samplecnt_t, const int32_t sub_num); + virtual void set_start_internal (samplecnt_t, const int32_t sub_num = 0); + bool verify_start_and_length (samplepos_t, samplecnt_t&); void first_edit (); DataType _type; @@ -375,14 +406,14 @@ class LIBARDOUR_API Region PBD::Property _left_of_split; PBD::Property _right_of_split; PBD::Property _valid_transients; - PBD::Property _start; - PBD::Property _length; - PBD::Property _position; + PBD::Property _start; + PBD::Property _length; + PBD::Property _position; PBD::Property _beat; /** Sync position relative to the start of our file */ - PBD::Property _sync_position; + PBD::Property _sync_position; - double _pos_beats; + double _quarter_note; SourceList _sources; /** Used when timefx are applied, so we can always use the original source */ @@ -390,31 +421,33 @@ class LIBARDOUR_API Region boost::weak_ptr _playlist; - void merge_features (AnalysisFeatureList&, const AnalysisFeatureList&, const frameoffset_t) const; + void merge_features (AnalysisFeatureList&, const AnalysisFeatureList&, const sampleoffset_t) const; AnalysisFeatureList _onsets; // used by the Ferret (Aubio OnsetDetector) // _transient_user_start is covered by _valid_transients AnalysisFeatureList _user_transients; // user added - framepos_t _transient_user_start; // region's _start relative to user_transients + samplepos_t _transient_user_start; // region's _start relative to user_transients // these are used by Playlist::find_next_transient() in absence of onsets AnalysisFeatureList _transients; // Source Analysis (QM Transient), user read-only - framepos_t _transient_analysis_start; - framepos_t _transient_analysis_end; + samplepos_t _transient_analysis_start; + samplepos_t _transient_analysis_end; + + bool _soloSelected; - private: +private: void mid_thaw (const PBD::PropertyChange&); - virtual void trim_to_internal (framepos_t position, framecnt_t length, const int32_t sub_num); - void modify_front (framepos_t new_position, bool reset_fade, const int32_t sub_num); - void modify_end (framepos_t new_position, bool reset_fade, const int32_t sub_num); + virtual void trim_to_internal (samplepos_t position, samplecnt_t length, const int32_t sub_num); + void modify_front (samplepos_t new_position, bool reset_fade, const int32_t sub_num); + void modify_end (samplepos_t new_position, bool reset_fade, const int32_t sub_num); void maybe_uncopy (); - bool verify_start (framepos_t); - bool verify_start_mutable (framepos_t&_start); - bool verify_length (framecnt_t&); + bool verify_start (samplepos_t); + bool verify_start_mutable (samplepos_t&_start); + bool verify_length (samplecnt_t&); virtual void recompute_at_start () = 0; virtual void recompute_at_end () = 0; @@ -429,15 +462,17 @@ class LIBARDOUR_API Region PBD::Property _external; PBD::Property _hidden; PBD::Property _position_locked; - PBD::Property _ancestral_start; - PBD::Property _ancestral_length; + PBD::Property _ancestral_start; + PBD::Property _ancestral_length; PBD::Property _stretch; PBD::Property _shift; PBD::EnumProperty _position_lock_style; PBD::Property _layering_index; + PBD::Property _tags; + PBD::Property _contents; // type is irrelevant - framecnt_t _last_length; - framepos_t _last_position; + samplecnt_t _last_length; + samplepos_t _last_position; mutable RegionEditState _first_edit; layer_t _layer;