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);
void send_change (const PBD::PropertyChange&);
void ensure_length_sanity ();
void set_tempo_stuff_from_source ();
};
} /* namespace ARDOUR */

View file

@ -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<Evoral::Parameter> _filtered_parameters; ///< parameters that we ask our source not to return when reading
PBD::ScopedConnection _model_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 &);
std::optional<Temporal::Meter> meter() const { return _meter; }
std::optional<Temporal::Meter> meter() const;
void set_meter (Temporal::Meter const &);
std::shared_ptr<Temporal::TempoMap> tempo_map() const;
@ -604,9 +604,6 @@ protected:
uint32_t _fx_tail;
RegionFxList _plugins;
std::optional<Temporal::Tempo> _tempo;
std::optional<Temporal::Meter> _meter;
PBD::Property<bool> _sync_marked;
PBD::Property<bool> _left_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
AudioRegion::post_set (const PropertyChange& /*ignored*/)
{

View file

@ -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<const MidiRegion> 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<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).
*/
bool

View file

@ -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<Temporal::TempoMap>
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<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);
}