b4a9ed236b63aa24c1955057c14beb5d68648622
[ardour.git] / libs / ardour / test / dsp_load_calculator_test.cc
1 #include <iostream>
2
3 #include "ardour/dsp_load_calculator.h"
4
5 #include "dsp_load_calculator_test.h"
6
7 CPPUNIT_TEST_SUITE_REGISTRATION (DSPLoadCalculatorTest);
8
9
10 #if defined(PLATFORM_WINDOWS) && defined(COMPILER_MINGW)
11 /* cppunit-1.13.2  uses assertion_traits<double>
12  *    sprintf( , "%.*g", precision, x)
13  * to format a double. The actual comparison is performed on a string.
14  * This is problematic with mingw/windows|wine, "%.*g" formatting fails.
15  *
16  * This quick hack compares float, however float compatisons are at most Y.MMMM+eXX,
17  * the max precision needs to be limited. to the last mantissa digit.
18  *
19  * Anyway, actual maths is verified with Linux and OSX unit-tests,
20  * and this needs to go to https://sourceforge.net/p/cppunit/bugs/
21  */
22 #define CPPUNIT_ASSERT_DOUBLES_EQUAL(A,B,P) CPPUNIT_ASSERT_EQUAL((float)rint ((A) / (P)),(float)rint ((B) / (P)))
23 #endif
24
25 using namespace std;
26 using namespace ARDOUR;
27
28 void
29 DSPLoadCalculatorTest::basicTest ()
30 {
31         DSPLoadCalculator dsp_calc;
32
33         dsp_calc.set_max_time(48000, 512);
34         int64_t dsp_100_pc_48k_us = 10666;
35
36         CPPUNIT_ASSERT(dsp_calc.get_max_time_us() == dsp_100_pc_48k_us);
37
38         // test equivalent of 10% load
39         dsp_calc.set_start_timestamp_us(0);
40         dsp_calc.set_stop_timestamp_us(dsp_100_pc_48k_us/10);
41         CPPUNIT_ASSERT(dsp_calc.get_dsp_load() <= 0.1f);
42
43         // test equivalent of 50% load and check that the load jumps to 50 percent
44         dsp_calc.set_start_timestamp_us(0);
45         dsp_calc.set_stop_timestamp_us(dsp_100_pc_48k_us/2);
46         CPPUNIT_ASSERT(dsp_calc.get_dsp_load() <= 0.5f);
47
48         // test equivalent of 100% load
49         dsp_calc.set_start_timestamp_us(0);
50         dsp_calc.set_stop_timestamp_us(dsp_100_pc_48k_us);
51         CPPUNIT_ASSERT(dsp_calc.elapsed_time_us() == dsp_100_pc_48k_us);
52         CPPUNIT_ASSERT(dsp_calc.get_dsp_load() <= 1.0f);
53
54         // test setting the equivalent of 100% twice doesn't lead to a dsp value > 1.0
55         dsp_calc.set_start_timestamp_us(dsp_100_pc_48k_us);
56         dsp_calc.set_stop_timestamp_us(dsp_100_pc_48k_us * 2);
57         CPPUNIT_ASSERT(dsp_calc.elapsed_time_us() == dsp_100_pc_48k_us);
58         CPPUNIT_ASSERT(dsp_calc.get_dsp_load() <= 1.0f);
59
60         // test setting the equivalent of 200% clamps the value to 1.0
61         dsp_calc.set_start_timestamp_us(dsp_100_pc_48k_us);
62         dsp_calc.set_stop_timestamp_us(dsp_100_pc_48k_us * 3);
63         CPPUNIT_ASSERT(dsp_calc.get_dsp_load() == 1.0f);
64
65         // test setting the an stop timestamp before the start timestamp is ignored
66         // and the previous dsp value is returned
67         dsp_calc.set_start_timestamp_us(dsp_100_pc_48k_us * 2);
68         dsp_calc.set_stop_timestamp_us(dsp_100_pc_48k_us);
69         CPPUNIT_ASSERT(dsp_calc.get_dsp_load() == 1.0f);
70
71         float dsp_load = dsp_calc.get_dsp_load();
72
73         // test setting the equivalent of beyond the max_timer_error_us is ignored and
74         // the previous dsp value is returned
75         dsp_calc.set_start_timestamp_us (0);
76         dsp_calc.set_stop_timestamp_us (dsp_100_pc_48k_us*10);
77         CPPUNIT_ASSERT(dsp_calc.elapsed_time_us() > dsp_calc.max_timer_error_us());
78         CPPUNIT_ASSERT(dsp_calc.get_dsp_load() == dsp_load);
79
80         // test the rate of rolloff of the LPF from 100% with load at constant 50%
81         // over the equivalent of 1 second
82         for (int i = 0; i < 1e6 / dsp_100_pc_48k_us; ++i) {
83                 dsp_calc.set_start_timestamp_us(0);
84                 dsp_calc.set_stop_timestamp_us(dsp_100_pc_48k_us / 2);
85                 CPPUNIT_ASSERT(dsp_calc.elapsed_time_us() == 5333);
86                 CPPUNIT_ASSERT(dsp_calc.get_dsp_load() <= 1.0);
87                 CPPUNIT_ASSERT(dsp_calc.get_dsp_load() >= 0.5);
88 #if 0
89                 std::cout << "DSP 50% load value = " << dsp_calc.get_dsp_load() << std::endl;
90 #endif
91         }
92
93         // test that the LPF is still working after one second of values
94         // TODO need to work out what is required in terms of responsiveness etc
95         CPPUNIT_ASSERT(dsp_calc.get_dsp_load() > 0.5f);
96
97         // compare 96k to 48k
98         DSPLoadCalculator dsp_calc_96k;
99         dsp_calc_96k.set_max_time(96000, 512);
100         int64_t dsp_100_pc_96k_us = 5333;
101
102         // reset both to 100%
103         dsp_calc.set_start_timestamp_us(dsp_100_pc_48k_us);
104         dsp_calc.set_stop_timestamp_us(dsp_100_pc_48k_us * 2);
105         CPPUNIT_ASSERT(dsp_calc.elapsed_time_us() == dsp_100_pc_48k_us);
106         CPPUNIT_ASSERT(dsp_calc.get_dsp_load() <= 1.0f);
107         dsp_calc_96k.set_start_timestamp_us(dsp_100_pc_96k_us);
108         dsp_calc_96k.set_stop_timestamp_us(dsp_100_pc_96k_us * 2);
109         CPPUNIT_ASSERT(dsp_calc_96k.elapsed_time_us() == dsp_100_pc_96k_us);
110         CPPUNIT_ASSERT(dsp_calc_96k.get_dsp_load() <= 1.0f);
111
112         // test the rate of rolloff of the LPF from 100% with load at constant 50%
113         // over the equivalent of 1 second for 48k and 96k and test for ~equality
114         for (int i = 0; i < 1e6 / dsp_100_pc_96k_us; ++i) {
115                 dsp_calc_96k.set_start_timestamp_us(0);
116                 dsp_calc_96k.set_stop_timestamp_us(dsp_100_pc_96k_us / 2);
117                 if (i % 2 == 0) {
118                         dsp_calc.set_start_timestamp_us(0);
119                         dsp_calc.set_stop_timestamp_us(dsp_100_pc_48k_us / 2);
120 #if 0
121                         std::cout << "DSP 50% load value 48k = " << dsp_calc.get_dsp_load()
122                                   << std::endl;
123                         std::cout << "DSP 50% load value 96k = " << dsp_calc_96k.get_dsp_load()
124                                   << std::endl;
125 #endif
126                         CPPUNIT_ASSERT_DOUBLES_EQUAL(dsp_calc.get_dsp_load(),
127                                                      dsp_calc_96k.get_dsp_load(), 0.001);
128                 }
129         }
130
131 }