Const-correct BufferSet.
[ardour.git] / libs / ardour / buffer_set.cc
1 /*
2     Copyright (C) 2006 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify it
5     under the terms of the GNU General Public License as published by the Free
6     Software Foundation; either version 2 of the License, or (at your option)
7     any later version.
8
9     This program is distributed in the hope that it will be useful, but WITHOUT
10     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12     for more details.
13
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19
20 #ifdef WAF_BUILD
21 #include "libardour-config.h"
22 #endif
23
24 #include <iostream>
25 #include <algorithm>
26 #include "ardour/buffer.h"
27 #include "ardour/buffer_set.h"
28 #include "ardour/midi_buffer.h"
29 #include "ardour/port.h"
30 #include "ardour/port_set.h"
31 #include "ardour/audioengine.h"
32 #ifdef HAVE_SLV2
33 #include "ardour/lv2_plugin.h"
34 #include "ardour/lv2_event_buffer.h"
35 #endif
36
37 namespace ARDOUR {
38
39 /** Create a new, empty BufferSet */
40 BufferSet::BufferSet()
41         : _is_mirror(false)
42         , _is_silent(false)
43 {
44         for (size_t i=0; i < DataType::num_types; ++i) {
45                 _buffers.push_back(BufferVec());
46         }
47
48         _count.reset();
49         _available.reset();
50 }
51
52 BufferSet::~BufferSet()
53 {
54         clear();
55 }
56
57 /** Destroy all contained buffers.
58  */
59 void
60 BufferSet::clear()
61 {
62         if (!_is_mirror) {
63                 for (std::vector<BufferVec>::iterator i = _buffers.begin(); i != _buffers.end(); ++i) {
64                         for (BufferVec::iterator j = (*i).begin(); j != (*i).end(); ++j) {
65                                 delete *j;
66                         }
67                         (*i).clear();
68                 }
69         }
70         _buffers.clear();
71         _count.reset();
72         _available.reset();
73 }
74
75 /** Make this BufferSet a direct mirror of a PortSet's buffers.
76  */
77 void
78 BufferSet::attach_buffers(PortSet& ports, nframes_t nframes, nframes_t offset)
79 {
80         clear();
81
82         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
83                 _buffers.push_back(BufferVec());
84                 BufferVec& v = _buffers[*t];
85
86                 for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) {
87                         assert(p->type() == *t);
88                         v.push_back(&(p->get_buffer(nframes, offset)));
89                 }
90         }
91
92         _count = ports.count();
93         _available = ports.count();
94
95         _is_mirror = true;
96 }
97
98 /** Ensure that there are @a num_buffers buffers of type @a type available,
99  * each of size at least @a buffer_size
100  */
101 void
102 BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity)
103 {
104         assert(type != DataType::NIL);
105         assert(type < _buffers.size());
106
107         if (num_buffers == 0) {
108                 return;
109         }
110
111         // The vector of buffers of the type we care about
112         BufferVec& bufs = _buffers[type];
113
114         // If we're a mirror just make sure we're ok
115         if (_is_mirror) {
116                 assert(_count.get(type) >= num_buffers);
117                 assert(bufs[0]->type() == type);
118                 return;
119         }
120
121         // If there's not enough or they're too small, just nuke the whole thing and
122         // rebuild it (so I'm lazy..)
123         if (bufs.size() < num_buffers
124                         || (bufs.size() > 0 && bufs[0]->capacity() < buffer_capacity)) {
125
126                 // Nuke it
127                 for (BufferVec::iterator i = bufs.begin(); i != bufs.end(); ++i) {
128                         delete (*i);
129                 }
130                 bufs.clear();
131
132                 // Rebuild it
133                 for (size_t i = 0; i < num_buffers; ++i) {
134                         bufs.push_back(Buffer::create(type, buffer_capacity));
135                 }
136
137                 _available.set(type, num_buffers);
138                 _count.set (type, num_buffers);
139         }
140
141 #ifdef HAVE_SLV2
142         // Ensure enough low level MIDI format buffers are available for conversion
143         // in both directions (input & output, out-of-place)
144         if (type == DataType::MIDI && _lv2_buffers.size() < _buffers[type].size() * 2 + 1) {
145                 while (_lv2_buffers.size() < _buffers[type].size() * 2) {
146                         _lv2_buffers.push_back(std::make_pair(false, new LV2EventBuffer(buffer_capacity)));
147                 }
148         }
149 #endif
150
151         // Post-conditions
152         assert(bufs[0]->type() == type);
153         assert(bufs.size() >= num_buffers);
154         assert(bufs.size() == _available.get(type));
155         assert(bufs[0]->capacity() >= buffer_capacity);
156 }
157
158 /** Ensure that the number of buffers of each type @a type matches @a chns
159  * and each buffer is of size at least @a buffer_capacity
160  */
161 void
162 BufferSet::ensure_buffers(const ChanCount& chns, size_t buffer_capacity)
163 {
164         if (chns == ChanCount::ZERO) {
165                 return;
166         }
167
168         // If we're a mirror just make sure we're ok
169         if (_is_mirror) {
170                 assert(_count >= chns);
171                 return;
172         }
173
174         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
175
176                 // The vector of buffers of this type
177                 BufferVec& bufs = _buffers[*t];
178
179                 uint32_t nbufs = chns.get (*t);
180
181                 if (nbufs == 0) {
182                         // Nuke it
183                         for (BufferVec::iterator i = bufs.begin(); i != bufs.end(); ++i) {
184                                 delete (*i);
185                         }
186                         bufs.clear();
187                         continue;
188                 }
189
190                 // If there's not enough or they're too small, just nuke the whole thing and
191                 // rebuild it (so I'm lazy..)
192                 if (bufs.size() < nbufs
193                     || (bufs.size() > 0 && bufs[0]->capacity() < buffer_capacity)) {
194
195                         // Nuke it
196                         for (BufferVec::iterator i = bufs.begin(); i != bufs.end(); ++i) {
197                                 delete (*i);
198                         }
199                         bufs.clear();
200
201                         // Rebuild it
202                         for (size_t i = 0; i < nbufs; ++i) {
203                                 bufs.push_back(Buffer::create(*t, buffer_capacity));
204                         }
205
206                         _available.set (*t, nbufs);
207                 }
208
209 #ifdef HAVE_SLV2
210                 // Ensure enough low level MIDI format buffers are available for conversion
211                 // in both directions (input & output, out-of-place)
212                 if (*t == DataType::MIDI && _lv2_buffers.size() < _buffers[DataType::MIDI].size() * 2 + 1) {
213                         while (_lv2_buffers.size() < _buffers[DataType::MIDI].size() * 2) {
214                                 _lv2_buffers.push_back(std::make_pair(false, new LV2EventBuffer(buffer_capacity)));
215                         }
216                 }
217 #endif
218
219                 // Post-conditions
220                 assert(bufs[0]->type() == *t);
221                 assert(bufs.size() == _available.get(*t));
222                 assert(bufs[0]->capacity() >= buffer_capacity);
223         }
224
225         assert (available() == chns);
226 }
227
228 /** Get the capacity (size) of the available buffers of the given type.
229  *
230  * All buffers of a certain type always have the same capacity.
231  */
232 size_t
233 BufferSet::buffer_capacity(DataType type) const
234 {
235         assert(_available.get(type) > 0);
236         return _buffers[type][0]->capacity();
237 }
238
239 Buffer&
240 BufferSet::get(DataType type, size_t i)
241 {
242         assert(i < _available.get(type));
243         return *_buffers[type][i];
244 }
245
246 const Buffer&
247 BufferSet::get(DataType type, size_t i) const
248 {
249         assert(i < _available.get(type));
250         return *_buffers[type][i];
251 }
252
253 #ifdef HAVE_SLV2
254
255 LV2EventBuffer&
256 BufferSet::get_lv2_midi(bool input, size_t i)
257 {
258         MidiBuffer& mbuf = get_midi(i);
259         LV2Buffers::value_type b = _lv2_buffers.at(i * 2 + (input ? 0 : 1));
260         LV2EventBuffer* ebuf = b.second;
261
262         ebuf->reset();
263         if (input) {
264                 for (MidiBuffer::iterator e = mbuf.begin(); e != mbuf.end(); ++e) {
265                         const Evoral::MIDIEvent<nframes_t> ev(*e, false);
266                         uint32_t type = LV2Plugin::midi_event_type();
267                         ebuf->append(ev.time(), 0, type, ev.size(), ev.buffer());
268                 }
269         }
270         return *ebuf;
271 }
272
273 void
274 BufferSet::flush_lv2_midi(bool input, size_t i)
275 {
276         MidiBuffer& mbuf = get_midi(i);
277         LV2Buffers::value_type b = _lv2_buffers.at(i * 2 + (input ? 0 : 1));
278         LV2EventBuffer* ebuf = b.second;
279
280         mbuf.silence(0, 0);
281         for (ebuf->rewind(); ebuf->is_valid(); ebuf->increment()) {
282                 uint32_t frames;
283                 uint32_t subframes;
284                 uint16_t type;
285                 uint16_t size;
286                 uint8_t* data;
287                 ebuf->get_event(&frames, &subframes, &type, &size, &data);
288                 mbuf.push_back(frames, size, data);
289         }
290 }
291
292 #endif
293
294 void
295 BufferSet::read_from (const BufferSet& in, nframes_t nframes)
296 {
297         assert(available() >= in.count());
298
299         // Copy all buffers 1:1
300         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
301                 BufferSet::iterator o = begin(*t);
302                 for (BufferSet::const_iterator i = in.begin(*t); i != in.end(*t); ++i, ++o) {
303                         o->read_from (*i, nframes);
304                 }
305         }
306
307         set_count(in.count());
308 }
309
310 void
311 BufferSet::merge_from (const BufferSet& in, nframes_t nframes)
312 {
313         /* merge all input buffers into out existing buffers.
314
315            NOTE: if "in" contains more buffers than this set,
316            we will drop the extra buffers.
317
318         */
319
320         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
321                 BufferSet::iterator o = begin(*t);
322                 for (BufferSet::const_iterator i = in.begin(*t); i != in.end(*t) && o != end (*t); ++i, ++o) {
323                         o->merge_from (*i, nframes);
324                 }
325         }
326 }
327
328 void
329 BufferSet::silence (nframes_t nframes, nframes_t offset)
330 {
331         for (std::vector<BufferVec>::iterator i = _buffers.begin(); i != _buffers.end(); ++i) {
332                 for (BufferVec::iterator b = i->begin(); b != i->end(); ++b) {
333                         (*b)->silence (nframes, offset);
334                 }
335         }
336 }
337
338 } // namespace ARDOUR
339