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