ardour
combine_regions_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 "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"
25 
27 
28 using namespace std;
29 using namespace ARDOUR;
30 
31 void
33 {
34  ARDOUR::Sample buf[512];
35  ARDOUR::Sample mbuf[512];
36  float gbuf[512];
37 
38  /* Read from the playlist */
39  _audio_playlist->read (buf, mbuf, gbuf, 0, 256 * 2 - 128, 0);
40 
41  /* _r[0]'s fade in */
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);
46  }
47 
48  /* Some more of _r[0] */
49  for (int i = 64; i < 128; ++i) {
50  CPPUNIT_ASSERT_DOUBLES_EQUAL (i, buf[i], 1e-16);
51  }
52 
53  float fade_in[128];
54  float fade_out[128];
55 
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);
58 
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.
61  */
62  for (int i = 128; i < 256; ++i) {
63 
64  float region_fade_out = 1;
65  if (i >= 192) {
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.
68  */
69  region_fade_out = (((double) 1 - 0.0000001) / 63) * (255 - i) + 0.0000001;
70  }
71 
72  /* This computation of r0 cannot be compressed into one line, or there
73  is a small floating point `error'
74  */
75  float r0 = i * region_fade_out;
76  r0 *= fade_out[i - 128];
77 
78  float const r1 = (i - 128) * fade_in[i - 128];
79  CPPUNIT_ASSERT_DOUBLES_EQUAL (r0 + r1, buf[i], 1e-16);
80  }
81 
82  /* Rest of _r[1] */
83  for (int i = 256; i < (384 - 64); ++i) {
84  CPPUNIT_ASSERT_DOUBLES_EQUAL (i - 128, buf[i], 1e-16);
85  }
86 
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);
91  }
92 }
93 
97 void
99 {
100  /* Two regions, both 256 frames in length, overlapping by 128 frames in the middle */
101 
102  _ar[0]->set_default_fade_in ();
103  _ar[0]->set_default_fade_out ();
104  _ar[1]->set_default_fade_out ();
105 
106  _playlist->add_region (_r[0], 0);
107  _r[0]->set_length (256);
108 
109  _playlist->add_region (_r[1], 128);
110  _r[1]->set_length (256);
111 
112  /* Check layering */
113  CPPUNIT_ASSERT_EQUAL (layer_t (0), _r[0]->layer ());
114  CPPUNIT_ASSERT_EQUAL (layer_t (1), _r[1]->layer ());
115 
116 #if 0
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 ());
122 #endif
123 
124  /* Check that the read comes back correctly */
125  check_crossfade1 ();
126 
127  /* Combine the two regions */
128 
129  RegionList rl;
130  rl.push_back (_r[0]);
131  rl.push_back (_r[1]);
132  _playlist->combine (rl);
133 
134  /* ...so we just have the one region... */
135  CPPUNIT_ASSERT_EQUAL ((uint32_t) 1, _playlist->n_regions ());
136 
137  /* And reading should give the same thing */
138  check_crossfade1 ();
139 }
140 
141 void
143 {
144  ARDOUR::Sample buf[512];
145  ARDOUR::Sample mbuf[512];
146  float gbuf[512];
147 
148  /* Read from the playlist */
149  _audio_playlist->read (buf, mbuf, gbuf, 0, 256 * 2 - 128, 0);
150 
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);
156  }
157 
158  /* Some more of _r[0] */
159  for (int i = 64; i < 128; ++i) {
160  CPPUNIT_ASSERT_DOUBLES_EQUAL (i, buf[i], 1e-16);
161  }
162 
163  float fade_in[128];
164  float fade_out[128];
165 
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);
168 
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.
171  */
172  for (int i = 128; i < 256; ++i) {
173 
174  float region_fade_in = 1;
175  if (i < (128 + 64)) {
176  region_fade_in = (i - 128) / ((double) 63);
177  }
178 
179  float r0 = i * fade_out[i - 128];
180  float r1 = (i - 128) * region_fade_in;
181  r1 *= fade_in[i - 128];
182 
183  CPPUNIT_ASSERT_DOUBLES_EQUAL (r0 + r1, buf[i], 1e-16);
184  }
185 
186  /* Rest of _r[1] */
187  for (int i = 256; i < (384 - 64); ++i) {
188  CPPUNIT_ASSERT_DOUBLES_EQUAL (i - 128, buf[i], 1e-16);
189  }
190 
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);
195  }
196 }
197 
201 void
203 {
204  /* Two regions, both 256 frames in length, overlapping by 128 frames in the middle */
205 
206  _ar[0]->set_default_fade_in ();
207  _ar[0]->set_default_fade_out ();
208  _ar[1]->set_default_fade_out ();
209 
210  _playlist->add_region (_r[0], 0);
211  _r[0]->set_length (256);
212 
213  _playlist->add_region (_r[1], 128);
214  _r[1]->set_length (256);
215 
216  _r[1]->lower_to_bottom ();
217 
218  /* Check layering */
219  CPPUNIT_ASSERT_EQUAL (layer_t (1), _r[0]->layer ());
220  CPPUNIT_ASSERT_EQUAL (layer_t (0), _r[1]->layer ());
221 
222 #if 0
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 ());
228 #endif
229 
230  /* Check that the read comes back correctly */
231  check_crossfade2 ();
232 
233  /* Combine the two regions */
234 
235  RegionList rl;
236  rl.push_back (_r[0]);
237  rl.push_back (_r[1]);
238  _playlist->combine (rl);
239 
240  /* ...so we just have the one region... */
241  CPPUNIT_ASSERT_EQUAL ((uint32_t) 1, _playlist->n_regions ());
242 
243  /* And reading should give the same thing */
244  check_crossfade2 ();
245 }
246 
LIBARDOUR_API PBD::PropertyDescriptor< layer_t > layer
Definition: region.cc:67
Definition: Beats.hpp:239
float Sample
Definition: types.h:54
Definition: amp.h:29
CPPUNIT_TEST_SUITE_REGISTRATION(CombineRegionsTest)
LIBARDOUR_API PBD::PropertyDescriptor< boost::shared_ptr< AutomationList > > fade_out
Definition: audioregion.cc:69
LIBARDOUR_API PBD::PropertyDescriptor< boost::shared_ptr< AutomationList > > fade_in
Definition: audioregion.cc:67
uint32_t layer_t
Definition: types.h:59
std::list< boost::shared_ptr< Region > > RegionList
Definition: types.h:87