Fairly major change to the way in which crossfades are handled;
[ardour.git] / libs / ardour / test / playlist_read_test.cc
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"
8
9 CPPUNIT_TEST_SUITE_REGISTRATION (PlaylistReadTest);
10
11 using namespace std;
12 using namespace ARDOUR;
13
14 void
15 PlaylistReadTest::setUp ()
16 {
17         TestNeedingPlaylistAndRegions::setUp ();
18
19         _N = 1024;
20         _buf = new Sample[_N];
21         _mbuf = new Sample[_N];
22         _gbuf = new float[_N];
23
24         _session->config.set_auto_xfade (false);
25
26         _apl = boost::dynamic_pointer_cast<AudioPlaylist> (_playlist);
27
28         for (int i = 0; i < _N; ++i) {
29                 _buf[i] = 0;
30         }
31 }
32
33 void
34 PlaylistReadTest::tearDown ()
35 {
36         delete[] _buf;
37         delete[] _mbuf;
38         delete[] _gbuf;
39
40         _apl.reset ();
41
42         TestNeedingPlaylistAndRegions::tearDown ();
43 }
44
45 void
46 PlaylistReadTest::singleReadTest ()
47 {
48         /* Single-region read with fades */
49
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);
59         
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.
63                 */
64                 CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * float (i / 63.0)), _buf[i], 1e-16);
65         }
66         
67         for (int i = 64; i < 256; ++i) {
68                 CPPUNIT_ASSERT_EQUAL (i, int (_buf[i]));
69         }
70 }
71
72 void
73 PlaylistReadTest::overlappingReadTest ()
74 {
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            and some more of ar1.
79         */
80
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);
89         
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 ();
95         
96         CPPUNIT_ASSERT_EQUAL (double (64), ar1->_fade_in->back()->when);
97         CPPUNIT_ASSERT_EQUAL (double (64), ar1->_fade_out->back()->when);
98         
99         ar1->set_length (1024);
100         _apl->read (_buf, _mbuf, _gbuf, 0, 256, 0);
101
102         /* ar0's fade in */
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.
106                 */
107                 CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * float (i / 63.0)), _buf[i], 1e-16);
108         }
109
110         /* bit of ar0 */
111         for (int i = 64; i < 128; ++i) {
112                 CPPUNIT_ASSERT_EQUAL (i, int (_buf[i]));
113         }
114
115         /* ar1's fade in */
116         for (int i = 0; i < 64; ++i) {
117                 /* Similar carry-on to above with float rounding */
118                 CPPUNIT_ASSERT_DOUBLES_EQUAL (i + 128 + float (i * float (i / 63.0)), _buf[i + 128], 1e-4);
119         }
120 }
121
122 void
123 PlaylistReadTest::transparentReadTest ()
124 {
125         boost::shared_ptr<AudioRegion> ar0 = boost::dynamic_pointer_cast<AudioRegion> (_region[0]);
126         ar0->set_name ("ar0");
127         _apl->add_region (ar0, 0);
128         ar0->set_default_fade_in ();
129         ar0->set_default_fade_out ();
130         CPPUNIT_ASSERT_EQUAL (double (64), ar0->_fade_in->back()->when);
131         CPPUNIT_ASSERT_EQUAL (double (64), ar0->_fade_out->back()->when);
132         ar0->set_length (1024);
133         
134         boost::shared_ptr<AudioRegion> ar1 = boost::dynamic_pointer_cast<AudioRegion> (_region[1]);
135         ar1->set_name ("ar1");
136         _apl->add_region (ar1, 0);
137         ar1->set_default_fade_in ();
138         ar1->set_default_fade_out ();
139         CPPUNIT_ASSERT_EQUAL (double (64), ar1->_fade_in->back()->when);
140         CPPUNIT_ASSERT_EQUAL (double (64), ar1->_fade_out->back()->when);
141         ar1->set_length (1024);
142         ar1->set_opaque (false);
143
144         _apl->read (_buf, _mbuf, _gbuf, 0, 1024, 0);
145
146         /* ar0 and ar1 fade-ins, mixed */
147         for (int i = 0; i < 64; ++i) {
148                 float const fade = i / 63.0;
149                 CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * fade) * 2, _buf[i], 1e-16);
150         }
151
152         /* ar0 and ar1 bodies, mixed */
153         for (int i = 64; i < (1024 - 64); ++i) {
154                 CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * 2), _buf[i], 1e-16);
155         }
156
157         /* ar0 and ar1 fade-outs, mixed */
158         for (int i = (1024 - 64); i < 1024; ++i) {
159                 float const fade = (1023 - i) / 63.0;
160                 CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * fade) * 2, _buf[i], 1e-16);
161         }
162 }
163
164 void
165 PlaylistReadTest::check_staircase (Sample* b, int offset, int N)
166 {
167         for (int i = 0; i < N; ++i) {
168                 int const j = i + offset;
169                 CPPUNIT_ASSERT_EQUAL (j, int (b[i]));
170         }
171 }