{
{
Glib::Threads::RWLock::WriterLock lm (lock);
- MeterSection& first (first_meter());
if (ms.movable()) {
remove_meter_locked (ms);
add_meter_locked (meter, bbt_to_beats_locked (_metrics, where), where, true);
} else {
+ MeterSection& first (first_meter());
const PositionLockStyle pl = ms.position_lock_style();
/* cannot move the first meter section */
*static_cast<Meter*>(&first) = meter;
const double beat = ms.beat();
const BBT_Time bbt = ms.bbt();
+
if (ms.movable()) {
remove_meter_locked (ms);
add_meter_locked (meter, frame, beat, bbt, true);
recompute_meters (metrics);
}
-double
-TempoMap::pulse_at_beat (const double& beat) const
+TempoMetric
+TempoMap::metric_at (framepos_t frame, Metrics::const_iterator* last) const
{
Glib::Threads::RWLock::ReaderLock lm (lock);
- return pulse_at_beat_locked (_metrics, beat);
+ TempoMetric m (first_meter(), first_tempo());
+
+ /* at this point, we are *guaranteed* to have m.meter and m.tempo pointing
+ at something, because we insert the default tempo and meter during
+ TempoMap construction.
+
+ now see if we can find better candidates.
+ */
+
+ for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
+
+ if ((*i)->frame() > frame) {
+ break;
+ }
+
+ m.set_metric(*i);
+
+ if (last) {
+ *last = i;
+ }
+ }
+
+ return m;
+}
+
+/* XX meters only */
+TempoMetric
+TempoMap::metric_at (BBT_Time bbt) const
+{
+ Glib::Threads::RWLock::ReaderLock lm (lock);
+ TempoMetric m (first_meter(), first_tempo());
+
+ /* at this point, we are *guaranteed* to have m.meter and m.tempo pointing
+ at something, because we insert the default tempo and meter during
+ TempoMap construction.
+
+ now see if we can find better candidates.
+ */
+
+ for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
+ MeterSection* mw;
+ if ((mw = dynamic_cast<MeterSection*> (*i)) != 0) {
+ BBT_Time section_start (mw->bbt());
+
+ if (section_start.bars > bbt.bars || (section_start.bars == bbt.bars && section_start.beats > bbt.beats)) {
+ break;
+ }
+
+ m.set_metric (*i);
+ }
+ }
+
+ return m;
+}
+
+double
+TempoMap::pulse_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const
+{
+ /* HOLD (at least) THE READER LOCK */
+ TempoSection* prev_ts = 0;
+ double accumulated_pulses = 0.0;
+
+ for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+ TempoSection* t;
+ if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+ if (!t->active()) {
+ continue;
+ }
+ if (prev_ts && t->frame() > frame) {
+ /*the previous ts is the one containing the frame */
+ const double ret = prev_ts->pulse_at_frame (frame, _frame_rate);
+ return ret;
+ }
+ accumulated_pulses = t->pulse();
+ prev_ts = t;
+ }
+ }
+
+ /* treated as constant for this ts */
+ const double pulses_in_section = (frame - prev_ts->frame()) / prev_ts->frames_per_pulse (_frame_rate);
+
+ return pulses_in_section + accumulated_pulses;
}
double
}
double
-TempoMap::beat_at_pulse (const double& pulse) const
+TempoMap::pulse_at_beat (const double& beat) const
{
Glib::Threads::RWLock::ReaderLock lm (lock);
- return beat_at_pulse_locked (_metrics, pulse);
+ return pulse_at_beat_locked (_metrics, beat);
}
double
return beats_in_section + accumulated_beats;
}
-TempoMetric
-TempoMap::metric_at (framepos_t frame, Metrics::const_iterator* last) const
+double
+TempoMap::beat_at_pulse (const double& pulse) const
{
Glib::Threads::RWLock::ReaderLock lm (lock);
- TempoMetric m (first_meter(), first_tempo());
-
- /* at this point, we are *guaranteed* to have m.meter and m.tempo pointing
- at something, because we insert the default tempo and meter during
- TempoMap construction.
-
- now see if we can find better candidates.
- */
-
- for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
-
- if ((*i)->frame() > frame) {
- break;
- }
-
- m.set_metric(*i);
-
- if (last) {
- *last = i;
- }
- }
-
- return m;
+ return beat_at_pulse_locked (_metrics, pulse);
}
-/* XX meters only */
-TempoMetric
-TempoMap::metric_at (BBT_Time bbt) const
+framecnt_t
+TempoMap::frame_at_pulse_locked (const Metrics& metrics, const double& pulse) const
{
- Glib::Threads::RWLock::ReaderLock lm (lock);
- TempoMetric m (first_meter(), first_tempo());
-
- /* at this point, we are *guaranteed* to have m.meter and m.tempo pointing
- at something, because we insert the default tempo and meter during
- TempoMap construction.
+ /* HOLD THE READER LOCK */
- now see if we can find better candidates.
- */
+ const TempoSection* prev_ts = 0;
+ double accumulated_pulses = 0.0;
- for (Metrics::const_iterator i = _metrics.begin(); i != _metrics.end(); ++i) {
- MeterSection* mw;
- if ((mw = dynamic_cast<MeterSection*> (*i)) != 0) {
- BBT_Time section_start (mw->bbt());
+ for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
+ TempoSection* t;
- if (section_start.bars > bbt.bars || (section_start.bars == bbt.bars && section_start.beats > bbt.beats)) {
- break;
+ if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
+ if (!t->active()) {
+ continue;
+ }
+ if (prev_ts && t->pulse() > pulse) {
+ return prev_ts->frame_at_pulse (pulse, _frame_rate);
}
- m.set_metric (*i);
+ accumulated_pulses = t->pulse();
+ prev_ts = t;
}
}
+ /* must be treated as constant, irrespective of _type */
+ double const pulses_in_section = pulse - accumulated_pulses;
+ double const dtime = pulses_in_section * prev_ts->frames_per_pulse (_frame_rate);
- return m;
+ framecnt_t const ret = (framecnt_t) floor (dtime) + prev_ts->frame();
+
+ return ret;
}
-void
-TempoMap::bbt_time (framepos_t frame, BBT_Time& bbt)
+double
+TempoMap::beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const
{
+ const double pulse = pulse_at_frame_locked (metrics, frame);
+ return beat_at_pulse_locked (metrics, pulse);
+}
- if (frame < 0) {
- bbt.bars = 1;
- bbt.beats = 1;
- bbt.ticks = 0;
- warning << string_compose (_("tempo map asked for BBT time at frame %1\n"), frame) << endmsg;
- return;
- }
+double
+TempoMap::beat_at_frame (const framecnt_t& frame) const
+{
Glib::Threads::RWLock::ReaderLock lm (lock);
- double const beat = beat_at_frame_locked (_metrics, frame);
+ return beat_at_frame_locked (_metrics, frame);
+}
- bbt = beats_to_bbt_locked (_metrics, beat);
+framecnt_t
+TempoMap::frame_at_beat_locked (const Metrics& metrics, const double& beat) const
+{
+ const framecnt_t frame = frame_at_pulse_locked (metrics, pulse_at_beat_locked (metrics, beat));
+ return frame;
}
-double
-TempoMap::bbt_to_beats (const Timecode::BBT_Time& bbt)
+framecnt_t
+TempoMap::frame_at_beat (const double& beat) const
{
Glib::Threads::RWLock::ReaderLock lm (lock);
-
- return bbt_to_beats_locked (_metrics, bbt);
+ return frame_at_beat_locked (_metrics, beat);
}
double
double accumulated_beats = 0.0;
double accumulated_bars = 0.0;
MeterSection* prev_ms = 0;
+
/* because audio-locked meters have 'fake' integral beats,
there is no pulse offset here.
*/
}
}
- double const remaining_bars = (bbt.bars - 1) - accumulated_bars;
- double const remaining_bars_in_beats = remaining_bars * prev_ms->divisions_per_bar();
- double const ret = remaining_bars_in_beats + accumulated_beats + (bbt.beats - 1) + (bbt.ticks / BBT_Time::ticks_per_beat);
+ const double remaining_bars = (bbt.bars - 1) - accumulated_bars;
+ const double remaining_bars_in_beats = remaining_bars * prev_ms->divisions_per_bar();
+ const double ret = remaining_bars_in_beats + accumulated_beats + (bbt.beats - 1) + (bbt.ticks / BBT_Time::ticks_per_beat);
return ret;
}
-Timecode::BBT_Time
-TempoMap::beats_to_bbt (const double& beats)
+double
+TempoMap::bbt_to_beats (const Timecode::BBT_Time& bbt)
{
Glib::Threads::RWLock::ReaderLock lm (lock);
-
- return beats_to_bbt_locked (_metrics, beats);
+ return bbt_to_beats_locked (_metrics, bbt);
}
Timecode::BBT_Time
MeterSection* m = 0;
if ((m = dynamic_cast<MeterSection*> (*i)) != 0) {
-
if (prev_ms) {
if (m->beat() > beats) {
/* this is the meter after the one our beat is on*/
}
}
- double const beats_in_ms = beats - accumulated_beats;
- uint32_t const bars_in_ms = (uint32_t) floor (beats_in_ms / prev_ms->divisions_per_bar());
- uint32_t const total_bars = bars_in_ms + accumulated_bars;
- double const remaining_beats = beats_in_ms - (bars_in_ms * prev_ms->divisions_per_bar());
- double const remaining_ticks = (remaining_beats - floor (remaining_beats)) * BBT_Time::ticks_per_beat;
+ const double beats_in_ms = beats - accumulated_beats;
+ const uint32_t bars_in_ms = (uint32_t) floor (beats_in_ms / prev_ms->divisions_per_bar());
+ const uint32_t total_bars = bars_in_ms + accumulated_bars;
+ const double remaining_beats = beats_in_ms - (bars_in_ms * prev_ms->divisions_per_bar());
+ const double remaining_ticks = (remaining_beats - floor (remaining_beats)) * BBT_Time::ticks_per_beat;
BBT_Time ret;
return ret;
}
+Timecode::BBT_Time
+TempoMap::beats_to_bbt (const double& beats)
+{
+ Glib::Threads::RWLock::ReaderLock lm (lock);
+ return beats_to_bbt_locked (_metrics, beats);
+}
+
Timecode::BBT_Time
TempoMap::pulse_to_bbt (const double& pulse)
{
prev_ms = m;
}
}
- double const beats_in_ms = (pulse - prev_ms->pulse()) * prev_ms->note_divisor();
- uint32_t const bars_in_ms = (uint32_t) floor (beats_in_ms / prev_ms->divisions_per_bar());
- uint32_t const total_bars = bars_in_ms + accumulated_bars;
- double const remaining_beats = beats_in_ms - (bars_in_ms * prev_ms->divisions_per_bar());
- double const remaining_ticks = (remaining_beats - floor (remaining_beats)) * BBT_Time::ticks_per_beat;
+ const double beats_in_ms = (pulse - prev_ms->pulse()) * prev_ms->note_divisor();
+ const uint32_t bars_in_ms = (uint32_t) floor (beats_in_ms / prev_ms->divisions_per_bar());
+ const uint32_t total_bars = bars_in_ms + accumulated_bars;
+ const double remaining_beats = beats_in_ms - (bars_in_ms * prev_ms->divisions_per_bar());
+ const double remaining_ticks = (remaining_beats - floor (remaining_beats)) * BBT_Time::ticks_per_beat;
BBT_Time ret;
return ret;
}
-double
-TempoMap::beat_at_frame (const framecnt_t& frame) const
-{
- Glib::Threads::RWLock::ReaderLock lm (lock);
- return beat_at_frame_locked (_metrics, frame);
-}
-
-double
-TempoMap::beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const
-{
- //framecnt_t const offset_frame = frame + frame_offset_at (metrics, frame);
- double const pulse = pulse_at_frame_locked (metrics, frame);
-
- return beat_at_pulse_locked (metrics, pulse);
-}
-
-double
-TempoMap::pulse_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const
+void
+TempoMap::bbt_time (framepos_t frame, BBT_Time& bbt)
{
- /* HOLD (at least) THE READER LOCK */
- TempoSection* prev_ts = 0;
- double accumulated_pulses = 0.0;
- for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
- TempoSection* t;
- if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
- if (!t->active()) {
- continue;
- }
- if (prev_ts && t->frame() > frame) {
- /*the previous ts is the one containing the frame */
- double const ret = prev_ts->pulse_at_frame (frame, _frame_rate);
- return ret;
- }
- accumulated_pulses = t->pulse();
- prev_ts = t;
- }
+ if (frame < 0) {
+ bbt.bars = 1;
+ bbt.beats = 1;
+ bbt.ticks = 0;
+ warning << string_compose (_("tempo map asked for BBT time at frame %1\n"), frame) << endmsg;
+ return;
}
-
- /* treated as constant for this ts */
- double const pulses_in_section = (frame - prev_ts->frame()) / prev_ts->frames_per_pulse (_frame_rate);
-
- return pulses_in_section + accumulated_pulses;
-}
-
-framecnt_t
-TempoMap::frame_at_beat (const double& beat) const
-{
Glib::Threads::RWLock::ReaderLock lm (lock);
- return frame_at_beat_locked (_metrics, beat);
-}
+ const double beat = beat_at_frame_locked (_metrics, frame);
-framecnt_t
-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));
- //frameoffset_t const frame_off = frame_offset_at (metrics, frame);
- return frame;
+ bbt = beats_to_bbt_locked (_metrics, beat);
}
-framecnt_t
-TempoMap::frame_at_pulse_locked (const Metrics& metrics, const double& pulse) const
+framepos_t
+TempoMap::frame_time_locked (const Metrics& metrics, const BBT_Time& bbt) const
{
/* HOLD THE READER LOCK */
- const TempoSection* prev_ts = 0;
- double accumulated_pulses = 0.0;
-
- for (Metrics::const_iterator i = metrics.begin(); i != metrics.end(); ++i) {
- TempoSection* t;
-
- if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
- if (!t->active()) {
- continue;
- }
- if (prev_ts && t->pulse() > pulse) {
- return prev_ts->frame_at_pulse (pulse, _frame_rate);
- }
-
- accumulated_pulses = t->pulse();
- prev_ts = t;
- }
- }
- /* must be treated as constant, irrespective of _type */
- double const pulses_in_section = pulse - accumulated_pulses;
- double const dtime = pulses_in_section * prev_ts->frames_per_pulse (_frame_rate);
-
- framecnt_t const ret = (framecnt_t) floor (dtime) + prev_ts->frame();
-
+ const framepos_t ret = frame_at_beat_locked (metrics, bbt_to_beats_locked (metrics, bbt));
return ret;
}
throw std::logic_error ("beats are counted from one");
}
Glib::Threads::RWLock::ReaderLock lm (lock);
- double const beat = bbt_to_beats_locked (_metrics, bbt);
- framecnt_t const frame = frame_at_beat_locked (_metrics, beat);
- return frame;
-}
-
-framepos_t
-TempoMap::frame_time_locked (const Metrics& metrics, const BBT_Time& bbt) const
-{
- /* HOLD THE READER LOCK */
-
- framepos_t const ret = frame_at_beat_locked (metrics, bbt_to_beats_locked (metrics, bbt));
+ const double beat = bbt_to_beats_locked (_metrics, bbt);
+ const framecnt_t frame = frame_at_beat_locked (_metrics, beat);
- return ret;
+ return frame;
}
bool
if (m->movable()) {
const double beats = ((pulse_at_frame_locked (imaginary, frame) - prev_ms->pulse()) * prev_ms->note_divisor()) - prev_ms->beat();
const double ceil_beats = beats - fmod (beats, prev_ms->divisions_per_bar());
- const int32_t bars = (ceil_beats + 1) / prev_ms->divisions_per_bar();
-
- b_bbt = make_pair (ceil_beats, BBT_Time (bars + 1, 1, 0));
+ b_bbt = make_pair (ceil_beats, BBT_Time (accumulated_bars + 1, 1, 0));
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());
pulse = true_pulse - pulse_off;
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 ceil_beats = beats - fmod (beats , prev_ms->divisions_per_bar());
- const double true_pulse = prev_ms->pulse() + (m->beat() - prev_ms->beat()) / prev_ms->note_divisor();
- const double pulse_off = true_pulse - ((ceil_beats - prev_ms->beat()) / prev_ms->note_divisor());
+ 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());
b_bbt = make_pair (ceil_beats, BBT_Time (accumulated_bars + 1, 1, 0));
pulse = true_pulse - pulse_off;
} else {
framepos_t ret = 0;
TempoSection* new_section = copy_metrics_and_point (future_map, section);
- double const beat = bbt_to_beats_locked (future_map, bbt);
+ const double 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 {
{
Glib::Threads::RWLock::ReaderLock lm (lock);
- double const tick_at_time = beat_at_frame_locked (_metrics, pos) * BBT_Time::ticks_per_beat;
- double const bbt_ticks = bbt.ticks + (bbt.beats * BBT_Time::ticks_per_beat);
- double const total_beats = (tick_at_time + bbt_ticks) / BBT_Time::ticks_per_beat;
- framecnt_t const time_at_bbt = frame_at_beat_locked (_metrics, total_beats);
- framecnt_t const ret = time_at_bbt;
+ const double tick_at_time = beat_at_frame_locked (_metrics, pos) * BBT_Time::ticks_per_beat;
+ const double bbt_ticks = bbt.ticks + (bbt.beats * BBT_Time::ticks_per_beat);
+ const double total_beats = (tick_at_time + bbt_ticks) / BBT_Time::ticks_per_beat;
+ const framecnt_t time_at_bbt = frame_at_beat_locked (_metrics, total_beats);
+ const framecnt_t ret = time_at_bbt;
return ret;
}
}
}
- framepos_t const ret_frame = frame_at_beat_locked (_metrics, beats + (ticks / BBT_Time::ticks_per_beat));
+ const framepos_t ret_frame = frame_at_beat_locked (_metrics, beats + (ticks / BBT_Time::ticks_per_beat));
return ret_frame;
}
{
Glib::Threads::RWLock::ReaderLock lm (lock);
- double const beat_at_framepos = beat_at_frame_locked (_metrics, frame);
+ const double beat_at_framepos = beat_at_frame_locked (_metrics, frame);
BBT_Time bbt (beats_to_bbt_locked (_metrics, beat_at_framepos));
switch (type) {
framepos_t lower, framepos_t upper)
{
Glib::Threads::RWLock::ReaderLock lm (lock);
- int32_t const upper_beat = (int32_t) ceil (beat_at_frame_locked (_metrics, upper));
+ const int32_t upper_beat = (int32_t) ceil (beat_at_frame_locked (_metrics, upper));
int32_t cnt = floor (beat_at_frame_locked (_metrics, lower));
/* although the map handles negative beats, bbt doesn't. */
if (cnt < 0.0) {
}
while (cnt <= upper_beat) {
framecnt_t pos = frame_at_beat_locked (_metrics, cnt);
- TempoSection const tempo = tempo_section_at_locked (pos);
- MeterSection const meter = meter_section_at_locked (pos);
- BBT_Time const bbt = beats_to_bbt (cnt);
- BBTPoint point = BBTPoint (meter, tempo_at_locked (pos), pos, bbt.bars, bbt.beats, tempo.get_c_func());
- points.push_back (point);
+ const TempoSection tempo = tempo_section_at_locked (pos);
+ const MeterSection meter = meter_section_at_locked (pos);
+ const BBT_Time bbt = beats_to_bbt (cnt);
+ points.push_back (BBTPoint (meter, tempo_at_locked (pos), pos, bbt.bars, bbt.beats, tempo.get_c_func()));
++cnt;
}
}
}
if ((prev_ts) && t->frame() > frame) {
/* t is the section past frame */
- double const ret = prev_ts->tempo_at_frame (frame, _frame_rate) * prev_ts->note_type();
- Tempo const ret_tempo (ret, prev_ts->note_type());
+ const double ret = prev_ts->tempo_at_frame (frame, _frame_rate) * prev_ts->note_type();
+ const Tempo ret_tempo (ret, prev_ts->note_type());
return ret_tempo;
}
prev_ts = t;
}
}
- double const ret = prev_ts->beats_per_minute();
- Tempo const ret_tempo (ret, prev_ts->note_type ());
+ const double ret = prev_ts->beats_per_minute();
+ const Tempo ret_tempo (ret, prev_ts->note_type ());
return ret_tempo;
}