From d40bdf5e956b2b0fb7e6f780cc222fd97e6d16eb Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sun, 9 Aug 2020 14:18:28 -0600 Subject: [PATCH] first round of changes to use timeline types, here basically for Region position/length/start UNFINISHED WORK. Does not compile. But region.cc will compile, hence this snapshot --- libs/ardour/ardour/audioregion.h | 1 - libs/ardour/ardour/audiorom.h | 2 +- libs/ardour/ardour/midi_region.h | 12 +- libs/ardour/ardour/readable.h | 2 +- libs/ardour/ardour/region.h | 141 ++++++---- libs/ardour/ardour/types.h | 6 + libs/ardour/ardour/types_convert.h | 55 ++++ libs/ardour/ebur128_analysis.cc | 2 +- libs/ardour/filter.cc | 8 +- libs/ardour/midi_region.cc | 18 -- libs/ardour/playlist.cc | 2 + libs/ardour/rb_effect.cc | 30 +- libs/ardour/region.cc | 438 +++++++++++++---------------- libs/ardour/reverse.cc | 12 +- libs/ardour/strip_silence.cc | 17 +- 15 files changed, 384 insertions(+), 362 deletions(-) diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index 83371abb3a..1288255221 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -113,7 +113,6 @@ class LIBARDOUR_API AudioRegion : public Region /* Readable interface */ virtual samplecnt_t read (Sample*, samplepos_t pos, samplecnt_t cnt, int channel) const; - virtual samplecnt_t readable_length() const { return length(); } virtual samplecnt_t read_at (Sample *buf, Sample *mixdown_buf, float *gain_buf, samplepos_t position, diff --git a/libs/ardour/ardour/audiorom.h b/libs/ardour/ardour/audiorom.h index 605e12dfa7..eda1e117b1 100644 --- a/libs/ardour/ardour/audiorom.h +++ b/libs/ardour/ardour/audiorom.h @@ -34,7 +34,7 @@ public: ~AudioRom(); samplecnt_t read (Sample*, samplepos_t pos, samplecnt_t cnt, int channel) const; - samplecnt_t readable_length() const { return _size; } + samplecnt_t readable_length_samples() const { return _size; } uint32_t n_channels () const { return 1; } private: diff --git a/libs/ardour/ardour/midi_region.h b/libs/ardour/ardour/midi_region.h index 16c7e2d113..75a03c7887 100644 --- a/libs/ardour/ardour/midi_region.h +++ b/libs/ardour/ardour/midi_region.h @@ -77,7 +77,6 @@ class LIBARDOUR_API MidiRegion : public Region /* Stub Readable interface */ virtual samplecnt_t read (Sample*, samplepos_t /*pos*/, samplecnt_t /*cnt*/, int /*channel*/) const { return 0; } - virtual samplecnt_t readable_length() const { return length(); } samplecnt_t read_at (Evoral::EventSink& dst, samplepos_t position, @@ -157,12 +156,11 @@ class LIBARDOUR_API MidiRegion : public Region bool set_name (const std::string & str); - void set_position_internal (samplepos_t pos, bool allow_bbt_recompute, const int32_t sub_num); - void set_position_music_internal (double qn); - void set_length_internal (samplecnt_t len, const int32_t sub_num); - void set_start_internal (samplecnt_t, const int32_t sub_num); - void trim_to_internal (samplepos_t position, samplecnt_t length, const int32_t sub_num); - void update_length_beats (const int32_t sub_num); + void set_position_internal (timepos_t pos); + void set_length_internal (timecnt_t const & len); + void set_start_internal (timecnt_t const &); + void trim_to_internal (timepos_t position, timecnt_t const & length); + void update_length_beats (); void model_changed (); void model_contents_changed (); diff --git a/libs/ardour/ardour/readable.h b/libs/ardour/ardour/readable.h index ada47776cf..2ac8c77ae0 100644 --- a/libs/ardour/ardour/readable.h +++ b/libs/ardour/ardour/readable.h @@ -35,7 +35,7 @@ public: load (Session&, std::string const&); virtual samplecnt_t read (Sample*, samplepos_t pos, samplecnt_t cnt, int channel) const = 0; - virtual samplecnt_t readable_length() const = 0; + virtual samplecnt_t readable_length_samples() const = 0; virtual uint32_t n_channels () const = 0; }; diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index 2ad1be7a8d..4b2662fb81 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -29,6 +29,8 @@ #include #include +#include "temporal/timeline.h" + #include "pbd/undo.h" #include "pbd/signals.h" #include "ardour/ardour.h" @@ -59,14 +61,14 @@ 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; @@ -116,9 +118,22 @@ public: * START: first sample of the region within its source(s) * LENGTH: number of samples the region represents */ - samplepos_t position () const { return _position; } - samplepos_t start () const { return _start; } - samplecnt_t length () const { return _length; } + + timepos_t nt_position () const { return _position.val(); } + timecnt_t nt_start () const { return _start.val(); } + timecnt_t nt_length () const { return _length.val(); } + timepos_t nt_end() const; + + timepos_t source_position () const; + timepos_t source_relative_position (Temporal::timepos_t const &) const; + timepos_t region_relative_position (Temporal::timepos_t const &) const; + + samplepos_t position_sample () const { return _position.val().samples(); } + samplecnt_t start_sample () const { return _start.val().samples(); } + samplecnt_t length_samples () const { return _length.val().samples(); } + + samplecnt_t readable_length_samples() const { return length_samples(); } + layer_t layer () const { return _layer; } void set_selected_for_solo(bool yn); @@ -128,38 +143,41 @@ public: /* these two are valid ONLY during a StateChanged signal handler */ - samplepos_t last_position () const { return _last_position; } - samplecnt_t last_length () const { return _last_length; } + timepos_t last_position () const { return _last_position; } + timecnt_t last_length () const { return _last_length; } - samplepos_t ancestral_start () const { return _ancestral_start; } - samplecnt_t ancestral_length () const { return _ancestral_length; } + samplecnt_t ancestral_start_sample () const { return _ancestral_start.val().samples(); } + samplecnt_t ancestral_length_samples () const { return _ancestral_length.val().samples(); } + timecnt_t ancestral_start () const { return _ancestral_start.val(); } + timecnt_t ancestral_length () const { return _ancestral_length.val(); } float stretch () const { return _stretch; } float shift () const { return _shift; } - void set_ancestral_data (samplepos_t start, samplecnt_t length, float stretch, float shift); + void set_ancestral_data (timecnt_t const & start, timecnt_t const & length, float stretch, float shift); - sampleoffset_t sync_offset (int& dir) const; - samplepos_t sync_position () const; + timecnt_t sync_offset (int& dir) const; + timepos_t sync_position () const; - samplepos_t adjust_to_sync (samplepos_t) const; + timepos_t adjust_to_sync (timepos_t) const; /* first_sample() is an alias; last_sample() just hides some math */ - samplepos_t first_sample () const { return _position; } - samplepos_t last_sample () const { return _position + _length - 1; } + samplepos_t first_sample () const { return _position.val().samples(); } + samplepos_t last_sample () const { return first_sample() + length_samples() - 1; } /** Return the earliest possible value of _position given the * value of _start within the region's sources */ - samplepos_t earliest_possible_position () const; + timepos_t earliest_possible_position () const; /** Return the last possible value of _last_sample given the * value of _startin the regions's sources */ samplepos_t latest_possible_sample () const; Evoral::Range last_range () const { - return Evoral::Range (_last_position, _last_position + _last_length - 1); + //return Evoral::Range (_last_position, _last_position + _last_length - 1); + return Evoral::Range (0, 0); } Evoral::Range range () const { @@ -184,7 +202,7 @@ public: PositionLockStyle position_lock_style () const { return _position_lock_style; } void set_position_lock_style (PositionLockStyle ps); - void recompute_position_from_lock_style (const int32_t sub_num); + void recompute_position_from_lock_style (); /* meter-based beat at the region position */ double beat () const { return _beat; } @@ -224,27 +242,27 @@ public: /* EDITING OPERATIONS */ - 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); + void set_length (timecnt_t const &); + void set_start (timecnt_t const &); + void set_position (timepos_t); + void set_initial_position (timepos_t); + void special_set_position (timepos_t); virtual void update_after_tempo_map_change (bool send_change = true); - void nudge_position (sampleoffset_t); + void nudge_position (timecnt_t const &); bool at_natural_position () const; void move_to_natural_position (); - 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); + void move_start (timecnt_t const & distance); + void trim_front (timepos_t new_position); + void trim_end (timepos_t new_position); + void trim_to (timepos_t pos, timecnt_t const & length); + /* fades are inherently audio in nature and we specify them in samples */ virtual void fade_range (samplepos_t, samplepos_t) {} - 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 cut_front (timepos_t new_position); + void cut_end (timepos_t new_position); void set_layer (layer_t l); /* ONLY Playlist can call this */ void raise (); @@ -252,7 +270,7 @@ public: void raise_to_top (); void lower_to_bottom (); - void set_sync_position (samplepos_t n); + void set_sync_position (timepos_t n); void clear_sync_position (); void set_hidden (bool yn); void set_muted (bool yn); @@ -389,13 +407,13 @@ protected: Region (boost::shared_ptr); /** Construct a region from another region, at an offset within that region */ - Region (boost::shared_ptr, ARDOUR::MusicSample start_offset); + Region (boost::shared_ptr, timecnt_t 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, samplepos_t start, samplecnt_t length, const std::string& name, DataType); + Region (Session& s, timepos_t start, timecnt_t length, const std::string& name, DataType); virtual bool can_trim_start_before_source_start () const { return false; @@ -406,25 +424,24 @@ 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 (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&); + virtual void set_position_internal (timepos_t pos); + virtual void set_length_internal (timecnt_t const &); + virtual void set_start_internal (timecnt_t const &); + bool verify_start_and_length (timecnt_t const &, timecnt_t&); void first_edit (); DataType _type; - PBD::Property _sync_marked; - 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 _beat; + PBD::Property _sync_marked; + 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 _beat; /** Sync position relative to the start of our file */ - PBD::Property _sync_position; + PBD::Property _sync_position; double _quarter_note; @@ -452,15 +469,15 @@ protected: private: void mid_thaw (const PBD::PropertyChange&); - 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); + virtual void trim_to_internal (timepos_t position, timecnt_t const & length); + void modify_front (timepos_t new_position, bool reset_fade); + void modify_end (timepos_t new_position, bool reset_fade); void maybe_uncopy (); - bool verify_start (samplepos_t); - bool verify_start_mutable (samplepos_t&_start); - bool verify_length (samplecnt_t&); + bool verify_start (timecnt_t const &); + bool verify_start_mutable (timecnt_t&); + bool verify_length (timecnt_t&); virtual void recompute_at_start () = 0; virtual void recompute_at_end () = 0; @@ -475,8 +492,8 @@ private: 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; @@ -484,8 +501,8 @@ private: PBD::Property _tags; PBD::Property _contents; // type is irrelevant - samplecnt_t _last_length; - samplepos_t _last_position; + timecnt_t _last_length; + timepos_t _last_position; mutable RegionEditState _first_edit; layer_t _layer; diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 5ed2f3d017..f46d80639b 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -43,7 +43,9 @@ #include #include "temporal/bbt_time.h" +#include "temporal/superclock.h" #include "temporal/time.h" +#include "temporal/timeline.h" #include "temporal/types.h" #include "pbd/id.h" @@ -85,6 +87,10 @@ typedef Temporal::samplecnt_t samplecnt_t; typedef Temporal::samplepos_t samplepos_t; typedef Temporal::sampleoffset_t sampleoffset_t; +typedef Temporal::timepos_t timepos_t; +typedef Temporal::timecnt_t timecnt_t; +typedef Temporal::superclock_t superclock_t; + static const layer_t max_layer = UINT32_MAX; // a set of (time) intervals: first of pair is the offset of the start within the region, second is the offset of the end diff --git a/libs/ardour/ardour/types_convert.h b/libs/ardour/ardour/types_convert.h index 0afde93aa9..98f543cce0 100644 --- a/libs/ardour/ardour/types_convert.h +++ b/libs/ardour/ardour/types_convert.h @@ -79,6 +79,61 @@ DEFINE_ENUM_CONVERT(ARDOUR::LoopFadeChoice) DEFINE_ENUM_CONVERT(MusicalMode::Type) +template <> +inline std::string to_string (ARDOUR::timepos_t val) +{ + return val.to_string (); +} + +template <> +inline ARDOUR::timepos_t string_to (std::string const & str) +{ + ARDOUR::timepos_t tmp; + tmp.string_to (str); + return tmp; +} + +template <> +inline bool to_string (ARDOUR::timepos_t val, std::string & str) +{ + str = val.to_string (); + return true; +} + +template <> +inline bool string_to (std::string const & str, ARDOUR::timepos_t & val) +{ + return val.string_to (str); +} + + +template <> +inline std::string to_string (ARDOUR::timecnt_t val) +{ + return val.to_string (); +} + +template <> +inline ARDOUR::timecnt_t string_to (std::string const & str) +{ + ARDOUR::timecnt_t tmp; + tmp.string_to (str); + return tmp; +} + +template <> +inline bool to_string (ARDOUR::timecnt_t val, std::string & str) +{ + str = val.to_string (); + return true; +} + +template <> +inline bool string_to (std::string const & str, ARDOUR::timecnt_t & val) +{ + return val.string_to (str); +} + template <> inline bool to_string (ARDOUR::AutoState val, std::string& str) { diff --git a/libs/ardour/ebur128_analysis.cc b/libs/ardour/ebur128_analysis.cc index 35b53882be..a8bc477994 100644 --- a/libs/ardour/ebur128_analysis.cc +++ b/libs/ardour/ebur128_analysis.cc @@ -46,7 +46,7 @@ EBUr128Analysis::run (Readable* src) { int ret = -1; bool done = false; - samplecnt_t len = src->readable_length(); + samplecnt_t len = src->readable_length_samples(); samplepos_t pos = 0; uint32_t n_channels = src->n_channels(); Plugin::FeatureSet features; diff --git a/libs/ardour/filter.cc b/libs/ardour/filter.cc index 040a1cab83..00e599b4e1 100644 --- a/libs/ardour/filter.cc +++ b/libs/ardour/filter.cc @@ -114,13 +114,13 @@ Filter::finish (boost::shared_ptr region, SourceList& nsrcs, string regi boost::shared_ptr afs = boost::dynamic_pointer_cast(*si); if (afs) { afs->done_with_peakfile_writes (); - afs->update_header (region->position(), *now, xnow); + afs->update_header (region->position_sample(), *now, xnow); afs->mark_immutable (); } boost::shared_ptr smfs = boost::dynamic_pointer_cast(*si); if (smfs) { - smfs->set_natural_position (region->position()); + smfs->set_natural_position (region->position_sample()); smfs->flush (); } @@ -139,10 +139,10 @@ Filter::finish (boost::shared_ptr region, SourceList& nsrcs, string regi PropertyList plist; plist.add (Properties::start, 0); - plist.add (Properties::length, region->length()); + plist.add (Properties::length, region->nt_length()); plist.add (Properties::name, region_name); plist.add (Properties::whole_file, true); - plist.add (Properties::position, region->position()); + plist.add (Properties::position, region->nt_position()); boost::shared_ptr r = RegionFactory::create (nsrcs, plist); diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index 8e3444b1e5..c48604112a 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -354,24 +354,6 @@ MidiRegion::set_position_internal (samplepos_t pos, bool allow_bbt_recompute, co } } -void -MidiRegion::set_position_music_internal (double qn) -{ - Region::set_position_music_internal (qn); - /* set _start to new position in tempo map */ - _start = _session.tempo_map().samples_between_quarter_notes (quarter_note() - start_beats(), quarter_note()); - - if (position_lock_style() == AudioTime) { - _length_beats = _session.tempo_map().quarter_note_at_sample (_position + _length) - quarter_note(); - - } else { - /* leave _length_beats alone, and change _length to reflect the state of things - at the new position (tempo map may dictate a different number of samples). - */ - _length = _session.tempo_map().samples_between_quarter_notes (quarter_note(), quarter_note() + length_beats()); - } -} - samplecnt_t MidiRegion::read_at (Evoral::EventSink& out, samplepos_t position, diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 0607aa71ba..6111b01529 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -776,7 +776,9 @@ Playlist::add_region_internal (boost::shared_ptr region, samplepos_t pos boost::shared_ptr foo (shared_from_this ()); region->set_playlist (boost::weak_ptr (foo)); } + if (for_music) { +#warning NUTEMPO FIXME need timepos_t here region->set_position_music (quarter_note); } else { region->set_position (position, sub_num); diff --git a/libs/ardour/rb_effect.cc b/libs/ardour/rb_effect.cc index f1c0223c29..261bd3032f 100644 --- a/libs/ardour/rb_effect.cc +++ b/libs/ardour/rb_effect.cc @@ -84,11 +84,11 @@ RBEffect::run (boost::shared_ptr r, Progress* progress) string::size_type at; #ifndef NDEBUG - cerr << "RBEffect: source region: position = " << region->position () - << ", start = " << region->start () - << ", length = " << region->length () - << ", ancestral_start = " << region->ancestral_start () - << ", ancestral_length = " << region->ancestral_length () + cerr << "RBEffect: source region: position = " << region->position_sample () + << ", start = " << region->start_sample () + << ", length = " << region->length_samples () + << ", ancestral_start = " << region->ancestral_start_sample () + << ", ancestral_length = " << region->ancestral_length_samples () << ", stretch " << region->stretch () << ", shift " << region->shift () << endl; #endif @@ -151,11 +151,10 @@ RBEffect::run (boost::shared_ptr r, Progress* progress) double stretch = region->stretch () * tsr.time_fraction; double shift = region->shift () * tsr.pitch_fraction; - samplecnt_t read_start = region->ancestral_start () + - samplecnt_t (region->start () / (double)region->stretch ()); + samplecnt_t read_start = region->ancestral_start_sample () + + samplecnt_t (region->start_sample () / (double)region->stretch ()); - samplecnt_t read_duration = - samplecnt_t (region->length () / (double)region->stretch ()); + samplecnt_t read_duration = samplecnt_t (region->length_samples () / (double)region->stretch ()); uint32_t channels = region->n_channels (); @@ -221,7 +220,7 @@ RBEffect::run (boost::shared_ptr r, Progress* progress) samplepos_t this_position; this_position = read_start + pos - - region->start () + region->position (); + region->start_sample () + region->position_sample (); this_read = region->master_read_at (buffers[i], buffers[i], @@ -258,7 +257,7 @@ RBEffect::run (boost::shared_ptr r, Progress* progress) samplepos_t this_position; this_position = read_start + pos - - region->start () + region->position (); + region->start_sample () + region->position_sample (); this_read = region->master_read_at (buffers[i], buffers[i], @@ -269,7 +268,7 @@ RBEffect::run (boost::shared_ptr r, Progress* progress) if (this_read != this_time) { error << string_compose (_("tempoize: error reading data from %1 at %2 (wanted %3, got %4)"), - region->name (), pos + region->position (), this_time, this_read) + region->name (), pos + region->position_sample (), this_time, this_read) << endmsg; goto out; } @@ -353,15 +352,16 @@ RBEffect::run (boost::shared_ptr r, Progress* progress) /* now reset ancestral data for each new region */ for (vector >::iterator x = results.begin (); x != results.end (); ++x) { - (*x)->set_ancestral_data (read_start, - read_duration, + (*x)->set_ancestral_data (timecnt_t (read_start, timepos_t()), + timecnt_t (read_duration, read_start), stretch, shift); (*x)->set_master_sources (region->master_sources ()); /* multiply the old (possibly previously stretched) region length by the extra * stretch this time around to get its new length. this is a non-music based edit atm. */ - (*x)->set_length ((*x)->length () * tsr.time_fraction, 0); +#warning NUTEMPO FIXME should use (*x)->position() sa 2nd arg also needs to figure out units for first arg + (*x)->set_length (timecnt_t (samplepos_t ((*x)->length_samples () * tsr.time_fraction), (*x)->position_samples())); } /* stretch region gain envelope */ diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 13d3b13ce2..62614fb653 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -69,14 +69,14 @@ namespace ARDOUR { PBD::PropertyDescriptor hidden; PBD::PropertyDescriptor position_locked; PBD::PropertyDescriptor valid_transients; - PBD::PropertyDescriptor start; - PBD::PropertyDescriptor length; - PBD::PropertyDescriptor position; + PBD::PropertyDescriptor start; + PBD::PropertyDescriptor length; + PBD::PropertyDescriptor position; PBD::PropertyDescriptor beat; - PBD::PropertyDescriptor sync_position; + PBD::PropertyDescriptor sync_position; PBD::PropertyDescriptor layer; - PBD::PropertyDescriptor ancestral_start; - PBD::PropertyDescriptor ancestral_length; + PBD::PropertyDescriptor ancestral_start; + PBD::PropertyDescriptor ancestral_length; PBD::PropertyDescriptor stretch; PBD::PropertyDescriptor shift; PBD::PropertyDescriptor position_lock_style; @@ -188,11 +188,11 @@ Region::register_properties () , _left_of_split (Properties::left_of_split, false) \ , _right_of_split (Properties::right_of_split, false) \ , _valid_transients (Properties::valid_transients, false) \ - , _start (Properties::start, (s)) \ - , _length (Properties::length, (l)) \ - , _position (Properties::position, 0) \ + , _start (Properties::start, timecnt_t (s, _type == DataType::MIDI ? timepos_t (Temporal::Beats()) : timepos_t (superclock_t (0)))) \ + , _length (Properties::length, timecnt_t (l,timepos_t (s))) \ + , _position (Properties::position, _type == DataType::MIDI ? timepos_t (Temporal::Beats()) : timepos_t (superclock_t (0))) \ , _beat (Properties::beat, 0.0) \ - , _sync_position (Properties::sync_position, (s)) \ + , _sync_position (Properties::sync_position, timecnt_t (s, _type == DataType::MIDI ? timepos_t (Temporal::Beats()) : timepos_t (superclock_t (0)))) \ , _quarter_note (0.0) \ , _transient_user_start (0) \ , _transient_analysis_start (0) \ @@ -208,7 +208,7 @@ Region::register_properties () , _external (Properties::external, false) \ , _hidden (Properties::hidden, false) \ , _position_locked (Properties::position_locked, false) \ - , _ancestral_start (Properties::ancestral_start, (s)) \ + , _ancestral_start (Properties::ancestral_start, timecnt_t (s, _type == DataType::MIDI ? timepos_t (Temporal::Beats()) : timepos_t (superclock_t (0)))) \ , _ancestral_length (Properties::ancestral_length, (l)) \ , _stretch (Properties::stretch, 1.0) \ , _shift (Properties::shift, 1.0) \ @@ -254,12 +254,12 @@ Region::register_properties () , _contents (Properties::contents, other->_contents) /* derived-from-derived constructor (no sources in constructor) */ -Region::Region (Session& s, samplepos_t start, samplecnt_t length, const string& name, DataType type) +Region::Region (Session& s, timepos_t start, timecnt_t length, const string& name, DataType type) : SessionObject(s, name) , _type(type) , REGION_DEFAULT_STATE(start,length) , _last_length (length) - , _last_position (0) + , _last_position (_type == DataType::MIDI ? timepos_t (Temporal::Beats()) : timepos_t (superclock_t (0))) , _first_edit (EditChangesNothing) , _layer (0) , _changemap (0) @@ -273,9 +273,10 @@ Region::Region (Session& s, samplepos_t start, samplecnt_t length, const string& Region::Region (const SourceList& srcs) : SessionObject(srcs.front()->session(), "toBeRenamed") , _type (srcs.front()->type()) - , REGION_DEFAULT_STATE(0,0) - , _last_length (0) - , _last_position (0) + , REGION_DEFAULT_STATE(_type == DataType::MIDI ? timecnt_t (Temporal::Beats()) : timecnt_t (superclock_t(0)), + _type == DataType::MIDI ? timecnt_t (Temporal::Beats()) : timecnt_t (superclock_t (0))) + , _last_length (_type == DataType::MIDI ? timecnt_t (Temporal::Beats()) : timecnt_t (superclock_t (0))) + , _last_position (_type == DataType::MIDI ? timepos_t (Temporal::Beats()) : timepos_t (superclock_t (0))) , _first_edit (EditChangesNothing) , _layer (0) , _changemap (0) @@ -354,7 +355,7 @@ Region::Region (boost::shared_ptr other) * the start within \a other is given by \a offset * (i.e. relative to the start of \a other's sources, the start is \a offset + \a other.start() */ -Region::Region (boost::shared_ptr other, MusicSample offset) +Region::Region (boost::shared_ptr other, timecnt_t offset) : SessionObject(other->session(), other->name()) , _type (other->data_type()) , REGION_COPY_STATE (other) @@ -376,19 +377,8 @@ Region::Region (boost::shared_ptr other, MusicSample offset) use_sources (other->_sources); set_master_sources (other->_master_sources); - _position = other->_position + offset.sample; - _start = other->_start + offset.sample; - - /* prevent offset of 0 from altering musical position */ - if (offset.sample != 0) { - const double offset_qn = _session.tempo_map().exact_qn_at_sample (other->_position + offset.sample, offset.division) - - other->_quarter_note; - - _quarter_note = other->_quarter_note + offset_qn; - _beat = _session.tempo_map().beat_at_quarter_note (_quarter_note); - } else { - _quarter_note = _session.tempo_map().quarter_note_at_beat (_beat); - } + _position = other->_position.val() + offset; + _start = other->_start.val() + offset; /* if the other region had a distinct sync point * set, then continue to use it as best we can. @@ -482,29 +472,31 @@ Region::set_selected_for_solo(bool yn) } void -Region::set_length (samplecnt_t len, const int32_t sub_num) +Region::set_length (timecnt_t const & len) { //cerr << "Region::set_length() len = " << len << endl; if (locked()) { return; } - if (_length != len && len != 0) { + if (_length != len && !len.zero()) { /* check that the current _position wouldn't make the new * length impossible. */ - if (max_samplepos - len < _position) { + if (timepos_t::max().earlier (len) < _position) { return; } - if (!verify_length (len)) { + timecnt_t l = len; + + if (!verify_length (l)) { return; } - set_length_internal (len, sub_num); + set_length_internal (l); _whole_file = false; first_edit (); maybe_uncopy (); @@ -519,7 +511,7 @@ Region::set_length (samplecnt_t len, const int32_t sub_num) } void -Region::set_length_internal (samplecnt_t len, const int32_t sub_num) +Region::set_length_internal (timecnt_t const & len) { _last_length = _length; _length = len; @@ -559,7 +551,7 @@ Region::at_natural_position () const boost::shared_ptr whole_file_region = get_parent(); if (whole_file_region) { - if (_position == whole_file_region->position() + _start) { + if (_position == whole_file_region->nt_position() + _start) { return true; } } @@ -579,12 +571,12 @@ Region::move_to_natural_position () boost::shared_ptr whole_file_region = get_parent(); if (whole_file_region) { - set_position (whole_file_region->position() + _start); + set_position (whole_file_region->nt_position() + _start); } } void -Region::special_set_position (samplepos_t pos) +Region::special_set_position (timepos_t pos) { /* this is used when creating a whole file region as * a way to store its "natural" or "captured" position. @@ -615,17 +607,10 @@ Region::update_after_tempo_map_change (bool send) return; } - if (_position_lock_style == AudioTime) { - /* don't signal as the actual position has not chnged */ - recompute_position_from_lock_style (0); + if (_position.val().time_domain() == Temporal::AudioTime) { return; } - /* prevent movement before 0 */ - const samplepos_t pos = max ((samplepos_t) 0, _session.tempo_map().sample_at_beat (_beat)); - /* we have _beat. update sample position non-musically */ - set_position_internal (pos, false, 0); - /* do this even if the position is the same. this helps out * a GUI that has moved its representation already. */ @@ -636,7 +621,7 @@ Region::update_after_tempo_map_change (bool send) } void -Region::set_position (samplepos_t pos, int32_t sub_num) +Region::set_position (timepos_t pos) { if (!can_move()) { return; @@ -649,18 +634,16 @@ Region::set_position (samplepos_t pos, int32_t sub_num) p_and_l.add (Properties::position); - if (position_lock_style() == AudioTime) { - set_position_internal (pos, true, sub_num); - } else { - if (!_session.loading()) { - _beat = _session.tempo_map().exact_beat_at_sample (pos, sub_num); - _quarter_note = _session.tempo_map().quarter_note_at_beat (_beat); - } + set_position_internal (pos); - set_position_internal (pos, false, sub_num); - } + /* if locked to beats or bbt, changing position can potentially change + * the length, because the tempo map may differ at the two different + * positions. Theoretically we could check this, but the cost of + * notifying about a (potential) length change is not that expensive + * given that we already are notifying about position change. + */ - if (position_lock_style() == MusicTime) { + if (position_lock_style() != AudioTime) { p_and_l.add (Properties::length); } @@ -669,85 +652,28 @@ Region::set_position (samplepos_t pos, int32_t sub_num) } void -Region::set_position_internal (samplepos_t pos, bool allow_bbt_recompute, const int32_t sub_num) +Region::set_position_internal (timepos_t pos) { /* We emit a change of Properties::position even if the position hasn't changed * (see Region::set_position), so we must always set this up so that * e.g. Playlist::notify_region_moved doesn't use an out-of-date last_position. */ _last_position = _position; + _last_length.set_position (_position); if (_position != pos) { _position = pos; - - if (allow_bbt_recompute) { - recompute_position_from_lock_style (sub_num); - } else { - /* MusicTime dictates that we glue to ardour beats. the pulse may have changed.*/ - _quarter_note = _session.tempo_map().quarter_note_at_beat (_beat); - } + _start.call().set_position (pos); + _length.call().set_position (pos); /* check that the new _position wouldn't make the current * length impossible - if so, change the length. * * XXX is this the right thing to do? */ - if (max_samplepos - _length < _position) { + if (timepos_t::max().earlier (_length) < _position) { _last_length = _length; - _length = max_samplepos - _position; - } - } -} - -void -Region::set_position_music (double qn) -{ - if (!can_move()) { - return; - } - - /* do this even if the position is the same. this helps out - * a GUI that has moved its representation already. - */ - PropertyChange p_and_l; - - p_and_l.add (Properties::position); - - if (!_session.loading()) { - _beat = _session.tempo_map().beat_at_quarter_note (qn); - } - - /* will set sample accordingly */ - set_position_music_internal (qn); - - if (position_lock_style() == MusicTime) { - p_and_l.add (Properties::length); - } - - send_change (p_and_l); -} - -void -Region::set_position_music_internal (double qn) -{ - /* We emit a change of Properties::position even if the position hasn't changed - * (see Region::set_position), so we must always set this up so that - * e.g. Playlist::notify_region_moved doesn't use an out-of-date last_position. - */ - _last_position = _position; - - if (_quarter_note != qn) { - _position = _session.tempo_map().sample_at_quarter_note (qn); - _quarter_note = qn; - - /* check that the new _position wouldn't make the current - * length impossible - if so, change the length. - * - * XXX is this the right thing to do? - */ - if (max_samplepos - _length < _position) { - _last_length = _length; - _length = max_samplepos - _position; + _length = _position.call().distance (timepos_t::max()); } } } @@ -758,7 +684,7 @@ Region::set_position_music_internal (double qn) * _last_position to prevent an implied move. */ void -Region::set_initial_position (samplepos_t pos) +Region::set_initial_position (timepos_t pos) { if (!can_move()) { return; @@ -773,14 +699,15 @@ Region::set_initial_position (samplepos_t pos) * XXX is this the right thing to do? */ - if (max_samplepos - _length < _position) { + if (timepos_t::max().earlier (_length) < _position) { _last_length = _length; - _length = max_samplepos - _position; + _length = _position.call().distance (timepos_t::max()); } - recompute_position_from_lock_style (0); + recompute_position_from_lock_style (); /* ensure that this move doesn't cause a range move */ _last_position = _position; + _last_length.set_position (_position); } @@ -791,46 +718,48 @@ Region::set_initial_position (samplepos_t pos) } void -Region::recompute_position_from_lock_style (const int32_t sub_num) +Region::recompute_position_from_lock_style () { - _beat = _session.tempo_map().exact_beat_at_sample (_position, sub_num); - _quarter_note = _session.tempo_map().exact_qn_at_sample (_position, sub_num); + /* XXX currently do nothing, but if we wanted to reduce lazy evaluation + * of timepos_t non-canonical values, we could possibly do it here. + */ } void -Region::nudge_position (sampleoffset_t n) +Region::nudge_position (timecnt_t const & n) { if (locked() || video_locked()) { return; } - if (n == 0) { + if (n.zero()) { return; } - samplepos_t new_position = _position; + timepos_t new_position = _position; - if (n > 0) { - if (_position > max_samplepos - n) { - new_position = max_samplepos; + if (n.positive()) { + if (nt_position() > timepos_t::max().earlier (n)) { + new_position = timepos_t::max(); } else { new_position += n; } } else { - if (_position < -n) { + if (nt_position() < -n) { new_position = 0; } else { new_position += n; } } + /* assumes non-musical nudge */ - set_position_internal (new_position, true, 0); + set_position_internal (new_position); send_change (Properties::position); } void -Region::set_ancestral_data (samplepos_t s, samplecnt_t l, float st, float sh) +Region::set_ancestral_data (timecnt_t const & s, timecnt_t const & l, float st, float sh) { _ancestral_length = l; _ancestral_start = s; @@ -839,7 +768,7 @@ Region::set_ancestral_data (samplepos_t s, samplecnt_t l, float st, float sh) } void -Region::set_start (samplepos_t pos) +Region::set_start (timecnt_t const & pos) { if (locked() || position_locked() || video_locked()) { return; @@ -851,11 +780,13 @@ Region::set_start (samplepos_t pos) if (_start != pos) { - if (!verify_start (pos)) { + timecnt_t p = pos; + + if (!verify_start (p)) { return; } - set_start_internal (pos); + set_start_internal (p); _whole_file = false; first_edit (); maybe_invalidate_transients (); @@ -865,43 +796,40 @@ Region::set_start (samplepos_t pos) } void -Region::move_start (sampleoffset_t distance, const int32_t sub_num) +Region::move_start (timecnt_t const & distance) { if (locked() || position_locked() || video_locked()) { return; } - samplepos_t new_start; + timecnt_t new_start (_start); - if (distance > 0) { + if (distance.positive()) { - if (_start > max_samplepos - distance) { - new_start = max_samplepos; // makes no sense + if (_start > timecnt_t::max() - distance) { + new_start = timecnt_t::max(); // makes no sense } else { - new_start = _start + distance; + new_start = nt_start() + distance; } if (!verify_start (new_start)) { return; } - } else if (distance < 0) { + } else { if (_start < -distance) { new_start = 0; } else { - new_start = _start + distance; + new_start = nt_start() + distance; } - - } else { - return; } if (new_start == _start) { return; } - set_start_internal (new_start, sub_num); + set_start_internal (new_start); _whole_file = false; first_edit (); @@ -910,55 +838,56 @@ Region::move_start (sampleoffset_t distance, const int32_t sub_num) } void -Region::trim_front (samplepos_t new_position, const int32_t sub_num) +Region::trim_front (timepos_t new_position) { - modify_front (new_position, false, sub_num); + modify_front (new_position, false); } void -Region::cut_front (samplepos_t new_position, const int32_t sub_num) +Region::cut_front (timepos_t new_position) { - modify_front (new_position, true, sub_num); + modify_front (new_position, true); } void -Region::cut_end (samplepos_t new_endpoint, const int32_t sub_num) +Region::cut_end (timepos_t new_endpoint) { - modify_end (new_endpoint, true, sub_num); + modify_end (new_endpoint, true); } void -Region::modify_front (samplepos_t new_position, bool reset_fade, const int32_t sub_num) +Region::modify_front (timepos_t new_position, bool reset_fade) { if (locked()) { return; } - samplepos_t end = last_sample(); - samplepos_t source_zero; + timepos_t end = nt_end().decrement(); + timepos_t source_zero; - if (_position > _start) { - source_zero = _position - _start; + if (nt_position() > nt_start()) { + source_zero = source_position (); } else { source_zero = 0; // its actually negative, but this will work for us } if (new_position < end) { /* can't trim it zero or negative length */ - samplecnt_t newlen = 0; + timecnt_t newlen (_length); + timepos_t np = new_position; if (!can_trim_start_before_source_start ()) { /* can't trim it back past where source position zero is located */ - new_position = max (new_position, source_zero); + np = max (np, source_zero); } - if (new_position > _position) { - newlen = _length - (new_position - _position); + if (np > nt_position()) { + newlen = nt_length() - (nt_position().distance (np)); } else { - newlen = _length + (_position - new_position); + newlen = nt_length() + (np.distance (nt_position())); } - trim_to_internal (new_position, newlen, sub_num); + trim_to_internal (np, newlen); if (reset_fade) { _right_of_split = true; @@ -973,14 +902,14 @@ Region::modify_front (samplepos_t new_position, bool reset_fade, const int32_t s } void -Region::modify_end (samplepos_t new_endpoint, bool reset_fade, const int32_t sub_num) +Region::modify_end (timepos_t new_endpoint, bool reset_fade) { if (locked()) { return; } if (new_endpoint > _position) { - trim_to_internal (_position, new_endpoint - _position, sub_num); + trim_to_internal (_position, nt_position().distance (new_endpoint)); if (reset_fade) { _left_of_split = true; } @@ -994,19 +923,19 @@ Region::modify_end (samplepos_t new_endpoint, bool reset_fade, const int32_t sub * a region at 0 of length 10 has an endpoint of 9. */ void -Region::trim_end (samplepos_t new_endpoint, const int32_t sub_num) +Region::trim_end (timepos_t new_endpoint) { - modify_end (new_endpoint, false, sub_num); + modify_end (new_endpoint, false); } void -Region::trim_to (samplepos_t position, samplecnt_t length, const int32_t sub_num) +Region::trim_to (timepos_t position, timecnt_t const & length) { if (locked()) { return; } - trim_to_internal (position, length, sub_num); + trim_to_internal (position, length); if (!property_changes_suspended()) { recompute_at_start (); @@ -1015,48 +944,50 @@ Region::trim_to (samplepos_t position, samplecnt_t length, const int32_t sub_num } void -Region::trim_to_internal (samplepos_t position, samplecnt_t length, const int32_t sub_num) +Region::trim_to_internal (timepos_t position, timecnt_t const & length) { - samplepos_t new_start; + timecnt_t new_start; if (locked()) { return; } - sampleoffset_t const start_shift = position - _position; + timecnt_t const start_shift = nt_position().distance (position); - if (start_shift > 0) { + if (start_shift.positive()) { - if (_start > max_samplepos - start_shift) { - new_start = max_samplepos; + if (nt_start() > timecnt_t::max() - start_shift) { + new_start = timecnt_t::max(); } else { - new_start = _start + start_shift; + new_start = nt_start() + start_shift; } - } else if (start_shift < 0) { + } else if (start_shift.negative()) { - if (_start < -start_shift && !can_trim_start_before_source_start ()) { + if (nt_start() < -start_shift && !can_trim_start_before_source_start ()) { new_start = 0; } else { - new_start = _start + start_shift; + new_start = nt_start() + start_shift; } } else { - new_start = _start; + new_start = nt_start(); } - if (!verify_start_and_length (new_start, length)) { + timecnt_t ns = new_start; + timecnt_t nl = length; + + if (!verify_start_and_length (ns, nl)) { return; } PropertyChange what_changed; - if (_start != new_start) { - set_start_internal (new_start, sub_num); + if (nt_start() != ns) { + set_start_internal (ns); what_changed.add (Properties::start); } - /* Set position before length, otherwise for MIDI regions this bad thing happens: * 1. we call set_length_internal; length in beats is computed using the region's current * (soon-to-be old) position @@ -1065,19 +996,19 @@ Region::trim_to_internal (samplepos_t position, samplecnt_t length, const int32_ * straddles a tempo/meter change. */ - if (_position != position) { + if (nt_position() != position) { if (!property_changes_suspended()) { _last_position = _position; } - set_position_internal (position, true, sub_num); + set_position_internal (position); what_changed.add (Properties::position); } - if (_length != length) { + if (nt_length() != nl) { if (!property_changes_suspended()) { _last_length = _length; } - set_length_internal (length, sub_num); + set_length_internal (nl); what_changed.add (Properties::length); } @@ -1169,10 +1100,10 @@ Region::set_position_locked (bool yn) * @param absolute_pos Session time. */ void -Region::set_sync_position (samplepos_t absolute_pos) +Region::set_sync_position (timepos_t absolute_pos) { /* position within our file */ - samplepos_t const file_pos = _start + (absolute_pos - _position); + const timecnt_t file_pos = nt_start() + nt_position().distance (absolute_pos); if (file_pos != _sync_position) { _sync_marked = true; @@ -1199,7 +1130,7 @@ Region::clear_sync_position () } /* @return the sync point relative the first sample of the region */ -sampleoffset_t +timecnt_t Region::sync_offset (int& dir) const { if (sync_marked()) { @@ -1212,42 +1143,43 @@ Region::sync_offset (int& dir) const } } else { dir = 0; - return 0; + return timecnt_t (); } } -samplepos_t -Region::adjust_to_sync (samplepos_t pos) const +timepos_t +Region::adjust_to_sync (timepos_t pos) const { int sync_dir; - sampleoffset_t offset = sync_offset (sync_dir); + timepos_t p = pos; + timecnt_t offset = sync_offset (sync_dir); // cerr << "adjusting pos = " << pos << " to sync at " << _sync_position << " offset = " << offset << " with dir = " << sync_dir << endl; if (sync_dir > 0) { if (pos > offset) { - pos -= offset; + p.shift_earlier (offset); } else { - pos = 0; + p = 0; } } else { - if (max_samplepos - pos > offset) { - pos += offset; + if (timepos_t::max().earlier (timecnt_t (p, p)) > offset) { + p += offset; } } - return pos; + return p; } /** @return Sync position in session time */ -samplepos_t +timepos_t Region::sync_position() const { if (sync_marked()) { - return _position - _start + _sync_position; + return source_position() + _sync_position; } else { /* if sync has not been marked, use the start of the region */ - return _position; + return nt_position(); } } @@ -1409,8 +1341,9 @@ Region::_set_state (const XMLNode& node, int /*version*/, PropertyChange& what_c */ if (!_sources.empty() && _type == DataType::AUDIO) { - if (_length > _sources.front()->length(_position)) { - _length = _sources.front()->length(_position) - _start; + if ((nt_length().time_domain() == Temporal::AudioTime) && (length_samples() > _sources.front()->length(position_sample()))) { +#warning NUTEMPO FIXME do this better + //_length = Temporal::samples_to_superclock (_sources.front()->length(position_sample()) - start_sample(), Temporal::_thread_sample_rate); } } @@ -1424,7 +1357,7 @@ Region::_set_state (const XMLNode& node, int /*version*/, PropertyChange& what_c &bbt_time.beats, &bbt_time.ticks) != 3) { _position_lock_style = AudioTime; - _beat = _session.tempo_map().beat_at_sample (_position); + _beat = _session.tempo_map().beat_at_sample (position_sample()); } else { _beat = _session.tempo_map().beat_at_bbt (bbt_time); } @@ -1745,20 +1678,23 @@ samplecnt_t Region::source_length(uint32_t n) const { assert (n < _sources.size()); - return _sources[n]->length (_position - _start); +#warning NUTEMPO FIXME needs Source to use timeline types + // return _sources[n]->length (_position - _start); + return 0; } bool -Region::verify_length (samplecnt_t& len) +Region::verify_length (timecnt_t& len) { if (source() && source()->length_mutable()) { return true; } - samplecnt_t maxlen = 0; + timecnt_t maxlen; for (uint32_t n = 0; n < _sources.size(); ++n) { - maxlen = max (maxlen, source_length(n) - _start); +#warning NUTEMPO FIXME source needs timeline types + // maxlen = max (maxlen, source_length(n) - _start); } len = min (len, maxlen); @@ -1767,16 +1703,17 @@ Region::verify_length (samplecnt_t& len) } bool -Region::verify_start_and_length (samplepos_t new_start, samplecnt_t& new_length) +Region::verify_start_and_length (timecnt_t const & new_start, timecnt_t& new_length) { if (source() && source()->length_mutable()) { return true; } - samplecnt_t maxlen = 0; + timecnt_t maxlen; for (uint32_t n = 0; n < _sources.size(); ++n) { - maxlen = max (maxlen, source_length(n) - new_start); +#warning NUTEMPO FIXME source needs timeline types + // maxlen = max (maxlen, source_length(n) - new_start); } new_length = min (new_length, maxlen); @@ -1785,31 +1722,33 @@ Region::verify_start_and_length (samplepos_t new_start, samplecnt_t& new_length) } bool -Region::verify_start (samplepos_t pos) +Region::verify_start (timecnt_t const & pos) { if (source() && source()->length_mutable()) { return true; } for (uint32_t n = 0; n < _sources.size(); ++n) { - if (pos > source_length(n) - _length) { - return false; - } +#warning NUTEMPO FIXME source needs timeline types + // if (pos > source_length(n) - _length) { + // return false; + // } } return true; } bool -Region::verify_start_mutable (samplepos_t& new_start) +Region::verify_start_mutable (timecnt_t & new_start) { if (source() && source()->length_mutable()) { return true; } for (uint32_t n = 0; n < _sources.size(); ++n) { - if (new_start > source_length(n) - _length) { - new_start = source_length(n) - _length; - } +#warning NUTEMPO FIXME source needs timeline types + // if (new_start > source_length(n) - _length) { + // new_start = source_length(n) - _length; + // } } return true; } @@ -1855,8 +1794,8 @@ Region::transients (AnalysisFeatureList& afl) { int cnt = afl.empty() ? 0 : 1; - Region::merge_features (afl, _onsets, _position); - Region::merge_features (afl, _user_transients, _position + _transient_user_start - _start); + Region::merge_features (afl, _onsets, position_sample()); + Region::merge_features (afl, _user_transients, position_sample() + _transient_user_start - start_sample()); if (!_onsets.empty ()) { ++cnt; } @@ -2000,14 +1939,15 @@ Region::can_trim () const ct = CanTrim (ct | FrontTrimLater | EndTrimEarlier); - if (start() != 0 || can_trim_start_before_source_start ()) { + if (nt_start() != 0 || can_trim_start_before_source_start ()) { ct = CanTrim (ct | FrontTrimEarlier); } if (!_sources.empty()) { - if ((start() + length()) < _sources.front()->length (0)) { - ct = CanTrim (ct | EndTrimLater); - } +#warning NUTEMPO FIXME source needs timeline types + //if ((nt_start() + nt_length()) < _sources.front()->length (0)) { + // ct = CanTrim (ct | EndTrimLater); + //} } return ct; @@ -2038,18 +1978,18 @@ Region::post_set (const PropertyChange& pc) } void -Region::set_start_internal (samplecnt_t s, const int32_t sub_num) +Region::set_start_internal (timecnt_t const & s) { _start = s; } -samplepos_t +timepos_t Region::earliest_possible_position () const { - if (_start > _position) { + if (nt_start() > timecnt_t (_position, timepos_t())) { return 0; } else { - return _position - _start; + return source_position(); } } @@ -2062,12 +2002,32 @@ Region::latest_possible_sample () const /* non-audio regions have a length that may vary based on their * position, so we have to pass it in the call. */ - minlen = min (minlen, (*i)->length (_position)); +#warning NUTEMPO FIXME source needs timeline types + // minlen = min (minlen, (*i)->length_samples ((*i)->timeline_position())); } /* the latest possible last sample is determined by the current * position, plus the shortest source extent past _start. */ - return _position + (minlen - _start) - 1; + return position_sample() + (minlen - start_sample()) - 1; } + +timepos_t +Region::source_position () const +{ + return _position.val().earlier (_start.val()); +} + +timepos_t +Region::source_relative_position (timepos_t const & p) const +{ + return p.earlier (source_position()); +} + +timepos_t +Region::region_relative_position (timepos_t const & p) const +{ + return p.earlier (_position.val()); +} + diff --git a/libs/ardour/reverse.cc b/libs/ardour/reverse.cc index 676480b8d8..4f1afe2875 100644 --- a/libs/ardour/reverse.cc +++ b/libs/ardour/reverse.cc @@ -52,8 +52,10 @@ Reverse::run (boost::shared_ptr r, Progress*) int ret = -1; boost::shared_ptr region = boost::dynamic_pointer_cast(r); - if (!region) + + if (!region) { return ret; + } /* create new sources */ @@ -61,13 +63,13 @@ Reverse::run (boost::shared_ptr r, Progress*) goto out; } - fstart = region->start(); + fstart = region->start_sample(); - if (blocksize > region->length()) { - blocksize = region->length(); + if (blocksize > region->length_samples()) { + blocksize = region->length_samples(); } - fpos = max (fstart, (fstart + region->length() - blocksize)); + fpos = max (fstart, (fstart + region->length_samples() - blocksize)); buf = new Sample[blocksize]; to_read = blocksize; diff --git a/libs/ardour/strip_silence.cc b/libs/ardour/strip_silence.cc index f1bb741d92..087ed75adf 100644 --- a/libs/ardour/strip_silence.cc +++ b/libs/ardour/strip_silence.cc @@ -66,7 +66,7 @@ StripSilence::run (boost::shared_ptr r, Progress* progress) const AudioIntervalResult& silence = sm->second; - if (silence.size () == 1 && silence.front().first == 0 && silence.front().second == region->length() - 1) { + if (silence.size () == 1 && silence.front().first == 0 && silence.front().second == region->length_samples() - 1) { /* the region is all silence, so just return with nothing */ return 0; } @@ -82,8 +82,8 @@ StripSilence::run (boost::shared_ptr r, Progress* progress) /* Add the possible audible section at the start of the region */ AudioIntervalResult::const_iterator first_silence = silence.begin (); - if (first_silence->first != region->start()) { - audible.push_back (std::make_pair (r->start(), first_silence->first)); + if (first_silence->first != region->start_sample()) { + audible.push_back (std::make_pair (r->start_sample(), first_silence->first)); } /* Add audible sections in the middle of the region */ @@ -100,7 +100,7 @@ StripSilence::run (boost::shared_ptr r, Progress* progress) AudioIntervalResult::const_iterator last_silence = silence.end (); --last_silence; - sampleoffset_t const end_of_region = r->start() + r->length(); + sampleoffset_t const end_of_region = r->start_sample() + r->length_samples(); if (last_silence->second < end_of_region - 1) { audible.push_back (std::make_pair (last_silence->second, end_of_region - 1)); @@ -115,11 +115,12 @@ StripSilence::run (boost::shared_ptr r, Progress* progress) boost::shared_ptr copy; plist.add (Properties::length, i->second - i->first); - plist.add (Properties::position, r->position() + (i->first - r->start())); + plist.add (Properties::position, r->position_sample() + (i->first - r->start_sample())); - copy = boost::dynamic_pointer_cast ( - RegionFactory::create (region, MusicSample (i->first - r->start(), 0), plist) - ); +#warning NUTEMPO FIXME need new constructors etc. +// copy = boost::dynamic_pointer_cast ( +// RegionFactory::create (region, MusicSample (i->first - r->start(), 0), plist) +// ); copy->set_name (RegionFactory::new_region_name (region->name ()));