X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Ftempo.cc;h=0ff94324bb088f369c92835006d9335791919708;hb=f21094937a2ae7dae7929de3ed883d93ed12b66b;hp=02884f062bbc9c180bc2a40442c673ed3c2dac07;hpb=a61f25dfe9dcf1f29852d917779529d26e762ea5;p=ardour.git diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 02884f062b..0ff94324bb 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -47,7 +47,7 @@ const double Meter::ticks_per_beat = 1920.0; /***********************************************************************/ double -Meter::frames_per_bar (const Tempo& tempo, jack_nframes_t sr) const +Meter::frames_per_bar (const Tempo& tempo, nframes_t sr) const { return ((60.0 * sr * _beats_per_bar) / tempo.beats_per_minute()); } @@ -200,13 +200,12 @@ struct MetricSectionSorter { } }; -TempoMap::TempoMap (jack_nframes_t fr) +TempoMap::TempoMap (nframes_t fr) { metrics = new Metrics; _frame_rate = fr; last_bbt_valid = false; BBT_Time start; - in_set_state = false; start.bars = 1; start.beats = 1; @@ -222,8 +221,6 @@ TempoMap::TempoMap (jack_nframes_t fr) metrics->push_back (t); metrics->push_back (m); - - save_state (_("initial")); } TempoMap::~TempoMap () @@ -256,7 +253,6 @@ TempoMap::move_metric_section (MetricSection& section, const BBT_Time& when) section.set_start (corrected); metrics->sort (cmp); timestamp_metrics (); - save_state (_("move metric")); return 0; } @@ -265,7 +261,7 @@ void TempoMap::move_tempo (TempoSection& tempo, const BBT_Time& when) { if (move_metric_section (tempo, when) == 0) { - send_state_changed (Change (0)); + StateChanged (Change (0)); } } @@ -273,7 +269,7 @@ void TempoMap::move_meter (MeterSection& meter, const BBT_Time& when) { if (move_metric_section (meter, when) == 0) { - send_state_changed (Change (0)); + StateChanged (Change (0)); } } @@ -301,7 +297,7 @@ TempoMap::remove_tempo (const TempoSection& tempo) } if (removed) { - send_state_changed (Change (0)); + StateChanged (Change (0)); } } @@ -325,14 +321,10 @@ TempoMap::remove_meter (const MeterSection& tempo) } } } - - if (removed) { - save_state (_("metric removed")); - } } if (removed) { - send_state_changed (Change (0)); + StateChanged (Change (0)); } } @@ -369,11 +361,9 @@ TempoMap::add_tempo (const Tempo& tempo, BBT_Time where) where.ticks = 0; do_insert (new TempoSection (where, tempo.beats_per_minute())); - - save_state (_("add tempo")); } - send_state_changed (Change (0)); + StateChanged (Change (0)); } void @@ -397,14 +387,10 @@ TempoMap::replace_tempo (TempoSection& existing, const Tempo& replacement) break; } } - - if (replaced) { - save_state (_("replace tempo")); - } } if (replaced) { - send_state_changed (Change (0)); + StateChanged (Change (0)); } } @@ -431,11 +417,9 @@ TempoMap::add_meter (const Meter& meter, BBT_Time where) where.ticks = 0; do_insert (new MeterSection (where, meter.beats_per_bar(), meter.note_divisor())); - - save_state (_("add meter")); } - send_state_changed (Change (0)); + StateChanged (Change (0)); } void @@ -458,14 +442,10 @@ TempoMap::replace_meter (MeterSection& existing, const Meter& replacement) break; } } - - if (replaced) { - save_state (_("replaced meter")); - } } if (replaced) { - send_state_changed (Change (0)); + StateChanged (Change (0)); } } @@ -509,8 +489,8 @@ TempoMap::timestamp_metrics () const Tempo* tempo; Meter *m; Tempo *t; - jack_nframes_t current; - jack_nframes_t section_frames; + nframes_t current; + nframes_t section_frames; BBT_Time start; BBT_Time end; @@ -542,7 +522,7 @@ TempoMap::timestamp_metrics () } TempoMap::Metric -TempoMap::metric_at (jack_nframes_t frame) const +TempoMap::metric_at (nframes_t frame) const { Metric m (first_meter(), first_tempo()); const Meter* meter; @@ -610,7 +590,7 @@ TempoMap::metric_at (BBT_Time bbt) const } void -TempoMap::bbt_time (jack_nframes_t frame, BBT_Time& bbt) const +TempoMap::bbt_time (nframes_t frame, BBT_Time& bbt) const { { Glib::RWLock::ReaderLock lm (lock); @@ -619,15 +599,15 @@ TempoMap::bbt_time (jack_nframes_t frame, BBT_Time& bbt) const } void -TempoMap::bbt_time_unlocked (jack_nframes_t frame, BBT_Time& bbt) const +TempoMap::bbt_time_unlocked (nframes_t frame, BBT_Time& bbt) const { bbt_time_with_metric (frame, bbt, metric_at (frame)); } void -TempoMap::bbt_time_with_metric (jack_nframes_t frame, BBT_Time& bbt, const Metric& metric) const +TempoMap::bbt_time_with_metric (nframes_t frame, BBT_Time& bbt, const Metric& metric) const { - jack_nframes_t frame_diff; + nframes_t frame_diff; uint32_t xtra_bars = 0; double xtra_beats = 0; @@ -667,7 +647,7 @@ TempoMap::bbt_time_with_metric (jack_nframes_t frame, BBT_Time& bbt, const Metri } -jack_nframes_t +nframes_t TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) const { @@ -676,9 +656,9 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con */ - jack_nframes_t frames = 0; - jack_nframes_t start_frame = 0; - jack_nframes_t end_frame = 0; + nframes_t frames = 0; + nframes_t start_frame = 0; + nframes_t end_frame = 0; Metric m = metric_at(start); @@ -688,7 +668,7 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con + start.ticks/Meter::ticks_per_beat; - start_frame = m.frame() + (jack_nframes_t) rint( beat_offset * m.tempo().frames_per_beat(_frame_rate)); + start_frame = m.frame() + (nframes_t) rint( beat_offset * m.tempo().frames_per_beat(_frame_rate)); m = metric_at(end); @@ -697,7 +677,7 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con beat_offset = bar_offset * m.meter().beats_per_bar() - (m.start().beats -1) + (end.beats - 1) + end.ticks/Meter::ticks_per_beat; - end_frame = m.frame() + (jack_nframes_t) rint(beat_offset * m.tempo().frames_per_beat(_frame_rate)); + end_frame = m.frame() + (nframes_t) rint(beat_offset * m.tempo().frames_per_beat(_frame_rate)); frames = end_frame - start_frame; @@ -705,12 +685,12 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con } -jack_nframes_t +nframes_t TempoMap::count_frames_between_metrics (const Meter& meter, const Tempo& tempo, const BBT_Time& start, const BBT_Time& end) const { /*this is used in timestamping the metrics by actually counting the beats */ - jack_nframes_t frames = 0; + nframes_t frames = 0; uint32_t bar = start.bars; double beat = (double) start.beats; double beats_counted = 0; @@ -739,13 +719,13 @@ TempoMap::count_frames_between_metrics (const Meter& meter, const Tempo& tempo, } } - frames = (jack_nframes_t) floor (beats_counted * beat_frames); + frames = (nframes_t) floor (beats_counted * beat_frames); return frames; } -jack_nframes_t +nframes_t TempoMap::frame_time (const BBT_Time& bbt) const { BBT_Time start ; /* 1|1|0 */ @@ -753,10 +733,10 @@ TempoMap::frame_time (const BBT_Time& bbt) const return count_frames_between ( start, bbt); } -jack_nframes_t -TempoMap::bbt_duration_at (jack_nframes_t pos, const BBT_Time& bbt, int dir) const +nframes_t +TempoMap::bbt_duration_at (nframes_t pos, const BBT_Time& bbt, int dir) const { - jack_nframes_t frames = 0; + nframes_t frames = 0; BBT_Time when; bbt_time(pos,when); @@ -769,11 +749,11 @@ TempoMap::bbt_duration_at (jack_nframes_t pos, const BBT_Time& bbt, int dir) con return frames; } -jack_nframes_t +nframes_t TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, int dir) const { - jack_nframes_t frames = 0; + nframes_t frames = 0; double beats_per_bar; BBT_Time result; @@ -896,8 +876,8 @@ TempoMap::bbt_duration_at_unlocked (const BBT_Time& when, const BBT_Time& bbt, i -jack_nframes_t -TempoMap::round_to_bar (jack_nframes_t fr, int dir) +nframes_t +TempoMap::round_to_bar (nframes_t fr, int dir) { { Glib::RWLock::ReaderLock lm (lock); @@ -906,8 +886,8 @@ TempoMap::round_to_bar (jack_nframes_t fr, int dir) } -jack_nframes_t -TempoMap::round_to_beat (jack_nframes_t fr, int dir) +nframes_t +TempoMap::round_to_beat (nframes_t fr, int dir) { { Glib::RWLock::ReaderLock lm (lock); @@ -915,22 +895,49 @@ TempoMap::round_to_beat (jack_nframes_t fr, int dir) } } -jack_nframes_t +nframes_t -TempoMap::round_to_beat_subdivision (jack_nframes_t fr, int sub_num) +TempoMap::round_to_beat_subdivision (nframes_t fr, int sub_num) { + + BBT_Time the_beat; + uint32_t ticks_one_half_subdivisions_worth; + uint32_t ticks_one_subdivisions_worth; + + bbt_time(fr, the_beat); + + ticks_one_subdivisions_worth = (uint32_t)Meter::ticks_per_beat / sub_num; + ticks_one_half_subdivisions_worth = ticks_one_subdivisions_worth / 2; + + if (the_beat.ticks % ticks_one_subdivisions_worth > ticks_one_half_subdivisions_worth) { + uint32_t difference = ticks_one_subdivisions_worth - (the_beat.ticks % ticks_one_subdivisions_worth); + if (the_beat.ticks + difference >= (uint32_t)Meter::ticks_per_beat) { + the_beat.beats++; + the_beat.ticks += difference; + the_beat.ticks -= (uint32_t)Meter::ticks_per_beat; + } else { + the_beat.ticks += difference; + } + } else { + the_beat.ticks -= the_beat.ticks % ticks_one_subdivisions_worth; + } + + return frame_time (the_beat); + + /* XXX just keeping this for reference + TempoMap::BBTPointList::iterator i; TempoMap::BBTPointList *more_zoomed_bbt_points; - jack_nframes_t frame_one_beats_worth; - jack_nframes_t pos = 0; - jack_nframes_t next_pos = 0 ; + nframes_t frame_one_beats_worth; + nframes_t pos = 0; + nframes_t next_pos = 0 ; double tempo = 1; double frames_one_subdivisions_worth; bool fr_has_changed = false; int n; - frame_one_beats_worth = (jack_nframes_t) ::floor ((double) _frame_rate * 60 / 20 ); //one beat @ 20 bpm + frame_one_beats_worth = (nframes_t) ::floor ((double) _frame_rate * 60 / 20 ); //one beat @ 20 bpm { Glib::RWLock::ReaderLock lm (lock); more_zoomed_bbt_points = get_points((fr >= frame_one_beats_worth) ? @@ -955,7 +962,7 @@ TempoMap::round_to_beat_subdivision (jack_nframes_t fr, int sub_num) for (n = sub_num; n > 0; n--) { if (fr >= (pos + ((n - 0.5) * frames_one_subdivisions_worth))) { - fr = (jack_nframes_t) round(pos + (n * frames_one_subdivisions_worth)); + fr = (nframes_t) round(pos + (n * frames_one_subdivisions_worth)); if (fr > next_pos) { fr = next_pos; //take care of fractional beats that don't match the subdivision asked } @@ -970,11 +977,14 @@ TempoMap::round_to_beat_subdivision (jack_nframes_t fr, int sub_num) delete more_zoomed_bbt_points; return fr ; + + */ + } -jack_nframes_t +nframes_t -TempoMap::round_to_type (jack_nframes_t frame, int dir, BBTPointType type) +TempoMap::round_to_type (nframes_t frame, int dir, BBTPointType type) { Metric metric = metric_at (frame); BBT_Time bbt; @@ -1025,7 +1035,7 @@ TempoMap::round_to_type (jack_nframes_t frame, int dir, BBTPointType type) } TempoMap::BBTPointList * -TempoMap::get_points (jack_nframes_t lower, jack_nframes_t upper) const +TempoMap::get_points (nframes_t lower, nframes_t upper) const { Metrics::const_iterator i; @@ -1041,7 +1051,10 @@ TempoMap::get_points (jack_nframes_t lower, jack_nframes_t upper) const double beat_frame; double beat_frames; double frames_per_bar; - jack_nframes_t limit; + double delta_bars; + double delta_beats; + double dummy; + nframes_t limit; meter = &first_meter (); tempo = &first_tempo (); @@ -1070,6 +1083,10 @@ TempoMap::get_points (jack_nframes_t lower, jack_nframes_t upper) const Now start generating points. */ + beats_per_bar = meter->beats_per_bar (); + frames_per_bar = meter->frames_per_bar (*tempo, _frame_rate); + beat_frames = tempo->frames_per_beat (_frame_rate); + if (meter->frame() > tempo->frame()) { bar = meter->start().bars; beat = meter->start().beats; @@ -1080,12 +1097,21 @@ TempoMap::get_points (jack_nframes_t lower, jack_nframes_t upper) const current = tempo->frame(); } + /* initialize current to point to the bar/beat just prior to the + lower frame bound passed in. assumes that current is initialized + above to be on a beat. + */ + + delta_bars = (lower-current) / frames_per_bar; + delta_beats = modf(delta_bars, &dummy) * beats_per_bar; + current += (floor(delta_bars) * frames_per_bar) + (floor(delta_beats) * beat_frames); + + // adjust bars and beats too + bar += (uint32_t) (floor(delta_bars)); + beat += (uint32_t) (floor(delta_beats)); + points = new BBTPointList; - beats_per_bar = meter->beats_per_bar (); - frames_per_bar = meter->frames_per_bar (*tempo, _frame_rate); - beat_frames = tempo->frames_per_beat (_frame_rate); - do { if (i == metrics->end()) { @@ -1102,7 +1128,7 @@ TempoMap::get_points (jack_nframes_t lower, jack_nframes_t upper) const if (beat == 1) { if (current >= lower) { - points->push_back (BBTPoint (*meter, *tempo,(jack_nframes_t)rint(current), Bar, bar, 1)); + points->push_back (BBTPoint (*meter, *tempo,(nframes_t)rint(current), Bar, bar, 1)); } } @@ -1113,7 +1139,7 @@ TempoMap::get_points (jack_nframes_t lower, jack_nframes_t upper) const while (beat <= ceil( beats_per_bar) && beat_frame < limit) { if (beat_frame >= lower) { - points->push_back (BBTPoint (*meter, *tempo, (jack_nframes_t) rint(beat_frame), Beat, bar, beat)); + points->push_back (BBTPoint (*meter, *tempo, (nframes_t) rint(beat_frame), Beat, bar, beat)); } beat_frame += beat_frames; current+= beat_frames; @@ -1167,6 +1193,10 @@ TempoMap::get_points (jack_nframes_t lower, jack_nframes_t upper) const beat = 1; } + beats_per_bar = meter->beats_per_bar (); + frames_per_bar = meter->frames_per_bar (*tempo, _frame_rate); + beat_frames = tempo->frames_per_beat (_frame_rate); + ++i; } @@ -1176,7 +1206,7 @@ TempoMap::get_points (jack_nframes_t lower, jack_nframes_t upper) const } const Tempo& -TempoMap::tempo_at (jack_nframes_t frame) +TempoMap::tempo_at (nframes_t frame) { Metric m (metric_at (frame)); return m.tempo(); @@ -1184,7 +1214,7 @@ TempoMap::tempo_at (jack_nframes_t frame) const Meter& -TempoMap::meter_at (jack_nframes_t frame) +TempoMap::meter_at (nframes_t frame) { Metric m (metric_at (frame)); return m.meter(); @@ -1216,8 +1246,6 @@ TempoMap::set_state (const XMLNode& node) XMLNodeConstIterator niter; Metrics old_metrics (*metrics); - in_set_state = true; - metrics->clear(); nlist = node.children(); @@ -1257,20 +1285,9 @@ TempoMap::set_state (const XMLNode& node) metrics->sort (cmp); timestamp_metrics (); } - - in_set_state = false; } - /* This state needs to be saved. This string will never be a part of the - object's history though, because the allow_save flag is false during - session load. This state will eventually be tagged "initial state", - by a call to StateManager::allow_save from Session::set_state. - - If this state is not saved, there is no way to reach it through undo actions. - */ - save_state(_("load XML data")); - - send_state_changed (Change (0)); + StateChanged (Change (0)); return 0; } @@ -1293,65 +1310,3 @@ TempoMap::dump (std::ostream& o) const } } -UndoAction -TempoMap::get_memento () const -{ - return sigc::bind (mem_fun (*(const_cast (this)), &StateManager::use_state), _current_state_id); -} - -Change -TempoMap::restore_state (StateManager::State& state) -{ - Glib::RWLock::ReaderLock lm (lock); - - TempoMapState* tmstate = dynamic_cast (&state); - - /* We can't just set the metrics pointer to the address of the metrics list - stored in the state, cause this would ruin this state for restoring in - the future. If they have the same address, they are the same list. - Thus we need to copy all the elements from the state metrics list to the - current metrics list. - */ - metrics->clear(); - for (Metrics::iterator i = tmstate->metrics->begin(); i != tmstate->metrics->end(); ++i) { - TempoSection *ts; - MeterSection *ms; - - if ((ts = dynamic_cast(*i)) != 0) { - metrics->push_back (new TempoSection (*ts)); - } else if ((ms = dynamic_cast(*i)) != 0) { - metrics->push_back (new MeterSection (*ms)); - } - } - - last_bbt_valid = false; - - return Change (0); -} - -StateManager::State* -TempoMap::state_factory (std::string why) const -{ - TempoMapState* state = new TempoMapState (why); - - for (Metrics::iterator i = metrics->begin(); i != metrics->end(); ++i) { - TempoSection *ts; - MeterSection *ms; - - if ((ts = dynamic_cast(*i)) != 0) { - state->metrics->push_back (new TempoSection (*ts)); - } else if ((ms = dynamic_cast(*i)) != 0) { - state->metrics->push_back (new MeterSection (*ms)); - } - } - - return state; -} - -void -TempoMap::save_state (std::string why) -{ - if (!in_set_state) { - StateManager::save_state (why); - } -}