1 /* 2 * Copyright (C) 2006-2016 David Robillard <d@drobilla.net> 3 * Copyright (C) 2007-2017 Paul Davis <paul@linuxaudiosystems.com> 4 * Copyright (C) 2009-2011 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 #ifndef __ardour_buffer_set_h__ 23 #define __ardour_buffer_set_h__ 24 25 #ifdef WAF_BUILD 26 #include "libardour-config.h" 27 #endif 28 29 #include <cassert> 30 #include <vector> 31 #include "ardour/chan_count.h" 32 #include "ardour/data_type.h" 33 #include "ardour/libardour_visibility.h" 34 #include "ardour/types.h" 35 36 #if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT 37 #include "evoral/Event.h" 38 struct _VstEvents; 39 typedef struct _VstEvents VstEvents; 40 struct _VstMidiEvent; 41 typedef struct _VstMidiEvent VstMidiEvent; 42 #endif 43 44 typedef struct LV2_Evbuf_Impl LV2_Evbuf; 45 46 namespace ARDOUR { 47 48 class Buffer; 49 class AudioBuffer; 50 class MidiBuffer; 51 class PortSet; 52 53 /** A set of buffers of various types. 54 * 55 * These are mainly accessed from Session and passed around as scratch buffers 56 * (eg as parameters to run() methods) to do in-place signal processing. 57 * 58 * There are two types of counts associated with a BufferSet - available, 59 * and the 'use count'. Available is the actual number of allocated buffers 60 * (and so is the maximum acceptable value for the use counts). 61 * 62 * The use counts are how things determine the form of their input and inform 63 * others the form of their output (eg what they did to the BufferSet). 64 * Setting the use counts is realtime safe. 65 */ 66 class LIBARDOUR_API BufferSet 67 { 68 public: 69 BufferSet(); 70 ~BufferSet(); 71 72 void clear(); 73 74 void attach_buffers (PortSet& ports); 75 void get_backend_port_addresses (PortSet &, samplecnt_t); 76 77 /* the capacity here is a size_t and has a different interpretation depending 78 on the DataType of the buffers. for audio, its a sample count. for MIDI 79 its a byte count. 80 */ 81 82 void ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capacity); 83 void ensure_buffers(const ChanCount& chns, size_t buffer_capacity); 84 available()85 const ChanCount& available() const { return _available; } available()86 ChanCount& available() { return _available; } 87 count()88 const ChanCount& count() const { return _count; } count()89 ChanCount& count() { return _count; } 90 91 void silence (samplecnt_t nframes, samplecnt_t offset); is_mirror()92 bool is_mirror() const { return _is_mirror; } 93 set_count(const ChanCount & count)94 void set_count(const ChanCount& count) { assert(count <= _available); _count = count; } 95 96 size_t buffer_capacity(DataType type) const; 97 get_audio(size_t i)98 AudioBuffer& get_audio(size_t i) { 99 return (AudioBuffer&)get_available (DataType::AUDIO, i); 100 } get_audio(size_t i)101 const AudioBuffer& get_audio(size_t i) const { 102 return (const AudioBuffer&)get_available(DataType::AUDIO, i); 103 } 104 get_midi(size_t i)105 MidiBuffer& get_midi(size_t i) { 106 return (MidiBuffer&)get_available(DataType::MIDI, i); 107 } get_midi(size_t i)108 const MidiBuffer& get_midi(size_t i) const { 109 return (const MidiBuffer&)get_available(DataType::MIDI, i); 110 } 111 112 Buffer& get_available(DataType type, size_t i); 113 const Buffer& get_available(DataType type, size_t i) const; 114 115 /** Get a MIDI buffer translated into an LV2 MIDI buffer for use with 116 * plugins. The index here corresponds directly to MIDI buffer numbers 117 * (i.e. the index passed to get_midi), translation back and forth will 118 * happen as needed. 119 */ 120 LV2_Evbuf* get_lv2_midi(bool input, size_t i); 121 122 /** ensure minimum size of LV2 Atom port buffer */ 123 void ensure_lv2_bufsize(bool input, size_t i, size_t buffer_capacity); 124 125 /** Flush modified LV2 event output buffers back to Ardour buffers */ 126 void flush_lv2_midi(bool input, size_t i); 127 128 /** Forward plugin MIDI output to to Ardour buffers */ 129 void forward_lv2_midi(LV2_Evbuf*, size_t, bool purge_ardour_buffer = true); 130 131 #if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT 132 VstEvents* get_vst_midi (size_t); 133 #endif 134 135 void read_from(const BufferSet& in, samplecnt_t nframes); 136 void read_from(const BufferSet& in, samplecnt_t nframes, DataType); 137 void merge_from(const BufferSet& in, samplecnt_t nframes); 138 139 template <typename BS, typename B> 140 class iterator_base { 141 public: iterator_base(const iterator_base & other)142 iterator_base(const iterator_base& other) 143 : _set(other._set), _type(other._type), _index(other._index) {} 144 B& operator*() { return (B&)_set.get_available(_type, _index); } 145 B* operator->() { return &(B&)_set.get_available(_type, _index); } 146 iterator_base<BS,B>& operator++() { ++_index; return *this; } // yes, prefix only 147 bool operator==(const iterator_base<BS,B>& other) { return (_index == other._index); } 148 bool operator!=(const iterator_base<BS,B>& other) { return (_index != other._index); } 149 iterator_base<BS,B> operator=(const iterator_base<BS,B>& other) { 150 _set = other._set; _type = other._type; _index = other._index; return *this; 151 } 152 153 private: 154 friend class BufferSet; 155 iterator_base(BS & list,DataType type,size_t index)156 iterator_base(BS& list, DataType type, size_t index) 157 : _set(list), _type(type), _index(index) {} 158 159 BS& _set; 160 DataType _type; 161 size_t _index; 162 }; 163 164 typedef iterator_base<BufferSet, Buffer> iterator; begin(DataType type)165 iterator begin(DataType type) { return iterator(*this, type, 0); } end(DataType type)166 iterator end(DataType type) { return iterator(*this, type, _count.get(type)); } 167 168 typedef iterator_base<const BufferSet, const Buffer> const_iterator; begin(DataType type)169 const_iterator begin(DataType type) const { return const_iterator(*this, type, 0); } end(DataType type)170 const_iterator end(DataType type) const { return const_iterator(*this, type, _count.get(type)); } 171 172 typedef iterator_base<BufferSet, AudioBuffer> audio_iterator; audio_begin()173 audio_iterator audio_begin() { return audio_iterator(*this, DataType::AUDIO, 0); } audio_end()174 audio_iterator audio_end() { return audio_iterator(*this, DataType::AUDIO, _count.n_audio()); } 175 176 typedef iterator_base<BufferSet, MidiBuffer> midi_iterator; midi_begin()177 midi_iterator midi_begin() { return midi_iterator(*this, DataType::MIDI, 0); } midi_end()178 midi_iterator midi_end() { return midi_iterator(*this, DataType::MIDI, _count.n_midi()); } 179 180 private: 181 typedef std::vector<Buffer*> BufferVec; 182 183 /// Vector of vectors, indexed by DataType 184 std::vector<BufferVec> _buffers; 185 186 /// LV2 MIDI buffers (for conversion to/from MIDI buffers) 187 typedef std::vector< std::pair<bool, LV2_Evbuf*> > LV2Buffers; 188 LV2Buffers _lv2_buffers; 189 190 #if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT 191 class VSTBuffer { 192 public: 193 VSTBuffer (size_t); 194 ~VSTBuffer (); 195 196 void clear (); 197 void push_back (Evoral::Event<samplepos_t> const &); events()198 VstEvents* events () const { 199 return _events; 200 } 201 202 private: 203 /* prevent copy construction */ 204 VSTBuffer (VSTBuffer const &); 205 206 VstEvents* _events; /// the parent VSTEvents struct 207 VstMidiEvent* _midi_events; ///< storage area for VSTMidiEvents 208 size_t _capacity; 209 }; 210 211 typedef std::vector<VSTBuffer*> VSTBuffers; 212 VSTBuffers _vst_buffers; 213 #endif 214 215 /// Use counts (there may be more actual buffers than this) 216 ChanCount _count; 217 218 /// Available counts (number of buffers actually allocated) 219 ChanCount _available; 220 221 /// False if we 'own' the contained buffers, if true we mirror a PortSet) 222 bool _is_mirror; 223 }; 224 225 226 } // namespace ARDOUR 227 228 #endif // __ardour_buffer_set_h__ 229