Fix merging of audio in various circumstances.
[dcpomatic.git] / test / dcpomatic_time_test.cc
1 /*
2     Copyright (C) 2015-2017 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/dcpomatic_time.h"
22 #include <boost/test/unit_test.hpp>
23 #include <list>
24
25 using std::list;
26
27 BOOST_AUTO_TEST_CASE (dcpomatic_time_test)
28 {
29         FrameRateChange frc (24, 48);
30         int j = 0;
31         int k = 0;
32         for (int64_t i = 0; i < 62000; i += 2000) {
33                 DCPTime d (i);
34                 ContentTime c (d, frc);
35                 BOOST_CHECK_EQUAL (c.frames_floor (24.0), j);
36                 ++k;
37                 if (k == 2) {
38                         ++j;
39                         k = 0;
40                 }
41         }
42 }
43
44 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_overlaps_test)
45 {
46         /* Taking times as the start of a sampling interval
47
48            |--|--|--|--|--|--|--|--|--|--|
49            0  1  2  3  4  5  6  7  8  9  |
50            |--|--|--|--|--|--|--|--|--|--|
51
52            <------a----><----b----->
53
54            and saying `from' is the start of the first sampling
55            interval and `to' is the start of the interval after
56            the period... a and b do not overlap.
57         */
58
59         TimePeriod<DCPTime> a (DCPTime (0), DCPTime (4));
60         TimePeriod<DCPTime> b (DCPTime (4), DCPTime (8));
61         BOOST_CHECK (!a.overlap (b));
62
63         /* Some more obvious non-overlaps */
64         a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
65         b = TimePeriod<DCPTime> (DCPTime (5), DCPTime (8));
66         BOOST_CHECK (!a.overlap (b));
67
68         /* Some overlaps */
69         a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
70         b = TimePeriod<DCPTime> (DCPTime (3), DCPTime (8));
71         BOOST_CHECK (a.overlap(b));
72         BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(3), DCPTime(4)));
73         a = TimePeriod<DCPTime> (DCPTime (1), DCPTime (9));
74         b = TimePeriod<DCPTime> (DCPTime (0), DCPTime (10));
75         BOOST_CHECK (a.overlap(b));
76         BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(1), DCPTime(9)));
77 }
78
79 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test1)
80 {
81         DCPTimePeriod A (DCPTime (0), DCPTime (106));
82         list<DCPTimePeriod> B;
83         B.push_back (DCPTimePeriod (DCPTime (0), DCPTime (42)));
84         B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
85         B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (106)));
86         list<DCPTimePeriod> r = subtract (A, B);
87         list<DCPTimePeriod>::const_iterator i = r.begin ();
88         BOOST_REQUIRE (i != r.end ());
89         BOOST_CHECK (i->from == DCPTime (42));
90         BOOST_CHECK (i->to == DCPTime (52));
91         ++i;
92         BOOST_REQUIRE (i != r.end ());
93         BOOST_CHECK (i->from == DCPTime (91));
94         BOOST_CHECK (i->to == DCPTime (94));
95         ++i;
96         BOOST_REQUIRE (i == r.end ());
97 }
98
99 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test2)
100 {
101         DCPTimePeriod A (DCPTime (0), DCPTime (106));
102         list<DCPTimePeriod> B;
103         B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
104         B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
105         B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (106)));
106         list<DCPTimePeriod> r = subtract (A, B);
107         list<DCPTimePeriod>::const_iterator i = r.begin ();
108         BOOST_REQUIRE (i != r.end ());
109         BOOST_CHECK (i->from == DCPTime (0));
110         BOOST_CHECK (i->to == DCPTime (14));
111         ++i;
112         BOOST_REQUIRE (i != r.end ());
113         BOOST_CHECK (i->from == DCPTime (42));
114         BOOST_CHECK (i->to == DCPTime (52));
115         ++i;
116         BOOST_REQUIRE (i != r.end ());
117         BOOST_CHECK (i->from == DCPTime (91));
118         BOOST_CHECK (i->to == DCPTime (94));
119         ++i;
120         BOOST_REQUIRE (i == r.end ());
121 }
122
123 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test3)
124 {
125         DCPTimePeriod A (DCPTime (0), DCPTime (106));
126         list<DCPTimePeriod> B;
127         B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
128         B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
129         B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (99)));
130         list<DCPTimePeriod> r = subtract (A, B);
131         list<DCPTimePeriod>::const_iterator i = r.begin ();
132         BOOST_REQUIRE (i != r.end ());
133         BOOST_CHECK (i->from == DCPTime (0));
134         BOOST_CHECK (i->to == DCPTime (14));
135         ++i;
136         BOOST_REQUIRE (i != r.end ());
137         BOOST_CHECK (i->from == DCPTime (42));
138         BOOST_CHECK (i->to == DCPTime (52));
139         ++i;
140         BOOST_REQUIRE (i != r.end ());
141         BOOST_CHECK (i->from == DCPTime (91));
142         BOOST_CHECK (i->to == DCPTime (94));
143         ++i;
144         BOOST_REQUIRE (i != r.end ());
145         BOOST_CHECK (i->from == DCPTime (99));
146         BOOST_CHECK (i->to == DCPTime (106));
147         ++i;
148         BOOST_REQUIRE (i == r.end ());
149 }
150
151 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test4)
152 {
153         DCPTimePeriod A (DCPTime (0), DCPTime (106));
154         list<DCPTimePeriod> B;
155         list<DCPTimePeriod> r = subtract (A, B);
156         list<DCPTimePeriod>::const_iterator i = r.begin ();
157         BOOST_REQUIRE (i != r.end ());
158         BOOST_CHECK (i->from == DCPTime (0));
159         BOOST_CHECK (i->to == DCPTime (106));
160         ++i;
161         BOOST_REQUIRE (i == r.end ());
162 }
163
164 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test5)
165 {
166         DCPTimePeriod A (DCPTime (0), DCPTime (106));
167         list<DCPTimePeriod> B;
168         B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
169         B.push_back (DCPTimePeriod (DCPTime (42), DCPTime (91)));
170         B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (99)));
171         list<DCPTimePeriod> r = subtract (A, B);
172         list<DCPTimePeriod>::const_iterator i = r.begin ();
173         BOOST_REQUIRE (i != r.end ());
174         BOOST_CHECK (i->from == DCPTime (0));
175         BOOST_CHECK (i->to == DCPTime (14));
176         ++i;
177         BOOST_REQUIRE (i != r.end ());
178         BOOST_CHECK (i->from ==DCPTime (91));
179         BOOST_CHECK (i->to == DCPTime (94));
180         ++i;
181         BOOST_REQUIRE (i != r.end ());
182         BOOST_CHECK (i->from == DCPTime (99));
183         BOOST_CHECK (i->to == DCPTime (106));
184         ++i;
185         BOOST_REQUIRE (i == r.end ());
186 }
187
188 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test6)
189 {
190         DCPTimePeriod A (DCPTime (0), DCPTime (106));
191         list<DCPTimePeriod> B;
192         B.push_back (DCPTimePeriod (DCPTime (0), DCPTime (42)));
193         B.push_back (DCPTimePeriod (DCPTime (42), DCPTime (91)));
194         B.push_back (DCPTimePeriod (DCPTime (91), DCPTime (106)));
195         list<DCPTimePeriod> r = subtract (A, B);
196         BOOST_CHECK (r.empty());
197 }
198
199 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test7)
200 {
201         DCPTimePeriod A (DCPTime (228), DCPTime (356));
202         list<DCPTimePeriod> B;
203         B.push_back (DCPTimePeriod (DCPTime (34), DCPTime (162)));
204         list<DCPTimePeriod> r = subtract (A, B);
205         list<DCPTimePeriod>::const_iterator i = r.begin ();
206         BOOST_REQUIRE (i != r.end ());
207         BOOST_CHECK (i->from == DCPTime (228));
208         BOOST_CHECK (i->to == DCPTime (356));
209         ++i;
210         BOOST_REQUIRE (i == r.end ());
211 }