Tempo ramps - more multi audio-locked meter work, code reorganisation.

This commit is contained in:
nick_m 2016-03-31 02:34:54 +11:00
parent d7de12428b
commit 5d37fc6e36
3 changed files with 149 additions and 122 deletions

View file

@ -3204,9 +3204,9 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
XMLNode &before = map.get_state(); XMLNode &before = map.get_state();
if (_real_section->position_lock_style() == AudioTime) { if (_real_section->position_lock_style() == AudioTime) {
map.add_meter (Meter (_real_section->divisions_per_bar(), _real_section->note_divisor()), _real_section->frame()); map.add_meter (Meter (_real_section->divisions_per_bar(), _real_section->note_divisor()), _real_section->frame(), _real_section->beat(), _real_section->bbt());
} else { } else {
map.add_meter (Meter (_real_section->divisions_per_bar(), _real_section->note_divisor()), _real_section->pulse(), _real_section->bbt()); map.add_meter (Meter (_real_section->divisions_per_bar(), _real_section->note_divisor()), _real_section->beat(), _real_section->bbt());
} }
XMLNode &after = map.get_state(); XMLNode &after = map.get_state();
_editor->session()->add_command(new MementoCommand<TempoMap>(map, &before, &after)); _editor->session()->add_command(new MementoCommand<TempoMap>(map, &before, &after));

View file

@ -144,8 +144,8 @@ class LIBARDOUR_API MeterSection : public MetricSection, public Meter {
public: public:
MeterSection (double pulse, double beat, const Timecode::BBT_Time& bbt, double bpb, double note_type) MeterSection (double pulse, double beat, const Timecode::BBT_Time& bbt, double bpb, double note_type)
: MetricSection (pulse), Meter (bpb, note_type), _bbt (bbt), _beat (beat) {} : MetricSection (pulse), Meter (bpb, note_type), _bbt (bbt), _beat (beat) {}
MeterSection (framepos_t frame, double beat, double bpb, double note_type) MeterSection (framepos_t frame, double beat, const Timecode::BBT_Time& bbt, double bpb, double note_type)
: MetricSection (frame), Meter (bpb, note_type), _bbt (1, 1, 0), _beat (beat) {} : MetricSection (frame), Meter (bpb, note_type), _bbt (bbt), _beat (beat) {}
MeterSection (const XMLNode&); MeterSection (const XMLNode&);
static const std::string xml_state_node_name; static const std::string xml_state_node_name;
@ -304,7 +304,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
struct BBTPoint { struct BBTPoint {
framepos_t frame; framepos_t frame;
const MeterSection* meter; const MeterSection* meter;
const Tempo tempo; Tempo tempo;
double c; double c;
uint32_t bar; uint32_t bar;
uint32_t beat; uint32_t beat;
@ -377,7 +377,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
void add_tempo (const Tempo&, const framepos_t& frame, TempoSection::Type type); void add_tempo (const Tempo&, const framepos_t& frame, TempoSection::Type type);
void add_meter (const Meter&, const double& beat, const Timecode::BBT_Time& where); void add_meter (const Meter&, const double& beat, const Timecode::BBT_Time& where);
void add_meter (const Meter&, const framepos_t& frame); void add_meter (const Meter&, const framepos_t& frame, const double& beat, const Timecode::BBT_Time& where);
void remove_tempo (const TempoSection&, bool send_signal); void remove_tempo (const TempoSection&, bool send_signal);
void remove_meter (const MeterSection&, bool send_signal); void remove_meter (const MeterSection&, bool send_signal);
@ -462,6 +462,7 @@ private:
const Tempo tempo_at_locked (const framepos_t& frame) const; const Tempo tempo_at_locked (const framepos_t& frame) const;
bool check_solved (Metrics& metrics, bool by_frame); bool check_solved (Metrics& metrics, bool by_frame);
bool set_active_tempos (const Metrics& metrics, const framepos_t& frame);
bool solve_map (Metrics& metrics, TempoSection* section, const Tempo& bpm, const framepos_t& frame); bool solve_map (Metrics& metrics, TempoSection* section, const Tempo& bpm, const framepos_t& frame);
bool solve_map (Metrics& metrics, TempoSection* section, const Tempo& bpm, const double& pulse); bool solve_map (Metrics& metrics, TempoSection* section, const Tempo& bpm, const double& pulse);
void solve_map (Metrics& metrics, MeterSection* section, const Meter& mt, const framepos_t& frame); void solve_map (Metrics& metrics, MeterSection* section, const Meter& mt, const framepos_t& frame);
@ -495,7 +496,7 @@ private:
void add_tempo_locked (const Tempo&, framepos_t frame, bool recompute, TempoSection::Type type); void add_tempo_locked (const Tempo&, framepos_t frame, bool recompute, TempoSection::Type type);
void add_meter_locked (const Meter&, double beat, Timecode::BBT_Time where, bool recompute); void add_meter_locked (const Meter&, double beat, Timecode::BBT_Time where, bool recompute);
void add_meter_locked (const Meter&, framepos_t frame, bool recompute); void add_meter_locked (const Meter&, framepos_t frame, double beat, Timecode::BBT_Time where, bool recompute);
bool remove_tempo_locked (const TempoSection&); bool remove_tempo_locked (const TempoSection&);
bool remove_meter_locked (const MeterSection&); bool remove_meter_locked (const MeterSection&);

View file

@ -925,11 +925,11 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const BBT_T
Glib::Threads::RWLock::WriterLock lm (lock); Glib::Threads::RWLock::WriterLock lm (lock);
MeterSection& first (first_meter()); MeterSection& first (first_meter());
const PositionLockStyle pl = ms.position_lock_style(); if (ms.movable()) {
if (ms.pulse() != first.pulse()) {
remove_meter_locked (ms); remove_meter_locked (ms);
add_meter_locked (meter, bbt_to_beats_locked (_metrics, where), where, true); add_meter_locked (meter, bbt_to_beats_locked (_metrics, where), where, true);
} else { } else {
const PositionLockStyle pl = ms.position_lock_style();
/* cannot move the first meter section */ /* cannot move the first meter section */
*static_cast<Meter*>(&first) = meter; *static_cast<Meter*>(&first) = meter;
first.set_position_lock_style (pl); first.set_position_lock_style (pl);
@ -945,13 +945,15 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const frame
{ {
{ {
Glib::Threads::RWLock::WriterLock lm (lock); Glib::Threads::RWLock::WriterLock lm (lock);
MeterSection& first (first_meter());
TempoSection& first_t (first_tempo());
if (ms.pulse() != first.pulse()) { const double beat = ms.beat();
const BBT_Time bbt = ms.bbt();
if (ms.movable()) {
remove_meter_locked (ms); remove_meter_locked (ms);
add_meter_locked (meter, frame, true); add_meter_locked (meter, frame, beat, bbt, true);
} else { } else {
MeterSection& first (first_meter());
TempoSection& first_t (first_tempo());
/* cannot move the first meter section */ /* cannot move the first meter section */
*static_cast<Meter*>(&first) = meter; *static_cast<Meter*>(&first) = meter;
first.set_position_lock_style (AudioTime); first.set_position_lock_style (AudioTime);
@ -959,7 +961,6 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const frame
first.set_frame (frame); first.set_frame (frame);
pair<double, BBT_Time> beat = make_pair (0.0, BBT_Time (1, 1, 0)); pair<double, BBT_Time> beat = make_pair (0.0, BBT_Time (1, 1, 0));
first.set_beat (beat); first.set_beat (beat);
recompute_meters (_metrics);
first_t.set_frame (first.frame()); first_t.set_frame (first.frame());
first_t.set_pulse (0.0); first_t.set_pulse (0.0);
first_t.set_position_lock_style (AudioTime); first_t.set_position_lock_style (AudioTime);
@ -990,11 +991,11 @@ TempoMap::add_meter (const Meter& meter, const double& beat, const BBT_Time& whe
} }
void void
TempoMap::add_meter (const Meter& meter, const framepos_t& frame) TempoMap::add_meter (const Meter& meter, const framepos_t& frame, const double& beat, const Timecode::BBT_Time& where)
{ {
{ {
Glib::Threads::RWLock::WriterLock lm (lock); Glib::Threads::RWLock::WriterLock lm (lock);
add_meter_locked (meter, frame, true); add_meter_locked (meter, frame, beat, where, true);
} }
@ -1035,10 +1036,13 @@ TempoMap::add_meter_locked (const Meter& meter, double beat, BBT_Time where, boo
} }
void void
TempoMap::add_meter_locked (const Meter& meter, framepos_t frame, bool recompute) TempoMap::add_meter_locked (const Meter& meter, framepos_t frame, double beat, Timecode::BBT_Time where, bool recompute)
{ {
MeterSection* new_meter = new MeterSection (frame, 0.0, meter.divisions_per_bar(), meter.note_divisor()); MeterSection* new_meter = new MeterSection (frame, beat, where, meter.divisions_per_bar(), meter.note_divisor());
double pulse = pulse_at_frame_locked (_metrics, frame);
new_meter->set_pulse (pulse);
do_insert (new_meter); do_insert (new_meter);
@ -1130,7 +1134,7 @@ TempoMap::gui_move_tempo_beat (TempoSection* ts, const Tempo& bpm, const double
Glib::Threads::RWLock::WriterLock lm (lock); Glib::Threads::RWLock::WriterLock lm (lock);
TempoSection* new_section = copy_metrics_and_point (future_map, ts); TempoSection* new_section = copy_metrics_and_point (future_map, ts);
if (solve_map (future_map, new_section, bpm, pulse_at_beat_locked (future_map, beat))) { if (solve_map (future_map, new_section, bpm, pulse_at_beat_locked (future_map, beat))) {
solve_map (_metrics, ts, bpm, pulse_at_beat_locked (_metrics, beat)); solve_map (_metrics, ts, bpm, pulse_at_beat_locked (_metrics, beat));
} }
} }
@ -1225,14 +1229,17 @@ TempoMap::copy_metrics_and_point (Metrics& copy, TempoSection* section)
copy.push_back (cp); copy.push_back (cp);
} }
if ((m = dynamic_cast<MeterSection *> (*i)) != 0) { if ((m = dynamic_cast<MeterSection *> (*i)) != 0) {
MeterSection* cp = 0;
if (m->position_lock_style() == MusicTime) { if (m->position_lock_style() == MusicTime) {
copy.push_back (new MeterSection (m->pulse(), m->beat(), m->bbt(), m->divisions_per_bar(), m->note_divisor())); cp = new MeterSection (m->pulse(), m->beat(), m->bbt(), m->divisions_per_bar(), m->note_divisor());
} else { } else {
copy.push_back (new MeterSection (m->frame(), m->beat(), m->divisions_per_bar(), m->note_divisor())); cp = new MeterSection (m->frame(), m->beat(), m->bbt(), m->divisions_per_bar(), m->note_divisor());
} }
cp->set_movable (m->movable());
copy.push_back (cp);
} }
} }
recompute_map (copy); //recompute_map (copy);
return ret; return ret;
} }
@ -1379,7 +1386,9 @@ TempoMap::first_tempo () const
if (!t->active()) { if (!t->active()) {
continue; continue;
} }
return *t; if (!t->movable()) {
return *t;
}
} }
} }
@ -1398,7 +1407,9 @@ TempoMap::first_tempo ()
if (!t->active()) { if (!t->active()) {
continue; continue;
} }
return *t; if (!t->movable()) {
return *t;
}
} }
} }
@ -1441,30 +1452,24 @@ TempoMap::recompute_meters (Metrics& metrics)
{ {
MeterSection* meter = 0; MeterSection* meter = 0;
MeterSection* prev_m = 0; MeterSection* prev_m = 0;
double accumulated_beats = 0.0;
uint32_t accumulated_bars = 0;
for (Metrics::const_iterator mi = metrics.begin(); mi != metrics.end(); ++mi) { for (Metrics::const_iterator mi = metrics.begin(); mi != metrics.end(); ++mi) {
if ((meter = dynamic_cast<MeterSection*> (*mi)) != 0) { if ((meter = dynamic_cast<MeterSection*> (*mi)) != 0) {
if (prev_m) {
const double beats_in_m = (meter->pulse() - prev_m->pulse()) * prev_m->note_divisor();
accumulated_beats += beats_in_m;
accumulated_bars += (beats_in_m + 1) / prev_m->divisions_per_bar();
}
if (meter->position_lock_style() == AudioTime) { if (meter->position_lock_style() == AudioTime) {
double pulse = 0.0; double pulse = 0.0;
pair<double, BBT_Time> bt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
meter->set_beat (bt);
if (prev_m) { if (prev_m) {
pulse = prev_m->pulse() + (meter->beat() - prev_m->beat()) / prev_m->note_divisor(); double beats = ((pulse_at_frame_locked (metrics, meter->frame()) - prev_m->pulse()) * prev_m->note_divisor()) - prev_m->beat();
} else {
if (meter->movable()) { const double true_pulse = prev_m->pulse() + (ceil (beats) - prev_m->beat()) / prev_m->note_divisor();
pulse = pulse_at_frame_locked (metrics, meter->frame()); const double pulse_off = true_pulse - ((beats - prev_m->beat()) / prev_m->note_divisor());
} else { pulse = true_pulse - pulse_off;
pulse = 0.0;
}
} }
meter->set_pulse (pulse); meter->set_pulse (pulse);
if (!meter->movable()) {
pair<double, BBT_Time> bt = make_pair (0.0, BBT_Time (1, 1, 0));
meter->set_beat (bt);
}
} else { } else {
double pulse = 0.0; double pulse = 0.0;
if (prev_m) { if (prev_m) {
@ -1816,8 +1821,8 @@ TempoMap::beat_at_frame (const framecnt_t& frame) const
double double
TempoMap::beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const TempoMap::beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const
{ {
framecnt_t const offset_frame = frame + frame_offset_at (metrics, frame); //framecnt_t const offset_frame = frame + frame_offset_at (metrics, frame);
double const pulse = pulse_at_frame_locked (metrics, offset_frame); double const pulse = pulse_at_frame_locked (metrics, frame);
return beat_at_pulse_locked (metrics, pulse); return beat_at_pulse_locked (metrics, pulse);
} }
@ -1862,8 +1867,8 @@ framecnt_t
TempoMap::frame_at_beat_locked (const Metrics& metrics, const double& beat) const TempoMap::frame_at_beat_locked (const Metrics& metrics, const double& beat) const
{ {
framecnt_t const frame = frame_at_pulse_locked (metrics, pulse_at_beat_locked (metrics, beat)); framecnt_t const frame = frame_at_pulse_locked (metrics, pulse_at_beat_locked (metrics, beat));
frameoffset_t const frame_off = frame_offset_at (metrics, frame); //frameoffset_t const frame_off = frame_offset_at (metrics, frame);
return frame - frame_off; return frame;
} }
framecnt_t framecnt_t
@ -2005,20 +2010,42 @@ TempoMap::check_solved (Metrics& metrics, bool by_frame)
return true; return true;
} }
bool
TempoMap::set_active_tempos (const Metrics& metrics, const framepos_t& frame)
{
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
TempoSection* t;
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
if (!t->movable()) {
t->set_active (true);
continue;
}
if (t->movable() && t->active () && t->position_lock_style() == AudioTime && t->frame() < frame) {
t->set_active (false);
t->set_pulse (0.0);
} else if (t->movable() && t->position_lock_style() == AudioTime && t->frame() > frame) {
t->set_active (true);
} else if (t->movable() && t->position_lock_style() == AudioTime && t->frame() == frame) {
return false;
}
}
}
return true;
}
bool bool
TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const framepos_t& frame) TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const framepos_t& frame)
{ {
TempoSection* prev_ts = 0; TempoSection* prev_ts = 0;
TempoSection* section_prev = 0; TempoSection* section_prev = 0;
MetricSectionFrameSorter fcmp;
MetricSectionSorter cmp;
framepos_t first_m_frame = 0; framepos_t first_m_frame = 0;
for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) { for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
MeterSection* m; MeterSection* m;
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) { if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
if (!m->movable()) { if (!m->movable()) {
first_m_frame = m->frame(); first_m_frame = m->frame();
break;
} }
} }
} }
@ -2072,6 +2099,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
return true; return true;
} }
MetricSectionFrameSorter fcmp;
imaginary.sort (fcmp); imaginary.sort (fcmp);
if (section->position_lock_style() == MusicTime) { if (section->position_lock_style() == MusicTime) {
/* we're setting the frame */ /* we're setting the frame */
@ -2086,6 +2114,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
return true; return true;
} }
MetricSectionSorter cmp;
imaginary.sort (cmp); imaginary.sort (cmp);
if (section->position_lock_style() == MusicTime) { if (section->position_lock_style() == MusicTime) {
/* we're setting the frame */ /* we're setting the frame */
@ -2107,8 +2136,6 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
bool bool
TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const double& pulse) TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm, const double& pulse)
{ {
MetricSectionSorter cmp;
MetricSectionFrameSorter fcmp;
TempoSection* prev_ts = 0; TempoSection* prev_ts = 0;
TempoSection* section_prev = 0; TempoSection* section_prev = 0;
@ -2154,6 +2181,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
return true; return true;
} }
MetricSectionSorter cmp;
imaginary.sort (cmp); imaginary.sort (cmp);
if (section->position_lock_style() == AudioTime) { if (section->position_lock_style() == AudioTime) {
/* we're setting the pulse */ /* we're setting the pulse */
@ -2169,6 +2197,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
return true; return true;
} }
MetricSectionFrameSorter fcmp;
imaginary.sort (fcmp); imaginary.sort (fcmp);
if (section->position_lock_style() == AudioTime) { if (section->position_lock_style() == AudioTime) {
/* we're setting the pulse */ /* we're setting the pulse */
@ -2189,81 +2218,17 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
return false; return false;
} }
void
TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const double& pulse)
{
MeterSection* prev_ms = 0;
double accumulated_beats = 0.0;
uint32_t accumulated_bars = 0;
section->set_pulse (pulse);
for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
MeterSection* m;
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
if (prev_ms) {
double const beats_in_m = (m->pulse() - prev_ms->pulse()) * prev_ms->note_divisor();
accumulated_beats += beats_in_m;
accumulated_bars += (beats_in_m + 1) / prev_ms->divisions_per_bar();
}
if (m == section){
section->set_frame (frame_at_pulse_locked (imaginary, pulse));
pair<double, BBT_Time> b_bbt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
section->set_beat (b_bbt);
prev_ms = section;
continue;
}
if (prev_ms) {
if (m->position_lock_style() == MusicTime) {
const double pulse = prev_ms->pulse() + (m->beat() - prev_ms->beat()) / prev_ms->note_divisor();
m->set_frame (frame_at_pulse_locked (imaginary, pulse));
m->set_pulse (pulse);
} else {
pair<double, BBT_Time> b_bbt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
m->set_beat (b_bbt);
const double pulse = prev_ms->pulse() + (m->beat() - prev_ms->beat()) / prev_ms->note_divisor();
m->set_pulse (pulse);
}
}
prev_ms = m;
}
}
if (section->position_lock_style() == AudioTime) {
/* we're setting the pulse */
section->set_position_lock_style (MusicTime);
recompute_meters (imaginary);
section->set_position_lock_style (AudioTime);
} else {
recompute_meters (imaginary);
}
}
void void
TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const framepos_t& frame) TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const framepos_t& frame)
{ {
MeterSection* prev_ms = 0; MeterSection* prev_ms = 0;
if (!section->movable()) { if (!section->movable()) {
TempoSection* first_t; /* lock the first tempo to our first meter */
for (Metrics::const_iterator i = imaginary.begin(); i != imaginary.end(); ++i) { if (!set_active_tempos (imaginary, frame)) {
TempoSection* t; return;
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
if (!t->movable()) {
t->set_active (true);
first_t = t;
}
if (t->movable() && t->active () && t->position_lock_style() == AudioTime && t->frame() < frame) {
t->set_active (false);
t->set_pulse (0.0);
} else if (t->movable() && t->position_lock_style() == AudioTime && t->frame() > frame) {
t->set_active (true);
} else if (t->movable() && t->position_lock_style() == AudioTime && t->frame() == frame) {
return;
}
}
} }
TempoSection* first_t = &first_tempo();
Metrics future_map; Metrics future_map;
TempoSection* new_section = copy_metrics_and_point (future_map, first_t); TempoSection* new_section = copy_metrics_and_point (future_map, first_t);
@ -2301,13 +2266,20 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt,
as an offset to the map as far as users of the public methods are concerned. as an offset to the map as far as users of the public methods are concerned.
(meters should go on absolute pulses to keep us sane) (meters should go on absolute pulses to keep us sane)
*/ */
pair<double, BBT_Time> b_bbt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0)); pair<double, BBT_Time> b_bbt;
if (m->movable()) { if (m->movable()) {
m->set_pulse (pulse_at_frame_locked (imaginary, frame)); double beats = ((pulse_at_frame_locked (imaginary, frame) - prev_ms->pulse()) * prev_ms->note_divisor()) - prev_ms->beat();
b_bbt = make_pair (ceil (beats), BBT_Time (accumulated_bars + 1, 1, 0));
m->set_beat (b_bbt);
const double true_pulse = prev_ms->pulse() + ((ceil (beats) - prev_ms->beat()) / prev_ms->note_divisor());
const double pulse_off = true_pulse - ((beats - prev_ms->beat()) / prev_ms->note_divisor());
m->set_pulse (true_pulse - pulse_off);
} else { } else {
b_bbt = make_pair (0.0, BBT_Time (1, 1, 0));
m->set_pulse (0.0); m->set_pulse (0.0);
m->set_beat (b_bbt);
} }
m->set_beat (b_bbt); //m->set_beat (b_bbt);
prev_ms = m; prev_ms = m;
continue; continue;
} }
@ -2317,8 +2289,10 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt,
m->set_frame (frame_at_pulse_locked (imaginary, pulse)); m->set_frame (frame_at_pulse_locked (imaginary, pulse));
m->set_pulse (pulse); m->set_pulse (pulse);
} else { } else {
pair<double, BBT_Time> b_bbt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0)); if (!m->movable()) {
m->set_beat (b_bbt); pair<double, BBT_Time> b_bbt = make_pair (0.0, BBT_Time (1, 1, 0));
m->set_beat (b_bbt);
}
const double pulse = prev_ms->pulse() + (m->beat() - prev_ms->beat()) / prev_ms->note_divisor(); const double pulse = prev_ms->pulse() + (m->beat() - prev_ms->beat()) / prev_ms->note_divisor();
m->set_pulse (pulse); m->set_pulse (pulse);
} }
@ -2338,6 +2312,58 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt,
//dump (imaginary, std::cerr); //dump (imaginary, std::cerr);
} }
void
TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const double& pulse)
{
MeterSection* prev_ms = 0;
double accumulated_beats = 0.0;
uint32_t accumulated_bars = 0;
section->set_pulse (pulse);
for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
MeterSection* m;
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
if (prev_ms) {
double const beats_in_m = (m->pulse() - prev_ms->pulse()) * prev_ms->note_divisor();
accumulated_beats += beats_in_m;
accumulated_bars += (beats_in_m + 1) / prev_ms->divisions_per_bar();
}
if (m == section){
section->set_frame (frame_at_pulse_locked (imaginary, pulse));
pair<double, BBT_Time> b_bbt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
section->set_beat (b_bbt);
prev_ms = section;
continue;
}
if (prev_ms) {
if (m->position_lock_style() == MusicTime) {
const double pulse = prev_ms->pulse() + (m->beat() - prev_ms->beat()) / prev_ms->note_divisor();
m->set_frame (frame_at_pulse_locked (imaginary, pulse));
m->set_pulse (pulse);
} else {
if (!m->movable()) {
pair<double, BBT_Time> b_bbt = make_pair (0.0, BBT_Time (1, 1, 0));
m->set_beat (b_bbt);
}
const double pulse = prev_ms->pulse() + (m->beat() - prev_ms->beat()) / prev_ms->note_divisor();
m->set_pulse (pulse);
}
}
prev_ms = m;
}
}
if (section->position_lock_style() == AudioTime) {
/* we're setting the pulse */
section->set_position_lock_style (MusicTime);
recompute_meters (imaginary);
section->set_position_lock_style (AudioTime);
} else {
recompute_meters (imaginary);
}
}
framecnt_t framecnt_t
TempoMap::bbt_duration_at (framepos_t pos, const BBT_Time& bbt, int dir) TempoMap::bbt_duration_at (framepos_t pos, const BBT_Time& bbt, int dir)
{ {