make extending the tempo map O(N) in the section to be filled in, rather than O(N) in the overall length of the map, and clean up some other details

git-svn-id: svn://localhost/ardour2/branches/3.0@11166 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis
2012-01-05 17:31:24 +00:00
parent 63f77717d7
commit 3678b7c962
3 changed files with 191 additions and 139 deletions

View File

@@ -204,27 +204,26 @@ class TempoMap : public PBD::StatefulDestructible
struct BBTPoint {
framepos_t frame;
const Meter* meter;
const Tempo* tempo;
const MeterSection* meter;
const TempoSection* tempo;
uint32_t bar;
uint32_t beat;
BBTPoint (const MeterSection& m, const TempoSection& t, framepos_t f,
uint32_t b, uint32_t e)
: frame (f), meter (&m), tempo (&t), bar (b), beat (e) {}
Timecode::BBT_Time bbt() const { return Timecode::BBT_Time (bar, beat, 0); }
operator Timecode::BBT_Time() const { return bbt(); }
operator framepos_t() const { return frame; }
bool is_bar() const { return beat == 1; }
BBTPoint (const Meter& m, const Tempo& t, framepos_t f,
uint32_t b, uint32_t e)
: frame (f), meter (&m), tempo (&t), bar (b), beat (e) {}
};
typedef std::vector<BBTPoint> BBTPointList;
template<class T> void apply_with_metrics (T& obj, void (T::*method)(const Metrics&)) {
Glib::RWLock::ReaderLock lm (lock);
(obj.*method)(*metrics);
(obj.*method)(metrics);
}
void map (BBTPointList::const_iterator&, BBTPointList::const_iterator&,
@@ -299,37 +298,31 @@ class TempoMap : public PBD::StatefulDestructible
static Tempo _default_tempo;
static Meter _default_meter;
Metrics* metrics;
Metrics metrics;
framecnt_t _frame_rate;
framepos_t last_bbt_when;
bool last_bbt_valid;
Timecode::BBT_Time last_bbt;
mutable Glib::RWLock lock;
BBTPointList* _map;
BBTPointList _map;
void recompute_map (bool reassign_tempo_bbt, framepos_t end = -1);
void extend_map (framepos_t end);
void require_map_to (framepos_t pos);
void require_map_to (const Timecode::BBT_Time&);
void _extend_map (TempoSection* tempo, MeterSection* meter,
Metrics::iterator next_metric,
Timecode::BBT_Time current, framepos_t current_frame, framepos_t end);
BBTPointList::const_iterator bbt_before_or_at (framepos_t);
BBTPointList::const_iterator bbt_before_or_at (const Timecode::BBT_Time&);
BBTPointList::const_iterator bbt_after_or_at (framepos_t);
framepos_t round_to_type (framepos_t fr, int dir, BBTPointType);
void bbt_time (framepos_t, Timecode::BBT_Time&, const BBTPointList::const_iterator&);
framecnt_t bbt_duration_at_unlocked (const Timecode::BBT_Time& when, const Timecode::BBT_Time& bbt, int dir);
const MeterSection& first_meter() const;
const TempoSection& first_tempo() const;
int move_metric_section (MetricSection&, const Timecode::BBT_Time& to);
void do_insert (MetricSection* section);
Timecode::BBT_Time bbt_add (const Timecode::BBT_Time&, const Timecode::BBT_Time&, const TempoMetric&) const;
Timecode::BBT_Time bbt_add (const Timecode::BBT_Time& a, const Timecode::BBT_Time& b) const;
Timecode::BBT_Time bbt_subtract (const Timecode::BBT_Time&, const Timecode::BBT_Time&) const;
};
}; /* namespace ARDOUR */

View File

@@ -277,10 +277,7 @@ struct MetricSectionSorter {
TempoMap::TempoMap (framecnt_t fr)
{
metrics = new Metrics;
_map = new BBTPointList;
_frame_rate = fr;
last_bbt_valid = false;
BBT_Time start;
start.bars = 1;
@@ -295,14 +292,12 @@ TempoMap::TempoMap (framecnt_t fr)
/* note: frame time is correct (zero) for both of these */
metrics->push_back (t);
metrics->push_back (m);
metrics.push_back (t);
metrics.push_back (m);
}
TempoMap::~TempoMap ()
{
delete metrics;
delete _map;
}
void
@@ -314,11 +309,11 @@ TempoMap::remove_tempo (const TempoSection& tempo, bool complete_operation)
Glib::RWLock::WriterLock lm (lock);
Metrics::iterator i;
for (i = metrics->begin(); i != metrics->end(); ++i) {
for (i = metrics.begin(); i != metrics.end(); ++i) {
if (dynamic_cast<TempoSection*> (*i) != 0) {
if (tempo.frame() == (*i)->frame()) {
if ((*i)->movable()) {
metrics->erase (i);
metrics.erase (i);
removed = true;
break;
}
@@ -327,7 +322,7 @@ TempoMap::remove_tempo (const TempoSection& tempo, bool complete_operation)
}
if (removed && complete_operation) {
recompute_map (false, false);
recompute_map (false);
}
}
@@ -345,11 +340,11 @@ TempoMap::remove_meter (const MeterSection& tempo, bool complete_operation)
Glib::RWLock::WriterLock lm (lock);
Metrics::iterator i;
for (i = metrics->begin(); i != metrics->end(); ++i) {
for (i = metrics.begin(); i != metrics.end(); ++i) {
if (dynamic_cast<MeterSection*> (*i) != 0) {
if (tempo.frame() == (*i)->frame()) {
if ((*i)->movable()) {
metrics->erase (i);
metrics.erase (i);
removed = true;
break;
}
@@ -358,7 +353,7 @@ TempoMap::remove_meter (const MeterSection& tempo, bool complete_operation)
}
if (removed && complete_operation) {
recompute_map (true, false);
recompute_map (true);
}
}
@@ -404,9 +399,9 @@ TempoMap::do_insert (MetricSection* section)
the new one.
*/
Metrics::iterator to_remove = metrics->end ();
Metrics::iterator to_remove = metrics.end ();
for (i = metrics->begin(); i != metrics->end(); ++i) {
for (i = metrics.begin(); i != metrics.end(); ++i) {
int const c = (*i)->compare (*section);
@@ -443,26 +438,26 @@ TempoMap::do_insert (MetricSection* section)
}
}
if (to_remove != metrics->end()) {
if (to_remove != metrics.end()) {
/* remove the MetricSection at the same time as the one we are about to add */
metrics->erase (to_remove);
metrics.erase (to_remove);
}
/* Add the given MetricSection */
if (need_add) {
for (i = metrics->begin(); i != metrics->end(); ++i) {
for (i = metrics.begin(); i != metrics.end(); ++i) {
if ((*i)->compare (*section) < 0) {
continue;
}
metrics->insert (i, section);
metrics.insert (i, section);
break;
}
if (i == metrics->end()) {
metrics->insert (metrics->end(), section);
if (i == metrics.end()) {
metrics.insert (metrics.end(), section);
}
}
}
@@ -480,7 +475,7 @@ TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const BBT_T
Glib::RWLock::WriterLock lm (lock);
/* cannot move the first tempo section */
*((Tempo*)&first) = tempo;
recompute_map (false, false);
recompute_map (false);
}
}
@@ -511,7 +506,7 @@ TempoMap::add_tempo (const Tempo& tempo, BBT_Time where)
now see if we can find better candidates.
*/
for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
const MeterSection* m;
@@ -530,7 +525,7 @@ TempoMap::add_tempo (const Tempo& tempo, BBT_Time where)
do_insert (ts);
recompute_map (false, false);
recompute_map (false);
}
@@ -550,7 +545,7 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const BBT_T
Glib::RWLock::WriterLock lm (lock);
/* cannot move the first meter section */
*((Meter*)&first) = meter;
recompute_map (true, false);
recompute_map (true);
}
}
@@ -579,7 +574,7 @@ TempoMap::add_meter (const Meter& meter, BBT_Time where)
where.ticks = 0;
do_insert (new MeterSection (where, meter.divisions_per_bar(), meter.note_divisor()));
recompute_map (true, false);
recompute_map (true);
}
@@ -598,12 +593,12 @@ TempoMap::change_initial_tempo (double beats_per_minute, double note_type)
Tempo newtempo (beats_per_minute, note_type);
TempoSection* t;
for (Metrics::iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
{
Glib::RWLock::WriterLock lm (lock);
*((Tempo*) t) = newtempo;
recompute_map (false, false);
recompute_map (false);
}
PropertyChanged (PropertyChange ());
break;
@@ -623,7 +618,7 @@ TempoMap::change_existing_tempo_at (framepos_t where, double beats_per_minute, d
/* find the TempoSection immediately preceding "where"
*/
for (first = 0, i = metrics->begin(), prev = 0; i != metrics->end(); ++i) {
for (first = 0, i = metrics.begin(), prev = 0; i != metrics.end(); ++i) {
if ((*i)->frame() > where) {
break;
@@ -654,7 +649,7 @@ TempoMap::change_existing_tempo_at (framepos_t where, double beats_per_minute, d
Glib::RWLock::WriterLock lm (lock);
/* cannot move the first tempo section */
*((Tempo*)prev) = newtempo;
recompute_map (false, false);
recompute_map (false);
}
PropertyChanged (PropertyChange ());
@@ -665,7 +660,7 @@ TempoMap::first_meter () const
{
const MeterSection *m = 0;
for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
if ((m = dynamic_cast<const MeterSection *> (*i)) != 0) {
return *m;
}
@@ -681,7 +676,7 @@ TempoMap::first_tempo () const
{
const TempoSection *t = 0;
for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
if ((t = dynamic_cast<const TempoSection *> (*i)) != 0) {
return *t;
}
@@ -697,8 +692,8 @@ TempoMap::require_map_to (framepos_t pos)
{
Glib::RWLock::WriterLock lm (lock);
if (_map->empty() || _map->back().frame < pos) {
recompute_map (false, pos);
if (_map.empty() || _map.back().frame < pos) {
extend_map (pos);
}
}
@@ -715,11 +710,11 @@ TempoMap::require_map_to (const BBT_Time& bbt)
int additional_minutes = 1;
while (1) {
if (!_map->empty() && _map->back().bar >= (bbt.bars + 1)) {
if (!_map.empty() && _map.back().bar >= (bbt.bars + 1)) {
break;
}
/* add some more distance, using bigger steps each time */
recompute_map (false, _map->back().frame + (_frame_rate * 60 * additional_minutes));
extend_map (_map.back().frame + (_frame_rate * 60 * additional_minutes));
additional_minutes *= 2;
}
}
@@ -733,38 +728,41 @@ TempoMap::recompute_map (bool reassign_tempo_bbt, framepos_t end)
TempoSection* tempo;
TempoSection* ts;
MeterSection* ms;
double divisions_per_bar;
double beat_frames;
double current_frame;
BBT_Time current;
Metrics::iterator next_metric;
BBTPointList* new_map = new BBTPointList;
if (end == 0) {
/* silly call from Session::process() during startup
*/
return;
}
if (end < 0) {
if (_map->empty()) {
if (_map.empty()) {
/* compute 1 mins worth */
end = _frame_rate * 60;
} else {
end = _map->back().frame;
end = _map.back().frame;
}
} else {
if (!_map->empty ()) {
if (!_map.empty ()) {
/* never allow the map to be shortened */
end = max (end, _map->back().frame);
end = max (end, _map.back().frame);
}
}
DEBUG_TRACE (DEBUG::TempoMath, string_compose ("recomputing tempo map, zero to %1\n", end));
for (Metrics::iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
if ((ms = dynamic_cast<MeterSection *> (*i)) != 0) {
meter = ms;
break;
}
}
for (Metrics::iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
if ((ts = dynamic_cast<TempoSection *> (*i)) != 0) {
tempo = ts;
break;
@@ -781,16 +779,13 @@ TempoMap::recompute_map (bool reassign_tempo_bbt, framepos_t end)
current.beats = 1;
current.ticks = 0;
divisions_per_bar = meter->divisions_per_bar ();
beat_frames = meter->frames_per_division (*tempo,_frame_rate);
if (reassign_tempo_bbt) {
MeterSection* rmeter = meter;
DEBUG_TRACE (DEBUG::TempoMath, "\tUpdating tempo marks BBT time from bar offset\n");
for (Metrics::iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
if ((ts = dynamic_cast<TempoSection*>(*i)) != 0) {
@@ -809,15 +804,82 @@ TempoMap::recompute_map (bool reassign_tempo_bbt, framepos_t end)
}
}
DEBUG_TRACE (DEBUG::TempoMath, string_compose ("start with meter = %1 tempo = %2 dpb %3 fpb %4\n",
*((Meter*)meter), *((Tempo*)tempo), divisions_per_bar, beat_frames));
DEBUG_TRACE (DEBUG::TempoMath, string_compose ("start with meter = %1 tempo = %2\n", *((Meter*)meter), *((Tempo*)tempo)));
next_metric = metrics->begin();
next_metric = metrics.begin();
++next_metric; // skip meter (or tempo)
++next_metric; // skip tempo (or meter)
_map.clear ();
DEBUG_TRACE (DEBUG::TempoMath, string_compose ("Add first bar at 1|1 @ %2\n", current.bars, current_frame));
new_map->push_back (BBTPoint (*meter, *tempo,(framepos_t) llrint(current_frame), 1, 1));
_map.push_back (BBTPoint (*meter, *tempo,(framepos_t) llrint(current_frame), 1, 1));
_extend_map (tempo, meter, next_metric, current, current_frame, end);
}
void
TempoMap::extend_map (framepos_t end)
{
/* CALLER MUST HOLD WRITE LOCK */
if (_map.empty()) {
recompute_map (false, end);
return;
}
BBTPointList::const_iterator i = _map.end();
Metrics::iterator next_metric;
--i;
BBT_Time last_metric_start;
if ((*i).tempo->frame() > (*i).meter->frame()) {
last_metric_start = (*i).tempo->start();
} else {
last_metric_start = (*i).meter->start();
}
/* find the metric immediately after the tempo + meter sections for the
* last point in the map
*/
for (next_metric = metrics.begin(); next_metric != metrics.end(); ++next_metric) {
if ((*next_metric)->start() > last_metric_start) {
break;
}
}
cerr << "extend map to " << end << " next_metric @ end ? " << (next_metric == metrics.end());
if (next_metric != metrics.end()) {
cerr << *next_metric;
}
cerr << endl;
/* we cast away const here because this is the one place where we need
* to actually modify the frame time of each metric section.
*/
_extend_map (const_cast<TempoSection*> ((*i).tempo),
const_cast<MeterSection*> ((*i).meter),
next_metric, BBT_Time ((*i).bar, (*i).beat, 0), (*i).frame, end);
}
void
TempoMap::_extend_map (TempoSection* tempo, MeterSection* meter,
Metrics::iterator next_metric,
BBT_Time current, framepos_t current_frame, framepos_t end)
{
/* CALLER MUST HOLD WRITE LOCK */
TempoSection* ts;
MeterSection* ms;
double divisions_per_bar;
double beat_frames;
divisions_per_bar = meter->divisions_per_bar ();
beat_frames = meter->frames_per_division (*tempo,_frame_rate);
while (current_frame < end) {
@@ -829,7 +891,7 @@ TempoMap::recompute_map (bool reassign_tempo_bbt, framepos_t end)
current.beats = 1;
}
if (next_metric != metrics->end()) {
if (next_metric != metrics.end()) {
/* no operator >= so invert operator < */
@@ -907,7 +969,7 @@ TempoMap::recompute_map (bool reassign_tempo_bbt, framepos_t end)
++next_metric;
if (next_metric != metrics->end() && ((*next_metric)->start() == current)) {
if (next_metric != metrics.end() && ((*next_metric)->start() == current)) {
/* same position so go back and set this one up before advancing
*/
goto set_metrics;
@@ -917,15 +979,12 @@ TempoMap::recompute_map (bool reassign_tempo_bbt, framepos_t end)
if (current.beats == 1) {
DEBUG_TRACE (DEBUG::TempoMath, string_compose ("Add Bar at %1|1 @ %2\n", current.bars, current_frame));
new_map->push_back (BBTPoint (*meter, *tempo,(framepos_t) llrint(current_frame), current.bars, 1));
_map.push_back (BBTPoint (*meter, *tempo,(framepos_t) llrint(current_frame), current.bars, 1));
} else {
DEBUG_TRACE (DEBUG::TempoMath, string_compose ("Add Beat at %1|%2 @ %3\n", current.bars, current.beats, current_frame));
new_map->push_back (BBTPoint (*meter, *tempo, (framepos_t) llrint(current_frame), current.bars, current.beats));
_map.push_back (BBTPoint (*meter, *tempo, (framepos_t) llrint(current_frame), current.bars, current.beats));
}
}
swap (_map, new_map);
delete new_map;
}
TempoMetric
@@ -943,7 +1002,7 @@ TempoMap::metric_at (framepos_t frame) const
now see if we can find better candidates.
*/
for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
// cerr << "Looking at a metric section " << **i << endl;
@@ -980,7 +1039,7 @@ TempoMap::metric_at (BBT_Time bbt) const
now see if we can find better candidates.
*/
for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
BBT_Time section_start ((*i)->start());
@@ -1019,7 +1078,7 @@ TempoMap::bbt_time_rt (framepos_t frame, BBT_Time& bbt)
throw std::logic_error ("TempoMap::bbt_time_rt() could not lock tempo map");
}
if (_map->empty() || _map->back().frame < frame) {
if (_map.empty() || _map.back().frame < frame) {
throw std::logic_error (string_compose ("map not long enough to reach %1", frame));
}
@@ -1085,7 +1144,7 @@ TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, i
BBTPointList::const_iterator start (wi);
double tick_frames = 0;
assert (wi != _map->end());
assert (wi != _map.end());
/* compute how much rounding we did because of non-zero ticks */
@@ -1096,19 +1155,19 @@ TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, i
uint32_t bars = 0;
uint32_t beats = 0;
while (wi != _map->end() && bars < bbt.bars) {
while (wi != _map.end() && bars < bbt.bars) {
++wi;
if ((*wi).is_bar()) {
++bars;
}
}
assert (wi != _map->end());
assert (wi != _map.end());
while (wi != _map->end() && beats < bbt.beats) {
while (wi != _map.end() && beats < bbt.beats) {
++wi;
++beats;
}
assert (wi != _map->end());
assert (wi != _map.end());
/* add any additional frames related to ticks in the added value */
@@ -1166,9 +1225,9 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, int dir)
}
if (the_beat.ticks > BBT_Time::ticks_per_bar_division) {
assert (i != _map->end());
assert (i != _map.end());
++i;
assert (i != _map->end());
assert (i != _map.end());
the_beat.ticks -= BBT_Time::ticks_per_bar_division;
}
@@ -1191,7 +1250,7 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, int dir)
}
if (the_beat.ticks < difference) {
if (i == _map->begin()) {
if (i == _map.begin()) {
/* can't go backwards from wherever pos is, so just return it */
return fr;
}
@@ -1217,9 +1276,9 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, int dir)
DEBUG_TRACE (DEBUG::SnapBBT, string_compose ("moved forward to %1\n", the_beat.ticks));
if (the_beat.ticks > BBT_Time::ticks_per_bar_division) {
assert (i != _map->end());
assert (i != _map.end());
++i;
assert (i != _map->end());
assert (i != _map.end());
the_beat.ticks -= BBT_Time::ticks_per_bar_division;
DEBUG_TRACE (DEBUG::SnapBBT, string_compose ("fold beat to %1\n", the_beat));
}
@@ -1229,7 +1288,7 @@ TempoMap::round_to_beat_subdivision (framepos_t fr, int sub_num, int dir)
/* closer to previous subdivision, so shift backward */
if (rem > the_beat.ticks) {
if (i == _map->begin()) {
if (i == _map.begin()) {
/* can't go backwards past zero, so ... */
return 0;
}
@@ -1264,7 +1323,7 @@ TempoMap::round_to_type (framepos_t frame, int dir, BBTPointType type)
fi = bbt_before_or_at (frame);
}
assert (fi != _map->end());
assert (fi != _map.end());
DEBUG_TRACE(DEBUG::SnapBBT, string_compose ("round from %1 (%3|%4 @ %5) to bars in direction %2\n", frame, dir, (*fi).bar, (*fi).beat, (*fi).frame));
@@ -1278,7 +1337,7 @@ TempoMap::round_to_type (framepos_t frame, int dir, BBTPointType type)
}
while (!(*fi).is_bar()) {
if (fi == _map->begin()) {
if (fi == _map.begin()) {
break;
}
fi--;
@@ -1297,7 +1356,7 @@ TempoMap::round_to_type (framepos_t frame, int dir, BBTPointType type)
while (!(*fi).is_bar()) {
fi++;
if (fi == _map->end()) {
if (fi == _map.end()) {
--fi;
break;
}
@@ -1319,7 +1378,7 @@ TempoMap::round_to_type (framepos_t frame, int dir, BBTPointType type)
}
while ((*prev).beat != 1) {
if (prev == _map->begin()) {
if (prev == _map.begin()) {
break;
}
prev--;
@@ -1327,7 +1386,7 @@ TempoMap::round_to_type (framepos_t frame, int dir, BBTPointType type)
while ((*next).beat != 1) {
next++;
if (next == _map->end()) {
if (next == _map.end()) {
--next;
break;
}
@@ -1392,13 +1451,13 @@ TempoMap::map (TempoMap::BBTPointList::const_iterator& begin,
{
{
Glib::RWLock::WriterLock lm (lock);
if (_map->empty() || (_map->back().frame < upper)) {
if (_map.empty() || (_map.back().frame < upper)) {
recompute_map (false, upper);
}
}
begin = lower_bound (_map->begin(), _map->end(), lower);
end = upper_bound (_map->begin(), _map->end(), upper);
begin = lower_bound (_map.begin(), _map.end(), lower);
end = upper_bound (_map.begin(), _map.end(), upper);
}
const TempoSection&
@@ -1408,7 +1467,7 @@ TempoMap::tempo_section_at (framepos_t frame) const
Metrics::const_iterator i;
TempoSection* prev = 0;
for (i = metrics->begin(); i != metrics->end(); ++i) {
for (i = metrics.begin(); i != metrics.end(); ++i) {
TempoSection* t;
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
@@ -1451,7 +1510,7 @@ TempoMap::get_state ()
{
Glib::RWLock::ReaderLock lm (lock);
for (i = metrics->begin(); i != metrics->end(); ++i) {
for (i = metrics.begin(); i != metrics.end(); ++i) {
root->add_child_nocopy ((*i)->get_state());
}
}
@@ -1467,10 +1526,10 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
XMLNodeList nlist;
XMLNodeConstIterator niter;
Metrics old_metrics (*metrics);
Metrics old_metrics (metrics);
MeterSection* last_meter = 0;
metrics->clear();
metrics.clear();
nlist = node.children();
@@ -1481,7 +1540,7 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
try {
TempoSection* ts = new TempoSection (*child);
metrics->push_back (ts);
metrics.push_back (ts);
if (ts->bar_offset() < 0.0) {
if (last_meter) {
@@ -1492,7 +1551,7 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
catch (failed_constructor& err){
error << _("Tempo map: could not set new state, restoring old one.") << endmsg;
*metrics = old_metrics;
metrics = old_metrics;
break;
}
@@ -1500,13 +1559,13 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
try {
MeterSection* ms = new MeterSection (*child);
metrics->push_back (ms);
metrics.push_back (ms);
last_meter = ms;
}
catch (failed_constructor& err) {
error << _("Tempo map: could not set new state, restoring old one.") << endmsg;
*metrics = old_metrics;
metrics = old_metrics;
break;
}
}
@@ -1514,10 +1573,10 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
if (niter == nlist.end()) {
MetricSectionSorter cmp;
metrics->sort (cmp);
metrics.sort (cmp);
}
recompute_map (true, false);
recompute_map (true);
}
PropertyChanged (PropertyChange ());
@@ -1532,7 +1591,7 @@ TempoMap::dump (std::ostream& o) const
const MeterSection* m;
const TempoSection* t;
for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
if ((t = dynamic_cast<const TempoSection*>(*i)) != 0) {
o << "Tempo @ " << *i << " (Bar-offset: " << t->bar_offset() << ") " << t->beats_per_minute() << " BPM (pulse = 1/" << t->note_type() << ") at " << t->start() << " frame= " << t->frame() << " (movable? "
@@ -1550,7 +1609,7 @@ TempoMap::n_tempos() const
Glib::RWLock::ReaderLock lm (lock);
int cnt = 0;
for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
if (dynamic_cast<const TempoSection*>(*i) != 0) {
cnt++;
}
@@ -1565,7 +1624,7 @@ TempoMap::n_meters() const
Glib::RWLock::ReaderLock lm (lock);
int cnt = 0;
for (Metrics::const_iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
if (dynamic_cast<const MeterSection*>(*i) != 0) {
cnt++;
}
@@ -1579,7 +1638,7 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
{
{
Glib::RWLock::WriterLock lm (lock);
for (Metrics::iterator i = metrics->begin(); i != metrics->end(); ++i) {
for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
if ((*i)->frame() >= where && (*i)->movable ()) {
(*i)->set_frame ((*i)->frame() + amount);
}
@@ -1607,7 +1666,7 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
bool first = true;
MetricSection* prev = 0;
for (i = metrics->begin(); i != metrics->end(); ++i) {
for (i = metrics.begin(); i != metrics.end(); ++i) {
BBT_Time bbt;
TempoMetric metric (*meter, *tempo);
@@ -1661,7 +1720,7 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
prev = (*i);
}
recompute_map (true, false);
recompute_map (true);
}
@@ -1701,7 +1760,7 @@ TempoMap::framepos_minus_bbt (framepos_t pos, BBT_Time op)
/* walk backwards */
while (i != _map->begin() && (op.bars || op.beats)) {
while (i != _map.begin() && (op.bars || op.beats)) {
--i;
if (had_bars) {
@@ -1758,7 +1817,7 @@ TempoMap::framepos_plus_bbt (framepos_t pos, BBT_Time op)
/* we know that (*i).frame is before or equal to pos */
backup_frames = pos - (*i).frame;
while (i != _map->end() && (op.bars || op.beats)) {
while (i != _map.end() && (op.bars || op.beats)) {
++i;
@@ -1781,19 +1840,19 @@ TempoMap::framepos_plus_bbt (framepos_t pos, BBT_Time op)
}
}
if (i != _map->end()) {
if (i != _map.end()) {
break;
}
/* we hit the end of the map before finish the bbt walk.
*/
recompute_map (pos + (_frame_rate * 60 * additional_minutes));
recompute_map (false, pos + (_frame_rate * 60 * additional_minutes));
additional_minutes *= 2;
/* go back and try again */
warning << "reached end of map with op now at " << op << " end = "
<< _map->back().frame << ' ' << _map->back().bar << '|' << _map->back().beat << ", trying to walk "
<< _map.back().frame << ' ' << _map.back().bar << '|' << _map.back().beat << ", trying to walk "
<< op_copy << " ... retry"
<< endmsg;
}
@@ -1828,12 +1887,12 @@ TempoMap::framewalk_to_beats (framepos_t pos, framecnt_t distance)
beats += ((*i).frame - pos) / (*i).meter->frames_per_division (*(*i).tempo, _frame_rate);
}
while (i != _map->end() && (*i).frame < end) {
while (i != _map.end() && (*i).frame < end) {
++i;
beats++;
}
assert (i != _map->end());
assert (i != _map.end());
/* if our ending BBTPoint is after the end, subtract a fractional beat
to represent that distance.
@@ -1853,10 +1912,10 @@ TempoMap::bbt_before_or_at (framepos_t pos)
BBTPointList::const_iterator i;
i = lower_bound (_map->begin(), _map->end(), pos);
assert (i != _map->end());
i = lower_bound (_map.begin(), _map.end(), pos);
assert (i != _map.end());
if ((*i).frame > pos) {
assert (i != _map->begin());
assert (i != _map.begin());
--i;
}
return i;
@@ -1874,10 +1933,10 @@ TempoMap::bbt_before_or_at (const BBT_Time& bbt)
BBTPointList::const_iterator i;
bbtcmp cmp;
i = lower_bound (_map->begin(), _map->end(), bbt, cmp);
assert (i != _map->end());
i = lower_bound (_map.begin(), _map.end(), bbt, cmp);
assert (i != _map.end());
if ((*i).bar > bbt.bars || (*i).beat > bbt.beats) {
assert (i != _map->begin());
assert (i != _map.begin());
--i;
}
return i;
@@ -1890,15 +1949,15 @@ TempoMap::bbt_after_or_at (framepos_t pos)
BBTPointList::const_iterator i;
if (_map->back().frame == pos) {
i = _map->end();
assert (i != _map->begin());
if (_map.back().frame == pos) {
i = _map.end();
assert (i != _map.begin());
--i;
return i;
}
i = upper_bound (_map->begin(), _map->end(), pos);
assert (i != _map->end());
i = upper_bound (_map.begin(), _map.end(), pos);
assert (i != _map.end());
return i;
}

View File

@@ -42,7 +42,7 @@ TempoTest::recomputeMapTest ()
map.add_meter (meterB, BBT_Time (4, 1, 0));
cout << "\n\n\n";
for (list<MetricSection*>::iterator i = map.metrics->begin(); i != map.metrics->end(); ++i) {
for (list<MetricSection*>::iterator i = map.metrics.begin(); i != map.metrics.end(); ++i) {
if (dynamic_cast<TempoSection*> (*i)) {
cout << "\tTempo MS @ " << (*i)->start() << " " << (*i)->frame() << "\n";
} else {
@@ -50,10 +50,10 @@ TempoTest::recomputeMapTest ()
}
}
list<MetricSection*>::iterator i = map.metrics->begin();
list<MetricSection*>::iterator i = map.metrics.begin();
CPPUNIT_ASSERT_EQUAL (framepos_t (0), (*i)->frame ());
i = map.metrics->end();
i = map.metrics.end();
--i;
CPPUNIT_ASSERT_EQUAL (framepos_t (288e3), (*i)->frame ());
}