From b35b30c230ff36701dbaf79759069a449ccdf259 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 2 Feb 2024 10:10:00 -0700 Subject: [PATCH] factor out code to extract a TempoMap from an SMF --- libs/evoral/SMF.cc | 52 ++++++++++++++++++++++++++++++++++++++++ libs/evoral/evoral/SMF.h | 6 +++++ 2 files changed, 58 insertions(+) diff --git a/libs/evoral/SMF.cc b/libs/evoral/SMF.cc index ca7c6c504d..d5af69dc58 100644 --- a/libs/evoral/SMF.cc +++ b/libs/evoral/SMF.cc @@ -33,6 +33,8 @@ #include "libsmf/smf.h" +#include "temporal/tempo.h" + #include "evoral/Event.h" #include "evoral/SMF.h" #include "evoral/midi_util.h" @@ -697,4 +699,54 @@ SMF::load_markers () } } +std::shared_ptr +SMF::tempo_map (bool& provided) const +{ + /* cannot create an empty TempoMap, so create one with "default" single + values for tempo and meter, then overwrite them. + */ + + std::shared_ptr new_map (new Temporal::TempoMap (Temporal::Tempo (120, 4), Temporal::Meter (4, 4))); + const size_t ntempos = num_tempos (); + + if (ntempos == 0) { + provided = false; + return new_map; + } + + Temporal::Meter last_meter (4, 4); + bool have_initial_meter = false; + + for (size_t n = 0; n < ntempos; ++n) { + + Evoral::SMF::Tempo* t = nth_tempo (n); + assert (t); + + Temporal::Tempo tempo (t->tempo(), 32.0 / (double) t->notes_per_note); + Temporal::Meter meter (t->numerator, t->denominator); + + Temporal::BBT_Argument bbt; /* 1|1|0 which is correct for the no-meter case */ + + if (have_initial_meter) { + + bbt = new_map->bbt_at (Temporal::timepos_t (Temporal::Beats (int_div_round (t->time_pulses, (size_t) ppqn()), 0))); + new_map->set_tempo (tempo, bbt); + + if (!(meter == last_meter)) { + new_map->set_meter (meter, bbt); + } + + } else { + new_map->set_meter (meter, bbt); + new_map->set_tempo (tempo, bbt); + have_initial_meter = true; + } + + last_meter = meter; + } + + provided = true; + return new_map; +} + } // namespace Evoral diff --git a/libs/evoral/evoral/SMF.h b/libs/evoral/evoral/SMF.h index d1af7fb3ac..42ff9c6f0c 100644 --- a/libs/evoral/evoral/SMF.h +++ b/libs/evoral/evoral/SMF.h @@ -35,6 +35,10 @@ typedef smf_struct smf_t; typedef smf_track_struct smf_track_t; typedef smf_tempo_struct smf_tempo_t; +namespace Temporal { + class TempoMap; +} + namespace Evoral { /** Standard Midi File. @@ -136,6 +140,8 @@ public: Markers const & markers() const { return _markers; } void load_markers (); + std::shared_ptr tempo_map (bool& provided) const; + private: smf_t* _smf; smf_track_t* _smf_track;