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 cout << setprecision(12);
80 cout << "\t\ti=" << i << " fade_out=" << fade_out[i - 128] << " r1=" << r1 << " r0=" << r0 << "\n";
81 CPPUNIT_ASSERT_DOUBLES_EQUAL (r0 + r1, buf[i], 1e-16);
85 for (int i = 256; i < (384 - 64); ++i) {
86 CPPUNIT_ASSERT_DOUBLES_EQUAL (i - 128, buf[i], 1e-16);
89 /* And _r[1]'s fade out */
90 for (int i = (384 - 64); i < 384; ++i) {
91 float const fade_out = (((double) 1 - 0.0000001) / 63) * (383 - i) + 0.0000001;
92 CPPUNIT_ASSERT_DOUBLES_EQUAL ((i - 128) * fade_out, buf[i], 1e-16);
96 /** Test combining two cross-faded regions, with the earlier region
100 CombineRegionsTest::crossfadeTest1 ()
102 /* Two regions, both 256 frames in length, overlapping by 128 frames in the middle */
104 _ar[0]->set_default_fade_in ();
105 _ar[0]->set_default_fade_out ();
106 _ar[1]->set_default_fade_out ();
108 _playlist->add_region (_r[0], 0);
109 _r[0]->set_length (256);
111 _playlist->add_region (_r[1], 128);
112 _r[1]->set_length (256);
115 CPPUNIT_ASSERT_EQUAL (layer_t (0), _r[0]->layer ());
116 CPPUNIT_ASSERT_EQUAL (layer_t (1), _r[1]->layer ());
118 /* Check that the right fades have been set up */
119 CPPUNIT_ASSERT_EQUAL (false, _ar[0]->fade_in_is_xfade ());
120 CPPUNIT_ASSERT_EQUAL (false, _ar[0]->fade_out_is_xfade ());
121 CPPUNIT_ASSERT_EQUAL (true, _ar[1]->fade_in_is_xfade ());
122 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 cout << setprecision(12);
184 cout << "\t\ti=" << i << " fade_out=" << fade_out[i - 128] << " r1=" << r1 << " r0=" << r0 << "\n";
185 CPPUNIT_ASSERT_DOUBLES_EQUAL (r0 + r1, buf[i], 1e-16);
189 for (int i = 256; i < (384 - 64); ++i) {
190 CPPUNIT_ASSERT_DOUBLES_EQUAL (i - 128, buf[i], 1e-16);
193 /* And _r[1]'s fade out */
194 for (int i = (384 - 64); i < 384; ++i) {
195 float const fade_out = (((double) 1 - 0.0000001) / 63) * (383 - i) + 0.0000001;
196 CPPUNIT_ASSERT_DOUBLES_EQUAL ((i - 128) * fade_out, buf[i], 1e-16);
200 /** As per crossfadeTest1, except that the earlier region is on the
204 CombineRegionsTest::crossfadeTest2 ()
206 cout << "\n\n\nCOMBINE\n";
208 /* Two regions, both 256 frames in length, overlapping by 128 frames in the middle */
210 _ar[0]->set_default_fade_in ();
211 _ar[0]->set_default_fade_out ();
212 _ar[1]->set_default_fade_out ();
214 _playlist->add_region (_r[0], 0);
215 _r[0]->set_length (256);
217 _playlist->add_region (_r[1], 128);
218 _r[1]->set_length (256);
220 _r[1]->lower_to_bottom ();
223 CPPUNIT_ASSERT_EQUAL (layer_t (1), _r[0]->layer ());
224 CPPUNIT_ASSERT_EQUAL (layer_t (0), _r[1]->layer ());
226 /* Check that the right fades have been set up */
228 CPPUNIT_ASSERT_EQUAL (false, _ar[0]->fade_in_is_xfade ());
229 CPPUNIT_ASSERT_EQUAL (true, _ar[0]->fade_out_is_xfade ());
230 CPPUNIT_ASSERT_EQUAL (false, _ar[1]->fade_in_is_xfade ());
231 CPPUNIT_ASSERT_EQUAL (false, _ar[1]->fade_out_is_xfade ());
233 /* Check that the read comes back correctly */
234 cout << "\n\n\nFIRST READ\n";
237 /* Combine the two regions */
240 rl.push_back (_r[0]);
241 rl.push_back (_r[1]);
242 _playlist->combine (rl);
244 /* ...so we just have the one region... */
245 CPPUNIT_ASSERT_EQUAL ((uint32_t) 1, _playlist->n_regions ());
247 /* And reading should give the same thing */
248 cout << "\n\n\SECOND READ\n";