13
0

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;
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);
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;
}
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);
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; }
void set_locked_to_meter (bool yn) { _locked_to_meter = yn; }
double tempo_at_minute (const double& minute) const;
double minute_at_tempo (const double& bpm, const double& pulse) const;
Tempo tempo_at_minute (const double& minute) const;
double minute_at_ntpm (const double& ntpm, const double& pulse) const;
double tempo_at_pulse (const double& pulse) const;
double pulse_at_tempo (const double& bpm, const double& minute) const;
Tempo tempo_at_pulse (const double& pulse) const;
double pulse_at_ntpm (const double& ntpm, const double& minute) const;
double pulse_at_minute (const double& minute) 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_minute (const double& end_bpm, const double& end_minute) const;
double compute_c_func_pulse (const double& end_ntpm, const double& end_pulse) 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; }
@ -450,11 +453,11 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
/* quarter note related functions are also tempo-sensitive and ignore meter.
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_rt (const framepos_t frame);
framepos_t frame_at_quarter_note (const double quarter_note);
double quarter_note_at_frame (const framepos_t frame) const;
double quarter_note_at_frame_rt (const framepos_t frame) const;
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 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 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_beat_locked (const Metrics& metrics, const double& beat) const;

View File

@ -238,63 +238,79 @@ TempoSection::set_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
{
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)
where the tempo in note types per minute occurs in this section.
pulse p is only used for constant tempi.
note that the tempo map may have multiple such values.
/** returns the session relative minute where the supplied tempo in note types per minute occurs.
* @param ntpm the tempo in mote types per minute used to calculate the returned minute
* @param p the pulse used to calculate the returned minute for constant tempi
* @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
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) {
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.
*/
double
/** returns the Tempo at the supplied whole-note pulse.
*/
Tempo
TempoSection::tempo_at_pulse (const double& p) const
{
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.
minute m is only used for constant tempi.
note that the session tempo map may have multiple locations where a given tempo occurs.
/** returns the whole-note pulse where a tempo in note types per minute occurs.
* constant tempi require minute m.
* @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
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) {
const double pulses = ((m - minute()) * pulses_per_minute()) + pulse();
return pulses;
return ((m - minute()) * pulses_per_minute()) + pulse();
}
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
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();
}
/** returns the minute (relative to session start) at the supplied pulse.
/** returns the session-relative minute at the supplied whole-note pulse.
*/
double
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 */
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 */
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 */
@ -1312,12 +1328,12 @@ TempoMap::recompute_tempi (Metrics& metrics)
if (t->position_lock_style() == AudioTime) {
prev_t->set_c_func (prev_t->compute_c_func_minute (t->note_types_per_minute(), t->minute()));
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 {
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) {
/* t is the section past frame */
const double ret_bpm = prev_t->tempo_at_minute (minute);
const Tempo ret_tempo (ret_bpm, prev_t->note_type());
return ret_tempo;
return prev_t->tempo_at_minute (minute);
}
prev_t = t;
}
}
const double ret = prev_t->note_types_per_minute();
const Tempo ret_tempo (ret, prev_t->note_type ());
return ret_tempo;
return Tempo (prev_t->note_types_per_minute(), prev_t->note_type());
}
/** 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();
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;
@ -1685,18 +1696,13 @@ TempoMap::tempo_at_pulse_locked (const Metrics& metrics, const double& pulse) co
}
if ((prev_t) && t->pulse() > pulse) {
/* t is the section past frame */
const double ret_bpm = prev_t->tempo_at_pulse (pulse);
const Tempo ret_tempo (ret_bpm, prev_t->note_type());
return ret_tempo;
return prev_t->tempo_at_pulse (pulse);
}
prev_t = t;
}
}
const double ret = prev_t->note_types_per_minute();
const Tempo ret_tempo (ret, prev_t->note_type ());
return ret_tempo;
return Tempo (prev_t->note_types_per_minute(), prev_t->note_type());
}
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();
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;
@ -2255,7 +2261,7 @@ TempoMap::minute_at_bbt_locked (const Metrics& metrics, const BBT_Time& bbt) con
*
*/
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);
@ -2273,7 +2279,7 @@ TempoMap::quarter_note_at_minute_locked (const Metrics& metrics, const double mi
}
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);
@ -2295,7 +2301,7 @@ TempoMap::quarter_note_at_frame_rt (const framepos_t frame)
*
*/
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);
@ -2372,7 +2378,7 @@ TempoMap::beat_at_quarter_note_locked (const Metrics& metrics, const double quar
*
*/
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);
@ -2380,7 +2386,7 @@ TempoMap::frames_between_quarter_notes (const double start, const double end)
}
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);
@ -2407,7 +2413,7 @@ TempoMap::check_solved (const Metrics& metrics) const
}
/* 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()) {
return false;
}
@ -2511,11 +2517,11 @@ TempoMap::solve_map_minute (Metrics& imaginary, TempoSection* section, const dou
}
if (t->position_lock_style() == MusicTime) {
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 {
prev_t->set_c_func (prev_t->compute_c_func_minute (t->note_types_per_minute(), t->minute()));
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) {
section_prev->set_c_func (section_prev->compute_c_func_minute (section->note_types_per_minute(), minute));
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) {
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 {
prev_t->set_c_func (prev_t->compute_c_func_minute (t->note_types_per_minute(), t->minute()));
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) {
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)
@ -3874,7 +3880,7 @@ TempoMap::frames_per_quarter_note_at (const framepos_t& frame, const framecnt_t&
}
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 */
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()
<< " | " << prev_t->pulse() << " | " << prev_t->frame() << " | " << prev_t->minute() << std::endl;
o << " calculated : " << prev_t->tempo_at_pulse (t->pulse())
<< " | " << prev_t->pulse_at_tempo (t->note_types_per_minute(), t->minute())
<< " | " << frame_at_minute (prev_t->minute_at_tempo (t->note_types_per_minute(), t->pulse()))
<< " | " << prev_t->minute_at_tempo (t->note_types_per_minute(), t->pulse()) << std::endl;
<< " | " << prev_t->pulse_at_ntpm (t->note_types_per_minute(), t->minute())
<< " | " << frame_at_minute (prev_t->minute_at_ntpm (t->note_types_per_minute(), t->pulse()))
<< " | " << prev_t->minute_at_ntpm (t->note_types_per_minute(), t->pulse()) << std::endl;
}
prev_t = t;
} 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 (0.1, tsa.minute_at_tempo (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);
CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_ntpm (240.0, 3.0), 1e-17);
/* do the same via the map */
@ -84,7 +84,7 @@ TempoTest::recomputeMapTest48 ()
/* tempo */
/* 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 (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 (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 (0.0, map.quarter_note_at_tempo (120.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 (tempoA), 1e-17);
/* 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);
@ -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 (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 (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 (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 (0.0, map.quarter_note_at_tempo (120.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 (tempoA), 1e-17);
/* 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);
@ -395,26 +395,26 @@ TempoTest::rampTest48 ()
TempoSection& tA = map.first_tempo();
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 (217.0, tA.tempo_at_minute (1.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).note_types_per_minute(), 1e-17);
/* 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 (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 */
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_tempo (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 (tB.pulse(), tA.pulse_at_ntpm (217.0, 1.0), 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. */
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 */
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.*/
CPPUNIT_ASSERT_DOUBLES_EQUAL (147.0, tA.tempo_at_pulse (tB.pulse() / 2.0), 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 (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_ntpm (147.0, 0), 1e-17);
/* self-check frame at pulse 20 seconds in. */
const double target = 20.0 / 60.0;
@ -457,26 +457,26 @@ TempoTest::rampTest44 ()
TempoSection& tA = map.first_tempo();
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 (217.0, tA.tempo_at_minute (1.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).note_types_per_minute(), 1e-17);
/* 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 (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 */
CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_tempo (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 (tB.pulse(), tA.pulse_at_ntpm (217.0, 1.0), 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. */
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 */
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.*/
CPPUNIT_ASSERT_DOUBLES_EQUAL (147.0, tA.tempo_at_pulse (tB.pulse() / 2.0), 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 (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_ntpm (147.0, 0), 1e-17);
/* self-check frame at pulse 20 seconds in. */
const double target = 20.0 / 60.0;
@ -524,35 +524,35 @@ TempoTest::tempoAtPulseTest ()
}
}
}
CPPUNIT_ASSERT_EQUAL (160.0, tA->tempo_at_pulse (20.0));
CPPUNIT_ASSERT_EQUAL (123.0, tB->tempo_at_pulse (30.0));
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_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).note_types_per_minute(), 1e-17);
/* 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 (20.0 / 2.0, tA->pulse_at_tempo (120, 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 (((20.0 - 30.0) / 2.0) + 30.0, tB->pulse_at_tempo (141.5, 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_ntpm (120.0, 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_ntpm (141.5, 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 (tB->minute(), tA->minute_at_tempo (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 (tB->minute(), tA->minute_at_ntpm (160.0, 20.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. */
CPPUNIT_ASSERT_DOUBLES_EQUAL (125.0, tA->tempo_at_pulse (tA->pulse_at_tempo (125.0, 0)), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (160.0, tA->tempo_at_pulse (20.0), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (123.0, tB->tempo_at_pulse (30.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).note_types_per_minute(), 1e-17);
CPPUNIT_ASSERT_DOUBLES_EQUAL (123.0, tB->tempo_at_pulse (30.0).note_types_per_minute(), 1e-17);
/* test minute based measurements */
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 (tB->minute(), tA->minute_at_tempo (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 (tB->minute(), tA->minute_at_ntpm (160.0, 20.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 (123.0, tB->tempo_at_minute (tC->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()).note_types_per_minute(), 1e-17);
}
void