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