Revert "separate out all bounds/position info from Region into "Slice""

This reverts commit f3da2cfd8b.
This commit is contained in:
Paul Davis 2024-01-10 11:46:39 -07:00
parent efcdf21444
commit c97bf1a4b7
5 changed files with 213 additions and 330 deletions

View File

@ -41,7 +41,6 @@
#include "ardour/movable.h"
#include "ardour/readable.h"
#include "ardour/session_object.h"
#include "ardour/slice.h"
#include "ardour/trimmable.h"
#include "ardour/types_convert.h"
@ -68,6 +67,8 @@ namespace Properties {
LIBARDOUR_API extern PBD::PropertyDescriptor<bool> hidden;
LIBARDOUR_API extern PBD::PropertyDescriptor<bool> position_locked;
LIBARDOUR_API extern PBD::PropertyDescriptor<bool> valid_transients; // used for signal only
LIBARDOUR_API extern PBD::PropertyDescriptor<timepos_t> start;
LIBARDOUR_API extern PBD::PropertyDescriptor<timecnt_t> length;
LIBARDOUR_API extern PBD::PropertyDescriptor<timepos_t> sync_position;
LIBARDOUR_API extern PBD::PropertyDescriptor<layer_t> layer;
LIBARDOUR_API extern PBD::PropertyDescriptor<timepos_t> ancestral_start;
@ -100,7 +101,6 @@ enum LIBARDOUR_API RegionOperationFlag {
class LIBARDOUR_API Region
: public SessionObject
, public std::enable_shared_from_this<Region>
, public Slice
, public Trimmable
, public Movable
, public Temporal::TimeDomainSwapper
@ -126,6 +126,27 @@ public:
void start_domain_bounce (Temporal::DomainBounceInfo&);
void finish_domain_bounce (Temporal::DomainBounceInfo&);
/** How the region parameters play together:
*
* 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
*/
timepos_t position () const { return _length.val().position(); }
timepos_t start () const { return _start.val(); }
timecnt_t length () const { return _length.val(); }
timepos_t end() const;
timepos_t nt_last() const { return end().decrement(); }
timepos_t source_position () const;
timecnt_t source_relative_position (Temporal::timepos_t const &) const;
timecnt_t region_relative_position (Temporal::timepos_t const &) const;
samplepos_t position_sample () const { return position().samples(); }
samplecnt_t start_sample () const { return _start.val().samples(); }
samplecnt_t length_samples () const { return _length.val().samples(); }
layer_t layer () const { return _layer; }
void set_selected_for_solo(bool yn);
@ -133,6 +154,11 @@ public:
timepos_t source_length (uint32_t n) const;
uint32_t max_source_level () const;
/* these two are valid ONLY during a StateChanged signal handler */
timepos_t last_position () const { return _last_length.position(); }
timecnt_t last_length () const { return _last_length; }
samplecnt_t ancestral_start_sample () const { return _ancestral_start.val().samples(); }
samplecnt_t ancestral_length_samples () const { return _ancestral_length.val().samples(); }
timepos_t ancestral_start () const { return _ancestral_start.val(); }
@ -206,8 +232,33 @@ public:
timepos_t sync_position () const;
timepos_t adjust_to_sync (timepos_t const &) const;
/* first_sample() is an alias; last_sample() just hides some math */
samplepos_t first_sample () const { return position().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
*/
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;
Temporal::TimeRange last_range () const {
return Temporal::TimeRange (last_position(), last_position() + _last_length);
}
Temporal::TimeRange range_samples () const {
return Temporal::TimeRange (timepos_t (first_sample()), timepos_t (first_sample() + length_samples()));
}
Temporal::TimeRange range () const {
return Temporal::TimeRange (position(), position() + length());
}
bool hidden () const { return _hidden; }
bool muted () const { return _muted; }
bool opaque () const { return _opaque; }
@ -224,6 +275,7 @@ public:
Trimmable::CanTrim can_trim () const;
Temporal::TimeDomain position_time_domain () const;
void set_position_time_domain (Temporal::TimeDomain ps);
void recompute_position_from_time_domain ();
@ -259,6 +311,7 @@ public:
std::string source_string () const;
/* EDITING OPERATIONS */
void set_length (timecnt_t const &);
@ -306,6 +359,34 @@ public:
void modify_front_unchecked (timepos_t const & new_position, bool reset_fade);
void modify_end_unchecked (timepos_t const & new_position, bool reset_fade);
Temporal::timepos_t region_beats_to_absolute_time(Temporal::Beats beats) const;
/** Convert a timestamp in beats into timepos_t (both relative to region position) */
Temporal::timepos_t region_beats_to_region_time (Temporal::Beats beats) const {
return timepos_t (position().distance (region_beats_to_absolute_time (beats)));
}
/** Convert a timestamp in beats relative to region position into beats relative to source start */
Temporal::Beats region_beats_to_source_beats (Temporal::Beats beats) const {
return position().distance (region_beats_to_absolute_time (beats)).beats ();
}
/** Convert a distance within a region to beats relative to region position */
Temporal::Beats region_distance_to_region_beats (Temporal::timecnt_t const &) const;
/** Convert a timestamp in beats measured from source start into absolute beats */
Temporal::Beats source_beats_to_absolute_beats(Temporal::Beats beats) const;
/** Convert a timestamp in beats measured from source start into absolute samples */
Temporal::timepos_t source_beats_to_absolute_time(Temporal::Beats beats) const;
/** Convert a timestamp in beats measured from source start into region-relative samples */
Temporal::timepos_t source_beats_to_region_time(Temporal::Beats beats) const {
return timepos_t (position().distance (source_beats_to_absolute_time (beats)));
}
/** Convert a timestamp in absolute time to beats measured from source start*/
Temporal::Beats absolute_time_to_source_beats(Temporal::timepos_t const &) const;
Temporal::Beats absolute_time_to_region_beats (Temporal::timepos_t const &) const;
Temporal::timepos_t absolute_time_to_region_time (Temporal::timepos_t const &) const;
int apply (Filter &, PBD::Progress* progress = 0);
@ -469,6 +550,8 @@ protected:
PBD::Property<bool> _left_of_split;
PBD::Property<bool> _right_of_split;
PBD::Property<bool> _valid_transients;
PBD::Property<timepos_t> _start;
PBD::Property<timecnt_t> _length;
/** Sync position relative to the start of our file */
PBD::Property<timepos_t> _sync_position;
@ -526,6 +609,7 @@ private:
PBD::Property<uint64_t> _reg_group;
PBD::Property<bool> _contents; // type is irrelevant
timecnt_t _last_length;
mutable RegionEditState _first_edit;
layer_t _layer;

View File

@ -1,122 +0,0 @@
#ifndef __libardour_slice_h__
#define __libardour_slice_h__
#include "pbd/properties.h"
#include "pbd/stateful.h"
#include "temporal/timeline.h"
#include "temporal/range.h"
#include "ardour/libardour_visibility.h"
#include "ardour/types.h"
#include "ardour/types_convert.h"
namespace ARDOUR {
namespace Properties {
LIBARDOUR_API extern PBD::PropertyDescriptor<timepos_t> start;
LIBARDOUR_API extern PBD::PropertyDescriptor<timecnt_t> length;
}
class LIBARDOUR_API Slice : virtual public PBD::Stateful
{
public:
Slice (Temporal::timepos_t const &, Temporal::timecnt_t const &);
Slice (Slice const &);
virtual ~Slice() {}
Slice& operator= (Slice const &);
timepos_t position () const { return _length.val().position(); }
timepos_t start () const { return _start.val(); }
timecnt_t length () const { return _length.val(); }
timepos_t end() const;
timepos_t nt_last() const { return end().decrement(); }
/* these two are valid ONLY during a StateChanged signal handler */
timepos_t last_position () const { return _last_length.position(); }
timecnt_t last_length () const { return _last_length; }
timepos_t source_position () const;
timecnt_t source_relative_position (Temporal::timepos_t const &) const;
timecnt_t region_relative_position (Temporal::timepos_t const &) const;
samplepos_t position_sample () const { return position().samples(); }
samplecnt_t start_sample () const { return _start.val().samples(); }
samplecnt_t length_samples () const { return _length.val().samples(); }
/* first_sample() is an alias; last_sample() just hides some math */
samplepos_t first_sample () const { return position().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
*/
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;
Temporal::TimeRange last_range () const {
return Temporal::TimeRange (last_position(), last_position() + _last_length);
}
Temporal::TimeRange range_samples () const {
return Temporal::TimeRange (timepos_t (first_sample()), timepos_t (first_sample() + length_samples()));
}
Temporal::TimeRange range () const {
return Temporal::TimeRange (position(), position() + length());
}
Temporal::timepos_t region_beats_to_absolute_time(Temporal::Beats beats) const;
/** Convert a timestamp in beats into timepos_t (both relative to region position) */
Temporal::timepos_t region_beats_to_region_time (Temporal::Beats beats) const {
return timepos_t (position().distance (region_beats_to_absolute_time (beats)));
}
/** Convert a timestamp in beats relative to region position into beats relative to source start */
Temporal::Beats region_beats_to_source_beats (Temporal::Beats beats) const {
return position().distance (region_beats_to_absolute_time (beats)).beats ();
}
/** Convert a distance within a region to beats relative to region position */
Temporal::Beats region_distance_to_region_beats (Temporal::timecnt_t const &) const;
/** Convert a timestamp in beats measured from source start into absolute beats */
Temporal::Beats source_beats_to_absolute_beats(Temporal::Beats beats) const;
/** Convert a timestamp in beats measured from source start into absolute samples */
Temporal::timepos_t source_beats_to_absolute_time(Temporal::Beats beats) const;
/** Convert a timestamp in beats measured from source start into region-relative samples */
Temporal::timepos_t source_beats_to_region_time(Temporal::Beats beats) const {
return timepos_t (position().distance (source_beats_to_absolute_time (beats)));
}
/** Convert a timestamp in absolute time to beats measured from source start*/
Temporal::Beats absolute_time_to_source_beats(Temporal::timepos_t const &) const;
Temporal::Beats absolute_time_to_region_beats (Temporal::timepos_t const &) const;
Temporal::timepos_t absolute_time_to_region_time (Temporal::timepos_t const &) const;
Temporal::TimeDomain position_time_domain () const;
protected:
PBD::Property<timepos_t> _start;
PBD::Property<timecnt_t> _length;
timecnt_t _last_length;
virtual void set_length_internal (timecnt_t const &);
virtual void set_start_internal (timepos_t const &);
virtual void set_position_internal (timepos_t const &);
private:
void register_properties ();
};
} /* namespace */
#endif /* __libardour_slice_h__ */

View File

@ -227,6 +227,8 @@ 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)) \
, _sync_position (Properties::sync_position, (s)) \
, _transient_user_start (0) \
, _transient_analysis_start (0) \
@ -256,6 +258,8 @@ Region::register_properties ()
, _left_of_split (Properties::left_of_split, other->_left_of_split) \
, _right_of_split (Properties::right_of_split, other->_right_of_split) \
, _valid_transients (Properties::valid_transients, other->_valid_transients) \
, _start(Properties::start, other->_start) \
, _length(Properties::length, other->_length) \
, _sync_position(Properties::sync_position, other->_sync_position) \
, _user_transients (other->_user_transients) \
, _transient_user_start (other->_transient_user_start) \
@ -285,9 +289,9 @@ Region::register_properties ()
/* derived-from-derived constructor (no sources in constructor) */
Region::Region (Session& s, timepos_t const & start, timecnt_t const & length, const string& name, DataType type)
: SessionObject(s, name)
, Slice (start, length)
, _type (type)
, REGION_DEFAULT_STATE (start,length)
, _last_length (length)
, _first_edit (EditChangesNothing)
, _layer (0)
, _changemap (0)
@ -300,11 +304,10 @@ Region::Region (Session& s, timepos_t const & start, timecnt_t const & length, c
/** Basic Region constructor (many sources) */
Region::Region (const SourceList& srcs)
: SessionObject(srcs.front()->session(), "toBeRenamed")
, Slice (_type == DataType::MIDI ? timepos_t (Temporal::Beats()) : timepos_t::from_superclock (0),
_type == DataType::MIDI ? timecnt_t (Temporal::Beats()) : timecnt_t::from_superclock (0))
, _type (srcs.front()->type())
, REGION_DEFAULT_STATE(_type == DataType::MIDI ? timepos_t (Temporal::Beats()) : timepos_t::from_superclock (0),
_type == DataType::MIDI ? timecnt_t (Temporal::Beats()) : timecnt_t::from_superclock (0))
, _last_length (_type == DataType::MIDI ? timecnt_t (Temporal::Beats()) : timecnt_t::from_superclock (0))
, _first_edit (EditChangesNothing)
, _layer (0)
, _changemap (0)
@ -322,9 +325,9 @@ Region::Region (const SourceList& srcs)
/** Create a new Region from an existing one */
Region::Region (std::shared_ptr<const Region> other)
: SessionObject(other->session(), other->name())
, Slice (*other.get())
, _type (other->data_type())
, REGION_COPY_STATE (other)
, _last_length (other->_last_length)
, _first_edit (EditChangesNothing)
, _layer (other->_layer)
, _changemap (other->_changemap)
@ -380,9 +383,9 @@ Region::Region (std::shared_ptr<const Region> other)
*/
Region::Region (std::shared_ptr<const Region> other, timecnt_t const & offset)
: SessionObject(other->session(), other->name())
, Slice (*other.get())
, _type (other->data_type())
, REGION_COPY_STATE (other)
, _last_length (other->_last_length)
, _first_edit (EditChangesNothing)
, _layer (other->_layer)
, _changemap (other->_changemap)
@ -425,9 +428,9 @@ Region::Region (std::shared_ptr<const Region> other, timecnt_t const & offset)
/** Create a copy of @p other but with different sources. Used by filters */
Region::Region (std::shared_ptr<const Region> other, const SourceList& srcs)
: SessionObject (other->session(), other->name())
, Slice (*other.get())
, _type (srcs.front()->type())
, REGION_COPY_STATE (other)
, _last_length (other->_last_length)
, _first_edit (EditChangesID)
, _layer (other->_layer)
, _changemap (other->_changemap)
@ -578,12 +581,6 @@ Region::maybe_uncopy ()
/* this does nothing but marked a semantic moment once upon a time */
}
void
Region::set_start_internal (timepos_t const & s)
{
_start = s;
}
void
Region::first_edit ()
{
@ -2154,6 +2151,22 @@ Region::is_compound () const
return max_source_level() > 0;
}
void
Region::set_start_internal (timepos_t const & s)
{
_start = s;
}
timepos_t
Region::earliest_possible_position () const
{
if (start() > timecnt_t (position(), timepos_t())) {
return timepos_t::from_superclock (0);
} else {
return source_position();
}
}
samplecnt_t
Region::latest_possible_sample () const
{
@ -2173,6 +2186,108 @@ Region::latest_possible_sample () const
return (position() + minlen).samples() - 1;
}
Temporal::TimeDomain
Region::position_time_domain() const
{
return position().time_domain();
}
timepos_t
Region::end() const
{
/* one day we might want to enforce _position, _start and _length (or
some combination thereof) all being in the same time domain.
*/
return _length.val().end();
}
timepos_t
Region::source_position () const
{
/* this is the position of the start of the source, in absolute time */
return position().earlier (_start.val());
}
Temporal::Beats
Region::region_distance_to_region_beats (timecnt_t const & region_relative_offset) const
{
return timecnt_t (region_relative_offset, position()).beats ();
}
Temporal::Beats
Region::source_beats_to_absolute_beats (Temporal::Beats beats) const
{
/* since the return type must be beats, force source_position() to
beats before adding, rather than after.
*/
return source_position().beats() + beats;
}
Temporal::Beats
Region::absolute_time_to_region_beats(timepos_t const & b) const
{
return (position().distance (b)).beats () + start().beats();
}
Temporal::timepos_t
Region::absolute_time_to_region_time (timepos_t const & t) const
{
return start() + position().distance (t);
}
Temporal::timepos_t
Region::region_beats_to_absolute_time (Temporal::Beats beats) const
{
return position() + timepos_t (beats);
}
Temporal::timepos_t
Region::source_beats_to_absolute_time (Temporal::Beats beats) const
{
/* return the time corresponding to `beats' relative to the start of
the source. The start of the source is an implied position given by
region->position - region->start aka ::source_position()
*/
return source_position() + timepos_t (beats);
}
/** Calculate (time - source_position) in Beats
*
* Measure the distance between the absolute time and the position of
* the source start, in beats. The result is positive if time is later
* than source position.
*
* @param p is an absolute time
* @returns time offset from p to the region's source position as the origin in Beat units
*/
Temporal::Beats
Region::absolute_time_to_source_beats(timepos_t const& p) const
{
return source_position().distance (p).beats();
}
/** Calculate (pos - source-position)
*
* @param p is an absolute time
* @returns time offset from p to the region's source position as the origin.
*/
timecnt_t
Region::source_relative_position (timepos_t const & p) const
{
return source_position().distance (p);
}
/** Calculate (p - region-position)
*
* @param p is an absolute time
* @returns the time offset using the region (timeline) position as origin
*/
timecnt_t
Region::region_relative_position (timepos_t const & p) const
{
return position().distance (p);
}
Temporal::TimeDomain
Region::time_domain() const
{

View File

@ -1,193 +0,0 @@
#include "ardour/slice.h"
using namespace ARDOUR;
using namespace Temporal;
Slice::Slice (timepos_t const & s, timecnt_t const & l)
: _start (Properties::start, s)
, _length (Properties::length, l)
, _last_length (l)
{
register_properties ();
}
Slice::Slice (Slice const & other)
: _start (Properties::start, other._start)
, _length (Properties::length, other._length)
, _last_length (other._last_length)
{
}
void
Slice::register_properties ()
{
add_property (_start);
add_property (_length);
}
timepos_t
Slice::source_position () const
{
/* this is the position of the start of the source, in absolute time */
return position().earlier (_start.val());
}
Temporal::Beats
Slice::region_distance_to_region_beats (timecnt_t const & region_relative_offset) const
{
return timecnt_t (region_relative_offset, position()).beats ();
}
Temporal::Beats
Slice::source_beats_to_absolute_beats (Temporal::Beats beats) const
{
/* since the return type must be beats, force source_position() to
beats before adding, rather than after.
*/
return source_position().beats() + beats;
}
Temporal::Beats
Slice::absolute_time_to_region_beats(timepos_t const & b) const
{
return (position().distance (b)).beats () + start().beats();
}
Temporal::timepos_t
Slice::absolute_time_to_region_time (timepos_t const & t) const
{
return start() + position().distance (t);
}
Temporal::timepos_t
Slice::region_beats_to_absolute_time (Temporal::Beats beats) const
{
return position() + timepos_t (beats);
}
Temporal::timepos_t
Slice::source_beats_to_absolute_time (Temporal::Beats beats) const
{
/* return the time corresponding to `beats' relative to the start of
the source. The start of the source is an implied position given by
region->position - region->start aka ::source_position()
*/
return source_position() + timepos_t (beats);
}
/** Calculate (time - source_position) in Beats
*
* Measure the distance between the absolute time and the position of
* the source start, in beats. The result is positive if time is later
* than source position.
*
* @param p is an absolute time
* @returns time offset from p to the region's source position as the origin in Beat units
*/
Temporal::Beats
Slice::absolute_time_to_source_beats(timepos_t const& p) const
{
return source_position().distance (p).beats();
}
/** Calculate (pos - source-position)
*
* @param p is an absolute time
* @returns time offset from p to the region's source position as the origin.
*/
timecnt_t
Slice::source_relative_position (timepos_t const & p) const
{
return source_position().distance (p);
}
/** Calculate (p - region-position)
*
* @param p is an absolute time
* @returns the time offset using the region (timeline) position as origin
*/
timecnt_t
Slice::region_relative_position (timepos_t const & p) const
{
return position().distance (p);
}
Temporal::TimeDomain
Slice::position_time_domain() const
{
return position().time_domain();
}
timepos_t
Slice::end() const
{
/* one day we might want to enforce _position, _start and _length (or
some combination thereof) all being in the same time domain.
*/
return _length.val().end();
}
void
Slice::set_start_internal (timepos_t const & s)
{
_start = s;
}
void
Slice::set_length_internal (timecnt_t const & len)
{
/* maintain position value of both _last_length and _length.
*
* This is very important: set_length() can only be used to the length
* component of _length, and set_position() can only be used to set the
* position component.
*/
_last_length = timecnt_t (_length.val().distance(), _last_length.position());
_length = timecnt_t (len.distance(), _length.val().position());
}
void
Slice::set_position_internal (timepos_t const & pos)
{
if (position() == pos) {
return;
}
/* We emit a change of Properties::length even if the position hasn't changed
* (see Slice::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.
*
* maintain length value of both _last_length and _length.
*
* This is very important: set_length() can only be used to the length
* component of _length, and set_position() can only be used to set the
* position component.
*/
_last_length.set_position (position());
_length = timecnt_t (_length.val().distance(), 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 (timepos_t::max (_length.val().time_domain()).earlier (_length) < position()) {
_last_length = _length;
_length = position().distance (timepos_t::max (position().time_domain()));
}
}
timepos_t
Slice::earliest_possible_position () const
{
if (start() > timecnt_t (position(), timepos_t())) {
return timepos_t::from_superclock (0);
} else {
return source_position();
}
}

View File

@ -233,7 +233,6 @@ libardour_sources = [
'simple_export.cc',
'slavable.cc',
'slavable_automation_control.cc',
'slice.cc',
'smf_source.cc',
'sndfile_helpers.cc',
'sndfileimportable.cc',