TempoSection::tempo_at methods return a Tempo, document the opposite direction.

This commit is contained in:
nick_m 2016-11-09 00:07:37 +11:00
parent 3ee59cf499
commit a432f6585c
4 changed files with 124 additions and 115 deletions

View file

@ -131,7 +131,7 @@ TempoCurve::set_position (framepos_t frame, framepos_t end_frame)
framepos_t current_frame = frame; framepos_t current_frame = frame;
while (current_frame < (end_frame - frame_step)) { while (current_frame < (end_frame - frame_step)) {
const double tempo_at = _tempo.tempo_at_minute (_tempo.minute_at_frame (current_frame)); const double tempo_at = _tempo.tempo_at_minute (_tempo.minute_at_frame (current_frame)).note_types_per_minute();
const double y_pos = max ((curve_height) - (((tempo_at - _min_tempo) / (_max_tempo - _min_tempo)) * curve_height), 0.0); const double y_pos = max ((curve_height) - (((tempo_at - _min_tempo) / (_max_tempo - _min_tempo)) * curve_height), 0.0);
points->push_back (ArdourCanvas::Duple (editor.sample_to_pixel (current_frame - frame), min (y_pos, curve_height))); points->push_back (ArdourCanvas::Duple (editor.sample_to_pixel (current_frame - frame), min (y_pos, curve_height)));
@ -139,7 +139,7 @@ TempoCurve::set_position (framepos_t frame, framepos_t end_frame)
current_frame += frame_step; current_frame += frame_step;
} }
const double tempo_at = _tempo.tempo_at_minute (_tempo.minute_at_frame (end_frame)); const double tempo_at = _tempo.tempo_at_minute (_tempo.minute_at_frame (end_frame)).note_types_per_minute();
const double y_pos = max ((curve_height) - (((tempo_at - _min_tempo) / (_max_tempo - _min_tempo)) * curve_height), 0.0); const double y_pos = max ((curve_height) - (((tempo_at - _min_tempo) / (_max_tempo - _min_tempo)) * curve_height), 0.0);
points->push_back (ArdourCanvas::Duple (editor.sample_to_pixel ((end_frame - 1) - frame), min (y_pos, curve_height))); points->push_back (ArdourCanvas::Duple (editor.sample_to_pixel ((end_frame - 1) - frame), min (y_pos, curve_height)));

View file

@ -207,17 +207,20 @@ class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
bool locked_to_meter () const { return _locked_to_meter; } bool locked_to_meter () const { return _locked_to_meter; }
void set_locked_to_meter (bool yn) { _locked_to_meter = yn; } void set_locked_to_meter (bool yn) { _locked_to_meter = yn; }
double tempo_at_minute (const double& minute) const; Tempo tempo_at_minute (const double& minute) const;
double minute_at_tempo (const double& bpm, const double& pulse) const; double minute_at_ntpm (const double& ntpm, const double& pulse) const;
double tempo_at_pulse (const double& pulse) const; Tempo tempo_at_pulse (const double& pulse) const;
double pulse_at_tempo (const double& bpm, const double& minute) const; double pulse_at_ntpm (const double& ntpm, const double& minute) const;
double pulse_at_minute (const double& minute) const; double pulse_at_minute (const double& minute) const;
double minute_at_pulse (const double& pulse) const; double minute_at_pulse (const double& pulse) const;
double compute_c_func_pulse (const double& end_bpm, const double& end_pulse) const; double compute_c_func_pulse (const double& end_ntpm, const double& end_pulse) const;
double compute_c_func_minute (const double& end_bpm, const double& end_minute) const; double compute_c_func_minute (const double& end_ntpm, const double& end_minute) const;
double pulse_at_frame (const framepos_t& frame) const;
framepos_t frame_at_pulse (const double& pulse) const;
Timecode::BBT_Time legacy_bbt () { return _legacy_bbt; } Timecode::BBT_Time legacy_bbt () { return _legacy_bbt; }
@ -450,11 +453,11 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
/* quarter note related functions are also tempo-sensitive and ignore meter. /* quarter note related functions are also tempo-sensitive and ignore meter.
quarter notes may be compared with and assigned to Evoral::Beats. quarter notes may be compared with and assigned to Evoral::Beats.
*/ */
double quarter_note_at_frame (const framepos_t frame); double quarter_note_at_frame (const framepos_t frame) const;
double quarter_note_at_frame_rt (const framepos_t frame); double quarter_note_at_frame_rt (const framepos_t frame) const;
framepos_t frame_at_quarter_note (const double quarter_note); framepos_t frame_at_quarter_note (const double quarter_note) const;
framecnt_t frames_between_quarter_notes (const double start, const double end); framecnt_t frames_between_quarter_notes (const double start, const double end) const;
double quarter_note_at_beat (const double beat); double quarter_note_at_beat (const double beat);
double beat_at_quarter_note (const double beat); double beat_at_quarter_note (const double beat);
@ -511,7 +514,7 @@ private:
double quarter_note_at_beat_locked (const Metrics& metrics, const double beat) const; double quarter_note_at_beat_locked (const Metrics& metrics, const double beat) const;
double beat_at_quarter_note_locked (const Metrics& metrics, const double beat) const; double beat_at_quarter_note_locked (const Metrics& metrics, const double beat) const;
double minutes_between_quarter_notes_locked (const Metrics& metrics, const double start_qn, const double end_qn); double minutes_between_quarter_notes_locked (const Metrics& metrics, const double start_qn, const double end_qn) const;
const TempoSection& tempo_section_at_minute_locked (const Metrics& metrics, double minute) const; const TempoSection& tempo_section_at_minute_locked (const Metrics& metrics, double minute) const;
const TempoSection& tempo_section_at_beat_locked (const Metrics& metrics, const double& beat) const; const TempoSection& tempo_section_at_beat_locked (const Metrics& metrics, const double& beat) const;

View file

@ -238,63 +238,79 @@ TempoSection::set_type (Type type)
_type = type; _type = type;
} }
/** returns the tempo on note types per minute at the zero-based (relative to session) minute. /** returns the Tempo at the session-relative minute.
*/ */
double Tempo
TempoSection::tempo_at_minute (const double& m) const TempoSection::tempo_at_minute (const double& m) const
{ {
if (_type == Constant || _c_func == 0.0) { if (_type == Constant || _c_func == 0.0) {
return note_types_per_minute(); return Tempo (note_types_per_minute(), note_type());
} }
return _tempo_at_time (m - minute()); return Tempo (_tempo_at_time (m - minute()), _note_type);
} }
/** returns the zero-based minute (relative to session) /** returns the session relative minute where the supplied tempo in note types per minute occurs.
where the tempo in note types per minute occurs in this section. * @param ntpm the tempo in mote types per minute used to calculate the returned minute
pulse p is only used for constant tempi. * @param p the pulse used to calculate the returned minute for constant tempi
note that the tempo map may have multiple such values. * @return the minute at the supplied tempo
*
* note that the note_type is currently ignored in this function. see below.
*
*/
/** user feedback dictates that if tempoA (120, 4.0) precedes tempoB (120, 8.0),
* there will be no ramp between the two even if set to ramped.
* in other words a ramp should only place a curve on note_types_per_minute.
* we should be able to use Tempo note type here, but the above
* complicates things a bit.
* we would ideally like to use arbitrary Tempo structs here.
*/ */
double double
TempoSection::minute_at_tempo (const double& npm, const double& p) const TempoSection::minute_at_ntpm (const double& ntpm, const double& p) const
{ {
if (_type == Constant || _c_func == 0.0) { if (_type == Constant || _c_func == 0.0) {
return ((p - pulse()) / pulses_per_minute()) + minute(); return ((p - pulse()) / pulses_per_minute()) + minute();
} }
return _time_at_tempo (npm) + minute(); return _time_at_tempo (ntpm) + minute();
} }
/** returns the tempo in note types per minute at the supplied pulse. /** returns the Tempo at the supplied whole-note pulse.
*/ */
double Tempo
TempoSection::tempo_at_pulse (const double& p) const TempoSection::tempo_at_pulse (const double& p) const
{ {
if (_type == Constant || _c_func == 0.0) { if (_type == Constant || _c_func == 0.0) {
return note_types_per_minute(); return Tempo (note_types_per_minute(), note_type());
} }
return _tempo_at_pulse (p - pulse()); return Tempo (_tempo_at_pulse (p - pulse()), _note_type);
} }
/** returns the pulse where the tempo in note types per minute occurs given minute m. /** returns the whole-note pulse where a tempo in note types per minute occurs.
minute m is only used for constant tempi. * constant tempi require minute m.
note that the session tempo map may have multiple locations where a given tempo occurs. * @param ntpm the note types per minute value used to calculate the returned pulse
* @param m the minute used to calculate the returned pulse if the tempo is constant
* @return the whole-note pulse at the supplied tempo
*
* note that note_type is currently ignored in this function. see minute_at_tempo().
*
* for constant tempi, this is anaologous to pulse_at_minute().
*/ */
double double
TempoSection::pulse_at_tempo (const double& npm, const double& m) const TempoSection::pulse_at_ntpm (const double& ntpm, const double& m) const
{ {
if (_type == Constant || _c_func == 0.0) { if (_type == Constant || _c_func == 0.0) {
const double pulses = ((m - minute()) * pulses_per_minute()) + pulse(); return ((m - minute()) * pulses_per_minute()) + pulse();
return pulses;
} }
return _pulse_at_tempo (npm) + pulse(); return _pulse_at_tempo (ntpm) + pulse();
} }
/** returns the pulse at the supplied session-relative minute. /** returns the whole-note pulse at the supplied session-relative minute.
*/ */
double double
TempoSection::pulse_at_minute (const double& m) const TempoSection::pulse_at_minute (const double& m) const
@ -306,7 +322,7 @@ TempoSection::pulse_at_minute (const double& m) const
return _pulse_at_time (m - minute()) + pulse(); return _pulse_at_time (m - minute()) + pulse();
} }
/** returns the minute (relative to session start) at the supplied pulse. /** returns the session-relative minute at the supplied whole-note pulse.
*/ */
double double
TempoSection::minute_at_pulse (const double& p) const TempoSection::minute_at_pulse (const double& p) const
@ -439,16 +455,16 @@ TempoSection::_tempo_at_time (const double& time) const
/* time in minutes at tempo in note types per minute */ /* time in minutes at tempo in note types per minute */
double double
TempoSection::_time_at_tempo (const double& tempo) const TempoSection::_time_at_tempo (const double& npm) const
{ {
return log (tempo / note_types_per_minute()) / _c_func; return log (npm / note_types_per_minute()) / _c_func;
} }
/* pulse at tempo in note types per minute */ /* pulse at tempo in note types per minute */
double double
TempoSection::_pulse_at_tempo (const double& tempo) const TempoSection::_pulse_at_tempo (const double& npm) const
{ {
return ((tempo - note_types_per_minute()) / _c_func) / _note_type; return ((npm - note_types_per_minute()) / _c_func) / _note_type;
} }
/* tempo in note types per minute at pulse */ /* tempo in note types per minute at pulse */
@ -1312,12 +1328,12 @@ TempoMap::recompute_tempi (Metrics& metrics)
if (t->position_lock_style() == AudioTime) { if (t->position_lock_style() == AudioTime) {
prev_t->set_c_func (prev_t->compute_c_func_minute (t->note_types_per_minute(), t->minute())); prev_t->set_c_func (prev_t->compute_c_func_minute (t->note_types_per_minute(), t->minute()));
if (!t->locked_to_meter()) { if (!t->locked_to_meter()) {
t->set_pulse (prev_t->pulse_at_tempo (t->note_types_per_minute(), t->minute())); t->set_pulse (prev_t->pulse_at_ntpm (t->note_types_per_minute(), t->minute()));
} }
} else { } else {
prev_t->set_c_func (prev_t->compute_c_func_pulse (t->note_types_per_minute(), t->pulse())); prev_t->set_c_func (prev_t->compute_c_func_pulse (t->note_types_per_minute(), t->pulse()));
t->set_minute (prev_t->minute_at_tempo (t->note_types_per_minute(), t->pulse())); t->set_minute (prev_t->minute_at_ntpm (t->note_types_per_minute(), t->pulse()));
} }
} }
@ -1606,18 +1622,13 @@ TempoMap::tempo_at_minute_locked (const Metrics& metrics, const double& minute)
} }
if ((prev_t) && t->minute() > minute) { if ((prev_t) && t->minute() > minute) {
/* t is the section past frame */ /* t is the section past frame */
const double ret_bpm = prev_t->tempo_at_minute (minute); return prev_t->tempo_at_minute (minute);
const Tempo ret_tempo (ret_bpm, prev_t->note_type());
return ret_tempo;
} }
prev_t = t; prev_t = t;
} }
} }
const double ret = prev_t->note_types_per_minute(); return Tempo (prev_t->note_types_per_minute(), prev_t->note_type());
const Tempo ret_tempo (ret, prev_t->note_type ());
return ret_tempo;
} }
/** returns the frame at which the supplied tempo occurs, or /** returns the frame at which the supplied tempo occurs, or
@ -1660,7 +1671,7 @@ TempoMap::minute_at_tempo_locked (const Metrics& metrics, const Tempo& tempo) co
const double prev_t_bpm = prev_t->note_types_per_minute(); const double prev_t_bpm = prev_t->note_types_per_minute();
if ((t_bpm > tempo_bpm && prev_t_bpm < tempo_bpm) || (t_bpm < tempo_bpm && prev_t_bpm > tempo_bpm)) { if ((t_bpm > tempo_bpm && prev_t_bpm < tempo_bpm) || (t_bpm < tempo_bpm && prev_t_bpm > tempo_bpm)) {
return prev_t->minute_at_tempo (tempo_bpm, prev_t->pulse()); return prev_t->minute_at_ntpm (prev_t->note_types_per_minute(), prev_t->pulse());
} }
} }
prev_t = t; prev_t = t;
@ -1685,18 +1696,13 @@ TempoMap::tempo_at_pulse_locked (const Metrics& metrics, const double& pulse) co
} }
if ((prev_t) && t->pulse() > pulse) { if ((prev_t) && t->pulse() > pulse) {
/* t is the section past frame */ /* t is the section past frame */
const double ret_bpm = prev_t->tempo_at_pulse (pulse); return prev_t->tempo_at_pulse (pulse);
const Tempo ret_tempo (ret_bpm, prev_t->note_type());
return ret_tempo;
} }
prev_t = t; prev_t = t;
} }
} }
const double ret = prev_t->note_types_per_minute(); return Tempo (prev_t->note_types_per_minute(), prev_t->note_type());
const Tempo ret_tempo (ret, prev_t->note_type ());
return ret_tempo;
} }
double double
@ -1726,7 +1732,7 @@ TempoMap::pulse_at_tempo_locked (const Metrics& metrics, const Tempo& tempo) con
const double prev_t_bpm = prev_t->note_types_per_minute(); const double prev_t_bpm = prev_t->note_types_per_minute();
if ((t_bpm > tempo_bpm && prev_t_bpm < tempo_bpm) || (t_bpm < tempo_bpm && prev_t_bpm > tempo_bpm)) { if ((t_bpm > tempo_bpm && prev_t_bpm < tempo_bpm) || (t_bpm < tempo_bpm && prev_t_bpm > tempo_bpm)) {
return prev_t->pulse_at_tempo (tempo_bpm, prev_t->minute()); return prev_t->pulse_at_ntpm (prev_t->note_types_per_minute(), prev_t->minute());
} }
} }
prev_t = t; prev_t = t;
@ -2255,7 +2261,7 @@ TempoMap::minute_at_bbt_locked (const Metrics& metrics, const BBT_Time& bbt) con
* *
*/ */
double double
TempoMap::quarter_note_at_frame (const framepos_t frame) TempoMap::quarter_note_at_frame (const framepos_t frame) const
{ {
Glib::Threads::RWLock::ReaderLock lm (lock); Glib::Threads::RWLock::ReaderLock lm (lock);
@ -2273,7 +2279,7 @@ TempoMap::quarter_note_at_minute_locked (const Metrics& metrics, const double mi
} }
double double
TempoMap::quarter_note_at_frame_rt (const framepos_t frame) TempoMap::quarter_note_at_frame_rt (const framepos_t frame) const
{ {
Glib::Threads::RWLock::ReaderLock lm (lock, Glib::Threads::TRY_LOCK); Glib::Threads::RWLock::ReaderLock lm (lock, Glib::Threads::TRY_LOCK);
@ -2295,7 +2301,7 @@ TempoMap::quarter_note_at_frame_rt (const framepos_t frame)
* *
*/ */
framepos_t framepos_t
TempoMap::frame_at_quarter_note (const double quarter_note) TempoMap::frame_at_quarter_note (const double quarter_note) const
{ {
Glib::Threads::RWLock::ReaderLock lm (lock); Glib::Threads::RWLock::ReaderLock lm (lock);
@ -2372,7 +2378,7 @@ TempoMap::beat_at_quarter_note_locked (const Metrics& metrics, const double quar
* *
*/ */
framecnt_t framecnt_t
TempoMap::frames_between_quarter_notes (const double start, const double end) TempoMap::frames_between_quarter_notes (const double start, const double end) const
{ {
Glib::Threads::RWLock::ReaderLock lm (lock); Glib::Threads::RWLock::ReaderLock lm (lock);
@ -2380,7 +2386,7 @@ TempoMap::frames_between_quarter_notes (const double start, const double end)
} }
double double
TempoMap::minutes_between_quarter_notes_locked (const Metrics& metrics, const double start, const double end) TempoMap::minutes_between_quarter_notes_locked (const Metrics& metrics, const double start, const double end) const
{ {
return minute_at_pulse_locked (metrics, end / 4.0) - minute_at_pulse_locked (metrics, start / 4.0); return minute_at_pulse_locked (metrics, end / 4.0) - minute_at_pulse_locked (metrics, start / 4.0);
@ -2407,7 +2413,7 @@ TempoMap::check_solved (const Metrics& metrics) const
} }
/* precision check ensures tempo and frames align.*/ /* precision check ensures tempo and frames align.*/
if (t->frame() != frame_at_minute (prev_t->minute_at_tempo (t->note_types_per_minute(), t->pulse()))) { if (t->frame() != frame_at_minute (prev_t->minute_at_ntpm (t->note_types_per_minute(), t->pulse()))) {
if (!t->locked_to_meter()) { if (!t->locked_to_meter()) {
return false; return false;
} }
@ -2511,11 +2517,11 @@ TempoMap::solve_map_minute (Metrics& imaginary, TempoSection* section, const dou
} }
if (t->position_lock_style() == MusicTime) { if (t->position_lock_style() == MusicTime) {
prev_t->set_c_func (prev_t->compute_c_func_pulse (t->note_types_per_minute(), t->pulse())); prev_t->set_c_func (prev_t->compute_c_func_pulse (t->note_types_per_minute(), t->pulse()));
t->set_minute (prev_t->minute_at_tempo (t->note_types_per_minute(), t->pulse())); t->set_minute (prev_t->minute_at_ntpm (t->note_types_per_minute(), t->pulse()));
} else { } else {
prev_t->set_c_func (prev_t->compute_c_func_minute (t->note_types_per_minute(), t->minute())); prev_t->set_c_func (prev_t->compute_c_func_minute (t->note_types_per_minute(), t->minute()));
if (!t->locked_to_meter()) { if (!t->locked_to_meter()) {
t->set_pulse (prev_t->pulse_at_tempo (t->note_types_per_minute(), t->minute())); t->set_pulse (prev_t->pulse_at_ntpm (t->note_types_per_minute(), t->minute()));
} }
} }
} }
@ -2526,7 +2532,7 @@ TempoMap::solve_map_minute (Metrics& imaginary, TempoSection* section, const dou
if (section_prev) { if (section_prev) {
section_prev->set_c_func (section_prev->compute_c_func_minute (section->note_types_per_minute(), minute)); section_prev->set_c_func (section_prev->compute_c_func_minute (section->note_types_per_minute(), minute));
if (!section->locked_to_meter()) { if (!section->locked_to_meter()) {
section->set_pulse (section_prev->pulse_at_tempo (section->note_types_per_minute(), minute)); section->set_pulse (section_prev->pulse_at_ntpm (section->note_types_per_minute(), minute));
} }
} }
@ -2579,11 +2585,11 @@ TempoMap::solve_map_pulse (Metrics& imaginary, TempoSection* section, const doub
} }
if (t->position_lock_style() == MusicTime) { if (t->position_lock_style() == MusicTime) {
prev_t->set_c_func (prev_t->compute_c_func_pulse (t->note_types_per_minute(), t->pulse())); prev_t->set_c_func (prev_t->compute_c_func_pulse (t->note_types_per_minute(), t->pulse()));
t->set_minute (prev_t->minute_at_tempo (t->note_types_per_minute(), t->pulse())); t->set_minute (prev_t->minute_at_ntpm (t->note_types_per_minute(), t->pulse()));
} else { } else {
prev_t->set_c_func (prev_t->compute_c_func_minute (t->note_types_per_minute(), t->minute())); prev_t->set_c_func (prev_t->compute_c_func_minute (t->note_types_per_minute(), t->minute()));
if (!t->locked_to_meter()) { if (!t->locked_to_meter()) {
t->set_pulse (prev_t->pulse_at_tempo (t->note_types_per_minute(), t->minute())); t->set_pulse (prev_t->pulse_at_ntpm (t->note_types_per_minute(), t->minute()));
} }
} }
} }
@ -2593,7 +2599,7 @@ TempoMap::solve_map_pulse (Metrics& imaginary, TempoSection* section, const doub
if (section_prev) { if (section_prev) {
section_prev->set_c_func (section_prev->compute_c_func_pulse (section->note_types_per_minute(), pulse)); section_prev->set_c_func (section_prev->compute_c_func_pulse (section->note_types_per_minute(), pulse));
section->set_minute (section_prev->minute_at_tempo (section->note_types_per_minute(), pulse)); section->set_minute (section_prev->minute_at_ntpm (section->note_types_per_minute(), pulse));
} }
#if (0) #if (0)
@ -3874,7 +3880,7 @@ TempoMap::frames_per_quarter_note_at (const framepos_t& frame, const framecnt_t&
} }
if (ts_after) { if (ts_after) {
return (60.0 * _frame_rate) / ((ts_at->tempo_at_minute (minute_at_frame (frame)) / ts_at->note_type()) * 4.0); return (60.0 * _frame_rate) / ts_at->tempo_at_minute (minute_at_frame (frame)).quarter_notes_per_minute();
} }
/* must be treated as constant tempo */ /* must be treated as constant tempo */
return ts_at->frames_per_quarter_note (_frame_rate); return ts_at->frames_per_quarter_note (_frame_rate);
@ -4154,9 +4160,9 @@ TempoMap::dump (const Metrics& metrics, std::ostream& o) const
o << " previous : " << prev_t->note_types_per_minute() o << " previous : " << prev_t->note_types_per_minute()
<< " | " << prev_t->pulse() << " | " << prev_t->frame() << " | " << prev_t->minute() << std::endl; << " | " << prev_t->pulse() << " | " << prev_t->frame() << " | " << prev_t->minute() << std::endl;
o << " calculated : " << prev_t->tempo_at_pulse (t->pulse()) o << " calculated : " << prev_t->tempo_at_pulse (t->pulse())
<< " | " << prev_t->pulse_at_tempo (t->note_types_per_minute(), t->minute()) << " | " << prev_t->pulse_at_ntpm (t->note_types_per_minute(), t->minute())
<< " | " << frame_at_minute (prev_t->minute_at_tempo (t->note_types_per_minute(), t->pulse())) << " | " << frame_at_minute (prev_t->minute_at_ntpm (t->note_types_per_minute(), t->pulse()))
<< " | " << prev_t->minute_at_tempo (t->note_types_per_minute(), t->pulse()) << std::endl; << " | " << prev_t->minute_at_ntpm (t->note_types_per_minute(), t->pulse()) << std::endl;
} }
prev_t = t; prev_t = t;
} else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) { } else if ((m = dynamic_cast<const MeterSection*>(*i)) != 0) {

View file

@ -60,8 +60,8 @@ TempoTest::recomputeMapTest48 ()
CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tsa.minute_at_frame (60.0 * sampling_rate), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tsa.minute_at_frame (60.0 * sampling_rate), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_tempo (240.0, 3.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_ntpm (240.0, 3.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_tempo (240.0, 3.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_ntpm (240.0, 3.0), 1e-17);
/* do the same via the map */ /* do the same via the map */
@ -84,7 +84,7 @@ TempoTest::recomputeMapTest48 ()
/* tempo */ /* tempo */
/* tempo - frame */ /* tempo - frame */
CPPUNIT_ASSERT_EQUAL (framepos_t (288e3), map.frame_at_tempo (240.0)); CPPUNIT_ASSERT_EQUAL (framepos_t (288e3), map.frame_at_tempo (tempoB));
CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_frame (288e3).note_types_per_minute(), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_frame (288e3).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_frame (288e3 - 1).note_types_per_minute(), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_frame (288e3 - 1).note_types_per_minute(), 1e-17);
@ -94,8 +94,8 @@ TempoTest::recomputeMapTest48 ()
CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (6.0).note_types_per_minute(), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (6.0).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (0.0).note_types_per_minute(), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (0.0).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (12.0, map.quarter_note_at_tempo (240.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (12.0, map.quarter_note_at_tempo (tempoB), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, map.quarter_note_at_tempo (120.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, map.quarter_note_at_tempo (tempoA), 1e-17);
/* tempo - internal minute interface */ /* tempo - internal minute interface */
CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_minute_locked (map._metrics, 0.1).note_types_per_minute(), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_minute_locked (map._metrics, 0.1).note_types_per_minute(), 1e-17);
@ -158,7 +158,7 @@ TempoTest::recomputeMapTest44 ()
CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tsa.minute_at_frame (60.0 * sampling_rate), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tsa.minute_at_frame (60.0 * sampling_rate), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_tempo (240.0, 3.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_ntpm (240.0, 3.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_pulse (3.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_pulse (3.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, tsa.pulse_at_minute (0.1), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, tsa.pulse_at_minute (0.1), 1e-17);
@ -194,8 +194,8 @@ TempoTest::recomputeMapTest44 ()
CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (6.0).note_types_per_minute(), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (6.0).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (0.0).note_types_per_minute(), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (0.0).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (12.0, map.quarter_note_at_tempo (240.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (12.0, map.quarter_note_at_tempo (tempoB), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, map.quarter_note_at_tempo (120.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, map.quarter_note_at_tempo (tempoA), 1e-17);
/* tempo - internal minute interface */ /* tempo - internal minute interface */
CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_minute_locked (map._metrics, 0.1).note_types_per_minute(), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_minute_locked (map._metrics, 0.1).note_types_per_minute(), 1e-17);
@ -395,26 +395,26 @@ TempoTest::rampTest48 ()
TempoSection& tA = map.first_tempo(); TempoSection& tA = map.first_tempo();
const TempoSection& tB = map.tempo_section_at_frame ((framepos_t) 60 * sampling_rate); const TempoSection& tB = map.tempo_section_at_frame ((framepos_t) 60 * sampling_rate);
CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_tempo (tB.note_types_per_minute(), 300.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_ntpm (217.0, 300.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (217.0, tA.tempo_at_minute (1.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (217.0, tA.tempo_at_minute (1.0).note_types_per_minute(), 1e-17);
/* note 1e-14 here. pulse is two derivatives away from time */ /* note 1e-14 here. pulse is two derivatives away from time */
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_minute (1.0), 1e-14); CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_minute (1.0), 1e-14);
CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_pulse (tB.pulse()), 1e-15); CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_pulse (tB.pulse()), 1e-15);
/* note 1e-17 here. tempo is one derivative away from pulse, so we can get the same stuff with more precision */ /* note 1e-17 here. tempo is one derivative away from pulse, so we can get the same stuff with more precision */
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_tempo (217.0, 1.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_ntpm (217.0, 1.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_tempo (217.0, tB.pulse()), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_ntpm (217.0, tB.pulse()), 1e-17);
/* self-check tempo at pulse @ 125 bpm. */ /* self-check tempo at pulse @ 125 bpm. */
CPPUNIT_ASSERT_DOUBLES_EQUAL (125.0, tA.tempo_at_pulse (tA.pulse_at_tempo (125.0, 0)), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (125.0, tA.tempo_at_pulse (tA.pulse_at_ntpm (125.0, 0)).note_types_per_minute(), 1e-17);
/* check that tB's pulse is what tA thinks it should be */ /* check that tB's pulse is what tA thinks it should be */
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_tempo (217.0, 0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_ntpm (217.0, 0), 1e-17);
/* check that the tempo at the halfway mark (in pulses) is half the tempo delta.*/ /* check that the tempo at the halfway mark (in pulses) is half the tempo delta.*/
CPPUNIT_ASSERT_DOUBLES_EQUAL (147.0, tA.tempo_at_pulse (tB.pulse() / 2.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (147.0, tA.tempo_at_pulse (tB.pulse() / 2.0).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL ((tB.pulse() - tA.pulse()) / 2.0, tA.pulse_at_tempo (147.0, 0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL ((tB.pulse() - tA.pulse()) / 2.0, tA.pulse_at_ntpm (147.0, 0), 1e-17);
/* self-check frame at pulse 20 seconds in. */ /* self-check frame at pulse 20 seconds in. */
const double target = 20.0 / 60.0; const double target = 20.0 / 60.0;
@ -457,26 +457,26 @@ TempoTest::rampTest44 ()
TempoSection& tA = map.first_tempo(); TempoSection& tA = map.first_tempo();
const TempoSection& tB = map.tempo_section_at_frame ((framepos_t) 60 * sampling_rate); const TempoSection& tB = map.tempo_section_at_frame ((framepos_t) 60 * sampling_rate);
CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_tempo (tB.note_types_per_minute(), 300.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_ntpm (217.0, 300.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (217.0, tA.tempo_at_minute (1.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (217.0, tA.tempo_at_minute (1.0).note_types_per_minute(), 1e-17);
/* note 1e-14 here. pulse is two derivatives away from time */ /* note 1e-14 here. pulse is two derivatives away from time */
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_minute (1.0), 1e-14); CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_minute (1.0), 1e-14);
CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_pulse (tB.pulse()), 1e-15); CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_pulse (tB.pulse()), 1e-15);
/* note 1e-17 here. tempo is one derivative away from pulse, so we can get the same stuff with more precision */ /* note 1e-17 here. tempo is one derivative away from pulse, so we can get the same stuff with more precision */
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_tempo (217.0, 1.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_ntpm (217.0, 1.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_tempo (217.0, tB.pulse()), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_ntpm (217.0, tB.pulse()), 1e-17);
/* self-check tempo at pulse @ 125 bpm. */ /* self-check tempo at pulse @ 125 bpm. */
CPPUNIT_ASSERT_DOUBLES_EQUAL (125.0, tA.tempo_at_pulse (tA.pulse_at_tempo (125.0, 0)), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (125.0, tA.tempo_at_pulse (tA.pulse_at_ntpm (125.0, 0)).note_types_per_minute(), 1e-17);
/* check that tB's pulse is what tA thinks it should be */ /* check that tB's pulse is what tA thinks it should be */
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_tempo (217.0, 0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_ntpm (217.0, 0), 1e-17);
/* check that the tempo at the halfway mark (in pulses) is half the tempo delta.*/ /* check that the tempo at the halfway mark (in pulses) is half the tempo delta.*/
CPPUNIT_ASSERT_DOUBLES_EQUAL (147.0, tA.tempo_at_pulse (tB.pulse() / 2.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (147.0, tA.tempo_at_pulse (tB.pulse() / 2.0).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL ((tB.pulse() - tA.pulse()) / 2.0, tA.pulse_at_tempo (147.0, 0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL ((tB.pulse() - tA.pulse()) / 2.0, tA.pulse_at_ntpm (147.0, 0), 1e-17);
/* self-check frame at pulse 20 seconds in. */ /* self-check frame at pulse 20 seconds in. */
const double target = 20.0 / 60.0; const double target = 20.0 / 60.0;
@ -524,35 +524,35 @@ TempoTest::tempoAtPulseTest ()
} }
} }
} }
std::cout << std::setprecision (18) << " tA->tempo_at_pulse (20.0).note_types_per_minute(): " << tA->tempo_at_pulse (20.0).note_types_per_minute() << std::endl;
CPPUNIT_ASSERT_EQUAL (160.0, tA->tempo_at_pulse (20.0)); CPPUNIT_ASSERT_DOUBLES_EQUAL (160.0, tA->tempo_at_pulse (20.0).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_EQUAL (123.0, tB->tempo_at_pulse (30.0)); CPPUNIT_ASSERT_DOUBLES_EQUAL (123.0, tB->tempo_at_pulse (30.0).note_types_per_minute(), 1e-17);
/* check that the tempo at the halfway mark (in pulses) is half the tempo delta.*/ /* check that the tempo at the halfway mark (in pulses) is half the tempo delta.*/
CPPUNIT_ASSERT_DOUBLES_EQUAL (((80.0 - 160.0) / 2.0) + 160.0, tA->tempo_at_pulse (10.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (((80.0 - 160.0) / 2.0) + 160.0, tA->tempo_at_pulse (10.0).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (20.0 / 2.0, tA->pulse_at_tempo (120, 0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (20.0 / 2.0, tA->pulse_at_ntpm (120.0, 0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (((160.0 - 123.0) / 2.0) + 123.0, tB->tempo_at_pulse (25.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (((160.0 - 123.0) / 2.0) + 123.0, tB->tempo_at_pulse (25.0).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (((20.0 - 30.0) / 2.0) + 30.0, tB->pulse_at_tempo (141.5, 0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (((20.0 - 30.0) / 2.0) + 30.0, tB->pulse_at_ntpm (141.5, 0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_pulse (20.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_pulse (20.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_pulse (30.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_pulse (30.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_tempo (160.0, 20.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_ntpm (160.0, 20.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_tempo (123.0, 30.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_ntpm (123.0, 30.0), 1e-17);
/* self-check tempo at pulse @ 125 bpm. */ /* self-check tempo at pulse @ 125 bpm. */
CPPUNIT_ASSERT_DOUBLES_EQUAL (125.0, tA->tempo_at_pulse (tA->pulse_at_tempo (125.0, 0)), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (125.0, tA->tempo_at_pulse (tA->pulse_at_ntpm (125.0, 0)).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (160.0, tA->tempo_at_pulse (20.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (160.0, tA->tempo_at_pulse (20.0).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (123.0, tB->tempo_at_pulse (30.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (123.0, tB->tempo_at_pulse (30.0).note_types_per_minute(), 1e-17);
/* test minute based measurements */ /* test minute based measurements */
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_pulse (20.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_pulse (20.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_pulse (30.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_pulse (30.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_tempo (160.0, 20.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_ntpm (160.0, 20.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_tempo (123.0, 30.0), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_ntpm (123.0, 30.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (160.0, tA->tempo_at_minute (tB->minute()), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (160.0, tA->tempo_at_minute (tB->minute()).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (123.0, tB->tempo_at_minute (tC->minute()), 1e-17); CPPUNIT_ASSERT_DOUBLES_EQUAL (123.0, tB->tempo_at_minute (tC->minute()).note_types_per_minute(), 1e-17);
} }
void void