Ardour  9.0-pre0-582-g084a23a80d
audio_buffer.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2012 David Robillard <d@drobilla.net>
3  * Copyright (C) 2007-2017 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2010-2012 Carl Hetherington <carl@carlh.net>
5  * Copyright (C) 2013-2016 Robin Gareus <robin@gareus.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #pragma once
23 
24 #include <cstring>
25 
26 #include "ardour/buffer.h"
28 
29 namespace ARDOUR
30 {
33 {
34 public:
35  AudioBuffer (size_t capacity);
37 
42  void silence (samplecnt_t len, samplecnt_t offset = 0);
43 
44  bool silent_data() const;
45 
52  void read_from (const Sample* src, samplecnt_t len, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0)
53  {
54  assert (src != 0);
55  assert (_capacity > 0);
56  assert (len <= _capacity);
57  copy_vector (_data + dst_offset, src + src_offset, len);
58  _silent = false;
59  _written = true;
60  }
61 
68  void read_from (const Buffer& src, samplecnt_t len, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0)
69  {
70  assert (&src != this);
71  assert (_capacity > 0);
72  assert (src.type () == DataType::AUDIO);
73  assert (dst_offset + len <= _capacity);
74  assert (src_offset <= ((samplecnt_t)src.capacity () - len));
75 
76  if (src.silent ()) {
77  memset (_data + dst_offset, 0, sizeof (Sample) * len);
78  } else {
79  copy_vector (_data + dst_offset, ((const AudioBuffer&)src).data () + src_offset, len);
80  }
81 
82  if (dst_offset == 0 && src_offset == 0 && len == _capacity) {
83  _silent = src.silent ();
84  } else {
85  _silent = _silent && src.silent ();
86  }
87  _written = true;
88  }
89 
91  void merge_from (const Buffer& src, samplecnt_t len, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0)
92  {
93  const AudioBuffer* ab = dynamic_cast<const AudioBuffer*> (&src);
94  assert (ab);
95  accumulate_from (*ab, len, dst_offset, src_offset);
96  }
97 
99  void accumulate_from (const AudioBuffer& src, samplecnt_t len, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0)
100  {
101  assert (_capacity > 0);
102  assert (len <= _capacity);
103  if (src.silent ()) {
104  return;
105  }
106  Sample* const dst_raw = _data + dst_offset;
107  const Sample* const src_raw = src.data () + src_offset;
108 
109  mix_buffers_no_gain (dst_raw, src_raw, len);
110 
111  _silent = (src.silent () && _silent);
112  _written = true;
113  }
114 
118  void accumulate_from (const Sample* src, samplecnt_t len, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0)
119  {
120  assert (_capacity > 0);
121  assert (len <= _capacity);
122 
123  Sample* const dst_raw = _data + dst_offset;
124  const Sample* const src_raw = src + src_offset;
125 
126  mix_buffers_no_gain (dst_raw, src_raw, len);
127 
128  _silent = false;
129  _written = true;
130  }
131 
135  void accumulate_with_gain_from (const AudioBuffer& src, samplecnt_t len, gain_t gain_coeff, sampleoffset_t dst_offset = 0, sampleoffset_t src_offset = 0)
136  {
137  assert (_capacity > 0);
138  assert (len <= _capacity);
139 
140  if (src.silent () || gain_coeff == 0) {
141  return;
142  }
143 
144  Sample* const dst_raw = _data + dst_offset;
145  const Sample* const src_raw = src.data () + src_offset;
146 
147  mix_buffers_with_gain (dst_raw, src_raw, len, gain_coeff);
148 
149  _silent = ((src.silent () && _silent) || (_silent && gain_coeff == 0));
150  _written = true;
151  }
152 
156  void accumulate_with_gain_from (const Sample* src_raw, samplecnt_t len, gain_t gain_coeff, sampleoffset_t dst_offset = 0)
157  {
158  assert (_capacity > 0);
159  assert (len <= _capacity);
160 
161  Sample* const dst_raw = _data + dst_offset;
162 
163  mix_buffers_with_gain (dst_raw, src_raw, len, gain_coeff);
164 
165  _silent = (_silent && gain_coeff == 0);
166  _written = true;
167  }
168 
172  void accumulate_with_ramped_gain_from (const Sample* src, samplecnt_t len, gain_t initial, gain_t target, sampleoffset_t dst_offset = 0)
173  {
174  assert (_capacity > 0);
175  assert (len <= _capacity);
176 
177  if (initial == 0 && target == 0) {
178  return;
179  }
180 
181  Sample* dst = _data + dst_offset;
182  gain_t gain_delta = (target - initial) / len;
183 
184  for (samplecnt_t n = 0; n < len; ++n) {
185  *dst++ += (*src++ * initial);
186  initial += gain_delta;
187  }
188 
189  _silent = (_silent && initial == 0 && target == 0);
190  _written = true;
191  }
192 
199  {
200  if (gain == 0) {
201  memset (_data, 0, sizeof (Sample) * len);
202  if (len == _capacity) {
203  _silent = true;
204  }
205  return;
206  }
207  apply_gain_to_buffer (_data, len, gain);
208  }
209 
214  void set_data (Sample* data, size_t size)
215  {
216  assert (!_owns_data); // prevent leaks
217  _capacity = size;
218  _data = data;
219  _silent = false;
220  _written = false;
221  }
222 
227  void resize (size_t nframes);
228 
229  const Sample* data (samplecnt_t offset = 0) const
230  {
231  assert (offset <= _capacity);
232  return _data + offset;
233  }
234 
235  Sample* data (samplecnt_t offset = 0)
236  {
237  assert (offset <= _capacity);
238  _silent = false;
239  return _data + offset;
240  }
241 
248  bool check_silence (pframes_t nframes, pframes_t& n) const;
249 
250  void prepare ()
251  {
252  if (!_owns_data) {
253  _data = 0;
254  }
255  _written = false;
256  _silent = false;
257  }
258 
259  bool written () const { return _written; }
260  void set_written (bool w) { _written = w; }
261 
262 private:
264  bool _written;
266 };
267 
268 } // namespace ARDOUR
269 
Sample * _data
Actual buffer contents.
Definition: audio_buffer.h:265
Sample * data(samplecnt_t offset=0)
Definition: audio_buffer.h:235
bool silent_data() const
bool check_silence(pframes_t nframes, pframes_t &n) const
void read_from(const Buffer &src, samplecnt_t len, sampleoffset_t dst_offset=0, sampleoffset_t src_offset=0)
Definition: audio_buffer.h:68
AudioBuffer(size_t capacity)
void set_data(Sample *data, size_t size)
Definition: audio_buffer.h:214
void apply_gain(gain_t gain, samplecnt_t len)
Definition: audio_buffer.h:198
void accumulate_with_gain_from(const AudioBuffer &src, samplecnt_t len, gain_t gain_coeff, sampleoffset_t dst_offset=0, sampleoffset_t src_offset=0)
Definition: audio_buffer.h:135
void merge_from(const Buffer &src, samplecnt_t len, sampleoffset_t dst_offset=0, sampleoffset_t src_offset=0)
Definition: audio_buffer.h:91
const Sample * data(samplecnt_t offset=0) const
Definition: audio_buffer.h:229
void set_written(bool w)
Definition: audio_buffer.h:260
void accumulate_from(const Sample *src, samplecnt_t len, sampleoffset_t dst_offset=0, sampleoffset_t src_offset=0)
Definition: audio_buffer.h:118
void accumulate_with_gain_from(const Sample *src_raw, samplecnt_t len, gain_t gain_coeff, sampleoffset_t dst_offset=0)
Definition: audio_buffer.h:156
void silence(samplecnt_t len, samplecnt_t offset=0)
void accumulate_from(const AudioBuffer &src, samplecnt_t len, sampleoffset_t dst_offset=0, sampleoffset_t src_offset=0)
Definition: audio_buffer.h:99
void accumulate_with_ramped_gain_from(const Sample *src, samplecnt_t len, gain_t initial, gain_t target, sampleoffset_t dst_offset=0)
Definition: audio_buffer.h:172
void read_from(const Sample *src, samplecnt_t len, sampleoffset_t dst_offset=0, sampleoffset_t src_offset=0)
Definition: audio_buffer.h:52
void resize(size_t nframes)
bool written() const
Definition: audio_buffer.h:259
DataType type() const
Definition: buffer.h:57
bool silent() const
Definition: buffer.h:59
size_t capacity() const
Definition: buffer.h:53
#define LIBARDOUR_API
void memset(float *data, const float val, const uint32_t n_samples)
PBD::PropertyDescriptor< gain_t > gain
uint32_t pframes_t
Temporal::samplecnt_t samplecnt_t
apply_gain_to_buffer_t apply_gain_to_buffer
mix_buffers_with_gain_t mix_buffers_with_gain
Temporal::sampleoffset_t sampleoffset_t
mix_buffers_no_gain_t mix_buffers_no_gain
copy_vector_t copy_vector