diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index 7f0723f5f1..bb078ef2f7 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -291,8 +291,6 @@ class LIBARDOUR_API AudioRegion : public Region, public AudioReadable int _set_state (const XMLNode&, int version, PBD::PropertyChange& what_changed, bool send_signal); void send_change (const PBD::PropertyChange&); void ensure_length_sanity (); - - void set_tempo_stuff_from_source (); }; } /* namespace ARDOUR */ diff --git a/libs/ardour/ardour/midi_region.h b/libs/ardour/ardour/midi_region.h index 795bf8f8a9..d5f8d97877 100644 --- a/libs/ardour/ardour/midi_region.h +++ b/libs/ardour/ardour/midi_region.h @@ -157,8 +157,6 @@ class LIBARDOUR_API MidiRegion : public Region void model_shifted (timecnt_t qn_distance); void model_automation_state_changed (Evoral::Parameter const &); - void set_tempo_stuff_from_source (); - std::set _filtered_parameters; ///< parameters that we ask our source not to return when reading PBD::ScopedConnection _model_connection; PBD::ScopedConnection _model_shift_connection; diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index 8f2dddb38a..cde7b24c0c 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -545,9 +545,9 @@ public: } } - std::optional tempo() const { return _tempo; } + std::optional tempo() const; void set_tempo (Temporal::Tempo const &); - std::optional meter() const { return _meter; } + std::optional meter() const; void set_meter (Temporal::Meter const &); std::shared_ptr tempo_map() const; @@ -604,9 +604,6 @@ protected: uint32_t _fx_tail; RegionFxList _plugins; - std::optional _tempo; - std::optional _meter; - PBD::Property _sync_marked; PBD::Property _left_of_split; PBD::Property _right_of_split; diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 44ff2a5792..e5846b4cca 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -433,23 +433,6 @@ AudioRegion::~AudioRegion () } } -void -AudioRegion::set_tempo_stuff_from_source () -{ - samplecnt_t data_size = _session.sample_rate() * 10; - std::unique_ptr data (new Sample[data_size]); - - if (read (data.get(), 0, data_size, 0) == data_size) { - double tempo; - double beatcount; - Temporal::Meter m (4, 4); - - estimate_audio_tempo (shared_from_this(), data.get(), data_size, _session.sample_rate(), tempo, m, beatcount); - _tempo = Temporal::Tempo (tempo, 4); - _meter = m; - } -} - void AudioRegion::post_set (const PropertyChange& /*ignored*/) { diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc index 76ce048621..e8cd3a5324 100644 --- a/libs/ardour/midi_region.cc +++ b/libs/ardour/midi_region.cc @@ -71,8 +71,6 @@ MidiRegion::MidiRegion (const SourceList& srcs) : Region (srcs) , _ignore_shift (false) { - set_tempo_stuff_from_source (); - /* by default MIDI regions are transparent, * this should probably be set depending on use-case, * (eg. loop recording, vs copy/edit/paste) @@ -99,8 +97,6 @@ MidiRegion::MidiRegion (std::shared_ptr other, timecnt_t const : Region (other, offset) , _ignore_shift (false) { - set_tempo_stuff_from_source (); - assert(_name.val().find("/") == string::npos); midi_source(0)->ModelChanged.connect_same_thread (_source_connection, std::bind (&MidiRegion::model_changed, this)); model_changed (); @@ -110,28 +106,6 @@ MidiRegion::~MidiRegion () { } -void -MidiRegion::set_tempo_stuff_from_source () -{ - std::shared_ptr smf = std::dynamic_pointer_cast (midi_source ()); - assert (smf); - - bool provided; - Temporal::TempoMap::SharedPtr new_map (smf->tempo_map (provided)); - - if (!provided) { - _tempo = Temporal::Tempo (120, 4); - _meter = Temporal::Meter (4, 4); - return; - } - - Temporal::TempoPoint const tp (new_map->tempo_at (start())); - Temporal::MeterPoint const mp (new_map->meter_at (start())); - - _tempo = tp; - _meter = mp; -} - /** Export the MIDI data of the MidiRegion to a new MIDI file (SMF). */ bool diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index e7e5904fdc..c77fb420f2 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -265,9 +265,7 @@ Region::register_properties () , _contents (Properties::contents, false) #define REGION_COPY_STATE(other) \ - _tempo (other->_tempo) \ - , _meter (other->_meter) \ - , _sync_marked (Properties::sync_marked, other->_sync_marked) \ + _sync_marked (Properties::sync_marked, other->_sync_marked) \ , _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) \ @@ -1426,13 +1424,6 @@ Region::state () const node->set_property ("id", id ()); node->set_property ("type", _type); - if (_tempo) { - node->add_child_nocopy (_tempo.value().get_state()); - } - if (_meter) { - node->add_child_nocopy (_meter.value().get_state()); - } - std::string fe; switch (_first_edit) { @@ -1638,12 +1629,6 @@ Region::_set_state (const XMLNode& node, int version, PropertyChange& what_chang } _plugins.push_back (rfx); changed = true; - } else if (child->name() == Temporal::Tempo::xml_node_name) { - Temporal::Tempo t (*child); - _tempo = t; - } else if (child->name() == Temporal::Meter::xml_node_name) { - Temporal::Meter m (*child); - _meter = m; } } lm.release (); @@ -2526,27 +2511,94 @@ Region::fx_tail_changed (bool) void Region::set_tempo (Temporal::Tempo const & t) { - if (_tempo != t) { - _tempo = t; - send_change (Properties::region_tempo); + assert (!_sources.empty()); + + bool changed = false; + TimelineRange r (start(), start() + length(), 0); /* ID doesn't matter */ + SegmentDescriptor sd; + + if (_sources.front()->get_segment_descriptor (r, sd)) { + if (t != sd.tempo()) { + changed = true; + } } + + if (!changed) { + return; + } + + sd.set_position (start().samples()); + sd.set_duration (length().samples()); + sd.set_tempo (t); + + for (auto & s : _sources) { + s->set_segment_descriptor (sd, true); + } + + send_change (Properties::region_tempo); } void Region::set_meter (Temporal::Meter const & m) { - if (_meter != m) { - _meter = m; - send_change (Properties::region_meter); + assert (!_sources.empty()); + + bool changed = false; + TimelineRange r (start(), start() + length(), 0); /* ID doesn't matter */ + SegmentDescriptor sd; + + if (_sources.front()->get_segment_descriptor (r, sd)) { + if (m != sd.meter()) { + changed = true; + } } + + if (!changed) { + return; + } + + sd.set_position (start().samples()); + sd.set_duration (length().samples()); + sd.set_meter (m); + + for (auto & s : _sources) { + s->set_segment_descriptor (sd, true); + } + + send_change (Properties::region_meter); } std::shared_ptr Region::tempo_map () const { - if (!_tempo || !_meter) { + assert (!_sources.empty()); + + TimelineRange r (start(), start() + length(), 0); /* ID doesn't matter */ + SegmentDescriptor sd; + + if (!_sources.front()->get_segment_descriptor (r, sd)) { return nullptr; } - return std::make_shared (_tempo.value(), _meter.value()); + return std::make_shared (sd.tempo(), sd.meter()); +} + +std::optional +Region::tempo() const +{ + std::shared_ptr tmap = tempo_map (); + if (!tmap) { + return std::optional(); + } + return tmap->tempo_at (0); +} + +std::optional +Region::meter() const +{ + std::shared_ptr tmap = tempo_map (); + if (!tmap) { + return std::optional(); + } + return tmap->meter_at (0); }