remove Region::_tempo and Region::_meter; use Source-level data instead

This commit is contained in:
Paul Davis 2025-10-14 14:32:55 -06:00
parent 6d92be80c1
commit e8cd0af1cc
6 changed files with 78 additions and 76 deletions

View file

@ -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); int _set_state (const XMLNode&, int version, PBD::PropertyChange& what_changed, bool send_signal);
void send_change (const PBD::PropertyChange&); void send_change (const PBD::PropertyChange&);
void ensure_length_sanity (); void ensure_length_sanity ();
void set_tempo_stuff_from_source ();
}; };
} /* namespace ARDOUR */ } /* namespace ARDOUR */

View file

@ -157,8 +157,6 @@ class LIBARDOUR_API MidiRegion : public Region
void model_shifted (timecnt_t qn_distance); void model_shifted (timecnt_t qn_distance);
void model_automation_state_changed (Evoral::Parameter const &); void model_automation_state_changed (Evoral::Parameter const &);
void set_tempo_stuff_from_source ();
std::set<Evoral::Parameter> _filtered_parameters; ///< parameters that we ask our source not to return when reading std::set<Evoral::Parameter> _filtered_parameters; ///< parameters that we ask our source not to return when reading
PBD::ScopedConnection _model_connection; PBD::ScopedConnection _model_connection;
PBD::ScopedConnection _model_shift_connection; PBD::ScopedConnection _model_shift_connection;

View file

@ -545,9 +545,9 @@ public:
} }
} }
std::optional<Temporal::Tempo> tempo() const { return _tempo; } std::optional<Temporal::Tempo> tempo() const;
void set_tempo (Temporal::Tempo const &); void set_tempo (Temporal::Tempo const &);
std::optional<Temporal::Meter> meter() const { return _meter; } std::optional<Temporal::Meter> meter() const;
void set_meter (Temporal::Meter const &); void set_meter (Temporal::Meter const &);
std::shared_ptr<Temporal::TempoMap> tempo_map() const; std::shared_ptr<Temporal::TempoMap> tempo_map() const;
@ -604,9 +604,6 @@ protected:
uint32_t _fx_tail; uint32_t _fx_tail;
RegionFxList _plugins; RegionFxList _plugins;
std::optional<Temporal::Tempo> _tempo;
std::optional<Temporal::Meter> _meter;
PBD::Property<bool> _sync_marked; PBD::Property<bool> _sync_marked;
PBD::Property<bool> _left_of_split; PBD::Property<bool> _left_of_split;
PBD::Property<bool> _right_of_split; PBD::Property<bool> _right_of_split;

View file

@ -433,23 +433,6 @@ AudioRegion::~AudioRegion ()
} }
} }
void
AudioRegion::set_tempo_stuff_from_source ()
{
samplecnt_t data_size = _session.sample_rate() * 10;
std::unique_ptr<Sample> 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 void
AudioRegion::post_set (const PropertyChange& /*ignored*/) AudioRegion::post_set (const PropertyChange& /*ignored*/)
{ {

View file

@ -71,8 +71,6 @@ MidiRegion::MidiRegion (const SourceList& srcs)
: Region (srcs) : Region (srcs)
, _ignore_shift (false) , _ignore_shift (false)
{ {
set_tempo_stuff_from_source ();
/* by default MIDI regions are transparent, /* by default MIDI regions are transparent,
* this should probably be set depending on use-case, * this should probably be set depending on use-case,
* (eg. loop recording, vs copy/edit/paste) * (eg. loop recording, vs copy/edit/paste)
@ -99,8 +97,6 @@ MidiRegion::MidiRegion (std::shared_ptr<const MidiRegion> other, timecnt_t const
: Region (other, offset) : Region (other, offset)
, _ignore_shift (false) , _ignore_shift (false)
{ {
set_tempo_stuff_from_source ();
assert(_name.val().find("/") == string::npos); assert(_name.val().find("/") == string::npos);
midi_source(0)->ModelChanged.connect_same_thread (_source_connection, std::bind (&MidiRegion::model_changed, this)); midi_source(0)->ModelChanged.connect_same_thread (_source_connection, std::bind (&MidiRegion::model_changed, this));
model_changed (); model_changed ();
@ -110,28 +106,6 @@ MidiRegion::~MidiRegion ()
{ {
} }
void
MidiRegion::set_tempo_stuff_from_source ()
{
std::shared_ptr<Evoral::SMF> smf = std::dynamic_pointer_cast<Evoral::SMF> (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). /** Export the MIDI data of the MidiRegion to a new MIDI file (SMF).
*/ */
bool bool

View file

@ -265,9 +265,7 @@ Region::register_properties ()
, _contents (Properties::contents, false) , _contents (Properties::contents, false)
#define REGION_COPY_STATE(other) \ #define REGION_COPY_STATE(other) \
_tempo (other->_tempo) \ _sync_marked (Properties::sync_marked, other->_sync_marked) \
, _meter (other->_meter) \
, _sync_marked (Properties::sync_marked, other->_sync_marked) \
, _left_of_split (Properties::left_of_split, other->_left_of_split) \ , _left_of_split (Properties::left_of_split, other->_left_of_split) \
, _right_of_split (Properties::right_of_split, other->_right_of_split) \ , _right_of_split (Properties::right_of_split, other->_right_of_split) \
, _valid_transients (Properties::valid_transients, other->_valid_transients) \ , _valid_transients (Properties::valid_transients, other->_valid_transients) \
@ -1426,13 +1424,6 @@ Region::state () const
node->set_property ("id", id ()); node->set_property ("id", id ());
node->set_property ("type", _type); 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; std::string fe;
switch (_first_edit) { switch (_first_edit) {
@ -1638,12 +1629,6 @@ Region::_set_state (const XMLNode& node, int version, PropertyChange& what_chang
} }
_plugins.push_back (rfx); _plugins.push_back (rfx);
changed = true; 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 (); lm.release ();
@ -2526,27 +2511,94 @@ Region::fx_tail_changed (bool)
void void
Region::set_tempo (Temporal::Tempo const & t) Region::set_tempo (Temporal::Tempo const & t)
{ {
if (_tempo != t) { assert (!_sources.empty());
_tempo = t;
send_change (Properties::region_tempo); 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 void
Region::set_meter (Temporal::Meter const & m) Region::set_meter (Temporal::Meter const & m)
{ {
if (_meter != m) { assert (!_sources.empty());
_meter = m;
send_change (Properties::region_meter); 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<Temporal::TempoMap> std::shared_ptr<Temporal::TempoMap>
Region::tempo_map () const 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 nullptr;
} }
return std::make_shared<Temporal::TempoMap> (_tempo.value(), _meter.value()); return std::make_shared<Temporal::TempoMap> (sd.tempo(), sd.meter());
}
std::optional<Temporal::Tempo>
Region::tempo() const
{
std::shared_ptr<Temporal::TempoMap> tmap = tempo_map ();
if (!tmap) {
return std::optional<Temporal::Tempo>();
}
return tmap->tempo_at (0);
}
std::optional<Temporal::Meter>
Region::meter() const
{
std::shared_ptr<Temporal::TempoMap> tmap = tempo_map ();
if (!tmap) {
return std::optional<Temporal::Meter>();
}
return tmap->meter_at (0);
} }