ardour
playlist_read_test.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2012 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18 
19 #include "ardour/playlist.h"
20 #include "ardour/region.h"
21 #include "ardour/audioplaylist.h"
22 #include "ardour/audioregion.h"
23 #include "ardour/session.h"
24 #include "playlist_read_test.h"
25 
27 
28 using namespace std;
29 using namespace ARDOUR;
30 
31 void
33 {
35 
36  _N = 1024;
37  _buf = new Sample[_N];
38  _mbuf = new Sample[_N];
39  _gbuf = new float[_N];
40 
41  //_session->config.set_auto_xfade (false);
42 
43  for (int i = 0; i < _N; ++i) {
44  _buf[i] = 0;
45  }
46 }
47 
48 void
50 {
51  delete[] _buf;
52  delete[] _mbuf;
53  delete[] _gbuf;
54 
56 }
57 
58 void
60 {
61  /* Single-region read with fades */
62 
63  _audio_playlist->add_region (_ar[0], 0);
64  _ar[0]->set_default_fade_in ();
65  _ar[0]->set_default_fade_out ();
66  CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_in->back()->when);
67  CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_out->back()->when);
68  _ar[0]->set_length (1024);
69  _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 256, 0);
70 
71  for (int i = 0; i < 64; ++i) {
72  /* Note: this specific float casting is necessary so that the rounding
73  is done here the same as it is done in AudioPlaylist.
74  */
75  CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * float (i / 63.0)), _buf[i], 1e-16);
76  }
77 
78  for (int i = 64; i < 256; ++i) {
79  CPPUNIT_ASSERT_EQUAL (i, int (_buf[i]));
80  }
81 }
82 
83 void
85 {
86  /* Overlapping read; _ar[0] and _ar[1] are both 1024 frames long, _ar[0] starts at 0,
87  _ar[1] starts at 128. We test a read from 0 to 256, which should consist
88  of the start of _ar[0], with its fade in, followed by _ar[1]'s fade in (mixed with _ar[0]
89  faded out with the inverse gain), and some more of _ar[1].
90  */
91 
92  _audio_playlist->add_region (_ar[0], 0);
93  _ar[0]->set_default_fade_in ();
94  _ar[0]->set_default_fade_out ();
95  CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_in->back()->when);
96  CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_out->back()->when);
97  _ar[0]->set_length (1024);
98 
99 #if 0
100  /* Note: these are ordinary fades, not xfades */
101  CPPUNIT_ASSERT_EQUAL (false, _ar[0]->fade_in_is_xfade());
102  CPPUNIT_ASSERT_EQUAL (false, _ar[0]->fade_out_is_xfade());
103 #endif
104 
105  _audio_playlist->add_region (_ar[1], 128);
106  _ar[1]->set_default_fade_in ();
107  _ar[1]->set_default_fade_out ();
108 
109 #if 0
110  /* Note: these are ordinary fades, not xfades */
111  CPPUNIT_ASSERT_EQUAL (false, _ar[1]->fade_in_is_xfade());
112  CPPUNIT_ASSERT_EQUAL (false, _ar[1]->fade_out_is_xfade());
113 #endif
114 
115  CPPUNIT_ASSERT_EQUAL (double (64), _ar[1]->_fade_in->back()->when);
116  CPPUNIT_ASSERT_EQUAL (double (64), _ar[1]->_fade_out->back()->when);
117 
118  _ar[1]->set_length (1024);
119  _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 256, 0);
120 
121  /* _ar[0]'s fade in */
122  for (int i = 0; i < 64; ++i) {
123  /* Note: this specific float casting is necessary so that the rounding
124  is done here the same as it is done in AudioPlaylist; the gain factor
125  must be computed using double precision, with the result then cast
126  to float.
127  */
128  CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * float (i / (double) 63)), _buf[i], 1e-16);
129  }
130 
131  /* bit of _ar[0] */
132  for (int i = 64; i < 128; ++i) {
133  CPPUNIT_ASSERT_EQUAL (i, int (_buf[i]));
134  }
135 
136  /* _ar[1]'s fade in with faded-out _ar[0] */
137  for (int i = 0; i < 64; ++i) {
138  /* Similar carry-on to above with float rounding */
139  float const from_ar0 = (128 + i) * float (1 - (i / (double) 63));
140  float const from_ar1 = i * float (i / (double) 63);
141  CPPUNIT_ASSERT_DOUBLES_EQUAL (from_ar0 + from_ar1, _buf[i + 128], 1e-16);
142  }
143 }
144 
145 void
147 {
148  _audio_playlist->add_region (_ar[0], 0);
149  _ar[0]->set_default_fade_in ();
150  _ar[0]->set_default_fade_out ();
151  CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_in->back()->when);
152  CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_out->back()->when);
153  _ar[0]->set_length (1024);
154 
155  _audio_playlist->add_region (_ar[1], 0);
156  _ar[1]->set_default_fade_in ();
157  _ar[1]->set_default_fade_out ();
158  CPPUNIT_ASSERT_EQUAL (double (64), _ar[1]->_fade_in->back()->when);
159  CPPUNIT_ASSERT_EQUAL (double (64), _ar[1]->_fade_out->back()->when);
160  _ar[1]->set_length (1024);
161  _ar[1]->set_opaque (false);
162 
163  _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 1024, 0);
164 
165  /* _ar[0] and _ar[1] fade-ins; _ar[1] is on top, but it is transparent, so
166  its fade in will not affect _ar[0]; _ar[0] will just fade in by itself,
167  and the two will be mixed.
168  */
169  for (int i = 0; i < 64; ++i) {
170  float const fade = i / (double) 63;
171  float const ar0 = i * fade;
172  float const ar1 = i * fade;
173  CPPUNIT_ASSERT_DOUBLES_EQUAL (ar0 + ar1, _buf[i], 1e-16);
174  }
175 
176  /* _ar[0] and _ar[1] bodies, mixed */
177  for (int i = 64; i < (1024 - 64); ++i) {
178  CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * 2), _buf[i], 1e-16);
179  }
180 
181  /* _ar[0] and _ar[1] fade-outs, mixed */
182  for (int i = (1024 - 64); i < 1024; ++i) {
183  /* Ardour fades out from 1 to VERY_SMALL_SIGNAL, which is 0.0000001,
184  so this fade out expression is a little long-winded.
185  */
186  float const fade = (((double) 1 - 0.0000001) / 63) * (1023 - i) + 0.0000001;
187  float const ar0 = i * fade;
188  float const ar1 = i * fade;
189  CPPUNIT_ASSERT_DOUBLES_EQUAL (ar0 + ar1, _buf[i], 1e-16);
190  }
191 }
192 
193 /* A few tests just to check that nothing nasty is happening with
194  memory corruption, really (for running with valgrind).
195 */
196 void
198 {
199  _audio_playlist->add_region (_ar[0], 0);
200  _ar[0]->set_default_fade_in ();
201  _ar[0]->set_default_fade_out ();
202  CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_in->back()->when);
203  CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_out->back()->when);
204  _ar[0]->set_length (128);
205 
206  /* Read for just longer than the region */
207  _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 129, 0);
208 
209  /* Read for much longer than the region */
210  _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 1024, 0);
211 
212  /* Read one sample */
213  _audio_playlist->read (_buf, _mbuf, _gbuf, 53, 54, 0);
214 }
215 
216 void
218 {
219  for (int i = 0; i < N; ++i) {
220  int const j = i + offset;
221  CPPUNIT_ASSERT_EQUAL (j, int (b[i]));
222  }
223 }
224 
225 /* Check the case where we have
226  * |----------- Region A (transparent) ------------------|
227  * |---- Region B (opaque) --|
228  *
229  * The result should be a mix of the two during region B's time.
230  */
231 
232 void
234 {
235  _audio_playlist->add_region (_ar[0], 256);
236  /* These calls will result in a 64-sample fade */
237  _ar[0]->set_fade_in_length (0);
238  _ar[0]->set_fade_out_length (0);
239  _ar[0]->set_length (256);
240 
241  _audio_playlist->add_region (_ar[1], 0);
242  /* These calls will result in a 64-sample fade */
243  _ar[1]->set_fade_in_length (0);
244  _ar[1]->set_fade_out_length (0);
245  _ar[1]->set_length (1024);
246  _ar[1]->set_opaque (false);
247 
248  _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 1024, 0);
249 
250  /* First 64 samples should just be _ar[1], faded in */
251  for (int i = 0; i < 64; ++i) {
252  CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * float (i / 63.0)), _buf[i], 1e-16);
253  }
254 
255  /* Then some of _ar[1] with no fade */
256  for (int i = 64; i < 256; ++i) {
257  CPPUNIT_ASSERT_DOUBLES_EQUAL (i, _buf[i], 1e-16);
258  }
259 
260  /* Then _ar[1] + _ar[0] (faded in) for 64 samples */
261  for (int i = 256; i < (256 + 64); ++i) {
262  CPPUNIT_ASSERT_DOUBLES_EQUAL (i + float ((i - 256) * float ((i - 256) / 63.0)), _buf[i], 1e-16);
263  }
264 
265  /* Then _ar[1] + _ar[0] for 128 samples */
266  for (int i = (256 + 64); i < (256 + 64 + 128); ++i) {
267  CPPUNIT_ASSERT_DOUBLES_EQUAL (i + i - (256 + 64) + 64, _buf[i], 1e-16);
268  }
269 
270  /* Then _ar[1] + _ar[0] (faded out) for 64 samples */
271  for (int i = (256 + 64 + 128); i < 512; ++i) {
272  float const ar0_without_fade = i - 256;
273  /* See above regarding VERY_SMALL_SIGNAL SNAFU */
274  float const fade = (((double) 1 - 0.0000001) / 63) * (511 - i) + 0.0000001;
275  CPPUNIT_ASSERT_DOUBLES_EQUAL (i + float (ar0_without_fade * fade), _buf[i], 1e-16);
276  }
277 
278  /* Then just _ar[1] for a while */
279  for (int i = 512; i < (1024 - 64); ++i) {
280  CPPUNIT_ASSERT_DOUBLES_EQUAL (i, _buf[i], 1e-16);
281  }
282 
283  /* And finally _ar[1]'s fade out */
284  for (int i = (1024 - 64); i < 1024; ++i) {
285  /* See above regarding VERY_SMALL_SIGNAL SNAFU */
286  float const fade = (((double) 1 - 0.0000001) / 63) * (1023 - i) + 0.0000001;
287  CPPUNIT_ASSERT_DOUBLES_EQUAL (i * fade, _buf[i], 1e-16);
288 
289  }
290 }
virtual void tearDown()
static int N
Definition: signals_test.cc:27
Definition: Beats.hpp:239
CPPUNIT_TEST_SUITE_REGISTRATION(PlaylistReadTest)
float Sample
Definition: types.h:54
Definition: amp.h:29
void check_staircase(ARDOUR::Sample *, int, int)
virtual void setUp()