few more basic ControList/Curve Tests
[ardour.git] / libs / evoral / test / CurveTest.cpp
1 #include "CurveTest.hpp"
2 #include "evoral/ControlList.hpp"
3 #include "evoral/Curve.hpp"
4 #include <stdlib.h>
5
6 CPPUNIT_TEST_SUITE_REGISTRATION (CurveTest);
7
8 using namespace Evoral;
9
10 // linear y = Y0 + YS * x ;  with x = i * (X1 - X0) + X0; and i = [0..1023]
11 #define VEC1024LINCMP(X0, X1, Y0, YS)                                        \
12     cl->curve ().get_vector ((X0), (X1), vec, 1024);                         \
13     for (int i = 0; i < 1024; ++i) {                                         \
14         char msg[64];                                                        \
15         snprintf (msg, 64, "at i=%d (x0=%.1f, x1=%.1f, y0=%.1f, ys=%.3f)",   \
16             i, X0, X1, Y0, YS);                                              \
17         CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE (                               \
18             msg,                                                             \
19             (Y0) + i * (YS), vec[i],                                         \
20             1e-24                                                            \
21             );                                                               \
22     }
23
24 void
25 CurveTest::twoPointLinear ()
26 {
27         float vec[1024];
28
29         boost::shared_ptr<Evoral::ControlList> cl = TestCtrlList();
30
31         cl->create_curve ();
32         cl->set_interpolation (ControlList::Linear);
33
34         // add two points to curve
35         cl->fast_simple_add (   0.0 , 2048.0);
36         cl->fast_simple_add (8192.0 , 4096.0);
37
38         cl->curve ().get_vector (1024.0, 2047.0, vec, 1024);
39
40         VEC1024LINCMP (1024.0, 2047.0, 2304.f,  .25f);
41         VEC1024LINCMP (2048.0, 2559.5, 2560.f,  .125f);
42         VEC1024LINCMP (   0.0, 4092.0, 2048.f, 1.f);
43
44         // greetings to tartina
45         cl->curve ().get_vector (2048.0, 2048.0, vec, 1);
46         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=1 @ 2048..2048", 2560.f, vec[0]);
47
48         /* XXX WHAT DO WE EXPECT WITH veclen=1 AND  x1 > x0 ? */
49 #if 0
50         /* .. interpolated value at (x1+x0)/2 */
51         cl->curve ().get_vector (2048.0, 2049.0, vec, 1);
52         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=1 @ 2048-2049", 2560.125f, vec[0]);
53
54         cl->curve ().get_vector (2048.0, 2056.0, vec, 1);
55         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=1 @ 2048-2049", 2561.f, vec[0]);
56 #else
57         /* .. value at x0 */
58         cl->curve ().get_vector (2048.0, 2049.0, vec, 1);
59         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=1 , 2048..2049", 2560.f, vec[0]);
60
61         cl->curve ().get_vector (2048.0, 2056.0, vec, 1);
62         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=1 , 2048..2049", 2560.f, vec[0]);
63 #endif
64
65         cl->curve ().get_vector (2048.0, 2048.0, vec, 2);
66         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=2 , 2048..2048 @ 0", 2560.f, vec[0]);
67         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=2 , 2048..2048 @ 1", 2560.f, vec[1]);
68
69         cl->curve ().get_vector (2048.0, 2056.0, vec, 2);
70         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=2 , 2048..2056 @ 0", 2560.f, vec[0]);
71         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=2 , 2048..2056 @ 0", 2562.f, vec[1]);
72
73         cl->curve ().get_vector (2048.0, 2056.0, vec, 3);
74         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=3 , 2048..2056 @ 0", 2560.f, vec[0]);
75         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=3 , 2048..2056 @ 1", 2561.f, vec[1]);
76         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=3 , 2048..2056 @ 2", 2562.f, vec[2]);
77
78         /* check out-of range..
79          * we expect the first and last value - no interpolation
80          */
81         cl->curve ().get_vector (-1, -1, vec, 1);
82         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=1 @ -1", 2048.f, vec[0]);
83
84         cl->curve ().get_vector (9999.0, 9999.0, vec, 1);
85         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=1 @ 9999", 4096.f, vec[0]);
86
87         cl->curve ().get_vector (-999.0, 0, vec, 13);
88         for (int i = 0; i < 13; ++i) {
89                 CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=13 @ -999..0", 2048.f, vec[i]);
90         }
91
92         cl->curve ().get_vector (9998.0, 9999.0, vec, 8);
93         for (int i = 0; i < 8; ++i) {
94                 CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=8 @ 9998..9999", 4096.f, vec[i]);
95         }
96 }
97
98 void
99 CurveTest::threePointLinear ()
100 {
101         float vec[4];
102
103         boost::shared_ptr<Evoral::ControlList> cl = TestCtrlList();
104
105         cl->create_curve ();
106         cl->set_interpolation (ControlList::Linear);
107
108         // add 3 points to curve
109         cl->fast_simple_add (   0.0 , 2.0);
110         cl->fast_simple_add ( 100.0 , 4.0);
111         cl->fast_simple_add ( 200.0 , 0.0);
112
113         cl->curve ().get_vector (50.0, 60.0, vec, 1);
114         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=1 @ 50", 3.f, vec[0]);
115
116         cl->curve ().get_vector (100.0, 100.0, vec, 1);
117         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=1 @ 100", 4.f, vec[0]);
118
119         cl->curve ().get_vector (150.0, 150.0, vec, 1);
120         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=1 @ 150", 2.f, vec[0]);
121
122         cl->curve ().get_vector (130.0, 150.0, vec, 3);
123         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=3 130..150 @ 0", 2.8f, vec[0]);
124         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=3 130..150 @ 2", 2.4f, vec[1]);
125         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=3 130..150 @ 3", 2.0f, vec[2]);
126
127         cl->curve ().get_vector (80.0, 160.0, vec, 3);
128         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=3 80..160 @ 0", 3.6f, vec[0]);
129         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=3 80..160 @ 2", 3.2f, vec[1]);
130         CPPUNIT_ASSERT_EQUAL_MESSAGE ("veclen=3 80..160 @ 3", 1.6f, vec[2]);
131 }
132
133 void
134 CurveTest::threePointDiscete ()
135 {
136         boost::shared_ptr<Evoral::ControlList> cl = TestCtrlList();
137         cl->set_interpolation (ControlList::Discrete);
138
139         // add 3 points to curve
140         cl->fast_simple_add (   0.0 , 2.0);
141         cl->fast_simple_add ( 100.0 , 4.0);
142         cl->fast_simple_add ( 200.0 , 0.0);
143
144         CPPUNIT_ASSERT_EQUAL(2.0, cl->unlocked_eval(80.));
145         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(120.));
146         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(160.));
147
148         cl->set_interpolation (ControlList::Linear);
149
150         CPPUNIT_ASSERT_EQUAL(3.6, cl->unlocked_eval(80.));
151         CPPUNIT_ASSERT_EQUAL(3.2, cl->unlocked_eval(120.));
152         CPPUNIT_ASSERT_EQUAL(1.6, cl->unlocked_eval(160.));
153 }
154
155 void
156 CurveTest::ctrlListEval ()
157 {
158         boost::shared_ptr<Evoral::ControlList> cl = TestCtrlList();
159
160         cl->fast_simple_add (   0.0 , 2.0);
161
162         cl->set_interpolation (ControlList::Discrete);
163         CPPUNIT_ASSERT_EQUAL(2.0, cl->unlocked_eval(80.));
164         CPPUNIT_ASSERT_EQUAL(2.0, cl->unlocked_eval(120.));
165         CPPUNIT_ASSERT_EQUAL(2.0, cl->unlocked_eval(160.));
166
167         cl->set_interpolation (ControlList::Linear);
168         CPPUNIT_ASSERT_EQUAL(2.0, cl->unlocked_eval(80.));
169         CPPUNIT_ASSERT_EQUAL(2.0, cl->unlocked_eval(120.));
170         CPPUNIT_ASSERT_EQUAL(2.0, cl->unlocked_eval(160.));
171
172         cl->fast_simple_add ( 100.0 , 4.0);
173
174         cl->set_interpolation (ControlList::Discrete);
175         CPPUNIT_ASSERT_EQUAL(2.0, cl->unlocked_eval(80.));
176         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(120.));
177         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(160.));
178
179         cl->set_interpolation (ControlList::Linear);
180         CPPUNIT_ASSERT_EQUAL(3.6, cl->unlocked_eval(80.));
181         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(120.));
182         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(160.));
183
184         cl->fast_simple_add ( 200.0 , 0.0);
185
186         cl->set_interpolation (ControlList::Discrete);
187         CPPUNIT_ASSERT_EQUAL(2.0, cl->unlocked_eval(80.));
188         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(120.));
189         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(160.));
190
191         cl->set_interpolation (ControlList::Linear);
192         CPPUNIT_ASSERT_EQUAL(3.6, cl->unlocked_eval(80.));
193         CPPUNIT_ASSERT_EQUAL(3.2, cl->unlocked_eval(120.));
194         CPPUNIT_ASSERT_EQUAL(1.6, cl->unlocked_eval(160.));
195
196         cl->fast_simple_add ( 300.0 , 8.0);
197
198         cl->set_interpolation (ControlList::Discrete);
199         CPPUNIT_ASSERT_EQUAL(2.0, cl->unlocked_eval(80.));
200         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(120.));
201         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(160.));
202         CPPUNIT_ASSERT_EQUAL(0.0, cl->unlocked_eval(250.));
203         CPPUNIT_ASSERT_EQUAL(8.0, cl->unlocked_eval(999.));
204
205         cl->set_interpolation (ControlList::Linear);
206         CPPUNIT_ASSERT_EQUAL(3.6, cl->unlocked_eval(80.));
207         CPPUNIT_ASSERT_EQUAL(3.2, cl->unlocked_eval(120.));
208         CPPUNIT_ASSERT_EQUAL(1.6, cl->unlocked_eval(160.));
209         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(250.));
210         CPPUNIT_ASSERT_EQUAL(8.0, cl->unlocked_eval(999.));
211
212         cl->fast_simple_add ( 400.0 , 9.0);
213
214         cl->set_interpolation (ControlList::Discrete);
215         CPPUNIT_ASSERT_EQUAL(2.0, cl->unlocked_eval(80.));
216         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(120.));
217         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(160.));
218         CPPUNIT_ASSERT_EQUAL(0.0, cl->unlocked_eval(250.));
219         CPPUNIT_ASSERT_EQUAL(8.0, cl->unlocked_eval(350.));
220         CPPUNIT_ASSERT_EQUAL(9.0, cl->unlocked_eval(999.));
221
222         cl->set_interpolation (ControlList::Linear);
223         CPPUNIT_ASSERT_EQUAL(3.6, cl->unlocked_eval(80.));
224         CPPUNIT_ASSERT_EQUAL(3.2, cl->unlocked_eval(120.));
225         CPPUNIT_ASSERT_EQUAL(1.6, cl->unlocked_eval(160.));
226         CPPUNIT_ASSERT_EQUAL(4.0, cl->unlocked_eval(250.));
227         CPPUNIT_ASSERT_EQUAL(8.5, cl->unlocked_eval(350.));
228         CPPUNIT_ASSERT_EQUAL(9.0, cl->unlocked_eval(999.));
229 }