1 #include "ardour/playlist.h"
2 #include "ardour/region.h"
3 #include "ardour/audioplaylist.h"
4 #include "ardour/audioregion.h"
5 #include "ardour/session.h"
6 #include "playlist_read_test.h"
7 #include "test_globals.h"
9 CPPUNIT_TEST_SUITE_REGISTRATION (PlaylistReadTest);
12 using namespace ARDOUR;
15 PlaylistReadTest::setUp ()
17 TestNeedingPlaylistAndRegions::setUp ();
20 _buf = new Sample[_N];
21 _mbuf = new Sample[_N];
22 _gbuf = new float[_N];
24 _session->config.set_auto_xfade (false);
26 _apl = boost::dynamic_pointer_cast<AudioPlaylist> (_playlist);
28 for (int i = 0; i < _N; ++i) {
34 PlaylistReadTest::tearDown ()
42 TestNeedingPlaylistAndRegions::tearDown ();
46 PlaylistReadTest::singleReadTest ()
48 /* Single-region read with fades */
50 boost::shared_ptr<AudioRegion> ar0 = boost::dynamic_pointer_cast<AudioRegion> (_region[0]);
51 ar0->set_name ("ar0");
52 _apl->add_region (ar0, 0);
53 ar0->set_default_fade_in ();
54 ar0->set_default_fade_out ();
55 CPPUNIT_ASSERT_EQUAL (double (64), ar0->_fade_in->back()->when);
56 CPPUNIT_ASSERT_EQUAL (double (64), ar0->_fade_out->back()->when);
57 ar0->set_length (1024);
58 _apl->read (_buf, _mbuf, _gbuf, 0, 256, 0);
60 for (int i = 0; i < 64; ++i) {
61 /* Note: this specific float casting is necessary so that the rounding
62 is done here the same as it is done in AudioPlaylist.
64 CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * float (i / 63.0)), _buf[i], 1e-16);
67 for (int i = 64; i < 256; ++i) {
68 CPPUNIT_ASSERT_EQUAL (i, int (_buf[i]));
73 PlaylistReadTest::overlappingReadTest ()
75 /* Overlapping read; ar0 and ar1 are both 1024 frames long, ar0 starts at 0,
76 ar1 starts at 128. We test a read from 0 to 256, which should consist
77 of the start of ar0, with its fade in, followed by ar1's fade in (mixed with ar0
78 faded out with the inverse gain), and some more of ar1.
81 boost::shared_ptr<AudioRegion> ar0 = boost::dynamic_pointer_cast<AudioRegion> (_region[0]);
82 ar0->set_name ("ar0");
83 _apl->add_region (ar0, 0);
84 ar0->set_default_fade_in ();
85 ar0->set_default_fade_out ();
86 CPPUNIT_ASSERT_EQUAL (double (64), ar0->_fade_in->back()->when);
87 CPPUNIT_ASSERT_EQUAL (double (64), ar0->_fade_out->back()->when);
88 ar0->set_length (1024);
90 boost::shared_ptr<AudioRegion> ar1 = boost::dynamic_pointer_cast<AudioRegion> (_region[1]);
91 ar1->set_name ("ar1");
92 _apl->add_region (ar1, 128);
93 ar1->set_default_fade_in ();
94 ar1->set_default_fade_out ();
96 CPPUNIT_ASSERT_EQUAL (double (64), ar1->_fade_in->back()->when);
97 CPPUNIT_ASSERT_EQUAL (double (64), ar1->_fade_out->back()->when);
99 ar1->set_length (1024);
100 _apl->read (_buf, _mbuf, _gbuf, 0, 256, 0);
103 for (int i = 0; i < 64; ++i) {
104 /* Note: this specific float casting is necessary so that the rounding
105 is done here the same as it is done in AudioPlaylist; the gain factor
106 must be computed using double precision, with the result then cast
109 CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * float (i / (double) 63)), _buf[i], 1e-16);
113 for (int i = 64; i < 128; ++i) {
114 CPPUNIT_ASSERT_EQUAL (i, int (_buf[i]));
117 /* ar1's fade in with faded-out ar0 */
118 for (int i = 0; i < 64; ++i) {
119 /* Similar carry-on to above with float rounding */
120 float const from_ar0 = (128 + i) * float (1 - (i / (double) 63));
121 float const from_ar1 = i * float (i / (double) 63);
122 CPPUNIT_ASSERT_DOUBLES_EQUAL (from_ar0 + from_ar1, _buf[i + 128], 1e-16);
127 PlaylistReadTest::transparentReadTest ()
129 boost::shared_ptr<AudioRegion> ar0 = boost::dynamic_pointer_cast<AudioRegion> (_region[0]);
130 ar0->set_name ("ar0");
131 _apl->add_region (ar0, 0);
132 ar0->set_default_fade_in ();
133 ar0->set_default_fade_out ();
134 CPPUNIT_ASSERT_EQUAL (double (64), ar0->_fade_in->back()->when);
135 CPPUNIT_ASSERT_EQUAL (double (64), ar0->_fade_out->back()->when);
136 ar0->set_length (1024);
138 boost::shared_ptr<AudioRegion> ar1 = boost::dynamic_pointer_cast<AudioRegion> (_region[1]);
139 ar1->set_name ("ar1");
140 _apl->add_region (ar1, 0);
141 ar1->set_default_fade_in ();
142 ar1->set_default_fade_out ();
143 CPPUNIT_ASSERT_EQUAL (double (64), ar1->_fade_in->back()->when);
144 CPPUNIT_ASSERT_EQUAL (double (64), ar1->_fade_out->back()->when);
145 ar1->set_length (1024);
146 ar1->set_opaque (false);
148 _apl->read (_buf, _mbuf, _gbuf, 0, 1024, 0);
150 /* ar0 and ar1 fade-ins; ar1 is on top, but it is transparent, so
151 its fade in will not affect ar0; ar0 will just fade in by itself,
152 and the two will be mixed.
154 for (int i = 0; i < 64; ++i) {
155 float const fade = i / (double) 63;
156 float const ar0 = i * fade;
157 float const ar1 = i * fade;
158 CPPUNIT_ASSERT_DOUBLES_EQUAL (ar0 + ar1, _buf[i], 1e-16);
161 /* ar0 and ar1 bodies, mixed */
162 for (int i = 64; i < (1024 - 64); ++i) {
163 CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * 2), _buf[i], 1e-16);
166 /* ar0 and ar1 fade-outs, mixed */
167 for (int i = (1024 - 64); i < 1024; ++i) {
168 /* Ardour fades out from 1 to VERY_SMALL_SIGNAL, which is 0.0000001,
169 so this fade out expression is a little long-winded.
171 float const fade = (((double) 1 - 0.0000001) / 63) * (1023 - i) + 0.0000001;
172 float const ar0 = i * fade;
173 float const ar1 = i * fade;
174 CPPUNIT_ASSERT_DOUBLES_EQUAL (ar0 + ar1, _buf[i], 1e-16);
178 /* A few tests just to check that nothing nasty is happening with
179 memory corruption, really (for running with valgrind).
182 PlaylistReadTest::miscReadTest ()
184 boost::shared_ptr<AudioRegion> ar0 = boost::dynamic_pointer_cast<AudioRegion> (_region[0]);
185 ar0->set_name ("ar0");
186 _apl->add_region (ar0, 0);
187 ar0->set_default_fade_in ();
188 ar0->set_default_fade_out ();
189 CPPUNIT_ASSERT_EQUAL (double (64), ar0->_fade_in->back()->when);
190 CPPUNIT_ASSERT_EQUAL (double (64), ar0->_fade_out->back()->when);
191 ar0->set_length (128);
193 /* Read for just longer than the region */
194 _apl->read (_buf, _mbuf, _gbuf, 0, 129, 0);
196 /* Read for much longer than the region */
197 _apl->read (_buf, _mbuf, _gbuf, 0, 1024, 0);
199 /* Read one sample */
200 _apl->read (_buf, _mbuf, _gbuf, 53, 54, 0);
204 PlaylistReadTest::check_staircase (Sample* b, int offset, int N)
206 for (int i = 0; i < N; ++i) {
207 int const j = i + offset;
208 CPPUNIT_ASSERT_EQUAL (j, int (b[i]));