Tempo ramps - respect tempo note type and meter note divisor correctly.
- tempo and meter position is now pulse-based, although meter still has a beat for convenience.
This commit is contained in:
@@ -1281,7 +1281,7 @@ AudioClock::set_bbt (framepos_t when, bool /*force*/)
|
||||
|
||||
TempoMetric m (_session->tempo_map().metric_at (pos));
|
||||
|
||||
sprintf (buf, "%-5.1f", _session->tempo_map().tempo_at (pos));
|
||||
sprintf (buf, "%-5.1f", _session->tempo_map().tempo_at (pos).beats_per_minute());
|
||||
_left_layout->set_markup (string_compose ("<span size=\"%1\">" TXTSPAN "%3</span> <span foreground=\"green\">%2</span></span>",
|
||||
INFO_FONT_SIZE, buf, _("Tempo")));
|
||||
|
||||
|
||||
@@ -3143,7 +3143,7 @@ void
|
||||
MeterMarkerDrag::motion (GdkEvent* event, bool first_move)
|
||||
{
|
||||
if (!_marker->meter().movable()) {
|
||||
return;
|
||||
//return;
|
||||
}
|
||||
|
||||
if (first_move) {
|
||||
@@ -3209,10 +3209,10 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||
|
||||
//motion (event, false);
|
||||
|
||||
Timecode::BBT_Time when;
|
||||
//Timecode::BBT_Time when;
|
||||
|
||||
TempoMap& map (_editor->session()->tempo_map());
|
||||
map.bbt_time (_marker->position(), when);
|
||||
//map.bbt_time (_marker->position(), when);
|
||||
|
||||
if (_copy == true) {
|
||||
_editor->begin_reversible_command (_("copy meter mark"));
|
||||
@@ -3221,7 +3221,7 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||
if (_marker->meter().position_lock_style() == AudioTime) {
|
||||
map.add_meter (_marker->meter(), _marker->position());
|
||||
} else {
|
||||
map.add_meter (_marker->meter(), map.bbt_to_beats (when), when);
|
||||
map.add_meter (_marker->meter(), _real_section->pulse(), _real_section->bbt());
|
||||
}
|
||||
|
||||
XMLNode &after = map.get_state();
|
||||
@@ -3233,7 +3233,7 @@ MeterMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||
if (_marker->meter().position_lock_style() == AudioTime) {
|
||||
map.replace_meter (*_real_section, _marker->meter(), _marker->position());
|
||||
} else {
|
||||
map.replace_meter (*_real_section, _marker->meter(), when);
|
||||
map.replace_meter (*_real_section, _marker->meter(), _real_section->bbt());
|
||||
}
|
||||
|
||||
XMLNode &after = map.get_state();
|
||||
@@ -3366,7 +3366,8 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||
XMLNode &before = map.get_state();
|
||||
|
||||
if (_marker->tempo().position_lock_style() == MusicTime) {
|
||||
map.add_tempo (_marker->tempo(), _real_section->beat(), _marker->tempo().type());
|
||||
double const beat = map.predict_tempo_beat (_real_section, _marker->tempo(), _real_section->frame());
|
||||
map.add_tempo (_marker->tempo(), beat, _marker->tempo().type());
|
||||
} else {
|
||||
map.add_tempo (_marker->tempo(), _real_section->frame(), _marker->tempo().type());
|
||||
}
|
||||
@@ -3378,9 +3379,12 @@ TempoMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||
} else {
|
||||
/* we removed it before, so add it back now */
|
||||
if (_marker->tempo().position_lock_style() == MusicTime) {
|
||||
map.replace_tempo (*_real_section, _marker->tempo().beats_per_minute() , _real_section->beat(), _marker->tempo().type());
|
||||
double const beat = map.predict_tempo_beat (_real_section, _marker->tempo(), _real_section->frame());
|
||||
map.replace_tempo (*_real_section, Tempo (_marker->tempo().beats_per_minute(), _marker->tempo().note_type())
|
||||
, beat, _marker->tempo().type());
|
||||
} else {
|
||||
map.replace_tempo (*_real_section, _marker->tempo().beats_per_minute() , _real_section->frame(), _marker->tempo().type());
|
||||
map.replace_tempo (*_real_section, Tempo (_marker->tempo().beats_per_minute(), _marker->tempo().note_type())
|
||||
, _real_section->frame(), _marker->tempo().type());
|
||||
}
|
||||
|
||||
XMLNode &after = map.get_state();
|
||||
@@ -3401,7 +3405,7 @@ TempoMarkerDrag::aborted (bool moved)
|
||||
TempoMap& map (_editor->session()->tempo_map());
|
||||
/* we removed it before, so add it back now */
|
||||
if (_marker->tempo().position_lock_style() == MusicTime) {
|
||||
map.add_tempo (_marker->tempo(), _marker->tempo().beat(), _marker->tempo().type());
|
||||
map.add_tempo (_marker->tempo(), _marker->tempo().pulse(), _marker->tempo().type());
|
||||
} else {
|
||||
map.add_tempo (_marker->tempo(), _marker->tempo().frame(), _marker->tempo().type());
|
||||
}
|
||||
|
||||
@@ -1109,15 +1109,11 @@ Editor::compute_bbt_ruler_scale (std::vector<ARDOUR::TempoMap::BBTPoint>& grid,
|
||||
i--;
|
||||
|
||||
/* XX ?? */
|
||||
/*
|
||||
if ((*i).beat >= (*grid.begin()).beat) {
|
||||
bbt_bars = (*i).bar - (*grid.begin()).bar;
|
||||
} else {
|
||||
bbt_bars = (*i).bar - (*grid.begin()).bar;
|
||||
}
|
||||
*/
|
||||
/*XXX totally wrong */
|
||||
bbt_bars = (floor (_session->tempo_map().beat_at_frame (upper)) - floor (_session->tempo_map().beat_at_frame (lower))) / 4;
|
||||
|
||||
beats = distance (grid.begin(), grid.end()) - bbt_bars;
|
||||
|
||||
|
||||
@@ -2512,8 +2512,6 @@ MidiRegionView::move_selection(double dx, double dy, double cumulative_dy)
|
||||
to_play.push_back ((*i)->note());
|
||||
}
|
||||
(*i)->move_event(dx, dy);
|
||||
Note* canvas_note = dynamic_cast<Note*>(*i);
|
||||
canvas_note->set_x1 (snap_to_pixel (canvas_note->x1(), false));
|
||||
}
|
||||
|
||||
if (dy && !_selection.empty() && !_no_sound_notes && UIConfiguration::instance().get_sound_midi_notes()) {
|
||||
|
||||
@@ -64,7 +64,7 @@ TempoDialog::TempoDialog (TempoMap& map, TempoSection& section, const string&)
|
||||
, tap_tempo_button (_("Tap tempo"))
|
||||
{
|
||||
Timecode::BBT_Time when;
|
||||
map.bbt_time (map.frame_at_beat (section.beat()), when);
|
||||
map.bbt_time (section.frame(), when);
|
||||
init (when, section.beats_per_minute(), section.note_type(), section.type(), section.movable(), section.position_lock_style());
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ MeterDialog::MeterDialog (TempoMap& map, MeterSection& section, const string&)
|
||||
: ArdourDialog (_("Edit Meter"))
|
||||
{
|
||||
Timecode::BBT_Time when;
|
||||
map.bbt_time (map.frame_at_beat (section.beat()), when);
|
||||
map.bbt_time (section.frame(), when);
|
||||
init (when, section.divisions_per_bar(), section.note_divisor(), section.movable(), section.position_lock_style());
|
||||
}
|
||||
|
||||
|
||||
@@ -56,15 +56,17 @@ class LIBARDOUR_API Tempo {
|
||||
: _beats_per_minute (bpm), _note_type(type) {}
|
||||
|
||||
double beats_per_minute () const { return _beats_per_minute; }
|
||||
|
||||
double ticks_per_minute () const { return _beats_per_minute * Timecode::BBT_Time::ticks_per_beat;}
|
||||
double note_type () const { return _note_type;}
|
||||
double note_type () const { return _note_type; }
|
||||
double pulses_per_minute () const { return _beats_per_minute / _note_type; }
|
||||
/** audio samples per beat
|
||||
* @param sr samplerate
|
||||
*/
|
||||
double frames_per_beat (framecnt_t sr) const {
|
||||
return (60.0 * sr) / _beats_per_minute;
|
||||
}
|
||||
double frames_per_pulse (framecnt_t sr) const {
|
||||
return (_note_type * 60.0 * sr) / _beats_per_minute;
|
||||
}
|
||||
|
||||
protected:
|
||||
double _beats_per_minute;
|
||||
@@ -99,16 +101,16 @@ class LIBARDOUR_API Meter {
|
||||
/** A section of timeline with a certain Tempo or Meter. */
|
||||
class LIBARDOUR_API MetricSection {
|
||||
public:
|
||||
MetricSection (double beat)
|
||||
: _beat (beat), _frame (0), _movable (true), _position_lock_style (PositionLockStyle::MusicTime) {}
|
||||
MetricSection (double pulse)
|
||||
: _pulse (pulse), _frame (0), _movable (true), _position_lock_style (PositionLockStyle::MusicTime) {}
|
||||
MetricSection (framepos_t frame)
|
||||
: _beat (0.0), _frame (frame), _movable (true), _position_lock_style (PositionLockStyle::AudioTime) {}
|
||||
: _pulse (0.0), _frame (frame), _movable (true), _position_lock_style (PositionLockStyle::AudioTime) {}
|
||||
|
||||
virtual ~MetricSection() {}
|
||||
|
||||
const double& beat () const { return _beat; }
|
||||
const double tick () const { return _beat * Timecode::BBT_Time::ticks_per_beat; }
|
||||
void set_beat (double beat) { _beat = beat;}
|
||||
const double& pulse () const { return _pulse; }
|
||||
//const double tick () const { return _beat * Timecode::BBT_Time::ticks_per_beat; }
|
||||
void set_pulse (double pulse) { _pulse = pulse; }
|
||||
|
||||
framepos_t frame() const { return _frame; }
|
||||
virtual void set_frame (framepos_t f) {
|
||||
@@ -128,7 +130,7 @@ class LIBARDOUR_API MetricSection {
|
||||
void set_position_lock_style (PositionLockStyle ps) { _position_lock_style = ps; }
|
||||
|
||||
private:
|
||||
double _beat;
|
||||
double _pulse;
|
||||
framepos_t _frame;
|
||||
bool _movable;
|
||||
PositionLockStyle _position_lock_style;
|
||||
@@ -147,14 +149,18 @@ class LIBARDOUR_API MeterSection : public MetricSection, public Meter {
|
||||
|
||||
XMLNode& get_state() const;
|
||||
|
||||
void set_beat (std::pair<double, Timecode::BBT_Time>& w) {
|
||||
MetricSection::set_beat (w.first);
|
||||
void set_pulse (std::pair<double, Timecode::BBT_Time>& w) {
|
||||
MetricSection::set_pulse (w.first);
|
||||
_bbt = w.second;
|
||||
}
|
||||
|
||||
const Timecode::BBT_Time& bbt() const { return _bbt; }
|
||||
double beat () { return _beat; }
|
||||
void set_beat (double beat) { _beat = beat; }
|
||||
|
||||
private:
|
||||
Timecode::BBT_Time _bbt;
|
||||
double _beat;
|
||||
};
|
||||
|
||||
/** A section of timeline with a certain Tempo. */
|
||||
@@ -185,16 +191,13 @@ class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
|
||||
double tempo_at_frame (framepos_t frame, framecnt_t frame_rate) const;
|
||||
framepos_t frame_at_tempo (double tempo, double beat, framecnt_t frame_rate) const;
|
||||
|
||||
double tempo_at_beat (double beat) const;
|
||||
double beat_at_tempo (double tempo, framepos_t frame, framecnt_t frame_rate) const;
|
||||
double tempo_at_pulse (double beat) const;
|
||||
double pulse_at_tempo (double tempo, framepos_t frame, framecnt_t frame_rate) const;
|
||||
|
||||
double beat_at_frame (framepos_t frame, framecnt_t frame_rate) const;
|
||||
framepos_t frame_at_beat (double beat, framecnt_t frame_rate) const;
|
||||
double pulse_at_frame (framepos_t frame, framecnt_t frame_rate) const;
|
||||
framepos_t frame_at_pulse (double pulse, framecnt_t frame_rate) const;
|
||||
|
||||
double tick_at_frame (framepos_t frame, framecnt_t frame_rate) const;
|
||||
framepos_t frame_at_tick (double tick, framecnt_t frame_rate) const;
|
||||
|
||||
double compute_c_func_beat (double end_bpm, double end_beat, framecnt_t frame_rate);
|
||||
double compute_c_func_pulse (double end_bpm, double end_pulse, framecnt_t frame_rate);
|
||||
double compute_c_func_frame (double end_bpm, framepos_t end_frame, framecnt_t frame_rate) const;
|
||||
|
||||
double get_c_func () const { return _c_func; }
|
||||
@@ -214,17 +217,14 @@ class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
|
||||
double a_func (double end_tpm, double c_func) const;
|
||||
double c_func (double end_tpm, double end_time) const;
|
||||
|
||||
double tick_tempo_at_time (double time) const;
|
||||
double time_at_tick_tempo (double tick_tempo) const;
|
||||
double pulse_tempo_at_time (double time) const;
|
||||
double time_at_pulse_tempo (double pulse_tempo) const;
|
||||
|
||||
double tick_tempo_at_tick (double tick) const;
|
||||
double tick_at_tick_tempo (double tick_tempo) const;
|
||||
double pulse_tempo_at_pulse (double pulse) const;
|
||||
double pulse_at_pulse_tempo (double pulse_tempo) const;
|
||||
|
||||
double tick_at_time (double time) const;
|
||||
double time_at_tick (double tick) const;
|
||||
|
||||
double beat_at_time (double time) const;
|
||||
double time_at_beat (double beat) const;
|
||||
double pulse_at_time (double time) const;
|
||||
double time_at_pulse (double pulse) const;
|
||||
|
||||
/* this value provides a fractional offset into the bar in which
|
||||
the tempo section is located in. A value of 0.0 indicates that
|
||||
@@ -253,7 +253,7 @@ class LIBARDOUR_API TempoMetric {
|
||||
void set_tempo (const Tempo& t) { _tempo = &t; }
|
||||
void set_meter (const Meter& m) { _meter = &m; }
|
||||
void set_frame (framepos_t f) { _frame = f; }
|
||||
void set_beat (const double& t) { _beat = t; }
|
||||
void set_pulse (const double& p) { _pulse = p; }
|
||||
|
||||
void set_metric (const MetricSection* section) {
|
||||
const MeterSection* meter;
|
||||
@@ -264,20 +264,20 @@ class LIBARDOUR_API TempoMetric {
|
||||
set_tempo(*tempo);
|
||||
}
|
||||
|
||||
set_frame(section->frame());
|
||||
set_beat(section->beat());
|
||||
set_frame (section->frame());
|
||||
set_pulse (section->pulse());
|
||||
}
|
||||
|
||||
const Meter& meter() const { return *_meter; }
|
||||
const Tempo& tempo() const { return *_tempo; }
|
||||
framepos_t frame() const { return _frame; }
|
||||
const double& beat() const { return _beat; }
|
||||
const double& pulse() const { return _pulse; }
|
||||
|
||||
private:
|
||||
const Meter* _meter;
|
||||
const Tempo* _tempo;
|
||||
framepos_t _frame;
|
||||
double _beat;
|
||||
double _pulse;
|
||||
};
|
||||
|
||||
/** Tempo Map - mapping of timecode to musical time.
|
||||
@@ -299,13 +299,13 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
|
||||
struct BBTPoint {
|
||||
framepos_t frame;
|
||||
const MeterSection* meter;
|
||||
const Tempo* tempo;
|
||||
const Tempo tempo;
|
||||
uint32_t bar;
|
||||
uint32_t beat;
|
||||
|
||||
BBTPoint (const MeterSection& m, const Tempo& t, framepos_t f,
|
||||
uint32_t b, uint32_t e)
|
||||
: frame (f), meter (&m), tempo (&t), bar (b), beat (e) {}
|
||||
: frame (f), meter (&m), tempo (t.beats_per_minute(), t.note_type()), bar (b), beat (e) {}
|
||||
|
||||
Timecode::BBT_Time bbt() const { return Timecode::BBT_Time (bar, beat, 0); }
|
||||
operator Timecode::BBT_Time() const { return bbt(); }
|
||||
@@ -363,10 +363,8 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
|
||||
|
||||
const Meter& meter_at (framepos_t) const;
|
||||
|
||||
const TempoSection& tempo_section_at (framepos_t) const;
|
||||
const MeterSection& meter_section_at (framepos_t) const;
|
||||
const MeterSection& meter_section_at (double) const;
|
||||
|
||||
const TempoSection& tempo_section_at (framepos_t frame) const;
|
||||
const MeterSection& meter_section_at (framepos_t frame) const;
|
||||
|
||||
void add_tempo (const Tempo&, double where, TempoSection::Type type);
|
||||
void add_tempo (const Tempo&, framepos_t frame, TempoSection::Type type);
|
||||
@@ -378,6 +376,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
|
||||
void remove_meter (const MeterSection&, bool send_signal);
|
||||
|
||||
framepos_t predict_tempo_frame (TempoSection* section, const Tempo& bpm, const Timecode::BBT_Time& bbt);
|
||||
double predict_tempo_beat (TempoSection* section, const Tempo& bpm, const framepos_t& beat);
|
||||
|
||||
void replace_tempo (const TempoSection&, const Tempo&, const double& where, TempoSection::Type type);
|
||||
void replace_tempo (const TempoSection&, const Tempo&, const framepos_t& frame, TempoSection::Type type);
|
||||
@@ -426,21 +425,27 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
|
||||
|
||||
double bbt_to_beats (Timecode::BBT_Time bbt);
|
||||
Timecode::BBT_Time beats_to_bbt (double beats);
|
||||
Timecode::BBT_Time pulse_to_bbt (double pulse);
|
||||
|
||||
PBD::Signal0<void> MetricPositionChanged;
|
||||
|
||||
private:
|
||||
double bbt_to_beats_locked (const Metrics& metrics, Timecode::BBT_Time bbt);
|
||||
Timecode::BBT_Time beats_to_bbt_locked (Metrics& metrics, double beats);
|
||||
double beat_at_frame_locked (const Metrics& metrics, framecnt_t frame) const;
|
||||
framecnt_t frame_at_beat_locked (const Metrics& metrics, double beat) const;
|
||||
double tick_at_frame_locked (const Metrics& metrics, framecnt_t frame) const;
|
||||
double pulse_at_beat (const Metrics& metrics, const double& beat) const;
|
||||
double beat_at_pulse (const Metrics& metrics, const double& pulse) 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 ;
|
||||
Timecode::BBT_Time beats_to_bbt_locked (const Metrics& metrics, const double& beats) const;
|
||||
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, double beat) const;
|
||||
frameoffset_t frame_offset_at (const Metrics& metrics, framepos_t frame) 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;
|
||||
|
||||
framecnt_t frame_at_tick_locked (const Metrics& metrics, double tick) const;
|
||||
framepos_t frame_time_locked (const Metrics& metrics, const Timecode::BBT_Time&);
|
||||
framepos_t frame_time_locked (const Metrics& metrics, const Timecode::BBT_Time&) const;
|
||||
|
||||
const MeterSection& meter_section_at_locked (framepos_t frame) const;
|
||||
const TempoSection& tempo_section_at_locked (framepos_t frame) const;
|
||||
|
||||
bool check_solved (Metrics& metrics, bool by_frame);
|
||||
bool solve_map (Metrics& metrics, TempoSection* section, const Tempo& bpm, const framepos_t& frame);
|
||||
|
||||
@@ -2342,7 +2342,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
|
||||
++m;
|
||||
} else {
|
||||
tmetric.set_metric(metric);
|
||||
bbt = tmap.beats_to_bbt (metric->beat());
|
||||
bbt = tmap.pulse_to_bbt (metric->pulse());
|
||||
write_position(&_impl->forge, _ev_buffers[port_index],
|
||||
tmetric, bbt, _session.transport_speed(),
|
||||
metric->frame(),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user