1 #include "ardour/tempo.h"
2 #include "tempo_test.h"
4 CPPUNIT_TEST_SUITE_REGISTRATION (TempoTest);
7 using namespace ARDOUR;
8 using namespace Timecode;
11 TempoTest::recomputeMapTest48 ()
13 int const sampling_rate = 48000;
15 TempoMap map (sampling_rate);
17 map.replace_meter (map.first_meter(), meterA, BBT_Time (1, 1, 0), 0, AudioTime);
20 120bpm at bar 1, 240bpm at bar 4
22 120bpm = 24e3 samples per beat
23 240bpm = 12e3 samples per beat
31 0 samples 288e3 samples
34 | 1.1 1.2 1.3 1.4 | 2.1 2.2 2.3.2.4 | 3.1 3.2 3.3 3.4 | 4.1 4.2 4.3 |
38 Tempo tempoA (120.0, 4.0);
39 map.replace_tempo (map.first_tempo(), tempoA, 0.0, 0, AudioTime);
40 Tempo tempoB (240.0, 4.0);
41 map.add_tempo (tempoB, 3.0, 0, MusicTime);
43 map.add_meter (meterB, BBT_Time (4, 1, 0), 0, MusicTime);
44 //map.dump (map._metrics, std::cout);
45 list<MetricSection*>::iterator i = map._metrics.begin();
46 CPPUNIT_ASSERT_EQUAL (samplepos_t (0), (*i)->sample ());
47 i = map._metrics.end();
49 CPPUNIT_ASSERT_EQUAL (samplepos_t (288e3), (*i)->sample ());
51 /* check the tempo section for expected result (no map) */
52 const TempoSection& tsa (map.tempo_section_at_sample (0));
53 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_pulse (3.0), 1e-17);
54 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1 / 2.0, tsa.minute_at_pulse (1.5), 1e-17);
55 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1 / 3.0, tsa.minute_at_pulse (1.0), 1e-17);
57 CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, tsa.pulse_at_minute (0.1), 1e-17);
58 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.5, tsa.pulse_at_minute (0.1 / 2.0), 1e-17);
59 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tsa.pulse_at_minute (0.1 / 3.0), 1e-17);
61 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tsa.minute_at_sample (60.0 * sampling_rate), 1e-17);
63 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_ntpm (240.0, 3.0), 1e-17);
64 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_ntpm (240.0, 3.0), 1e-17);
66 /* do the same via the map */
70 /* quarter note - sample*/
71 CPPUNIT_ASSERT_EQUAL (samplepos_t (288e3), map.sample_at_quarter_note (12.0));
72 CPPUNIT_ASSERT_EQUAL (samplepos_t (144e3), map.sample_at_quarter_note (6.0));
73 CPPUNIT_ASSERT_EQUAL (samplepos_t (96e3), map.sample_at_quarter_note (4.0));
75 /* sample - quarter note*/
76 CPPUNIT_ASSERT_DOUBLES_EQUAL (12.0, map.quarter_note_at_sample (288e3), 1e-17);
77 CPPUNIT_ASSERT_DOUBLES_EQUAL (6.0, map.quarter_note_at_sample (144e3), 1e-17);
78 CPPUNIT_ASSERT_DOUBLES_EQUAL (4.0, map.quarter_note_at_sample (96e3), 1e-17);
80 /* pulse - internal minute based interface */
81 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, map.minute_at_pulse_locked (map._metrics, 3.0), 1e-17);
82 CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, map.pulse_at_minute_locked (map._metrics, 0.1), 1e-17);
87 CPPUNIT_ASSERT_EQUAL (samplepos_t (288e3), map.sample_at_tempo (tempoB));
88 CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_sample (288e3).note_types_per_minute(), 1e-17);
89 CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_sample (288e3 - 1).note_types_per_minute(), 1e-17);
91 /* tempo - quarter note */
92 CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_quarter_note (24.0).note_types_per_minute(), 1e-17);
93 CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_quarter_note (12.0).note_types_per_minute(), 1e-17);
94 CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (6.0).note_types_per_minute(), 1e-17);
95 CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (0.0).note_types_per_minute(), 1e-17);
97 CPPUNIT_ASSERT_DOUBLES_EQUAL (12.0, map.quarter_note_at_tempo (tempoB), 1e-17);
98 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, map.quarter_note_at_tempo (tempoA), 1e-17);
100 /* tempo - internal minute interface */
101 CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_minute_locked (map._metrics, 0.1).note_types_per_minute(), 1e-17);
102 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, map.minute_at_tempo_locked (map._metrics, tempoB), 1e-17);
104 CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_pulse_locked (map._metrics, 3.0).note_types_per_minute(), 1e-17);
105 CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, map.pulse_at_tempo_locked (map._metrics, tempoB), 1e-17);
109 TempoTest::recomputeMapTest44 ()
111 int const sampling_rate = 44100;
113 TempoMap map (sampling_rate);
115 map.replace_meter (map.first_meter(), meterA, BBT_Time (1, 1, 0), 0, AudioTime);
118 120bpm at bar 1, 240bpm at bar 4
120 120bpm = 24e3 samples per beat
121 240bpm = 12e3 samples per beat
129 0 samples 288e3 samples
132 | 1.1 1.2 1.3 1.4 | 2.1 2.2 2.3.2.4 | 3.1 3.2 3.3 3.4 | 4.1 4.2 4.3 |
136 Tempo tempoA (120.0, 4.0);
137 map.replace_tempo (map.first_tempo(), tempoA, 0.0, 0, AudioTime);
138 Tempo tempoB (240.0, 4.0);
139 map.add_tempo (tempoB, 3.0, 0, MusicTime);
141 map.add_meter (meterB, BBT_Time (4, 1, 0), 288e3, MusicTime);
143 list<MetricSection*>::iterator i = map._metrics.begin();
144 CPPUNIT_ASSERT_EQUAL (samplepos_t (0), (*i)->sample ());
145 i = map._metrics.end();
147 CPPUNIT_ASSERT_EQUAL (samplepos_t (264600), (*i)->sample ());
149 /* check the tempo section for expected result (no map) */
150 const TempoSection& tsa (map.tempo_section_at_sample (0));
151 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_pulse (3.0), 1e-17);
152 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1 / 2.0, tsa.minute_at_pulse (1.5), 1e-17);
153 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1 / 3.0, tsa.minute_at_pulse (1.0), 1e-17);
155 CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, tsa.pulse_at_minute (0.1), 1e-17);
156 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.5, tsa.pulse_at_minute (0.1 / 2.0), 1e-17);
157 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tsa.pulse_at_minute (0.1 / 3.0), 1e-17);
159 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tsa.minute_at_sample (60.0 * sampling_rate), 1e-17);
161 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_ntpm (240.0, 3.0), 1e-17);
163 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, tsa.minute_at_pulse (3.0), 1e-17);
164 CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, tsa.pulse_at_minute (0.1), 1e-17);
166 /* do the same via the map */
170 /* quarter note - sample */
171 CPPUNIT_ASSERT_EQUAL (samplepos_t (264600), map.sample_at_quarter_note (12.0));
172 CPPUNIT_ASSERT_EQUAL (samplepos_t (132300), map.sample_at_quarter_note (6.0));
173 CPPUNIT_ASSERT_EQUAL (samplepos_t (88200), map.sample_at_quarter_note (4.0));
175 /* sample - quarter note */
176 CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0 * 4.0, map.quarter_note_at_sample (264600), 1e-17);
177 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.5 * 4.0, map.quarter_note_at_sample (132300), 1e-17);
178 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0 * 4.0, map.quarter_note_at_sample (88200), 1e-17);
180 /* pulse - internal minute based interface */
181 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, map.minute_at_pulse_locked (map._metrics, 3.0), 1e-17);
182 CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, map.pulse_at_minute_locked (map._metrics, 0.1), 1e-17);
187 CPPUNIT_ASSERT_EQUAL (samplepos_t (264600), map.sample_at_tempo (tempoB));
188 CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_sample (264600).note_types_per_minute(), 1e-17);
189 CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_sample (264600 - 1).note_types_per_minute(), 1e-17);
191 /* tempo - quarter note */
192 CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_quarter_note (24.0).note_types_per_minute(), 1e-17);
193 CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_quarter_note (12.0).note_types_per_minute(), 1e-17);
194 CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (6.0).note_types_per_minute(), 1e-17);
195 CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, map.tempo_at_quarter_note (0.0).note_types_per_minute(), 1e-17);
197 CPPUNIT_ASSERT_DOUBLES_EQUAL (12.0, map.quarter_note_at_tempo (tempoB), 1e-17);
198 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, map.quarter_note_at_tempo (tempoA), 1e-17);
200 /* tempo - internal minute interface */
201 CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_minute_locked (map._metrics, 0.1).note_types_per_minute(), 1e-17);
202 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, map.minute_at_tempo_locked (map._metrics, tempoB), 1e-17);
204 CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, map.tempo_at_pulse_locked (map._metrics, 3.0).note_types_per_minute(), 1e-17);
205 CPPUNIT_ASSERT_DOUBLES_EQUAL (3.0, map.pulse_at_tempo_locked (map._metrics, tempoB), 1e-17);
209 TempoTest::qnDistanceTestConstant ()
211 int const sampling_rate = 44100;
213 TempoMap map (sampling_rate);
215 map.replace_meter (map.first_meter(), meterA, BBT_Time (1, 1, 0), 0, AudioTime);
218 120bpm at bar 1, 240bpm at bar 4
220 120bpm = 24e3 samples per beat
221 240bpm = 12e3 samples per beat
229 0 samples 288e3 samples
232 | 1.1 1.2 1.3 1.4 | 2.1 2.2 2.3.2.4 | 3.1 3.2 3.3 3.4 | 4.1 4.2 4.3 |
236 Tempo tempoA (120.0, 4.0);
237 map.replace_tempo (map.first_tempo(), tempoA, 0.0, 0, AudioTime);
238 /* should have no effect on pulse */
239 Tempo tempoB (120.0, 4.0);
240 map.add_tempo (tempoB, 2.0, 0, MusicTime);
241 /* equivalent to pulse 3.0 @ 120 bpm*/
242 Tempo tempoC (240.0, 4.0);
243 map.add_tempo (tempoC, 0.0, 6 * sampling_rate, AudioTime);
244 Tempo tempoD (90.4, 4.0);
245 map.add_tempo (tempoD, 9.0, 0, MusicTime);
246 Tempo tempoE (110.6, 4.0);
247 map.add_tempo (tempoE, 12.0, 0, MusicTime);
248 Tempo tempoF (123.7, 4.0);
249 map.add_tempo (tempoF, 15.0, 0, MusicTime);
250 Tempo tempoG (111.8, 4.0);
251 map.add_tempo (tempoG, 0.0, (samplepos_t) 2 * 60 * sampling_rate, AudioTime);
254 map.add_meter (meterB, BBT_Time (4, 1, 0), 288e3, MusicTime);
256 list<MetricSection*>::iterator i = map._metrics.begin();
257 CPPUNIT_ASSERT_EQUAL (samplepos_t (0), (*i)->sample ());
258 i = map._metrics.end();
260 CPPUNIT_ASSERT_EQUAL ((*i)->sample(), map.samples_between_quarter_notes (0.0, (*i)->pulse() * 4.0));
264 CPPUNIT_ASSERT_EQUAL ((*i)->sample(), map.samples_between_quarter_notes (0.0, 15.0 * 4.0));
265 CPPUNIT_ASSERT_DOUBLES_EQUAL ((*i)->minute(), map.minutes_between_quarter_notes_locked (map._metrics, 0.0, 15.0 * 4.0), 1e-17);
269 CPPUNIT_ASSERT_EQUAL ((*i)->sample(), map.samples_between_quarter_notes (0.0, 12.0 * 4.0));
270 CPPUNIT_ASSERT_DOUBLES_EQUAL ((*i)->minute(), map.minutes_between_quarter_notes_locked (map._metrics, 0.0, 12.0 * 4.0), 1e-17);
273 CPPUNIT_ASSERT_EQUAL ((*i)->sample(), map.samples_between_quarter_notes (0.0, 9.0 * 4.0));
274 CPPUNIT_ASSERT_DOUBLES_EQUAL ((*i)->minute(), map.minutes_between_quarter_notes_locked (map._metrics, 0.0, 9.0 * 4.0), 1e-17);
278 CPPUNIT_ASSERT_EQUAL (samplecnt_t (6 * sampling_rate), map.samples_between_quarter_notes (0.0, (*i)->pulse() * 4.0));
279 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, map.minutes_between_quarter_notes_locked (map._metrics, 0.0, (*i)->pulse() * 4.0), 1e-17);
281 /* distance from beat 12.0 to 0.0 should be 6.0 seconds */
282 CPPUNIT_ASSERT_EQUAL (samplecnt_t (264600), map.samples_between_quarter_notes (0.0, 3.0 * 4.0));
283 CPPUNIT_ASSERT_EQUAL (samplecnt_t (-264600), map.samples_between_quarter_notes (3.0 * 4.0, 0.0));
284 CPPUNIT_ASSERT_EQUAL (samplecnt_t (396900), map.samples_between_quarter_notes (0.0, 24.0));
285 CPPUNIT_ASSERT_EQUAL (samplecnt_t (-396900), map.samples_between_quarter_notes (24.0, 0.0));
286 CPPUNIT_ASSERT_EQUAL (samplecnt_t (88200), map.samples_between_quarter_notes (2.0 * 4.0, 3.0 * 4.0));
289 TempoTest::qnDistanceTestRamp ()
291 int const sampling_rate = 44100;
293 TempoMap map (sampling_rate);
295 map.replace_meter (map.first_meter(), meterA, BBT_Time (1, 1, 0), 0, AudioTime);
298 120bpm at bar 1, 240bpm at bar 4
300 120bpm = 24e3 samples per beat
301 240bpm = 12e3 samples per beat
309 0 samples 288e3 samples
312 | 1.1 1.2 1.3 1.4 | -no music- | 2.1 2.2 2.3.2.4 | 3.1 3.2 3.3 3.4 | 4.1 4.2 4.3 |
316 Tempo tempoA (120.2, 4.0, 240.5);
317 map.replace_tempo (map.first_tempo(), tempoA, 0.0, 0, AudioTime);
318 Tempo tempoB (240.5, 4.0, 130.1);
319 map.add_tempo (tempoB, 3.0, 0, MusicTime);
321 Tempo tempoC (130.1, 4.0, 90.3);
322 map.add_tempo (tempoC, 0.0, 6 * sampling_rate, AudioTime);
323 Tempo tempoD (90.3, 4.0, 110.7);
324 map.add_tempo (tempoD, 9.0, 0, MusicTime);
325 Tempo tempoE (110.7, 4.0, 123.9);
326 map.add_tempo (tempoE, 12.0, 0, MusicTime);
327 Tempo tempoF (123.9, 4.0, 111.8);
328 map.add_tempo (tempoF, 15.0, 0, MusicTime);
329 Tempo tempoG (111.8, 4.0);
330 map.add_tempo (tempoG, 0.0, (samplepos_t) 2 * 60 * sampling_rate, AudioTime);
332 map.add_meter (meterB, BBT_Time (2, 1, 0), 288e3, AudioTime);
333 map.recompute_map (map._metrics, 1);
335 list<MetricSection*>::iterator i = map._metrics.begin();
336 CPPUNIT_ASSERT_EQUAL (samplepos_t (0), (*i)->sample ());
337 i = map._metrics.end();
340 CPPUNIT_ASSERT_EQUAL ((*i)->sample(), map.samples_between_quarter_notes (0.0, (*i)->pulse() * 4.0));
341 CPPUNIT_ASSERT_DOUBLES_EQUAL ((*i)->minute(), map.minutes_between_quarter_notes_locked (map._metrics, 0.0, (*i)->pulse() * 4.0), 1e-17);
344 CPPUNIT_ASSERT_EQUAL ((*i)->sample(), map.samples_between_quarter_notes (0.0, 60.0));
345 CPPUNIT_ASSERT_DOUBLES_EQUAL ((*i)->minute(), map.minutes_between_quarter_notes_locked (map._metrics, 0.0, 60.0), 1e-17);
349 CPPUNIT_ASSERT_EQUAL ((*i)->sample(), map.samples_between_quarter_notes (0.0, 48.0));
350 CPPUNIT_ASSERT_DOUBLES_EQUAL ((*i)->minute(), map.minutes_between_quarter_notes_locked (map._metrics, 0.0, 48.0), 1e-17);
353 CPPUNIT_ASSERT_EQUAL ((*i)->sample(), map.samples_between_quarter_notes (0.0, 36.0));
354 CPPUNIT_ASSERT_DOUBLES_EQUAL ((*i)->minute(), map.minutes_between_quarter_notes_locked (map._metrics, 0.0, 36.0), 1e-17);
358 CPPUNIT_ASSERT_EQUAL (samplecnt_t (6 * sampling_rate), map.samples_between_quarter_notes (0.0, (*i)->pulse() * 4.0));
359 CPPUNIT_ASSERT_DOUBLES_EQUAL (0.1, map.minutes_between_quarter_notes_locked (map._metrics, 0.0, (*i)->pulse() * 4.0), 1e-17);
364 TempoTest::rampTest48 ()
366 int const sampling_rate = 48000;
368 TempoMap map (sampling_rate);
370 Tempo tempoA (77.0, 4.0, 217.0);
371 Tempo tempoB (217.0, 4.0);
372 map.replace_tempo (map.first_tempo(), tempoA, 0.0, 0, AudioTime);
373 map.add_tempo (tempoB, 0.0, (samplepos_t) 60 * sampling_rate, AudioTime);
374 map.replace_meter (map.first_meter(), meterA, BBT_Time (1, 1, 0), 0, AudioTime);
379 0 samples 60 * sample rate samples
391 -------------------|-----------|-----------------------
392 20 seconds 125.0 bpm / note_type
395 TempoSection& tA = map.first_tempo();
396 const TempoSection& tB = map.tempo_section_at_sample ((samplepos_t) 60 * sampling_rate);
398 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_ntpm (217.0, 300.0), 1e-17);
399 CPPUNIT_ASSERT_DOUBLES_EQUAL (217.0, tA.tempo_at_minute (1.0).note_types_per_minute(), 1e-17);
401 /* note 1e-14 here. pulse is two derivatives away from time */
402 CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_minute (1.0), 1e-14);
403 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_pulse (tB.pulse()), 1e-15);
405 /* note 1e-17 here. tempo is one derivative away from pulse, so we can get the same stuff with more precision */
406 CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_ntpm (217.0, 1.0), 1e-17);
407 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_ntpm (217.0, tB.pulse()), 1e-17);
409 /* self-check tempo at pulse @ 125 bpm. */
410 CPPUNIT_ASSERT_DOUBLES_EQUAL (125.0, tA.tempo_at_pulse (tA.pulse_at_ntpm (125.0, 0)).note_types_per_minute(), 1e-17);
412 /* check that tB's pulse is what tA thinks it should be */
413 CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_ntpm (217.0, 0), 1e-17);
415 /* check that the tempo at the halfway mark (in pulses) is half the tempo delta.*/
416 CPPUNIT_ASSERT_DOUBLES_EQUAL (147.0, tA.tempo_at_pulse (tB.pulse() / 2.0).note_types_per_minute(), 1e-17);
417 CPPUNIT_ASSERT_DOUBLES_EQUAL ((tB.pulse() - tA.pulse()) / 2.0, tA.pulse_at_ntpm (147.0, 0), 1e-17);
419 /* self-check sample at pulse 20 seconds in. */
420 const double target = 20.0 / 60.0;
421 const double result = tA.minute_at_pulse (tA.pulse_at_minute (target));
422 CPPUNIT_ASSERT_DOUBLES_EQUAL (target, result, 1e-14);
426 TempoTest::rampTest44 ()
428 int const sampling_rate = 44100;
430 TempoMap map (sampling_rate);
432 Tempo tempoA (77.0, 4.0, 217.0);
433 Tempo tempoB (217.0, 4.0);
434 map.replace_tempo (map.first_tempo(), tempoA, 0.0, 0, AudioTime);
435 map.add_tempo (tempoB, 0.0, (samplepos_t) 60 * sampling_rate, AudioTime);
436 map.replace_meter (map.first_meter(), meterA, BBT_Time (1, 1, 0), 0, AudioTime);
441 0 samples 60 * sample rate samples
453 -------------------|-----------|-----------------------
454 20 seconds 125.0 bpm / note_type
457 TempoSection& tA = map.first_tempo();
458 const TempoSection& tB = map.tempo_section_at_sample ((samplepos_t) 60 * sampling_rate);
460 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_ntpm (217.0, 300.0), 1e-17);
461 CPPUNIT_ASSERT_DOUBLES_EQUAL (217.0, tA.tempo_at_minute (1.0).note_types_per_minute(), 1e-17);
463 /* note 1e-14 here. pulse is two derivatives away from time */
464 CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_minute (1.0), 1e-14);
465 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_pulse (tB.pulse()), 1e-15);
467 /* note 1e-17 here. tempo is one derivative away from pulse, so we can get the same stuff with more precision */
468 CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_ntpm (217.0, 1.0), 1e-17);
469 CPPUNIT_ASSERT_DOUBLES_EQUAL (1.0, tA.minute_at_ntpm (217.0, tB.pulse()), 1e-17);
471 /* self-check tempo at pulse @ 125 bpm. */
472 CPPUNIT_ASSERT_DOUBLES_EQUAL (125.0, tA.tempo_at_pulse (tA.pulse_at_ntpm (125.0, 0)).note_types_per_minute(), 1e-17);
474 /* check that tB's pulse is what tA thinks it should be */
475 CPPUNIT_ASSERT_DOUBLES_EQUAL (tB.pulse(), tA.pulse_at_ntpm (217.0, 0), 1e-17);
477 /* check that the tempo at the halfway mark (in pulses) is half the tempo delta.*/
478 CPPUNIT_ASSERT_DOUBLES_EQUAL (147.0, tA.tempo_at_pulse (tB.pulse() / 2.0).note_types_per_minute(), 1e-17);
479 CPPUNIT_ASSERT_DOUBLES_EQUAL ((tB.pulse() - tA.pulse()) / 2.0, tA.pulse_at_ntpm (147.0, 0), 1e-17);
481 /* self-check sample at pulse 20 seconds in. */
482 const double target = 20.0 / 60.0;
483 const double result = tA.minute_at_pulse (tA.pulse_at_minute (target));
484 CPPUNIT_ASSERT_DOUBLES_EQUAL (target, result, 1e-14);
488 TempoTest::tempoAtPulseTest ()
490 int const sampling_rate = 48000;
492 TempoMap map (sampling_rate);
494 Tempo tempoA (80.0, 8.0, 160.0);
495 Tempo tempoB (160.0, 3.0, 123.0);
496 Tempo tempoC (123.0, 4.0);
498 map.replace_meter (map.first_meter(), meterA, BBT_Time (1, 1, 0), 0, AudioTime);
499 map.replace_tempo (map.first_tempo(), tempoA, 0.0, 0, AudioTime);
501 map.add_tempo (tempoB, 20.0, 0, MusicTime);
502 map.add_tempo (tempoC, 30.0, 0, MusicTime);
504 TempoSection* tA = 0;
505 TempoSection* tB = 0;
506 TempoSection* tC = 0;
508 list<MetricSection*>::iterator i;
510 for (i = map._metrics.begin(); i != map._metrics.end(); ++i) {
512 if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
528 CPPUNIT_ASSERT_DOUBLES_EQUAL (160.0, tA->tempo_at_pulse (20.0).note_types_per_minute(), 1e-17);
529 CPPUNIT_ASSERT_DOUBLES_EQUAL (123.0, tB->tempo_at_pulse (30.0).note_types_per_minute(), 1e-17);
531 /* check that the tempo at the halfway mark (in pulses) is half the tempo delta.*/
532 CPPUNIT_ASSERT_DOUBLES_EQUAL (((80.0 - 160.0) / 2.0) + 160.0, tA->tempo_at_pulse (10.0).note_types_per_minute(), 1e-17);
533 CPPUNIT_ASSERT_DOUBLES_EQUAL (20.0 / 2.0, tA->pulse_at_ntpm (120.0, 0), 1e-17);
534 CPPUNIT_ASSERT_DOUBLES_EQUAL (((160.0 - 123.0) / 2.0) + 123.0, tB->tempo_at_pulse (25.0).note_types_per_minute(), 1e-17);
535 CPPUNIT_ASSERT_DOUBLES_EQUAL (((20.0 - 30.0) / 2.0) + 30.0, tB->pulse_at_ntpm (141.5, 0), 1e-17);
537 CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_pulse (20.0), 1e-17);
538 CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_pulse (30.0), 1e-17);
540 CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_ntpm (160.0, 20.0), 1e-17);
541 CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_ntpm (123.0, 30.0), 1e-17);
543 /* self-check tempo at pulse @ 125 bpm. */
544 CPPUNIT_ASSERT_DOUBLES_EQUAL (125.0, tA->tempo_at_pulse (tA->pulse_at_ntpm (125.0, 0)).note_types_per_minute(), 1e-17);
545 CPPUNIT_ASSERT_DOUBLES_EQUAL (160.0, tA->tempo_at_pulse (20.0).note_types_per_minute(), 1e-17);
546 CPPUNIT_ASSERT_DOUBLES_EQUAL (123.0, tB->tempo_at_pulse (30.0).note_types_per_minute(), 1e-17);
547 /* test minute based measurements */
548 CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_pulse (20.0), 1e-17);
549 CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_pulse (30.0), 1e-17);
551 CPPUNIT_ASSERT_DOUBLES_EQUAL (tB->minute(), tA->minute_at_ntpm (160.0, 20.0), 1e-17);
552 CPPUNIT_ASSERT_DOUBLES_EQUAL (tC->minute(), tB->minute_at_ntpm (123.0, 30.0), 1e-17);
554 CPPUNIT_ASSERT_DOUBLES_EQUAL (160.0, tA->tempo_at_minute (tB->minute()).note_types_per_minute(), 1e-17);
555 CPPUNIT_ASSERT_DOUBLES_EQUAL (123.0, tB->tempo_at_minute (tC->minute()).note_types_per_minute(), 1e-17);
559 TempoTest::tempoFundamentalsTest ()
561 int const sampling_rate = 48000;
563 TempoMap map (sampling_rate);
565 Tempo tempoA (120.0, 4.0);
566 Tempo tempoB (120.0, 8.0);
567 Tempo tempoC (120.0, 2.0);
568 Tempo tempoD (160.0, 2.0);
569 Tempo tempoE (123.0, 3.0);
571 map.replace_meter (map.first_meter(), meterA, BBT_Time (1, 1, 0), 0, AudioTime);
572 map.replace_tempo (map.first_tempo(), tempoA, 0.0, 0, AudioTime);
574 map.add_tempo (tempoB, 20.0, 0, MusicTime);
575 map.add_tempo (tempoC, 30.0, 0, MusicTime);
577 map.add_tempo (tempoD, 40.0, 0, MusicTime);
578 map.add_tempo (tempoE, 50.0, 0, MusicTime);
580 TempoSection* tA = 0;
581 TempoSection* tB = 0;
582 TempoSection* tC = 0;
583 TempoSection* tD = 0;
584 TempoSection* tE = 0;
585 list<MetricSection*>::iterator i;
587 for (i = map._metrics.begin(); i != map._metrics.end(); ++i) {
589 if ((t = dynamic_cast<TempoSection*> (*i)) != 0) {
613 CPPUNIT_ASSERT_DOUBLES_EQUAL (24000.0, tA->samples_per_quarter_note (sampling_rate), 1e-17);
614 CPPUNIT_ASSERT_DOUBLES_EQUAL (24000.0, tA->samples_per_note_type (sampling_rate), 1e-17);
615 CPPUNIT_ASSERT_DOUBLES_EQUAL (120.0, tA->quarter_notes_per_minute (), 1e-17);
616 CPPUNIT_ASSERT_DOUBLES_EQUAL (30.0, tA->pulses_per_minute (), 1e-17);
618 CPPUNIT_ASSERT_DOUBLES_EQUAL (48000.0, tB->samples_per_quarter_note (sampling_rate), 1e-17);
619 CPPUNIT_ASSERT_DOUBLES_EQUAL (24000.0, tB->samples_per_note_type (sampling_rate), 1e-17);
620 CPPUNIT_ASSERT_DOUBLES_EQUAL (60.0, tB->quarter_notes_per_minute (), 1e-17);
621 CPPUNIT_ASSERT_DOUBLES_EQUAL (15.0, tB->pulses_per_minute (), 1e-17);
623 CPPUNIT_ASSERT_DOUBLES_EQUAL (12000.0, tC->samples_per_quarter_note (sampling_rate), 1e-17);
624 CPPUNIT_ASSERT_DOUBLES_EQUAL (24000.0, tC->samples_per_note_type (sampling_rate), 1e-17);
625 CPPUNIT_ASSERT_DOUBLES_EQUAL (240.0, tC->quarter_notes_per_minute (), 1e-17);
626 CPPUNIT_ASSERT_DOUBLES_EQUAL (60.0, tC->pulses_per_minute (), 1e-17);
628 CPPUNIT_ASSERT_DOUBLES_EQUAL (9000.0, tD->samples_per_quarter_note (sampling_rate), 1e-17);
629 CPPUNIT_ASSERT_DOUBLES_EQUAL (18000.0, tD->samples_per_note_type (sampling_rate), 1e-17);
630 CPPUNIT_ASSERT_DOUBLES_EQUAL (320.0, tD->quarter_notes_per_minute (), 1e-17);
631 CPPUNIT_ASSERT_DOUBLES_EQUAL (80.0, tD->pulses_per_minute (), 1e-17);
633 CPPUNIT_ASSERT_DOUBLES_EQUAL (17560.975609756097, tE->samples_per_quarter_note (sampling_rate), 1e-17);
634 CPPUNIT_ASSERT_DOUBLES_EQUAL (23414.634146341465, tE->samples_per_note_type (sampling_rate), 1e-17);
635 CPPUNIT_ASSERT_DOUBLES_EQUAL (164.0, tE->quarter_notes_per_minute (), 1e-17);
636 CPPUNIT_ASSERT_DOUBLES_EQUAL (41.0, tE->pulses_per_minute (), 1e-17);