diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index 136bb70d23..d6c4f54f99 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -1392,3 +1392,9 @@ AutomationLine::set_offset (timecnt_t const & off) _offset = off; reset (); } + +void +AutomationLine::set_distance_measure_origin (timepos_t const & pos) +{ + _distance_measure.set_origin (pos); +} diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc index 08110c2ee1..0fac6abcbd 100644 --- a/gtk2_ardour/editor_export_audio.cc +++ b/gtk2_ardour/editor_export_audio.cc @@ -479,10 +479,10 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list { boost::shared_ptr fs; const samplepos_t chunk_size = 4096; - timecnt_t nframes; + samplecnt_t nframes; Sample buf[chunk_size]; gain_t gain_buffer[chunk_size]; - timepos_t pos; + samplepos_t pos; char s[PATH_MAX+1]; uint32_t cnt; string path; @@ -531,18 +531,18 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list for (list::iterator i = range.begin(); i != range.end();) { - nframes = (*i).length(); - pos = (*i).start(); + nframes = (*i).length().samples(); + pos = (*i).start().samples(); - while (nframes.positive()) { + while (nframes) { - timecnt_t this_time = min (nframes, timecnt_t (chunk_size)); + timecnt_t this_time = timecnt_t (min (nframes, chunk_size)); for (uint32_t n=0; n < channels; ++n) { fs = sources[n]; - if (playlist.read (buf, buf, gain_buffer, pos, this_time, n) != this_time) { + if (playlist.read (buf, buf, gain_buffer, timepos_t (pos), this_time, n) != this_time) { break; } @@ -551,8 +551,8 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list } } - nframes -= this_time; - pos += this_time; + nframes -= this_time.samples(); + pos += this_time.samples(); } list::iterator tmp = i; @@ -562,11 +562,11 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list /* fill gaps with silence */ - nframes = (*i).end().distance ((*tmp).start()); + nframes = (*i).end().distance ((*tmp).start()).samples(); - while (nframes.positive()) { + while (nframes) { - timecnt_t this_time = min (nframes, timecnt_t (chunk_size)); + timecnt_t this_time = timecnt_t (min (nframes, chunk_size)); memset (buf, 0, sizeof (Sample) * this_time.samples()); for (uint32_t n=0; n < channels; ++n) { @@ -577,7 +577,7 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list } } - nframes -= this_time; + nframes -= this_time.samples(); } } diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc index f5dde17804..8078352980 100644 --- a/libs/ardour/location.cc +++ b/libs/ardour/location.cc @@ -61,6 +61,7 @@ PBD::Signal1 Location::end_changed; PBD::Signal1 Location::start_changed; PBD::Signal1 Location::flags_changed; PBD::Signal1 Location::lock_changed; +PBD::Signal1 Location::position_time_domain_changed; PBD::Signal1 Location::changed; Location::Location (Session& s) diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 25b9fa9164..b6652e2bdd 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -82,6 +82,7 @@ namespace ARDOUR { PBD::PropertyDescriptor layering_index; PBD::PropertyDescriptor tags; PBD::PropertyDescriptor contents; + PBD::PropertyDescriptor time_domain; } } @@ -571,6 +572,20 @@ Region::special_set_position (timepos_t const & pos) _position = pos; } +void +Region::set_position_time_domain (Temporal::TimeDomain ps) +{ + if (_position.val().time_domain() != ps) { + + boost::shared_ptr pl (playlist()); + +#warning NUTEMPO are we going to allow this operation? + // _position.call().set_time_domain (ps); + + send_change (Properties::time_domain); + } +} + void Region::recompute_position_from_time_domain () { @@ -598,7 +613,7 @@ Region::update_after_tempo_map_change (bool send) PropertyChange what_changed; -#warning NUTEMPO THINKME make this more nuanced ... nothing may have changed and maybe we don't need this at all +#warning NUTEMPO THINKME make this more nuanced ... nothing may have changed and maybe we do not need this at all what_changed.add (Properties::start); what_changed.add (Properties::length); diff --git a/libs/temporal/timeline.cc b/libs/temporal/timeline.cc index 7057e5ec3c..b50aca7c4f 100644 --- a/libs/temporal/timeline.cc +++ b/libs/temporal/timeline.cc @@ -219,6 +219,100 @@ timecnt_t::to_string () const return ss.str(); } +timecnt_t +timecnt_t::operator+ (timecnt_t const & other) const +{ + if (time_domain() == AudioTime) { + if (other.time_domain() == AudioTime) { + /* both audio, just add and use an arbitrary position */ + return timecnt_t (_distance + other.distance(), _position); + } else { + return timecnt_t (_distance + other.samples(), _position); + } + } + + return timecnt_t (beats() + other.beats(), _position); +} + +timecnt_t +timecnt_t::operator- (timecnt_t const & other) const +{ + if (time_domain() == AudioTime) { + if (other.time_domain() == AudioTime) { + return timecnt_t (_distance - other.distance(), _position); + } else { + return timecnt_t (_distance - other.samples(), _position); + } + } + + return timecnt_t (beats() - other.beats(), _position); +} + +timecnt_t & +timecnt_t::operator+= (timecnt_t const & other) +{ + if (time_domain() == AudioTime) { + if (other.time_domain() == AudioTime) { + _distance += other.distance(); + } else { + _distance += other.samples(); + } + } else { + _distance += other.ticks (); + } + + return *this; +} + +timecnt_t +timecnt_t::operator+ (timepos_t const & other) const +{ + if (time_domain() == AudioTime) { + if (other.time_domain() == AudioTime) { + /* both audio, just add and use an arbitrary position */ + return timecnt_t (_distance + other.val(), _position); + } else { + return timecnt_t (_distance + other.samples(), _position); + } + } + + return timecnt_t (beats() + other.beats(), _position); +} + +timecnt_t +timecnt_t::operator- (timepos_t const & other) const +{ + if (time_domain() == AudioTime) { + if (other.time_domain() == AudioTime) { + return timecnt_t (_distance - other.val(), _position); + } else { + return timecnt_t (_distance - other.samples(), _position); + } + } + + return timecnt_t (beats() - other.beats(), _position); +} + +timecnt_t & +timecnt_t::operator-= (timecnt_t const & other) +{ + if (time_domain() == other.time_domain()) { + _distance -= other.distance(); + } else if (time_domain() == AudioTime) { + _distance -= other.samples(); + } else { + _distance -= other.ticks (); + } + + return *this; +} + +timecnt_t +timecnt_t::operator- () const +{ + return timecnt_t (-_distance, _position); +} + /* timepos */ timepos_t::timepos_t (timecnt_t const & t) @@ -239,6 +333,46 @@ timepos_t::operator= (timecnt_t const & t) return *this; } +bool +timepos_t::operator< (timecnt_t const & t) const +{ + if (time_domain() == AudioTime) { + return superclocks() < t.superclocks(); + } + + return beats() < t.beats (); +} + +bool +timepos_t::operator> (timecnt_t const & t) const +{ + if (time_domain() == AudioTime) { + return superclocks() > t.superclocks(); + } + + return beats() > t.beats (); +} + +bool +timepos_t::operator<= (timecnt_t const & t) const +{ + if (time_domain() == AudioTime) { + return superclocks() <= t.superclocks(); + } + + return beats() <= t.beats (); +} + +bool +timepos_t::operator>= (timecnt_t const & t) const +{ + if (time_domain() == AudioTime) { + return superclocks() >= t.superclocks(); + } + + return beats() >= t.beats (); +} + void timepos_t::set_superclock (superclock_t s) { @@ -386,6 +520,34 @@ timepos_t::earlier (Temporal::Beats const & b) const return timepos_t (bb - b); } +timepos_t +timepos_t::earlier (Temporal::BBT_Offset const & offset) const +{ + TempoMap::SharedPtr tm (TempoMap::use()); + + if (is_superclock()) { + return timepos_t (tm->superclock_at (tm->bbt_walk (tm->bbt_at (superclocks()), -offset))); + } + + return timepos_t (tm->bbtwalk_to_quarters (beats(), -offset)); +} + + +timepos_t & +timepos_t::shift_earlier (Temporal::BBT_Offset const & offset) +{ + TempoMap::SharedPtr tm (TempoMap::use()); + + if (is_superclock()) { + v = build (false, (tm->superclock_at (tm->bbt_walk (tm->bbt_at (superclocks()), -offset)))); + } else { + v = build (true, tm->bbtwalk_to_quarters (beats(), -offset).to_ticks()); + } + + return *this; +} + + timepos_t timepos_t::earlier (timepos_t const & other) const { @@ -405,6 +567,46 @@ timepos_t::earlier (timecnt_t const & distance) const return earlier (distance.beats()); } +bool +timepos_t::expensive_lt (timepos_t const & other) const +{ + if (time_domain() == AudioTime) { + return superclocks() < other.superclocks(); + } + + return beats() < other.beats (); +} + +bool +timepos_t::expensive_gt (timepos_t const & other) const +{ + if (time_domain() == AudioTime) { + return superclocks() < other.superclocks(); + } + + return beats() > other.beats (); +} + +bool +timepos_t::expensive_lte (timepos_t const & other) const +{ + if (time_domain() == AudioTime) { + return superclocks() < other.superclocks(); + } + + return beats() <= other.beats (); +} + +bool +timepos_t::expensive_gte (timepos_t const & other) const +{ + if (time_domain() == AudioTime) { + return superclocks() < other.superclocks(); + } + + return beats() >= other.beats (); +} + /* */ timepos_t & @@ -446,6 +648,19 @@ timepos_t::shift_earlier (Temporal::Beats const & b) /* */ +timepos_t & +timepos_t::operator+= (Temporal::BBT_Offset const & offset) +{ + TempoMap::SharedPtr tm (TempoMap::use()); + if (is_beats()) { + v = build (true, tm->bbtwalk_to_quarters (beats(), offset)); + } else { + v = build (false, tm->superclock_at (tm->bbt_walk (tm->bbt_at (superclocks()), offset))); + } + + return *this; +} + timepos_t & timepos_t::operator+=(Temporal::Beats const & b) {