mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-25 14:47:20 +01:00
Tempo ramps - more code reorganization, almost audio-locked meter nirvana.
This commit is contained in:
parent
bc44f9bcaf
commit
6f5e8a885e
2 changed files with 235 additions and 274 deletions
|
|
@ -447,9 +447,6 @@ private:
|
|||
double pulse_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const;
|
||||
framecnt_t frame_at_pulse_locked (const Metrics& metrics, const double& beat) const;
|
||||
|
||||
double beat_offset_at (const Metrics& metrics, const double& beat) const;
|
||||
frameoffset_t frame_offset_at (const Metrics& metrics, const framepos_t& frame) const;
|
||||
|
||||
double beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const;
|
||||
framecnt_t frame_at_beat_locked (const Metrics& metrics, const double& beat) const;
|
||||
double bbt_to_beats_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const ;
|
||||
|
|
|
|||
|
|
@ -1062,220 +1062,6 @@ TempoMap::add_meter_locked (const Meter& meter, framepos_t frame, double beat, T
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is for a gui that needs to know the frame of a tempo section if it were to be moved to some bbt time,
|
||||
* taking any possible reordering as a consequence of this into account.
|
||||
* @param section - the section to be altered
|
||||
* @param bpm - the new Tempo
|
||||
* @param bbt - the bbt where the altered tempo will fall
|
||||
* @return returns - the position in frames where the new tempo section will lie.
|
||||
*/
|
||||
framepos_t
|
||||
TempoMap::predict_tempo_frame (TempoSection* section, const Tempo& bpm, const BBT_Time& bbt)
|
||||
{
|
||||
Glib::Threads::RWLock::ReaderLock lm (lock);
|
||||
Metrics future_map;
|
||||
framepos_t ret = 0;
|
||||
TempoSection* new_section = copy_metrics_and_point (future_map, section);
|
||||
|
||||
double const beat = bbt_to_beats_locked (future_map, bbt);
|
||||
if (solve_map (future_map, new_section, bpm, pulse_at_beat_locked (future_map, beat))) {
|
||||
ret = new_section->frame();
|
||||
} else {
|
||||
ret = frame_at_beat_locked (_metrics, beat);
|
||||
}
|
||||
|
||||
Metrics::const_iterator d = future_map.begin();
|
||||
while (d != future_map.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
double
|
||||
TempoMap::predict_tempo_pulse (TempoSection* section, const Tempo& bpm, const framepos_t& frame)
|
||||
{
|
||||
Glib::Threads::RWLock::ReaderLock lm (lock);
|
||||
Metrics future_map;
|
||||
double ret = 0.0;
|
||||
TempoSection* new_section = copy_metrics_and_point (future_map, section);
|
||||
|
||||
if (solve_map (future_map, new_section, bpm, frame)) {
|
||||
ret = new_section->pulse();
|
||||
} else {
|
||||
ret = pulse_at_frame_locked (_metrics, frame);
|
||||
}
|
||||
|
||||
Metrics::const_iterator d = future_map.begin();
|
||||
while (d != future_map.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::gui_move_tempo_frame (TempoSection* ts, const Tempo& bpm, const framepos_t& frame)
|
||||
{
|
||||
Metrics future_map;
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (lock);
|
||||
TempoSection* new_section = copy_metrics_and_point (future_map, ts);
|
||||
if (solve_map (future_map, new_section, bpm, frame)) {
|
||||
solve_map (_metrics, ts, bpm, frame);
|
||||
}
|
||||
}
|
||||
|
||||
Metrics::const_iterator d = future_map.begin();
|
||||
while (d != future_map.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
|
||||
MetricPositionChanged (); // Emit Signal
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::gui_move_tempo_beat (TempoSection* ts, const Tempo& bpm, const double& beat)
|
||||
{
|
||||
Metrics future_map;
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (lock);
|
||||
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))) {
|
||||
solve_map (_metrics, ts, bpm, pulse_at_beat_locked (_metrics, beat));
|
||||
}
|
||||
}
|
||||
|
||||
Metrics::const_iterator d = future_map.begin();
|
||||
while (d != future_map.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
|
||||
MetricPositionChanged (); // Emit Signal
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const framepos_t& frame)
|
||||
{
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (lock);
|
||||
solve_map (_metrics, ms, mt, frame);
|
||||
}
|
||||
|
||||
MetricPositionChanged (); // Emit Signal
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const double& beat)
|
||||
{
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (lock);
|
||||
solve_map (_metrics, ms, mt, pulse_at_beat_locked (_metrics, beat));
|
||||
}
|
||||
|
||||
MetricPositionChanged (); // Emit Signal
|
||||
}
|
||||
|
||||
bool
|
||||
TempoMap::gui_change_tempo (TempoSection* ts, const Tempo& bpm)
|
||||
{
|
||||
Metrics future_map;
|
||||
bool can_solve = false;
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (lock);
|
||||
TempoSection* new_section = copy_metrics_and_point (future_map, ts);
|
||||
new_section->set_beats_per_minute (bpm.beats_per_minute());
|
||||
recompute_tempos (future_map);
|
||||
|
||||
if (check_solved (future_map, true)) {
|
||||
ts->set_beats_per_minute (bpm.beats_per_minute());
|
||||
recompute_map (_metrics);
|
||||
can_solve = true;
|
||||
}
|
||||
}
|
||||
|
||||
Metrics::const_iterator d = future_map.begin();
|
||||
while (d != future_map.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
if (can_solve) {
|
||||
MetricPositionChanged (); // Emit Signal
|
||||
}
|
||||
return can_solve;
|
||||
}
|
||||
|
||||
TempoSection*
|
||||
TempoMap::copy_metrics_and_point (Metrics& copy, TempoSection* section)
|
||||
{
|
||||
TempoSection* t;
|
||||
TempoSection* ret = 0;
|
||||
MeterSection* m;
|
||||
|
||||
for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
|
||||
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||
if (t == section) {
|
||||
if (t->position_lock_style() == MusicTime) {
|
||||
ret = new TempoSection (t->pulse(), t->beats_per_minute(), t->note_type(), t->type());
|
||||
} else {
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
TempoSection* cp = 0;
|
||||
if (t->position_lock_style() == MusicTime) {
|
||||
cp = new TempoSection (t->pulse(), t->beats_per_minute(), t->note_type(), t->type());
|
||||
} else {
|
||||
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) {
|
||||
MeterSection* cp = 0;
|
||||
if (m->position_lock_style() == MusicTime) {
|
||||
cp = new MeterSection (m->pulse(), m->beat(), m->bbt(), m->divisions_per_bar(), m->note_divisor());
|
||||
} else {
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
TempoMap::can_solve_bbt (TempoSection* ts, const Tempo& bpm, const BBT_Time& bbt)
|
||||
{
|
||||
Metrics copy;
|
||||
TempoSection* new_section = 0;
|
||||
|
||||
{
|
||||
Glib::Threads::RWLock::ReaderLock lm (lock);
|
||||
new_section = copy_metrics_and_point (copy, ts);
|
||||
}
|
||||
|
||||
double const beat = bbt_to_beats_locked (copy, bbt);
|
||||
bool ret = solve_map (copy, new_section, bpm, pulse_at_beat_locked (copy, beat));
|
||||
|
||||
Metrics::const_iterator d = copy.begin();
|
||||
while (d != copy.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::change_initial_tempo (double beats_per_minute, double note_type)
|
||||
{
|
||||
|
|
@ -1473,14 +1259,13 @@ TempoMap::recompute_meters (Metrics& metrics)
|
|||
if (meter->position_lock_style() == AudioTime) {
|
||||
double pulse = 0.0;
|
||||
pair<double, BBT_Time> b_bbt;
|
||||
if (prev_m) {
|
||||
double beats = ((pulse_at_frame_locked (metrics, meter->frame()) - prev_m->pulse()) * prev_m->note_divisor()) - prev_m->beat();
|
||||
if (meter->movable()) {
|
||||
const double beats = ((pulse_at_frame_locked (metrics, meter->frame()) - prev_m->pulse()) * prev_m->note_divisor()) - prev_m->beat();
|
||||
b_bbt = make_pair (ceil (beats), BBT_Time (accumulated_bars + 1, 1, 0));
|
||||
const double true_pulse = prev_m->pulse() + (ceil (beats) - prev_m->beat()) / prev_m->note_divisor();
|
||||
const double pulse_off = true_pulse - ((beats - prev_m->beat()) / prev_m->note_divisor());
|
||||
pulse = true_pulse - pulse_off;
|
||||
}
|
||||
if (!meter->movable()) {
|
||||
} else {
|
||||
b_bbt = make_pair (0.0, BBT_Time (1, 1, 0));
|
||||
}
|
||||
meter->set_beat (b_bbt);
|
||||
|
|
@ -1918,54 +1703,6 @@ TempoMap::frame_at_pulse_locked (const Metrics& metrics, const double& pulse) co
|
|||
return ret;
|
||||
}
|
||||
|
||||
double
|
||||
TempoMap::beat_offset_at (const Metrics& metrics, const double& beat) const
|
||||
{
|
||||
MeterSection* prev_m = 0;
|
||||
double beat_off = first_meter().pulse();
|
||||
|
||||
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
|
||||
MeterSection* m = 0;
|
||||
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
|
||||
if (prev_m) {
|
||||
if (m->beat() > beat) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (m->position_lock_style() == AudioTime) {
|
||||
beat_off += ((m->beat() - prev_m->beat()) / prev_m->note_divisor()) - floor (m->pulse() - prev_m->pulse());
|
||||
}
|
||||
}
|
||||
prev_m = m;
|
||||
}
|
||||
}
|
||||
|
||||
return beat_off;
|
||||
}
|
||||
|
||||
frameoffset_t
|
||||
TempoMap::frame_offset_at (const Metrics& metrics, const framepos_t& frame) const
|
||||
{
|
||||
frameoffset_t frame_off = 0;
|
||||
MeterSection* prev_m = 0;
|
||||
|
||||
for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
|
||||
MeterSection* m = 0;
|
||||
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
|
||||
if (m->frame() > frame) {
|
||||
break;
|
||||
}
|
||||
if (prev_m && m->position_lock_style() == AudioTime) {
|
||||
const double pulse = prev_m->pulse() + ((m->beat() - prev_m->beat()) / prev_m->note_divisor());
|
||||
frame_off += frame_at_pulse_locked (metrics, pulse) - m->frame();
|
||||
}
|
||||
prev_m = m;
|
||||
}
|
||||
}
|
||||
|
||||
return frame_off;
|
||||
}
|
||||
|
||||
framepos_t
|
||||
TempoMap::frame_time (const BBT_Time& bbt)
|
||||
{
|
||||
|
|
@ -2276,7 +2013,7 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt,
|
|||
/*
|
||||
here we set the beat for this frame.
|
||||
we're going to set it 'incorrectly' to the next integer and use this difference
|
||||
to find the meter's pulse later.
|
||||
to find the meter's pulse.
|
||||
(meters should fall on integral beats to keep us sane)
|
||||
*/
|
||||
double pulse = 0.0;
|
||||
|
|
@ -2301,11 +2038,19 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt,
|
|||
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);
|
||||
double pulse = 0.0;
|
||||
pair<double, BBT_Time> b_bbt;
|
||||
if (m->movable()) {
|
||||
const double beats = ((pulse_at_frame_locked (imaginary, m->frame()) - prev_ms->pulse()) * prev_ms->note_divisor()) - prev_ms->beat();
|
||||
const double true_pulse = prev_ms->pulse() + (m->beat() - prev_ms->beat()) / prev_ms->note_divisor();
|
||||
const double pulse_off = true_pulse - ((beats - prev_ms->beat()) / prev_ms->note_divisor());
|
||||
b_bbt = make_pair (ceil (beats), BBT_Time (accumulated_bars + 1, 1, 0));
|
||||
pulse = true_pulse - pulse_off;
|
||||
} else {
|
||||
b_bbt = make_pair (0.0, BBT_Time (1, 1, 0));
|
||||
pulse = 0.0;
|
||||
}
|
||||
const double pulse = prev_ms->pulse() + (m->beat() - prev_ms->beat()) / prev_ms->note_divisor();
|
||||
m->set_beat (b_bbt);
|
||||
m->set_pulse (pulse);
|
||||
}
|
||||
}
|
||||
|
|
@ -2376,6 +2121,225 @@ TempoMap::solve_map (Metrics& imaginary, MeterSection* section, const Meter& mt,
|
|||
}
|
||||
}
|
||||
|
||||
/** places a copy of _metrics into copy and returns a pointer
|
||||
* to section's equivalent.
|
||||
*/
|
||||
TempoSection*
|
||||
TempoMap::copy_metrics_and_point (Metrics& copy, TempoSection* section)
|
||||
{
|
||||
TempoSection* t;
|
||||
TempoSection* ret = 0;
|
||||
MeterSection* m;
|
||||
|
||||
for (Metrics::iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
|
||||
if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
|
||||
if (t == section) {
|
||||
if (t->position_lock_style() == MusicTime) {
|
||||
ret = new TempoSection (t->pulse(), t->beats_per_minute(), t->note_type(), t->type());
|
||||
} else {
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
TempoSection* cp = 0;
|
||||
if (t->position_lock_style() == MusicTime) {
|
||||
cp = new TempoSection (t->pulse(), t->beats_per_minute(), t->note_type(), t->type());
|
||||
} else {
|
||||
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) {
|
||||
MeterSection* cp = 0;
|
||||
if (m->position_lock_style() == MusicTime) {
|
||||
cp = new MeterSection (m->pulse(), m->beat(), m->bbt(), m->divisions_per_bar(), m->note_divisor());
|
||||
cp->set_frame (m->frame());
|
||||
} else {
|
||||
cp = new MeterSection (m->frame(), m->beat(), m->bbt(), m->divisions_per_bar(), m->note_divisor());
|
||||
cp->set_pulse (m->pulse());
|
||||
}
|
||||
cp->set_movable (m->movable());
|
||||
copy.push_back (cp);
|
||||
}
|
||||
}
|
||||
//recompute_map (copy);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
TempoMap::can_solve_bbt (TempoSection* ts, const Tempo& bpm, const BBT_Time& bbt)
|
||||
{
|
||||
Metrics copy;
|
||||
TempoSection* new_section = 0;
|
||||
|
||||
{
|
||||
Glib::Threads::RWLock::ReaderLock lm (lock);
|
||||
new_section = copy_metrics_and_point (copy, ts);
|
||||
}
|
||||
|
||||
double const beat = bbt_to_beats_locked (copy, bbt);
|
||||
bool ret = solve_map (copy, new_section, bpm, pulse_at_beat_locked (copy, beat));
|
||||
|
||||
Metrics::const_iterator d = copy.begin();
|
||||
while (d != copy.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is for a gui that needs to know the frame of a tempo section if it were to be moved to some bbt time,
|
||||
* taking any possible reordering as a consequence of this into account.
|
||||
* @param section - the section to be altered
|
||||
* @param bpm - the new Tempo
|
||||
* @param bbt - the bbt where the altered tempo will fall
|
||||
* @return returns - the position in frames where the new tempo section will lie.
|
||||
*/
|
||||
framepos_t
|
||||
TempoMap::predict_tempo_frame (TempoSection* section, const Tempo& bpm, const BBT_Time& bbt)
|
||||
{
|
||||
Glib::Threads::RWLock::ReaderLock lm (lock);
|
||||
Metrics future_map;
|
||||
framepos_t ret = 0;
|
||||
TempoSection* new_section = copy_metrics_and_point (future_map, section);
|
||||
|
||||
double const beat = bbt_to_beats_locked (future_map, bbt);
|
||||
if (solve_map (future_map, new_section, bpm, pulse_at_beat_locked (future_map, beat))) {
|
||||
ret = new_section->frame();
|
||||
} else {
|
||||
ret = frame_at_beat_locked (_metrics, beat);
|
||||
}
|
||||
|
||||
Metrics::const_iterator d = future_map.begin();
|
||||
while (d != future_map.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
double
|
||||
TempoMap::predict_tempo_pulse (TempoSection* section, const Tempo& bpm, const framepos_t& frame)
|
||||
{
|
||||
Glib::Threads::RWLock::ReaderLock lm (lock);
|
||||
Metrics future_map;
|
||||
double ret = 0.0;
|
||||
TempoSection* new_section = copy_metrics_and_point (future_map, section);
|
||||
|
||||
if (solve_map (future_map, new_section, bpm, frame)) {
|
||||
ret = new_section->pulse();
|
||||
} else {
|
||||
ret = pulse_at_frame_locked (_metrics, frame);
|
||||
}
|
||||
|
||||
Metrics::const_iterator d = future_map.begin();
|
||||
while (d != future_map.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::gui_move_tempo_frame (TempoSection* ts, const Tempo& bpm, const framepos_t& frame)
|
||||
{
|
||||
Metrics future_map;
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (lock);
|
||||
TempoSection* new_section = copy_metrics_and_point (future_map, ts);
|
||||
if (solve_map (future_map, new_section, bpm, frame)) {
|
||||
solve_map (_metrics, ts, bpm, frame);
|
||||
}
|
||||
}
|
||||
|
||||
Metrics::const_iterator d = future_map.begin();
|
||||
while (d != future_map.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
|
||||
MetricPositionChanged (); // Emit Signal
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::gui_move_tempo_beat (TempoSection* ts, const Tempo& bpm, const double& beat)
|
||||
{
|
||||
Metrics future_map;
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (lock);
|
||||
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))) {
|
||||
solve_map (_metrics, ts, bpm, pulse_at_beat_locked (_metrics, beat));
|
||||
}
|
||||
}
|
||||
|
||||
Metrics::const_iterator d = future_map.begin();
|
||||
while (d != future_map.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
|
||||
MetricPositionChanged (); // Emit Signal
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const framepos_t& frame)
|
||||
{
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (lock);
|
||||
solve_map (_metrics, ms, mt, frame);
|
||||
}
|
||||
|
||||
MetricPositionChanged (); // Emit Signal
|
||||
}
|
||||
|
||||
void
|
||||
TempoMap::gui_move_meter (MeterSection* ms, const Meter& mt, const double& beat)
|
||||
{
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (lock);
|
||||
solve_map (_metrics, ms, mt, pulse_at_beat_locked (_metrics, beat));
|
||||
}
|
||||
|
||||
MetricPositionChanged (); // Emit Signal
|
||||
}
|
||||
|
||||
bool
|
||||
TempoMap::gui_change_tempo (TempoSection* ts, const Tempo& bpm)
|
||||
{
|
||||
Metrics future_map;
|
||||
bool can_solve = false;
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (lock);
|
||||
TempoSection* new_section = copy_metrics_and_point (future_map, ts);
|
||||
new_section->set_beats_per_minute (bpm.beats_per_minute());
|
||||
recompute_tempos (future_map);
|
||||
|
||||
if (check_solved (future_map, true)) {
|
||||
ts->set_beats_per_minute (bpm.beats_per_minute());
|
||||
recompute_map (_metrics);
|
||||
can_solve = true;
|
||||
}
|
||||
}
|
||||
|
||||
Metrics::const_iterator d = future_map.begin();
|
||||
while (d != future_map.end()) {
|
||||
delete (*d);
|
||||
++d;
|
||||
}
|
||||
if (can_solve) {
|
||||
MetricPositionChanged (); // Emit Signal
|
||||
}
|
||||
return can_solve;
|
||||
}
|
||||
|
||||
framecnt_t
|
||||
TempoMap::bbt_duration_at (framepos_t pos, const BBT_Time& bbt, int dir)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue