mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
Tempo ramps - another approach to first meter/tempo.
- first tempo is glued to first meter position as they are now both locked to AudioTime. - all existing audio-locked tempos to the left of the first meter are made inactive. all to the right are made active.
This commit is contained in:
parent
4de28f0745
commit
cb43d485fa
4 changed files with 190 additions and 35 deletions
|
|
@ -3262,7 +3262,11 @@ void
|
||||||
TempoMarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
TempoMarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||||
{
|
{
|
||||||
Drag::start_grab (event, cursor);
|
Drag::start_grab (event, cursor);
|
||||||
show_verbose_cursor_time (adjusted_current_frame (event));
|
if (!_real_section->active()) {
|
||||||
|
show_verbose_cursor_text (_("inactive"));
|
||||||
|
} else {
|
||||||
|
show_verbose_cursor_time (adjusted_current_frame (event));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -3274,6 +3278,9 @@ TempoMarkerDrag::setup_pointer_frame_offset ()
|
||||||
void
|
void
|
||||||
TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
|
TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
|
||||||
{
|
{
|
||||||
|
if (!_real_section->active()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (first_move) {
|
if (first_move) {
|
||||||
|
|
||||||
// create a dummy marker for visual representation of moving the
|
// create a dummy marker for visual representation of moving the
|
||||||
|
|
@ -3313,9 +3320,11 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
|
||||||
Tempo const tp = _marker->tempo();
|
Tempo const tp = _marker->tempo();
|
||||||
|
|
||||||
if (Keyboard::modifier_state_equals (event->button.state, ArdourKeyboard::constraint_modifier ())) {
|
if (Keyboard::modifier_state_equals (event->button.state, ArdourKeyboard::constraint_modifier ())) {
|
||||||
//_marker->set_position (pf);
|
|
||||||
double new_bpm = _real_section->beats_per_minute() + ((last_pointer_y() - current_pointer_y()) / 5.0);
|
double new_bpm = _real_section->beats_per_minute() + ((last_pointer_y() - current_pointer_y()) / 5.0);
|
||||||
_editor->session()->tempo_map().gui_change_tempo (_real_section, Tempo (new_bpm, _real_section->note_type()));
|
_editor->session()->tempo_map().gui_change_tempo (_real_section, Tempo (new_bpm, _real_section->note_type()));
|
||||||
|
stringstream strs;
|
||||||
|
strs << new_bpm;
|
||||||
|
show_verbose_cursor_text (strs.str());
|
||||||
} else if (_movable) {
|
} else if (_movable) {
|
||||||
|
|
||||||
_marker->set_position (pf);
|
_marker->set_position (pf);
|
||||||
|
|
@ -3327,14 +3336,16 @@ TempoMarkerDrag::motion (GdkEvent* event, bool first_move)
|
||||||
*/
|
*/
|
||||||
_editor->session()->tempo_map().gui_move_tempo_frame (_real_section, tp, pf);
|
_editor->session()->tempo_map().gui_move_tempo_frame (_real_section, tp, pf);
|
||||||
//}
|
//}
|
||||||
|
show_verbose_cursor_time (pf);
|
||||||
}
|
}
|
||||||
|
|
||||||
show_verbose_cursor_time (pf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
|
TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||||
{
|
{
|
||||||
|
if (!_real_section->active()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!movement_occurred) {
|
if (!movement_occurred) {
|
||||||
if (was_double_click()) {
|
if (was_double_click()) {
|
||||||
_editor->edit_tempo_marker (*_marker);
|
_editor->edit_tempo_marker (*_marker);
|
||||||
|
|
|
||||||
|
|
@ -809,6 +809,9 @@ Editor::tempo_or_meter_marker_context_menu (GdkEventButton* ev, ArdourCanvas::It
|
||||||
if (mm) {
|
if (mm) {
|
||||||
can_remove = mm->meter().movable ();
|
can_remove = mm->meter().movable ();
|
||||||
} else if (tm) {
|
} else if (tm) {
|
||||||
|
if (!tm->tempo().active()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
can_remove = tm->tempo().movable ();
|
can_remove = tm->tempo().movable ();
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -175,9 +175,9 @@ class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
|
||||||
};
|
};
|
||||||
|
|
||||||
TempoSection (const double& beat, double qpm, double note_type, Type tempo_type)
|
TempoSection (const double& beat, double qpm, double note_type, Type tempo_type)
|
||||||
: MetricSection (beat), Tempo (qpm, note_type), _bar_offset (-1.0), _type (tempo_type), _c_func (0.0) {}
|
: MetricSection (beat), Tempo (qpm, note_type), _bar_offset (-1.0), _type (tempo_type), _c_func (0.0), _active (true) {}
|
||||||
TempoSection (framepos_t frame, double qpm, double note_type, Type tempo_type)
|
TempoSection (framepos_t frame, double qpm, double note_type, Type tempo_type)
|
||||||
: MetricSection (frame), Tempo (qpm, note_type), _bar_offset (-1.0), _type (tempo_type), _c_func (0.0) {}
|
: MetricSection (frame), Tempo (qpm, note_type), _bar_offset (-1.0), _type (tempo_type), _c_func (0.0), _active (true) {}
|
||||||
TempoSection (const XMLNode&);
|
TempoSection (const XMLNode&);
|
||||||
|
|
||||||
static const std::string xml_state_node_name;
|
static const std::string xml_state_node_name;
|
||||||
|
|
@ -188,6 +188,9 @@ class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
|
||||||
void update_bbt_time_from_bar_offset (const Meter&);
|
void update_bbt_time_from_bar_offset (const Meter&);
|
||||||
double bar_offset() const { return _bar_offset; }
|
double bar_offset() const { return _bar_offset; }
|
||||||
|
|
||||||
|
bool active () const { return _active; }
|
||||||
|
void set_active (bool yn) { _active = yn; }
|
||||||
|
|
||||||
void set_type (Type type);
|
void set_type (Type type);
|
||||||
Type type () const { return _type; }
|
Type type () const { return _type; }
|
||||||
|
|
||||||
|
|
@ -240,6 +243,7 @@ class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
|
||||||
double _bar_offset;
|
double _bar_offset;
|
||||||
Type _type;
|
Type _type;
|
||||||
double _c_func;
|
double _c_func;
|
||||||
|
bool _active;
|
||||||
Timecode::BBT_Time _legacy_bbt;
|
Timecode::BBT_Time _legacy_bbt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,13 @@ TempoSection::TempoSection (const XMLNode& node)
|
||||||
|
|
||||||
set_movable (string_is_affirmative (prop->value()));
|
set_movable (string_is_affirmative (prop->value()));
|
||||||
|
|
||||||
|
if ((prop = node.property ("active")) == 0) {
|
||||||
|
warning << _("TempoSection XML node has no \"active\" property") << endmsg;
|
||||||
|
set_active(true);
|
||||||
|
} else {
|
||||||
|
set_active (string_is_affirmative (prop->value()));
|
||||||
|
}
|
||||||
|
|
||||||
if ((prop = node.property ("bar-offset")) == 0) {
|
if ((prop = node.property ("bar-offset")) == 0) {
|
||||||
_bar_offset = -1.0;
|
_bar_offset = -1.0;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -179,6 +186,8 @@ TempoSection::get_state() const
|
||||||
// root->add_property ("bar-offset", buf);
|
// root->add_property ("bar-offset", buf);
|
||||||
snprintf (buf, sizeof (buf), "%s", movable()?"yes":"no");
|
snprintf (buf, sizeof (buf), "%s", movable()?"yes":"no");
|
||||||
root->add_property ("movable", buf);
|
root->add_property ("movable", buf);
|
||||||
|
snprintf (buf, sizeof (buf), "%s", active()?"yes":"no");
|
||||||
|
root->add_property ("active", buf);
|
||||||
root->add_property ("tempo-type", enum_2_string (_type));
|
root->add_property ("tempo-type", enum_2_string (_type));
|
||||||
root->add_property ("lock-style", enum_2_string (position_lock_style()));
|
root->add_property ("lock-style", enum_2_string (position_lock_style()));
|
||||||
|
|
||||||
|
|
@ -757,6 +766,7 @@ TempoMap::do_insert (MetricSection* section)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
*(dynamic_cast<Tempo*>(*i)) = *(dynamic_cast<Tempo*>(insert_tempo));
|
*(dynamic_cast<Tempo*>(*i)) = *(dynamic_cast<Tempo*>(insert_tempo));
|
||||||
|
(*i)->set_position_lock_style (AudioTime);
|
||||||
need_add = false;
|
need_add = false;
|
||||||
} else {
|
} else {
|
||||||
_metrics.erase (i);
|
_metrics.erase (i);
|
||||||
|
|
@ -864,6 +874,8 @@ TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const frame
|
||||||
add_tempo_locked (tempo, frame, true, type);
|
add_tempo_locked (tempo, frame, true, type);
|
||||||
} else {
|
} else {
|
||||||
first.set_type (type);
|
first.set_type (type);
|
||||||
|
first.set_pulse (0.0);
|
||||||
|
first.set_position_lock_style (AudioTime);
|
||||||
{
|
{
|
||||||
/* cannot move the first tempo section */
|
/* cannot move the first tempo section */
|
||||||
*static_cast<Tempo*>(&first) = tempo;
|
*static_cast<Tempo*>(&first) = tempo;
|
||||||
|
|
@ -871,6 +883,7 @@ TempoMap::replace_tempo (const TempoSection& ts, const Tempo& tempo, const frame
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyChanged (PropertyChange ());
|
PropertyChanged (PropertyChange ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -927,10 +940,12 @@ 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());
|
||||||
|
TempoSection& first_t (first_tempo());
|
||||||
|
|
||||||
const PositionLockStyle pl = ms.position_lock_style();
|
const PositionLockStyle pl = ms.position_lock_style();
|
||||||
if (ms.pulse() != first.pulse()) {
|
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, pulse_at_beat_locked (_metrics, bbt_to_beats_locked (_metrics, where)), where, true);
|
||||||
} else {
|
} else {
|
||||||
/* cannot move the first meter section */
|
/* cannot move the first meter section */
|
||||||
*static_cast<Meter*>(&first) = meter;
|
*static_cast<Meter*>(&first) = meter;
|
||||||
|
|
@ -948,6 +963,8 @@ 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());
|
MeterSection& first (first_meter());
|
||||||
|
TempoSection& first_t (first_tempo());
|
||||||
|
|
||||||
const PositionLockStyle pl = ms.position_lock_style();
|
const PositionLockStyle pl = ms.position_lock_style();
|
||||||
if (ms.pulse() != first.pulse()) {
|
if (ms.pulse() != first.pulse()) {
|
||||||
remove_meter_locked (ms);
|
remove_meter_locked (ms);
|
||||||
|
|
@ -955,12 +972,19 @@ TempoMap::replace_meter (const MeterSection& ms, const Meter& meter, const frame
|
||||||
} else {
|
} else {
|
||||||
/* 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 (AudioTime);
|
||||||
|
first.set_pulse (0.0);
|
||||||
first.set_frame (frame);
|
first.set_frame (frame);
|
||||||
|
pair<double, BBT_Time> beat = make_pair (0.0, BBT_Time (1, 1, 0));
|
||||||
|
first.set_beat (beat);
|
||||||
|
recompute_meters (_metrics);
|
||||||
|
first_t.set_frame (first.frame());
|
||||||
|
first_t.set_pulse (0.0);
|
||||||
|
first_t.set_position_lock_style (AudioTime);
|
||||||
|
|
||||||
recompute_map (_metrics);
|
recompute_map (_metrics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyChanged (PropertyChange ());
|
PropertyChanged (PropertyChange ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1187,6 +1211,7 @@ TempoMap::gui_change_tempo (TempoSection* ts, const Tempo& bpm)
|
||||||
}
|
}
|
||||||
return can_solve;
|
return can_solve;
|
||||||
}
|
}
|
||||||
|
|
||||||
TempoSection*
|
TempoSection*
|
||||||
TempoMap::copy_metrics_and_point (Metrics& copy, TempoSection* section)
|
TempoMap::copy_metrics_and_point (Metrics& copy, TempoSection* section)
|
||||||
{
|
{
|
||||||
|
|
@ -1202,14 +1227,20 @@ TempoMap::copy_metrics_and_point (Metrics& copy, TempoSection* section)
|
||||||
} else {
|
} else {
|
||||||
ret = new TempoSection (t->frame(), t->beats_per_minute(), t->note_type(), t->type());
|
ret = new TempoSection (t->frame(), t->beats_per_minute(), t->note_type(), t->type());
|
||||||
}
|
}
|
||||||
|
ret->set_active (t->active());
|
||||||
|
ret->set_movable (t->movable());
|
||||||
copy.push_back (ret);
|
copy.push_back (ret);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
TempoSection* cp = 0;
|
||||||
if (t->position_lock_style() == MusicTime) {
|
if (t->position_lock_style() == MusicTime) {
|
||||||
copy.push_back (new TempoSection (t->pulse(), t->beats_per_minute(), t->note_type(), t->type()));
|
cp = new TempoSection (t->pulse(), t->beats_per_minute(), t->note_type(), t->type());
|
||||||
} else {
|
} else {
|
||||||
copy.push_back (new TempoSection (t->frame(), t->beats_per_minute(), t->note_type(), t->type()));
|
cp = new TempoSection (t->frame(), t->beats_per_minute(), t->note_type(), t->type());
|
||||||
}
|
}
|
||||||
|
cp->set_active (t->active());
|
||||||
|
cp->set_movable (t->movable());
|
||||||
|
copy.push_back (cp);
|
||||||
}
|
}
|
||||||
if ((m = dynamic_cast<MeterSection *> (*i)) != 0) {
|
if ((m = dynamic_cast<MeterSection *> (*i)) != 0) {
|
||||||
if (m->position_lock_style() == MusicTime) {
|
if (m->position_lock_style() == MusicTime) {
|
||||||
|
|
@ -1254,6 +1285,9 @@ TempoMap::change_initial_tempo (double beats_per_minute, double note_type)
|
||||||
|
|
||||||
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) {
|
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
Glib::Threads::RWLock::WriterLock lm (lock);
|
Glib::Threads::RWLock::WriterLock lm (lock);
|
||||||
*((Tempo*) t) = newtempo;
|
*((Tempo*) t) = newtempo;
|
||||||
|
|
@ -1286,6 +1320,9 @@ TempoMap::change_existing_tempo_at (framepos_t where, double beats_per_minute, d
|
||||||
TempoSection* t;
|
TempoSection* t;
|
||||||
|
|
||||||
if ((t = dynamic_cast<TempoSection*>(*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection*>(*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!first) {
|
if (!first) {
|
||||||
first = t;
|
first = t;
|
||||||
}
|
}
|
||||||
|
|
@ -1357,6 +1394,9 @@ TempoMap::first_tempo () const
|
||||||
|
|
||||||
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) {
|
if ((t = dynamic_cast<const TempoSection *> (*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
return *t;
|
return *t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1373,6 +1413,9 @@ TempoMap::first_tempo ()
|
||||||
|
|
||||||
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<TempoSection *> (*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection *> (*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
return *t;
|
return *t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1390,6 +1433,9 @@ TempoMap::recompute_tempos (Metrics& metrics)
|
||||||
TempoSection* t;
|
TempoSection* t;
|
||||||
|
|
||||||
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (prev_ts) {
|
if (prev_ts) {
|
||||||
if (t->position_lock_style() == AudioTime) {
|
if (t->position_lock_style() == AudioTime) {
|
||||||
prev_ts->set_c_func (prev_ts->compute_c_func_frame (t->pulses_per_minute(), t->frame(), _frame_rate));
|
prev_ts->set_c_func (prev_ts->compute_c_func_frame (t->pulses_per_minute(), t->frame(), _frame_rate));
|
||||||
|
|
@ -1414,6 +1460,7 @@ TempoMap::recompute_meters (Metrics& metrics)
|
||||||
MeterSection* prev_m = 0;
|
MeterSection* prev_m = 0;
|
||||||
double accumulated_beats = 0.0;
|
double accumulated_beats = 0.0;
|
||||||
uint32_t accumulated_bars = 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) {
|
if (prev_m) {
|
||||||
|
|
@ -1421,27 +1468,29 @@ TempoMap::recompute_meters (Metrics& metrics)
|
||||||
accumulated_beats += beats_in_m;
|
accumulated_beats += beats_in_m;
|
||||||
accumulated_bars += (beats_in_m + 1) / prev_m->divisions_per_bar();
|
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;
|
||||||
pair<double, BBT_Time> bt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
|
pair<double, BBT_Time> bt = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
|
||||||
meter->set_beat (bt);
|
meter->set_beat (bt);
|
||||||
if (prev_m) {
|
if (prev_m) {
|
||||||
const double pulse = prev_m->pulse() + (meter->beat() - prev_m->beat()) / prev_m->note_divisor();
|
pulse = prev_m->pulse() + (meter->beat() - prev_m->beat()) / prev_m->note_divisor();
|
||||||
meter->set_pulse (pulse);
|
|
||||||
} else {
|
} else {
|
||||||
const double pulse = pulse_at_frame_locked (metrics, meter->frame());
|
if (meter->movable()) {
|
||||||
meter->set_pulse (pulse);
|
pulse = pulse_at_frame_locked (metrics, meter->frame());
|
||||||
|
} else {
|
||||||
|
pulse = 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
meter->set_pulse (pulse);
|
||||||
} else {
|
} else {
|
||||||
|
double pulse = 0.0;
|
||||||
if (prev_m) {
|
if (prev_m) {
|
||||||
const double pulse = prev_m->pulse() + (meter->beat() - prev_m->beat()) / prev_m->note_divisor();
|
pulse = prev_m->pulse() + (meter->beat() - prev_m->beat()) / prev_m->note_divisor();
|
||||||
meter->set_frame (frame_at_pulse_locked (metrics, pulse));
|
|
||||||
meter->set_pulse (pulse);
|
|
||||||
} else {
|
} else {
|
||||||
const double pulse = pulse_at_beat_locked (metrics, meter->beat());
|
pulse = pulse_at_beat_locked (metrics, meter->beat());
|
||||||
meter->set_frame (frame_at_pulse_locked (metrics, pulse));
|
|
||||||
meter->set_pulse (pulse);
|
|
||||||
}
|
}
|
||||||
|
meter->set_frame (frame_at_pulse_locked (metrics, pulse));
|
||||||
|
meter->set_pulse (pulse);
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_m = meter;
|
prev_m = meter;
|
||||||
|
|
@ -1800,7 +1849,9 @@ TempoMap::pulse_at_frame_locked (const Metrics& metrics, const framecnt_t& frame
|
||||||
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
|
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
|
||||||
TempoSection* t;
|
TempoSection* t;
|
||||||
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (prev_ts && t->frame() > frame) {
|
if (prev_ts && t->frame() > frame) {
|
||||||
/*the previous ts is the one containing the frame */
|
/*the previous ts is the one containing the frame */
|
||||||
double const ret = prev_ts->pulse_at_frame (frame, _frame_rate);
|
double const ret = prev_ts->pulse_at_frame (frame, _frame_rate);
|
||||||
|
|
@ -1844,6 +1895,9 @@ TempoMap::frame_at_pulse_locked (const Metrics& metrics, const double& pulse) co
|
||||||
TempoSection* t;
|
TempoSection* t;
|
||||||
|
|
||||||
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (prev_ts && t->pulse() > pulse) {
|
if (prev_ts && t->pulse() > pulse) {
|
||||||
return prev_ts->frame_at_pulse (pulse, _frame_rate);
|
return prev_ts->frame_at_pulse (pulse, _frame_rate);
|
||||||
}
|
}
|
||||||
|
|
@ -1944,11 +1998,14 @@ TempoMap::check_solved (Metrics& metrics, bool by_frame)
|
||||||
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
|
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
|
||||||
TempoSection* t;
|
TempoSection* t;
|
||||||
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (prev_ts) {
|
if (prev_ts) {
|
||||||
if ((by_frame && t->frame() < prev_ts->frame()) || (!by_frame && t->pulse() < prev_ts->pulse())) {
|
if ((by_frame && t->frame() < prev_ts->frame()) || (!by_frame && t->pulse() < prev_ts->pulse())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (by_frame && t->frame() != prev_ts->frame_at_tempo (t->pulses_per_minute(), t->pulse(), _frame_rate)) {
|
if (by_frame && t->frame() != prev_ts->frame_at_pulse (t->pulse(), _frame_rate)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
@ -1971,16 +2028,34 @@ TempoMap::check_solved (Metrics& metrics, bool by_frame)
|
||||||
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;
|
MetricSectionFrameSorter fcmp;
|
||||||
MetricSectionSorter cmp;
|
MetricSectionSorter cmp;
|
||||||
|
framepos_t first_m_frame = 0;
|
||||||
|
for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
|
||||||
|
MeterSection* m;
|
||||||
|
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
|
||||||
|
if (!m->movable()) {
|
||||||
|
first_m_frame = m->frame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (section->movable() && frame < first_m_frame) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
section->set_active (true);
|
||||||
|
}
|
||||||
section->set_frame (frame);
|
section->set_frame (frame);
|
||||||
|
|
||||||
for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
|
for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
|
||||||
TempoSection* t;
|
TempoSection* t;
|
||||||
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||||
|
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (prev_ts) {
|
if (prev_ts) {
|
||||||
if (t == section) {
|
if (t == section) {
|
||||||
section_prev = prev_ts;
|
section_prev = prev_ts;
|
||||||
|
|
@ -1999,7 +2074,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
|
||||||
}
|
}
|
||||||
|
|
||||||
if (section_prev) {
|
if (section_prev) {
|
||||||
section_prev->set_c_func (section_prev->compute_c_func_frame (bpm.pulses_per_minute(), frame, _frame_rate));
|
section_prev->set_c_func (section_prev->compute_c_func_frame (section->pulses_per_minute(), frame, _frame_rate));
|
||||||
section->set_pulse (section_prev->pulse_at_frame (frame, _frame_rate));
|
section->set_pulse (section_prev->pulse_at_frame (frame, _frame_rate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2058,11 +2133,13 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
|
||||||
TempoSection* section_prev = 0;
|
TempoSection* section_prev = 0;
|
||||||
|
|
||||||
section->set_pulse (pulse);
|
section->set_pulse (pulse);
|
||||||
section->set_beats_per_minute (bpm.beats_per_minute());
|
|
||||||
|
|
||||||
for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
|
for (Metrics::iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
|
||||||
TempoSection* t;
|
TempoSection* t;
|
||||||
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (prev_ts) {
|
if (prev_ts) {
|
||||||
if (t == section) {
|
if (t == section) {
|
||||||
section_prev = prev_ts;
|
section_prev = prev_ts;
|
||||||
|
|
@ -2080,7 +2157,7 @@ TempoMap::solve_map (Metrics& imaginary, TempoSection* section, const Tempo& bpm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (section_prev) {
|
if (section_prev) {
|
||||||
section_prev->set_c_func (section_prev->compute_c_func_pulse (bpm.pulses_per_minute(), pulse, _frame_rate));
|
section_prev->set_c_func (section_prev->compute_c_func_pulse (section->pulses_per_minute(), pulse, _frame_rate));
|
||||||
section->set_frame (section_prev->frame_at_pulse (pulse, _frame_rate));
|
section->set_frame (section_prev->frame_at_pulse (pulse, _frame_rate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2136,7 +2213,6 @@ void
|
||||||
TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const double& pulse)
|
TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt, const double& pulse)
|
||||||
{
|
{
|
||||||
MeterSection* prev_ms = 0;
|
MeterSection* prev_ms = 0;
|
||||||
|
|
||||||
double accumulated_beats = 0.0;
|
double accumulated_beats = 0.0;
|
||||||
uint32_t accumulated_bars = 0;
|
uint32_t accumulated_bars = 0;
|
||||||
|
|
||||||
|
|
@ -2187,6 +2263,44 @@ 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()) {
|
||||||
|
TempoSection* first_t;
|
||||||
|
for (Metrics::const_iterator i = imaginary.begin(); i != imaginary.end(); ++i) {
|
||||||
|
TempoSection* t;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Metrics future_map;
|
||||||
|
TempoSection* new_section = copy_metrics_and_point (future_map, first_t);
|
||||||
|
|
||||||
|
new_section->set_frame (frame);
|
||||||
|
new_section->set_pulse (0.0);
|
||||||
|
new_section->set_active (true);
|
||||||
|
|
||||||
|
if (solve_map (future_map, new_section, Tempo (new_section->beats_per_minute(), new_section->note_type()), frame)) {
|
||||||
|
first_t->set_frame (frame);
|
||||||
|
first_t->set_pulse (0.0);
|
||||||
|
first_t->set_active (true);
|
||||||
|
solve_map (imaginary, first_t, Tempo (first_t->beats_per_minute(), first_t->note_type()), frame);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double accumulated_beats = 0.0;
|
double accumulated_beats = 0.0;
|
||||||
uint32_t accumulated_bars = 0;
|
uint32_t accumulated_bars = 0;
|
||||||
|
|
||||||
|
|
@ -2208,7 +2322,11 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt,
|
||||||
(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 = make_pair (accumulated_beats, BBT_Time (accumulated_bars + 1, 1, 0));
|
||||||
m->set_pulse (pulse_at_frame_locked (imaginary, frame));
|
if (m->movable()) {
|
||||||
|
m->set_pulse (pulse_at_frame_locked (imaginary, frame));
|
||||||
|
} else {
|
||||||
|
m->set_pulse (0.0);
|
||||||
|
}
|
||||||
m->set_beat (b_bbt);
|
m->set_beat (b_bbt);
|
||||||
prev_ms = m;
|
prev_ms = m;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -2455,7 +2573,9 @@ TempoMap::tempo_section_at_locked (framepos_t frame) const
|
||||||
TempoSection* t;
|
TempoSection* t;
|
||||||
|
|
||||||
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (t->frame() > frame) {
|
if (t->frame() > frame) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2489,7 +2609,9 @@ TempoMap::frames_per_beat_at (const framepos_t& frame, const framecnt_t& sr) con
|
||||||
TempoSection* t;
|
TempoSection* t;
|
||||||
|
|
||||||
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ((*i)->frame() > frame) {
|
if ((*i)->frame() > frame) {
|
||||||
ts_after = t;
|
ts_after = t;
|
||||||
break;
|
break;
|
||||||
|
|
@ -2516,6 +2638,9 @@ TempoMap::tempo_at (const framepos_t& frame) const
|
||||||
for (i = _metrics.begin(); i != _metrics.end(); ++i) {
|
for (i = _metrics.begin(); i != _metrics.end(); ++i) {
|
||||||
TempoSection* t;
|
TempoSection* t;
|
||||||
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ((prev_ts) && t->frame() > frame) {
|
if ((prev_ts) && t->frame() > frame) {
|
||||||
/* t is the section past frame */
|
/* t is the section past frame */
|
||||||
double const ret = prev_ts->tempo_at_frame (frame, _frame_rate) * prev_ts->note_type();
|
double const ret = prev_ts->tempo_at_frame (frame, _frame_rate) * prev_ts->note_type();
|
||||||
|
|
@ -2547,15 +2672,15 @@ TempoMap::meter_section_at_locked (framepos_t frame) const
|
||||||
MeterSection* prev = 0;
|
MeterSection* prev = 0;
|
||||||
|
|
||||||
for (i = _metrics.begin(); i != _metrics.end(); ++i) {
|
for (i = _metrics.begin(); i != _metrics.end(); ++i) {
|
||||||
MeterSection* t;
|
MeterSection* m;
|
||||||
|
|
||||||
if ((t = dynamic_cast<MeterSection*> (*i)) != 0) {
|
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
|
||||||
|
|
||||||
if (prev && (*i)->frame() > frame) {
|
if (prev && (*i)->frame() > frame) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = t;
|
prev = m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2662,6 +2787,9 @@ TempoMap::set_state (const XMLNode& node, int /*version*/)
|
||||||
}
|
}
|
||||||
prev_ms = m;
|
prev_ms = m;
|
||||||
} else if ((t = dynamic_cast<TempoSection*>(*i)) != 0) {
|
} else if ((t = dynamic_cast<TempoSection*>(*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (prev_ts && prev_ts->pulse() < 0.0) {
|
if (prev_ts && prev_ts->pulse() < 0.0) {
|
||||||
double const start = ((prev_ts->legacy_bbt().bars - 1) * prev_ms->note_divisor()) + (prev_ts->legacy_bbt().beats - 1) + (prev_ts->legacy_bbt().ticks / BBT_Time::ticks_per_beat);
|
double const start = ((prev_ts->legacy_bbt().bars - 1) * prev_ms->note_divisor()) + (prev_ts->legacy_bbt().beats - 1) + (prev_ts->legacy_bbt().ticks / BBT_Time::ticks_per_beat);
|
||||||
prev_ts->set_pulse (start);
|
prev_ts->set_pulse (start);
|
||||||
|
|
@ -2804,6 +2932,9 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
|
||||||
if (prev) {
|
if (prev) {
|
||||||
if (ts){
|
if (ts){
|
||||||
if ((t = dynamic_cast<TempoSection*>(prev)) != 0) {
|
if ((t = dynamic_cast<TempoSection*>(prev)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
ts->set_pulse (t->pulse());
|
ts->set_pulse (t->pulse());
|
||||||
}
|
}
|
||||||
if ((m = dynamic_cast<MeterSection*>(prev)) != 0) {
|
if ((m = dynamic_cast<MeterSection*>(prev)) != 0) {
|
||||||
|
|
@ -2819,6 +2950,9 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
|
||||||
ms->set_pulse (m->pulse());
|
ms->set_pulse (m->pulse());
|
||||||
}
|
}
|
||||||
if ((t = dynamic_cast<TempoSection*>(prev)) != 0) {
|
if ((t = dynamic_cast<TempoSection*>(prev)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const double beat = beat_at_pulse_locked (_metrics, t->pulse());
|
const double beat = beat_at_pulse_locked (_metrics, t->pulse());
|
||||||
pair<double, BBT_Time> start = make_pair (beat, beats_to_bbt_locked (_metrics, beat));
|
pair<double, BBT_Time> start = make_pair (beat, beats_to_bbt_locked (_metrics, beat));
|
||||||
ms->set_beat (start);
|
ms->set_beat (start);
|
||||||
|
|
@ -2835,6 +2969,9 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
|
||||||
// cerr << bbt << endl;
|
// cerr << bbt << endl;
|
||||||
|
|
||||||
if ((t = dynamic_cast<TempoSection*>(*i)) != 0) {
|
if ((t = dynamic_cast<TempoSection*>(*i)) != 0) {
|
||||||
|
if (!t->active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
t->set_pulse (pulse_at_frame_locked (_metrics, m->frame()));
|
t->set_pulse (pulse_at_frame_locked (_metrics, m->frame()));
|
||||||
tempo = t;
|
tempo = t;
|
||||||
// cerr << "NEW TEMPO, frame = " << (*i)->frame() << " beat = " << (*i)->pulse() <<endl;
|
// cerr << "NEW TEMPO, frame = " << (*i)->frame() << " beat = " << (*i)->pulse() <<endl;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue