Preliminary MIDI plugin support.
[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 #include <iostream>
20 #include <algorithm>
21 #include "ardour/buffer.h"
22 #include "ardour/buffer_set.h"
23 #include "ardour/lv2_event_buffer.h"
24 #include "ardour/lv2_plugin.h"
25 #include "ardour/midi_buffer.h"
26 #include "ardour/port.h"
27 #include "ardour/port_set.h"
28 #include "ardour/audioengine.h"
29
30 namespace ARDOUR {
31
32 /** Create a new, empty BufferSet */
33 BufferSet::BufferSet()
34         : _is_mirror(false)
35 {
36         for (size_t i=0; i < DataType::num_types; ++i) {
37                 _buffers.push_back(BufferVec());
38         }
39
40         _count.reset();
41         _available.reset();
42 }
43
44 BufferSet::~BufferSet()
45 {
46         clear();
47 }
48
49 /** Destroy all contained buffers.
50  */
51 void
52 BufferSet::clear()
53 {
54         if (!_is_mirror) {
55                 for (std::vector<BufferVec>::iterator i = _buffers.begin(); i != _buffers.end(); ++i) {
56                         for (BufferVec::iterator j = (*i).begin(); j != (*i).end(); ++j) {
57                                 delete *j;
58                         }
59                         (*i).clear();
60                 }
61         }
62         _buffers.clear();
63         _count.reset();
64         _available.reset();
65 }
66
67 /** Make this BufferSet a direct mirror of a PortSet's buffers.
68  */
69 void
70 BufferSet::attach_buffers(PortSet& ports, nframes_t nframes, nframes_t offset)
71 {
72         clear();
73
74         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
75                 _buffers.push_back(BufferVec());
76                 BufferVec& v = _buffers[*t];
77
78                 for (PortSet::iterator p = ports.begin(*t); p != ports.end(*t); ++p) {
79                         assert(p->type() == *t);
80                         v.push_back(&(p->get_buffer(nframes, offset)));
81                 }
82         }
83         
84         _count = ports.count();
85
86         _is_mirror = true;
87 }
88
89 /** Ensure that there are @a num_buffers buffers of type @a type available,
90  * each of size at least @a buffer_size
91  */
92 void
93 BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity)
94 {
95         assert(type != DataType::NIL);
96         assert(type < _buffers.size());
97
98         if (num_buffers == 0)
99                 return;
100
101         // The vector of buffers of the type we care about
102         BufferVec& bufs = _buffers[type];
103         
104         // If we're a mirror just make sure we're ok
105         if (_is_mirror) {
106                 assert(_count.get(type) >= num_buffers);
107                 assert(bufs[0]->type() == type);
108                 return;
109         }
110
111         // If there's not enough or they're too small, just nuke the whole thing and
112         // rebuild it (so I'm lazy..)
113         if (bufs.size() < num_buffers
114                         || (bufs.size() > 0 && bufs[0]->capacity() < buffer_capacity)) {
115
116                 // Nuke it
117                 for (BufferVec::iterator i = bufs.begin(); i != bufs.end(); ++i) {
118                         delete (*i);
119                 }
120                 bufs.clear();
121
122                 // Rebuild it
123                 for (size_t i = 0; i < num_buffers; ++i) {
124                         bufs.push_back(Buffer::create(type, buffer_capacity));
125                 }
126         
127                 _available.set(type, num_buffers);
128         }
129
130         // Ensure enough low level MIDI format buffers are available for conversion
131         // in both directions (input & output, out-of-place)
132         if (type == DataType::MIDI && _lv2_buffers.size() < _buffers[type].size() * 2) {
133                 while (_lv2_buffers.size() < _buffers[type].size() * 2) {
134                         _lv2_buffers.push_back(std::make_pair(false, new LV2EventBuffer(buffer_capacity)));
135                 }
136         }
137
138         // Post-conditions
139         assert(bufs[0]->type() == type);
140         assert(bufs.size() >= num_buffers);
141         assert(bufs.size() == _available.get(type));
142         assert(bufs[0]->capacity() >= buffer_capacity);
143 }
144
145 /** Get the capacity (size) of the available buffers of the given type.
146  *
147  * All buffers of a certain type always have the same capacity.
148  */
149 size_t
150 BufferSet::buffer_capacity(DataType type) const
151 {
152         assert(_available.get(type) > 0);
153         return _buffers[type][0]->capacity();
154 }
155
156 Buffer&
157 BufferSet::get(DataType type, size_t i)
158 {
159         assert(i <= _count.get(type));
160         return *_buffers[type][i];
161 }
162
163 LV2EventBuffer&
164 BufferSet::get_lv2_midi(bool input, size_t i)
165 {
166         MidiBuffer& mbuf = get_midi(i);
167         LV2Buffers::value_type b = _lv2_buffers.at(i * 2 + (input ? 0 : 1));
168         LV2EventBuffer* ebuf = b.second;
169         
170         ebuf->reset();
171         if (input) {
172                 for (MidiBuffer::iterator e = mbuf.begin(); e != mbuf.end(); ++e) {
173                         const Evoral::MIDIEvent<nframes_t> ev(*e, false);
174                         uint32_t type = LV2Plugin::midi_event_type();
175                         ebuf->append(ev.time(), 0, type, ev.size(), ev.buffer());
176                 }
177         }
178         return *ebuf;
179 }
180
181 void
182 BufferSet::flush_lv2_midi(bool input, size_t i)
183 {
184         MidiBuffer& mbuf = get_midi(i);
185         LV2Buffers::value_type b = _lv2_buffers.at(i * 2 + (input ? 0 : 1));
186         LV2EventBuffer* ebuf = b.second;
187
188         mbuf.silence(0, 0);
189         for (ebuf->rewind(); ebuf->is_valid(); ebuf->increment()) {
190                 uint32_t frames;
191                 uint32_t subframes;
192                 uint16_t type;
193                 uint16_t size;
194                 uint8_t* data;
195                 ebuf->get_event(&frames, &subframes, &type, &size, &data);
196                 mbuf.push_back(frames, size, data);
197         }
198 }
199
200 // FIXME: make 'in' const
201 void
202 BufferSet::read_from (BufferSet& in, nframes_t nframes)
203 {
204         assert(available() >= in.count());
205
206         // Copy all buffers 1:1
207         for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
208                 BufferSet::iterator o = begin(*t);
209                 for (BufferSet::iterator i = in.begin(*t); i != in.end(*t); ++i, ++o) {
210                         o->read_from (*i, nframes);
211                 }
212         }
213
214         set_count(in.count());
215 }
216
217 } // namespace ARDOUR
218