Fill test disk partitions with random noise to expose more bugs.
[dcpomatic.git] / test / audio_ring_buffers_test.cc
1 /*
2     Copyright (C) 2016-2018 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 #include "lib/audio_ring_buffers.h"
22 #include <boost/test/unit_test.hpp>
23 #include <iostream>
24
25 using std::cout;
26 using std::make_shared;
27 using std::shared_ptr;
28 using namespace dcpomatic;
29
30 #define CANARY 9999
31
32 /* XXX: these tests don't check the timestamping in AudioRingBuffers */
33
34 /** Basic tests fetching the same number of channels as went in */
35 BOOST_AUTO_TEST_CASE (audio_ring_buffers_test1)
36 {
37         AudioRingBuffers rb;
38
39         /* Should start off empty */
40         BOOST_CHECK_EQUAL (rb.size(), 0);
41
42         /* Getting some data should give an underrun and write zeros */
43         float buffer[256 * 6];
44         buffer[240 * 6] = CANARY;
45         BOOST_CHECK (!rb.get(buffer, 6, 240));
46         for (int i = 0; i < 240 * 6; ++i) {
47                 BOOST_REQUIRE_EQUAL (buffer[i], 0);
48         }
49         BOOST_CHECK_EQUAL (buffer[240 * 6], CANARY);
50
51         /* clear() should give the same result */
52         rb.clear ();
53         BOOST_CHECK_EQUAL (rb.size(), 0);
54         buffer[240 * 6] = CANARY;
55         BOOST_CHECK (rb.get(buffer, 6, 240) == boost::optional<DCPTime>());
56         for (int i = 0; i < 240 * 6; ++i) {
57                 BOOST_REQUIRE_EQUAL (buffer[i], 0);
58         }
59         BOOST_CHECK_EQUAL (buffer[240 * 6], CANARY);
60
61         /* Put some data in */
62         auto data = make_shared<AudioBuffers>(6, 91);
63         int value = 0;
64         for (int i = 0; i < 91; ++i) {
65                 for (int j = 0; j < 6; ++j) {
66                         data->data(j)[i] = value++;
67                 }
68         }
69         rb.put (data, DCPTime(), 48000);
70         BOOST_CHECK_EQUAL (rb.size(), 91);
71
72         /* Get part of it out */
73         buffer[40 * 6] = CANARY;
74         BOOST_CHECK (*rb.get(buffer, 6, 40) == DCPTime());
75         int check = 0;
76         for (int i = 0; i < 40 * 6; ++i) {
77                 BOOST_REQUIRE_EQUAL (buffer[i], check++);
78         }
79         BOOST_CHECK_EQUAL (buffer[40 * 6], CANARY);
80         BOOST_CHECK_EQUAL (rb.size(), 51);
81
82         /* Get the rest */
83         buffer[51 * 6] = CANARY;
84         BOOST_CHECK (*rb.get(buffer, 6, 51) == DCPTime::from_frames(40, 48000));
85         for (int i = 0; i < 51 * 6; ++i) {
86                 BOOST_REQUIRE_EQUAL (buffer[i], check++);
87         }
88         BOOST_CHECK_EQUAL (buffer[51 * 6], CANARY);
89         BOOST_CHECK_EQUAL (rb.size(), 0);
90
91         /* Now there should be an underrun */
92         buffer[240 * 6] = CANARY;
93         BOOST_CHECK (!rb.get(buffer, 6, 240));
94         BOOST_CHECK_EQUAL (buffer[240 * 6], CANARY);
95 }
96
97 /** Similar tests but fetching more channels than were put in */
98 BOOST_AUTO_TEST_CASE (audio_ring_buffers_test2)
99 {
100         AudioRingBuffers rb;
101
102         /* Put some data in */
103         auto data = make_shared<AudioBuffers>(2, 91);
104         int value = 0;
105         for (int i = 0; i < 91; ++i) {
106                 for (int j = 0; j < 2; ++j) {
107                         data->data(j)[i] = value++;
108                 }
109         }
110         rb.put (data, DCPTime(), 48000);
111         BOOST_CHECK_EQUAL (rb.size(), 91);
112
113         /* Get part of it out */
114         float buffer[256 * 6];
115         buffer[40 * 6] = CANARY;
116         BOOST_CHECK (*rb.get(buffer, 6, 40) == DCPTime());
117         int check = 0;
118         for (int i = 0; i < 40; ++i) {
119                 for (int j = 0; j < 2; ++j) {
120                         BOOST_REQUIRE_EQUAL (buffer[i * 6 + j], check++);
121                 }
122                 for (int j = 2; j < 6; ++j) {
123                         BOOST_REQUIRE_EQUAL (buffer[i * 6 + j], 0);
124                 }
125         }
126         BOOST_CHECK_EQUAL (buffer[40 * 6], CANARY);
127         BOOST_CHECK_EQUAL (rb.size(), 51);
128
129         /* Get the rest */
130         buffer[51 * 6] = CANARY;
131         BOOST_CHECK (*rb.get(buffer, 6, 51) == DCPTime::from_frames(40, 48000));
132         for (int i = 0; i < 51; ++i) {
133                 for (int j = 0; j < 2; ++j) {
134                         BOOST_REQUIRE_EQUAL (buffer[i * 6 + j], check++);
135                 }
136                 for (int j = 2; j < 6; ++j) {
137                         BOOST_REQUIRE_EQUAL (buffer[i * 6 + j], 0);
138                 }
139         }
140         BOOST_CHECK_EQUAL (buffer[51 * 6], CANARY);
141         BOOST_CHECK_EQUAL (rb.size(), 0);
142
143         /* Now there should be an underrun */
144         buffer[240 * 6] = CANARY;
145         BOOST_CHECK (!rb.get(buffer, 6, 240));
146         BOOST_CHECK_EQUAL (buffer[240 * 6], CANARY);
147 }
148
149 /** Similar tests but fetching fewer channels than were put in */
150 BOOST_AUTO_TEST_CASE (audio_ring_buffers_test3)
151 {
152         AudioRingBuffers rb;
153
154         /* Put some data in */
155         auto data = make_shared<AudioBuffers>(6, 91);
156         int value = 0;
157         for (int i = 0; i < 91; ++i) {
158                 for (int j = 0; j < 6; ++j) {
159                         data->data(j)[i] = value++;
160                 }
161         }
162         rb.put (data, DCPTime(), 48000);
163         BOOST_CHECK_EQUAL (rb.size(), 91);
164
165         /* Get part of it out */
166         float buffer[256 * 6];
167         buffer[40 * 2] = CANARY;
168         BOOST_CHECK (*rb.get(buffer, 2, 40) == DCPTime());
169         int check = 0;
170         for (int i = 0; i < 40; ++i) {
171                 for (int j = 0; j < 2; ++j) {
172                         BOOST_REQUIRE_EQUAL (buffer[i * 2 + j], check++);
173                 }
174                 check += 4;
175         }
176         BOOST_CHECK_EQUAL (buffer[40 * 2], CANARY);
177         BOOST_CHECK_EQUAL (rb.size(), 51);
178
179         /* Get the rest */
180         buffer[51 * 2] = CANARY;
181         BOOST_CHECK (*rb.get(buffer, 2, 51) == DCPTime::from_frames(40, 48000));
182         for (int i = 0; i < 51; ++i) {
183                 for (int j = 0; j < 2; ++j)  {
184                         BOOST_REQUIRE_EQUAL (buffer[i * 2 + j], check++);
185                 }
186                 check += 4;
187         }
188         BOOST_CHECK_EQUAL (buffer[51 * 2], CANARY);
189         BOOST_CHECK_EQUAL (rb.size(), 0);
190
191         /* Now there should be an underrun */
192         buffer[240 * 2] = CANARY;
193         BOOST_CHECK (!rb.get(buffer, 2, 240));
194         BOOST_CHECK_EQUAL (buffer[240 * 2], CANARY);
195 }