~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to libs/ardour/test/playlist_read_test.cc

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#include "test_globals.h"
 
26
 
 
27
CPPUNIT_TEST_SUITE_REGISTRATION (PlaylistReadTest);
 
28
 
 
29
using namespace std;
 
30
using namespace ARDOUR;
 
31
 
 
32
void
 
33
PlaylistReadTest::setUp ()
 
34
{
 
35
        AudioRegionTest::setUp ();
 
36
 
 
37
        _N = 1024;
 
38
        _buf = new Sample[_N];
 
39
        _mbuf = new Sample[_N];
 
40
        _gbuf = new float[_N];
 
41
 
 
42
        //_session->config.set_auto_xfade (false);
 
43
 
 
44
        for (int i = 0; i < _N; ++i) {
 
45
                _buf[i] = 0;
 
46
        }
 
47
}
 
48
 
 
49
void
 
50
PlaylistReadTest::tearDown ()
 
51
{
 
52
        delete[] _buf;
 
53
        delete[] _mbuf;
 
54
        delete[] _gbuf;
 
55
 
 
56
        AudioRegionTest::tearDown ();
 
57
}
 
58
 
 
59
void
 
60
PlaylistReadTest::singleReadTest ()
 
61
{
 
62
        /* Single-region read with fades */
 
63
 
 
64
        _audio_playlist->add_region (_ar[0], 0);
 
65
        _ar[0]->set_default_fade_in ();
 
66
        _ar[0]->set_default_fade_out ();
 
67
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_in->back()->when);
 
68
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_out->back()->when);
 
69
        _ar[0]->set_length (1024);
 
70
        _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 256, 0);
 
71
        
 
72
        for (int i = 0; i < 64; ++i) {
 
73
                /* Note: this specific float casting is necessary so that the rounding
 
74
                   is done here the same as it is done in AudioPlaylist.
 
75
                */
 
76
                CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * float (i / 63.0)), _buf[i], 1e-16);
 
77
        }
 
78
        
 
79
        for (int i = 64; i < 256; ++i) {
 
80
                CPPUNIT_ASSERT_EQUAL (i, int (_buf[i]));
 
81
        }
 
82
}
 
83
 
 
84
void
 
85
PlaylistReadTest::overlappingReadTest ()
 
86
{
 
87
        /* Overlapping read; _ar[0] and _ar[1] are both 1024 frames long, _ar[0] starts at 0,
 
88
           _ar[1] starts at 128.  We test a read from 0 to 256, which should consist
 
89
           of the start of _ar[0], with its fade in, followed by _ar[1]'s fade in (mixed with _ar[0]
 
90
           faded out with the inverse gain), and some more of _ar[1].
 
91
        */
 
92
 
 
93
        _audio_playlist->add_region (_ar[0], 0);
 
94
        _ar[0]->set_default_fade_in ();
 
95
        _ar[0]->set_default_fade_out ();
 
96
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_in->back()->when);
 
97
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_out->back()->when);
 
98
        _ar[0]->set_length (1024);
 
99
 
 
100
#if 0
 
101
        /* Note: these are ordinary fades, not xfades */
 
102
        CPPUNIT_ASSERT_EQUAL (false, _ar[0]->fade_in_is_xfade());
 
103
        CPPUNIT_ASSERT_EQUAL (false, _ar[0]->fade_out_is_xfade());
 
104
#endif
 
105
        
 
106
        _audio_playlist->add_region (_ar[1], 128);
 
107
        _ar[1]->set_default_fade_in ();
 
108
        _ar[1]->set_default_fade_out ();
 
109
 
 
110
#if 0
 
111
        /* Note: these are ordinary fades, not xfades */
 
112
        CPPUNIT_ASSERT_EQUAL (false, _ar[1]->fade_in_is_xfade());
 
113
        CPPUNIT_ASSERT_EQUAL (false, _ar[1]->fade_out_is_xfade());
 
114
#endif
 
115
        
 
116
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[1]->_fade_in->back()->when);
 
117
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[1]->_fade_out->back()->when);
 
118
        
 
119
        _ar[1]->set_length (1024);
 
120
        _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 256, 0);
 
121
 
 
122
        /* _ar[0]'s fade in */
 
123
        for (int i = 0; i < 64; ++i) {
 
124
                /* Note: this specific float casting is necessary so that the rounding
 
125
                   is done here the same as it is done in AudioPlaylist; the gain factor
 
126
                   must be computed using double precision, with the result then cast
 
127
                   to float.
 
128
                */
 
129
                CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * float (i / (double) 63)), _buf[i], 1e-16);
 
130
        }
 
131
 
 
132
        /* bit of _ar[0] */
 
133
        for (int i = 64; i < 128; ++i) {
 
134
                CPPUNIT_ASSERT_EQUAL (i, int (_buf[i]));
 
135
        }
 
136
 
 
137
        /* _ar[1]'s fade in with faded-out _ar[0] */
 
138
        for (int i = 0; i < 64; ++i) {
 
139
                /* Similar carry-on to above with float rounding */
 
140
                float const from_ar0 = (128 + i) * float (1 - (i / (double) 63));
 
141
                float const from_ar1 = i * float (i / (double) 63);
 
142
                CPPUNIT_ASSERT_DOUBLES_EQUAL (from_ar0 + from_ar1, _buf[i + 128], 1e-16);
 
143
        }
 
144
}
 
145
 
 
146
void
 
147
PlaylistReadTest::transparentReadTest ()
 
148
{
 
149
        _audio_playlist->add_region (_ar[0], 0);
 
150
        _ar[0]->set_default_fade_in ();
 
151
        _ar[0]->set_default_fade_out ();
 
152
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_in->back()->when);
 
153
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_out->back()->when);
 
154
        _ar[0]->set_length (1024);
 
155
        
 
156
        _audio_playlist->add_region (_ar[1], 0);
 
157
        _ar[1]->set_default_fade_in ();
 
158
        _ar[1]->set_default_fade_out ();
 
159
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[1]->_fade_in->back()->when);
 
160
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[1]->_fade_out->back()->when);
 
161
        _ar[1]->set_length (1024);
 
162
        _ar[1]->set_opaque (false);
 
163
 
 
164
        _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 1024, 0);
 
165
 
 
166
        /* _ar[0] and _ar[1] fade-ins; _ar[1] is on top, but it is transparent, so
 
167
           its fade in will not affect _ar[0]; _ar[0] will just fade in by itself,
 
168
           and the two will be mixed.
 
169
        */
 
170
        for (int i = 0; i < 64; ++i) {
 
171
                float const fade = i / (double) 63;
 
172
                float const ar0 = i * fade;
 
173
                float const ar1 = i * fade;
 
174
                CPPUNIT_ASSERT_DOUBLES_EQUAL (ar0 + ar1, _buf[i], 1e-16);
 
175
        }
 
176
 
 
177
        /* _ar[0] and _ar[1] bodies, mixed */
 
178
        for (int i = 64; i < (1024 - 64); ++i) {
 
179
                CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * 2), _buf[i], 1e-16);
 
180
        }
 
181
 
 
182
        /* _ar[0] and _ar[1] fade-outs, mixed */
 
183
        for (int i = (1024 - 64); i < 1024; ++i) {
 
184
                /* Ardour fades out from 1 to VERY_SMALL_SIGNAL, which is 0.0000001,
 
185
                   so this fade out expression is a little long-winded.
 
186
                */
 
187
                float const fade = (((double) 1 - 0.0000001) / 63) * (1023 - i) + 0.0000001;
 
188
                float const ar0 = i * fade;
 
189
                float const ar1 = i * fade;
 
190
                CPPUNIT_ASSERT_DOUBLES_EQUAL (ar0 + ar1, _buf[i], 1e-16);
 
191
        }
 
192
}
 
193
 
 
194
/* A few tests just to check that nothing nasty is happening with
 
195
   memory corruption, really (for running with valgrind).
 
196
*/
 
197
void
 
198
PlaylistReadTest::miscReadTest ()
 
199
{
 
200
        _audio_playlist->add_region (_ar[0], 0);
 
201
        _ar[0]->set_default_fade_in ();
 
202
        _ar[0]->set_default_fade_out ();
 
203
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_in->back()->when);
 
204
        CPPUNIT_ASSERT_EQUAL (double (64), _ar[0]->_fade_out->back()->when);
 
205
        _ar[0]->set_length (128);
 
206
 
 
207
        /* Read for just longer than the region */
 
208
        _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 129, 0);
 
209
 
 
210
        /* Read for much longer than the region */
 
211
        _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 1024, 0);
 
212
 
 
213
        /* Read one sample */
 
214
        _audio_playlist->read (_buf, _mbuf, _gbuf, 53, 54, 0);
 
215
}
 
216
 
 
217
void
 
218
PlaylistReadTest::check_staircase (Sample* b, int offset, int N)
 
219
{
 
220
        for (int i = 0; i < N; ++i) {
 
221
                int const j = i + offset;
 
222
                CPPUNIT_ASSERT_EQUAL (j, int (b[i]));
 
223
        }
 
224
}
 
225
 
 
226
/* Check the case where we have
 
227
 *    |----------- Region A (transparent) ------------------|
 
228
 *                     |---- Region B (opaque) --|
 
229
 *
 
230
 * The result should be a mix of the two during region B's time.
 
231
 */
 
232
 
 
233
void
 
234
PlaylistReadTest::enclosedTransparentReadTest ()
 
235
{
 
236
        _audio_playlist->add_region (_ar[0], 256);
 
237
        /* These calls will result in a 64-sample fade */
 
238
        _ar[0]->set_fade_in_length (0);
 
239
        _ar[0]->set_fade_out_length (0);
 
240
        _ar[0]->set_length (256);
 
241
        
 
242
        _audio_playlist->add_region (_ar[1], 0);
 
243
        /* These calls will result in a 64-sample fade */
 
244
        _ar[1]->set_fade_in_length (0);
 
245
        _ar[1]->set_fade_out_length (0);
 
246
        _ar[1]->set_length (1024);
 
247
        _ar[1]->set_opaque (false);
 
248
 
 
249
        _audio_playlist->read (_buf, _mbuf, _gbuf, 0, 1024, 0);
 
250
 
 
251
        /* First 64 samples should just be _ar[1], faded in */
 
252
        for (int i = 0; i < 64; ++i) {
 
253
                CPPUNIT_ASSERT_DOUBLES_EQUAL (float (i * float (i / 63.0)), _buf[i], 1e-16);
 
254
        }
 
255
 
 
256
        /* Then some of _ar[1] with no fade */
 
257
        for (int i = 64; i < 256; ++i) {
 
258
                CPPUNIT_ASSERT_DOUBLES_EQUAL (i, _buf[i], 1e-16);
 
259
        }
 
260
 
 
261
        /* Then _ar[1] + _ar[0] (faded in) for 64 samples */
 
262
        for (int i = 256; i < (256 + 64); ++i) {
 
263
                CPPUNIT_ASSERT_DOUBLES_EQUAL (i + float ((i - 256) * float ((i - 256) / 63.0)), _buf[i], 1e-16);
 
264
        }
 
265
 
 
266
        /* Then _ar[1] + _ar[0] for 128 samples */
 
267
        for (int i = (256 + 64); i < (256 + 64 + 128); ++i) {
 
268
                CPPUNIT_ASSERT_DOUBLES_EQUAL (i + i - (256 + 64) + 64, _buf[i], 1e-16);
 
269
        }
 
270
        
 
271
        /* Then _ar[1] + _ar[0] (faded out) for 64 samples */
 
272
        for (int i = (256 + 64 + 128); i < 512; ++i) {
 
273
                float const ar0_without_fade = i - 256;
 
274
                /* See above regarding VERY_SMALL_SIGNAL SNAFU */
 
275
                float const fade = (((double) 1 - 0.0000001) / 63) * (511 - i) + 0.0000001;
 
276
                CPPUNIT_ASSERT_DOUBLES_EQUAL (i + float (ar0_without_fade * fade), _buf[i], 1e-16);
 
277
        }
 
278
 
 
279
        /* Then just _ar[1] for a while */
 
280
        for (int i = 512; i < (1024 - 64); ++i) {
 
281
                CPPUNIT_ASSERT_DOUBLES_EQUAL (i, _buf[i], 1e-16);
 
282
        }
 
283
 
 
284
        /* And finally _ar[1]'s fade out */
 
285
        for (int i = (1024 - 64); i < 1024; ++i) {
 
286
                /* See above regarding VERY_SMALL_SIGNAL SNAFU */
 
287
                float const fade = (((double) 1 - 0.0000001) / 63) * (1023 - i) + 0.0000001;
 
288
                CPPUNIT_ASSERT_DOUBLES_EQUAL (i * fade, _buf[i], 1e-16);
 
289
 
 
290
        }
 
291
}