Rename TYPE_DEBUG_PLAYER to TYPE_DEBUG_VIDEO_VIEW.
[dcpomatic.git] / src / lib / audio_buffers.cc
1 /*
2     Copyright (C) 2012-2020 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 "util.h"
22 #include "audio_buffers.h"
23 #include "dcpomatic_assert.h"
24 #include <cassert>
25 #include <cstring>
26 #include <cmath>
27 #include <stdexcept>
28
29 using std::bad_alloc;
30 using boost::shared_ptr;
31
32 /** Construct an AudioBuffers.  Audio data is undefined after this constructor.
33  *  @param channels Number of channels.
34  *  @param frames Number of frames to reserve space for.
35  */
36 AudioBuffers::AudioBuffers (int channels, int32_t frames)
37 {
38         allocate (channels, frames);
39 }
40
41 /** Copy constructor.
42  *  @param other Other AudioBuffers; data is copied.
43  */
44 AudioBuffers::AudioBuffers (AudioBuffers const & other)
45 {
46         allocate (other._channels, other._frames);
47         copy_from (&other, other._frames, 0, 0);
48 }
49
50 AudioBuffers::AudioBuffers (boost::shared_ptr<const AudioBuffers> other)
51 {
52         allocate (other->_channels, other->_frames);
53         copy_from (other.get(), other->_frames, 0, 0);
54 }
55
56 AudioBuffers::AudioBuffers (boost::shared_ptr<const AudioBuffers> other, int32_t frames_to_copy, int32_t read_offset)
57 {
58         allocate (other->_channels, frames_to_copy);
59         copy_from (other.get(), frames_to_copy, read_offset, 0);
60 }
61
62 AudioBuffers &
63 AudioBuffers::operator= (AudioBuffers const & other)
64 {
65         if (this == &other) {
66                 return *this;
67         }
68
69         deallocate ();
70         allocate (other._channels, other._frames);
71         copy_from (&other, other._frames, 0, 0);
72
73         return *this;
74 }
75
76 /** AudioBuffers destructor */
77 AudioBuffers::~AudioBuffers ()
78 {
79         deallocate ();
80 }
81
82 void
83 AudioBuffers::allocate (int channels, int32_t frames)
84 {
85         DCPOMATIC_ASSERT (frames >= 0);
86         DCPOMATIC_ASSERT (channels >= 0);
87
88         _channels = channels;
89         _frames = frames;
90         _allocated_frames = frames;
91
92         _data = static_cast<float**> (malloc (_channels * sizeof (float *)));
93         if (!_data) {
94                 throw bad_alloc ();
95         }
96
97         for (int i = 0; i < _channels; ++i) {
98                 _data[i] = static_cast<float*> (malloc (frames * sizeof (float)));
99                 if (!_data[i]) {
100                         throw bad_alloc ();
101                 }
102         }
103 }
104
105 void
106 AudioBuffers::deallocate ()
107 {
108         for (int i = 0; i < _channels; ++i) {
109                 free (_data[i]);
110         }
111
112         free (_data);
113 }
114
115 /** @param c Channel index.
116  *  @return Buffer for this channel.
117  */
118 float*
119 AudioBuffers::data (int c) const
120 {
121         DCPOMATIC_ASSERT (c >= 0 && c < _channels);
122         return _data[c];
123 }
124
125 /** Set the number of frames that these AudioBuffers will report themselves
126  *  as having.  If we reduce the number of frames, the `lost' frames will
127  *  be silenced.
128  *  @param f Frames; must be less than or equal to the number of allocated frames.
129  */
130 void
131 AudioBuffers::set_frames (int32_t f)
132 {
133         DCPOMATIC_ASSERT (f <= _allocated_frames);
134
135         if (f < _frames) {
136                 make_silent (f, _frames - f);
137         }
138         _frames = f;
139 }
140
141 /** Make all frames silent */
142 void
143 AudioBuffers::make_silent ()
144 {
145         for (int i = 0; i < _channels; ++i) {
146                 make_silent (i);
147         }
148 }
149
150 /** Make all samples on a given channel silent.
151  *  @param c Channel.
152  */
153 void
154 AudioBuffers::make_silent (int c)
155 {
156         DCPOMATIC_ASSERT (c >= 0 && c < _channels);
157
158         /* This isn't really allowed, as all-bits-0 is not guaranteed to mean a 0 float,
159            but it seems that we can get away with it.
160         */
161         memset (_data[c], 0, _frames * sizeof(float));
162 }
163
164 /** Make some frames.
165  *  @param from Start frame.
166  *  @param frames Number of frames to silence.
167  */
168 void
169 AudioBuffers::make_silent (int32_t from, int32_t frames)
170 {
171         DCPOMATIC_ASSERT ((from + frames) <= _allocated_frames);
172
173         for (int c = 0; c < _channels; ++c) {
174                 /* This isn't really allowed, as all-bits-0 is not guaranteed to mean a 0 float,
175                    but it seems that we can get away with it.
176                 */
177                 memset (_data[c] + from, 0, frames * sizeof(float));
178         }
179 }
180
181 /** Copy data from another AudioBuffers to this one.  All channels are copied.
182  *  @param from AudioBuffers to copy from; must have the same number of channels as this.
183  *  @param frames_to_copy Number of frames to copy.
184  *  @param read_offset Offset to read from in `from'.
185  *  @param write_offset Offset to write to in `to'.
186  */
187 void
188 AudioBuffers::copy_from (AudioBuffers const * from, int32_t frames_to_copy, int32_t read_offset, int32_t write_offset)
189 {
190         if (frames_to_copy == 0) {
191                 /* Prevent the asserts from firing if there is nothing to do */
192                 return;
193         }
194
195         DCPOMATIC_ASSERT (from->channels() == channels());
196
197         DCPOMATIC_ASSERT (from);
198         DCPOMATIC_ASSERT (read_offset >= 0 && (read_offset + frames_to_copy) <= from->_allocated_frames);
199         DCPOMATIC_ASSERT (write_offset >= 0 && (write_offset + frames_to_copy) <= _allocated_frames);
200
201         for (int i = 0; i < _channels; ++i) {
202                 memcpy (_data[i] + write_offset, from->_data[i] + read_offset, frames_to_copy * sizeof(float));
203         }
204 }
205
206 /** Move audio data around.
207  *  @param from Offset to move from.
208  *  @param to Offset to move to.
209  *  @param frames Number of frames to move.
210  */
211 void
212 AudioBuffers::move (int32_t frames, int32_t from, int32_t to)
213 {
214         if (frames == 0) {
215                 return;
216         }
217
218         DCPOMATIC_ASSERT (from >= 0);
219         DCPOMATIC_ASSERT (from < _frames);
220         DCPOMATIC_ASSERT (to >= 0);
221         DCPOMATIC_ASSERT (to < _frames);
222         DCPOMATIC_ASSERT (frames > 0);
223         DCPOMATIC_ASSERT (frames <= _frames);
224         DCPOMATIC_ASSERT ((from + frames) <= _frames);
225         DCPOMATIC_ASSERT ((to + frames) <= _allocated_frames);
226
227         for (int i = 0; i < _channels; ++i) {
228                 memmove (_data[i] + to, _data[i] + from, frames * sizeof(float));
229         }
230 }
231
232 /** Add data from from `from', `from_channel' to our channel `to_channel'.
233  *  @param from Buffers to copy data from.
234  *  @param from_channel Channel index to read in \p from.
235  *  @param to_channel Channel index to accumulate into.
236  *  @param gain Linear gain to apply to the data before it is added.
237  */
238 void
239 AudioBuffers::accumulate_channel (AudioBuffers const * from, int from_channel, int to_channel, float gain)
240 {
241         int const N = frames ();
242         DCPOMATIC_ASSERT (from->frames() == N);
243         DCPOMATIC_ASSERT (to_channel <= _channels);
244
245         float* s = from->data (from_channel);
246         float* d = _data[to_channel];
247
248         for (int i = 0; i < N; ++i) {
249                 *d++ += (*s++) * gain;
250         }
251 }
252
253 /** Ensure we have space for at least a certain number of frames.  If we extend
254  *  the buffers, fill the new space with silence.
255  */
256 void
257 AudioBuffers::ensure_size (int32_t frames)
258 {
259         if (_allocated_frames >= frames) {
260                 return;
261         }
262
263         /* Round up frames to the next power of 2 to reduce the number
264            of realloc()s that are necessary.
265         */
266         frames--;
267         frames |= frames >> 1;
268         frames |= frames >> 2;
269         frames |= frames >> 4;
270         frames |= frames >> 8;
271         frames |= frames >> 16;
272         frames++;
273
274         for (int i = 0; i < _channels; ++i) {
275                 _data[i] = static_cast<float*> (realloc (_data[i], frames * sizeof (float)));
276                 if (!_data[i]) {
277                         throw bad_alloc ();
278                 }
279         }
280
281         int32_t const old_allocated = _allocated_frames;
282         _allocated_frames = frames;
283         if (old_allocated < _allocated_frames) {
284                 make_silent (old_allocated, _allocated_frames - old_allocated);
285         }
286 }
287
288 /** Mix some other buffers with these ones.  The AudioBuffers must have the same number of channels.
289  *  @param from Audio buffers to get data from.
290  *  @param frames Number of frames to mix.
291  *  @param read_offset Offset within `from' to read from.
292  *  @param write_offset Offset within this to mix into.
293  */
294 void
295 AudioBuffers::accumulate_frames (AudioBuffers const * from, int32_t frames, int32_t read_offset, int32_t write_offset)
296 {
297         DCPOMATIC_ASSERT (_channels == from->channels ());
298         DCPOMATIC_ASSERT (read_offset >= 0);
299         DCPOMATIC_ASSERT (write_offset >= 0);
300
301         float** from_data = from->data ();
302         for (int i = 0; i < _channels; ++i) {
303                 for (int j = 0; j < frames; ++j) {
304                         _data[i][j + write_offset] += from_data[i][j + read_offset];
305                 }
306         }
307 }
308
309 /** @param dB gain in dB */
310 void
311 AudioBuffers::apply_gain (float dB)
312 {
313         float const linear = db_to_linear (dB);
314
315         for (int i = 0; i < _channels; ++i) {
316                 for (int j = 0; j < _frames; ++j) {
317                         _data[i][j] *= linear;
318                 }
319         }
320 }
321
322 /** @param c Channel index.
323  *  @return AudioBuffers object containing only channel `c' from this AudioBuffers.
324  */
325 shared_ptr<AudioBuffers>
326 AudioBuffers::channel (int c) const
327 {
328         shared_ptr<AudioBuffers> o (new AudioBuffers (1, frames ()));
329         o->copy_channel_from (this, c, 0);
330         return o;
331 }
332
333 /** Copy all the samples from a channel on another AudioBuffers to a channel on this one.
334  *  @param from AudioBuffers to copy from.
335  *  @param from_channel Channel index in `from' to copy from.
336  *  @param to_channel Channel index in this to copy into, overwriting what's already there.
337  */
338 void
339 AudioBuffers::copy_channel_from (AudioBuffers const * from, int from_channel, int to_channel)
340 {
341         DCPOMATIC_ASSERT (from->frames() == frames());
342         memcpy (data(to_channel), from->data(from_channel), frames() * sizeof (float));
343 }
344
345 /** Make a copy of these AudioBuffers */
346 shared_ptr<AudioBuffers>
347 AudioBuffers::clone () const
348 {
349         shared_ptr<AudioBuffers> b (new AudioBuffers (channels (), frames ()));
350         b->copy_from (this, frames (), 0, 0);
351         return b;
352 }
353
354 /** Extend these buffers with the data from another.  The AudioBuffers must have the same number of channels. */
355 void
356 AudioBuffers::append (shared_ptr<const AudioBuffers> other)
357 {
358         DCPOMATIC_ASSERT (channels() == other->channels());
359         ensure_size (_frames + other->frames());
360         copy_from (other.get(), other->frames(), 0, _frames);
361         _frames += other->frames();
362 }
363
364 /** Remove some frames from the start of these AudioBuffers */
365 void
366 AudioBuffers::trim_start (int32_t frames)
367 {
368         DCPOMATIC_ASSERT (frames <= _frames);
369         move (_frames - frames, frames, 0);
370         set_frames (_frames - frames);
371 }