Missing library from test link list.
[dcpomatic.git] / test / audio_buffers_test.cc
1 /*
2     Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 /** @file  test/audio_buffers_test.cc
22  *  @brief Test AudioBuffers class.
23  *  @ingroup selfcontained
24  */
25
26 #include <cmath>
27 #include <boost/test/unit_test.hpp>
28 #include "lib/audio_buffers.h"
29
30 using std::pow;
31
32 static float tolerance = 1e-3;
33
34 static float
35 random_float ()
36 {
37         return float (rand ()) / RAND_MAX;
38 }
39
40 static void
41 random_fill (AudioBuffers& buffers)
42 {
43         for (int i = 0; i < buffers.frames(); ++i) {
44                 for (int j = 0; j < buffers.channels(); ++j) {
45                         buffers.data(j)[i] = random_float ();
46                 }
47         }
48 }
49
50 static void
51 random_check (AudioBuffers& buffers, int from, int frames)
52 {
53         for (int i = from; i < (from + frames); ++i) {
54                 for (int j = 0; j < buffers.channels(); ++j) {
55                         BOOST_CHECK_CLOSE (buffers.data(j)[i], random_float (), tolerance);
56                 }
57         }
58 }
59
60 /** Basic setup */
61 BOOST_AUTO_TEST_CASE (audio_buffers_setup_test)
62 {
63         AudioBuffers buffers (4, 9155);
64
65         BOOST_CHECK (buffers.data ());
66         for (int i = 0; i < 4; ++i) {
67                 BOOST_CHECK (buffers.data (i));
68         }
69
70         BOOST_CHECK_EQUAL (buffers.channels(), 4);
71         BOOST_CHECK_EQUAL (buffers.frames(), 9155);
72 }
73
74 /** Extending some buffers */
75 BOOST_AUTO_TEST_CASE (audio_buffers_extend_test)
76 {
77         AudioBuffers buffers (3, 150);
78         srand (1);
79         random_fill (buffers);
80
81         /* Extend */
82         buffers.ensure_size (299);
83
84         srand (1);
85         random_check (buffers, 0, 150);
86
87         /* New space should be silent */
88         for (int i = 150; i < 299; ++i) {
89                 for (int c = 0; c < 3; ++c) {
90                         BOOST_CHECK_EQUAL (buffers.data(c)[i], 0);
91                 }
92         }
93 }
94
95 /** make_silent() */
96 BOOST_AUTO_TEST_CASE (audio_buffers_make_silent_test)
97 {
98         AudioBuffers buffers (9, 9933);
99         srand (2);
100         random_fill (buffers);
101
102         buffers.make_silent ();
103
104         for (int i = 0; i < 9933; ++i) {
105                 for (int c = 0; c < 9; ++c) {
106                         BOOST_CHECK_EQUAL (buffers.data(c)[i], 0);
107                 }
108         }
109 }
110
111 /** make_silent (int c) */
112 BOOST_AUTO_TEST_CASE (audio_buffers_make_silent_channel_test)
113 {
114         AudioBuffers buffers (9, 9933);
115         srand (3);
116         random_fill (buffers);
117
118         buffers.make_silent (4);
119
120         srand (3);
121         for (int i = 0; i < 9933; ++i) {
122                 for (int c = 0; c < 9; ++c) {
123                         if (c == 4) {
124                                 random_float ();
125                                 BOOST_CHECK_EQUAL (buffers.data(c)[i], 0);
126                         } else {
127                                 BOOST_CHECK_CLOSE (buffers.data(c)[i], random_float (), tolerance);
128                         }
129                 }
130         }
131 }
132
133 /** make_silent (int from, int frames) */
134 BOOST_AUTO_TEST_CASE (audio_buffers_make_silent_part_test)
135 {
136         AudioBuffers buffers (9, 9933);
137         srand (4);
138         random_fill (buffers);
139
140         buffers.make_silent (145, 833);
141
142         srand (4);
143         for (int i = 0; i < 145; ++i) {
144                 for (int c = 0; c < 9; ++c) {
145                         BOOST_CHECK_EQUAL (buffers.data(c)[i], random_float ());
146                 }
147         }
148
149         for (int i = 145; i < (145 + 833); ++i) {
150                 for (int c = 0; c < 9; ++c) {
151                         random_float ();
152                         BOOST_CHECK_EQUAL (buffers.data(c)[i], 0);
153                 }
154         }
155
156         for (int i = (145 + 833); i < 9933; ++i) {
157                 for (int c = 0; c < 9; ++c) {
158                         BOOST_CHECK_EQUAL (buffers.data(c)[i], random_float ());
159                 }
160         }
161 }
162
163 /* apply_gain */
164 BOOST_AUTO_TEST_CASE (audio_buffers_apply_gain)
165 {
166         AudioBuffers buffers (2, 417315);
167         srand (9);
168         random_fill (buffers);
169
170         buffers.apply_gain (5.4);
171
172         srand (9);
173         for (int i = 0; i < 417315; ++i) {
174                 for (int c = 0; c < 2; ++c) {
175                         BOOST_CHECK_CLOSE (buffers.data(c)[i], random_float() * pow (10, 5.4 / 20), tolerance);
176                 }
177         }
178 }
179
180 /* copy_from */
181 BOOST_AUTO_TEST_CASE (audio_buffers_copy_from)
182 {
183         AudioBuffers a (5, 63711);
184         AudioBuffers b (5, 12345);
185
186         srand (42);
187         random_fill (a);
188
189         srand (99);
190         random_fill (b);
191
192         a.copy_from (&b, 517, 233, 194);
193
194         /* Re-seed a's generator and check the numbers that came from it */
195
196         /* First part; not copied-over */
197         srand (42);
198         random_check (a, 0, 194);
199
200         /* Second part; copied-over (just burn generator a's numbers) */
201         for (int i = 0; i < (517 * 5); ++i) {
202                 random_float ();
203         }
204
205         /* Third part; not copied-over */
206         random_check (a, 194 + 517, a.frames() - 194 - 517);
207
208         /* Re-seed b's generator and check the numbers that came from it */
209         srand (99);
210
211         /* First part; burn */
212         for (int i = 0; i < 194 * 5; ++i) {
213                 random_float ();
214         }
215
216         /* Second part; copied */
217         random_check (b, 194, 517);
218 }
219
220 /* move */
221 BOOST_AUTO_TEST_CASE (audio_buffers_move)
222 {
223         AudioBuffers buffers (7, 65536);
224
225         srand (84);
226         random_fill (buffers);
227
228         int const from = 888;
229         int const to = 666;
230         int const frames = 444;
231
232         buffers.move (frames, from, to);
233
234         /* Re-seed and check the un-moved parts */
235         srand (84);
236
237         random_check (buffers, 0, to);
238
239         /* Burn a few */
240         for (int i = 0; i < (from - to + frames) * 7; ++i) {
241                 random_float ();
242         }
243
244         random_check (buffers, from + frames, 65536 - frames - from);
245
246         /* Re-seed and check the moved part */
247         srand (84);
248
249         /* Burn a few */
250         for (int i = 0; i < from * 7; ++i) {
251                 random_float ();
252         }
253
254         random_check (buffers, to, frames);
255 }
256
257 /** accumulate_channel */
258 BOOST_AUTO_TEST_CASE (audio_buffers_accumulate_channel)
259 {
260         AudioBuffers a (3, 256);
261         srand (38);
262         random_fill (a);
263
264         AudioBuffers b (3, 256);
265         random_fill (b);
266
267         a.accumulate_channel (&b, 2, 1, 1.2);
268
269         srand (38);
270         for (int i = 0; i < 256; ++i) {
271                 for (int c = 0; c < 3; ++c) {
272                         float const A = random_float ();
273                         if (c == 1) {
274                                 BOOST_CHECK_CLOSE (a.data(c)[i], A + b.data(2)[i] * 1.2, tolerance);
275                         } else {
276                                 BOOST_CHECK_CLOSE (a.data(c)[i], A, tolerance);
277                         }
278                 }
279         }
280 }
281
282 /** accumulate_frames */
283 BOOST_AUTO_TEST_CASE (audio_buffers_accumulate_frames)
284 {
285         AudioBuffers a (3, 256);
286         srand (38);
287         random_fill (a);
288
289         AudioBuffers b (3, 256);
290         random_fill (b);
291
292         a.accumulate_frames (&b, 129, 91, 44);
293
294         srand (38);
295         for (int i = 0; i < 256; ++i) {
296                 for (int c = 0; c < 3; ++c) {
297                         float const A = random_float ();
298                         if (i < 44 || i >= (44 + 129)) {
299                                 BOOST_CHECK_CLOSE (a.data(c)[i], A, tolerance);
300                         } else {
301                                 BOOST_CHECK_CLOSE (a.data(c)[i], A + b.data(c)[i + 91 - 44], tolerance);
302                         }
303                 }
304         }
305 }