2
Copyright (C) 2012 Paul Davis
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.
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.
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.
19
#include "combine_regions_test.h"
20
#include "ardour/types.h"
21
#include "ardour/audioplaylist.h"
22
#include "ardour/region.h"
23
#include "ardour/audioregion.h"
24
#include "evoral/Curve.hpp"
26
CPPUNIT_TEST_SUITE_REGISTRATION (CombineRegionsTest);
29
using namespace ARDOUR;
32
CombineRegionsTest::check_crossfade1 ()
34
ARDOUR::Sample buf[512];
35
ARDOUR::Sample mbuf[512];
38
/* Read from the playlist */
39
_audio_playlist->read (buf, mbuf, gbuf, 0, 256 * 2 - 128, 0);
42
for (int i = 0; i < 64; ++i) {
43
float const fade = i / (double) 63;
44
float const r0 = i * fade;
45
CPPUNIT_ASSERT_DOUBLES_EQUAL (r0, buf[i], 1e-16);
48
/* Some more of _r[0] */
49
for (int i = 64; i < 128; ++i) {
50
CPPUNIT_ASSERT_DOUBLES_EQUAL (i, buf[i], 1e-16);
56
_ar[1]->fade_in()->curve().get_vector (0, 128, fade_in, 128);
57
_ar[1]->inverse_fade_in()->curve().get_vector (0, 128, fade_out, 128);
59
/* Crossfading _r[0] to _r[1] using _r[1]'s fade in and inverse fade in.
60
_r[0] also has a standard region fade out to add to the fun.
62
for (int i = 128; i < 256; ++i) {
64
float region_fade_out = 1;
66
/* Ardour fades out from 1 to VERY_SMALL_SIGNAL, which is 0.0000001,
67
so this fade out expression is a little long-winded.
69
region_fade_out = (((double) 1 - 0.0000001) / 63) * (255 - i) + 0.0000001;
72
/* This computation of r0 cannot be compressed into one line, or there
73
is a small floating point `error'
75
float r0 = i * region_fade_out;
76
r0 *= fade_out[i - 128];
78
float const r1 = (i - 128) * fade_in[i - 128];
79
CPPUNIT_ASSERT_DOUBLES_EQUAL (r0 + r1, buf[i], 1e-16);
83
for (int i = 256; i < (384 - 64); ++i) {
84
CPPUNIT_ASSERT_DOUBLES_EQUAL (i - 128, buf[i], 1e-16);
87
/* And _r[1]'s fade out */
88
for (int i = (384 - 64); i < 384; ++i) {
89
float const fade_out = (((double) 1 - 0.0000001) / 63) * (383 - i) + 0.0000001;
90
CPPUNIT_ASSERT_DOUBLES_EQUAL ((i - 128) * fade_out, buf[i], 1e-16);
94
/** Test combining two cross-faded regions, with the earlier region
98
CombineRegionsTest::crossfadeTest1 ()
100
/* Two regions, both 256 frames in length, overlapping by 128 frames in the middle */
102
_ar[0]->set_default_fade_in ();
103
_ar[0]->set_default_fade_out ();
104
_ar[1]->set_default_fade_out ();
106
_playlist->add_region (_r[0], 0);
107
_r[0]->set_length (256);
109
_playlist->add_region (_r[1], 128);
110
_r[1]->set_length (256);
113
CPPUNIT_ASSERT_EQUAL (layer_t (0), _r[0]->layer ());
114
CPPUNIT_ASSERT_EQUAL (layer_t (1), _r[1]->layer ());
117
/* Check that the right fades have been set up */
118
CPPUNIT_ASSERT_EQUAL (false, _ar[0]->fade_in_is_xfade ());
119
CPPUNIT_ASSERT_EQUAL (false, _ar[0]->fade_out_is_xfade ());
120
CPPUNIT_ASSERT_EQUAL (true, _ar[1]->fade_in_is_xfade ());
121
CPPUNIT_ASSERT_EQUAL (false, _ar[1]->fade_out_is_xfade ());
124
/* Check that the read comes back correctly */
127
/* Combine the two regions */
130
rl.push_back (_r[0]);
131
rl.push_back (_r[1]);
132
_playlist->combine (rl);
134
/* ...so we just have the one region... */
135
CPPUNIT_ASSERT_EQUAL ((uint32_t) 1, _playlist->n_regions ());
137
/* And reading should give the same thing */
142
CombineRegionsTest::check_crossfade2 ()
144
ARDOUR::Sample buf[512];
145
ARDOUR::Sample mbuf[512];
148
/* Read from the playlist */
149
_audio_playlist->read (buf, mbuf, gbuf, 0, 256 * 2 - 128, 0);
151
/* _r[0]'s fade in */
152
for (int i = 0; i < 64; ++i) {
153
float const fade = i / (double) 63;
154
float const r0 = i * fade;
155
CPPUNIT_ASSERT_DOUBLES_EQUAL (r0, buf[i], 1e-16);
158
/* Some more of _r[0] */
159
for (int i = 64; i < 128; ++i) {
160
CPPUNIT_ASSERT_DOUBLES_EQUAL (i, buf[i], 1e-16);
166
_ar[0]->inverse_fade_out()->curve().get_vector (0, 128, fade_in, 128);
167
_ar[0]->fade_out()->curve().get_vector (0, 128, fade_out, 128);
169
/* Crossfading _r[0] to _r[1] using _r[0]'s fade out and inverse fade out.
170
_r[1] also has a standard region fade in to add to the fun.
172
for (int i = 128; i < 256; ++i) {
174
float region_fade_in = 1;
175
if (i < (128 + 64)) {
176
region_fade_in = (i - 128) / ((double) 63);
179
float r0 = i * fade_out[i - 128];
180
float r1 = (i - 128) * region_fade_in;
181
r1 *= fade_in[i - 128];
183
CPPUNIT_ASSERT_DOUBLES_EQUAL (r0 + r1, buf[i], 1e-16);
187
for (int i = 256; i < (384 - 64); ++i) {
188
CPPUNIT_ASSERT_DOUBLES_EQUAL (i - 128, buf[i], 1e-16);
191
/* And _r[1]'s fade out */
192
for (int i = (384 - 64); i < 384; ++i) {
193
float const fade_out = (((double) 1 - 0.0000001) / 63) * (383 - i) + 0.0000001;
194
CPPUNIT_ASSERT_DOUBLES_EQUAL ((i - 128) * fade_out, buf[i], 1e-16);
198
/** As per crossfadeTest1, except that the earlier region is on the
202
CombineRegionsTest::crossfadeTest2 ()
204
/* Two regions, both 256 frames in length, overlapping by 128 frames in the middle */
206
_ar[0]->set_default_fade_in ();
207
_ar[0]->set_default_fade_out ();
208
_ar[1]->set_default_fade_out ();
210
_playlist->add_region (_r[0], 0);
211
_r[0]->set_length (256);
213
_playlist->add_region (_r[1], 128);
214
_r[1]->set_length (256);
216
_r[1]->lower_to_bottom ();
219
CPPUNIT_ASSERT_EQUAL (layer_t (1), _r[0]->layer ());
220
CPPUNIT_ASSERT_EQUAL (layer_t (0), _r[1]->layer ());
223
/* Check that the right fades have been set up */
224
CPPUNIT_ASSERT_EQUAL (false, _ar[0]->fade_in_is_xfade ());
225
CPPUNIT_ASSERT_EQUAL (true, _ar[0]->fade_out_is_xfade ());
226
CPPUNIT_ASSERT_EQUAL (false, _ar[1]->fade_in_is_xfade ());
227
CPPUNIT_ASSERT_EQUAL (false, _ar[1]->fade_out_is_xfade ());
230
/* Check that the read comes back correctly */
233
/* Combine the two regions */
236
rl.push_back (_r[0]);
237
rl.push_back (_r[1]);
238
_playlist->combine (rl);
240
/* ...so we just have the one region... */
241
CPPUNIT_ASSERT_EQUAL ((uint32_t) 1, _playlist->n_regions ());
243
/* And reading should give the same thing */