Move panner bypass state up to the PannerShell so that it is preserved even when...
[ardour2.git] / libs / ardour / lv2_event_buffer.cc
blobdd666203fd58039872bd23450c6b4c0d1fd8b8e8
1 /*
2 Copyright (C) 2009 Paul Davis
3 Author: David Robillard
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2 of the License, or (at your option)
8 any later version.
10 This program is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdint.h>
21 #include <iostream>
22 #include "lv2ext/lv2_event.h"
23 #include "lv2ext/lv2_event_helpers.h"
24 #include "ardour/lv2_event_buffer.h"
26 using namespace std;
28 namespace ARDOUR {
31 /** Allocate a new event buffer.
32 * \a capacity is in bytes (not number of events).
34 LV2EventBuffer::LV2EventBuffer(size_t capacity)
35 : _latest_frames(0)
36 , _latest_subframes(0)
38 if (capacity > UINT32_MAX) {
39 cerr << "Event buffer size " << capacity << " too large, aborting." << endl;
40 throw std::bad_alloc();
43 if (capacity == 0) {
44 cerr << "ERROR: LV2 event buffer of size 0 created." << endl;
45 capacity = 1024;
48 #ifdef NO_POSIX_MEMALIGN
49 _data = (LV2_Event_Buffer*)malloc(sizeof(LV2_Event_Buffer) + capacity);
50 int ret = (_data != NULL) ? 0 : -1;
51 #else
52 int ret = posix_memalign((void**)&_data, 16, sizeof(LV2_Event_Buffer) + capacity);
53 #endif
55 if (ret != 0) {
56 cerr << "Failed to allocate event buffer. Aborting." << endl;
57 exit(EXIT_FAILURE);
60 _data->event_count = 0;
61 _data->capacity = (uint32_t)capacity;
62 _data->size = 0;
63 _data->data = reinterpret_cast<uint8_t*>(_data + 1);
65 reset();
69 LV2EventBuffer::~LV2EventBuffer()
71 free(_data);
75 /** Increment the read position by one event.
77 * \return true if increment was successful, or false if end of buffer reached.
79 bool
80 LV2EventBuffer::increment() const
82 if (lv2_event_is_valid(&_iter)) {
83 lv2_event_increment(&_iter);
84 return true;
85 } else {
86 return false;
91 /** \return true iff the cursor is valid (ie get_event is safe)
93 bool
94 LV2EventBuffer::is_valid() const
96 return lv2_event_is_valid(&_iter);
100 /** Read an event from the current position in the buffer
102 * \return true if read was successful, or false if end of buffer reached
104 bool
105 LV2EventBuffer::get_event(uint32_t* frames,
106 uint32_t* subframes,
107 uint16_t* type,
108 uint16_t* size,
109 uint8_t** data) const
111 if (lv2_event_is_valid(&_iter)) {
112 LV2_Event* ev = lv2_event_get(&_iter, data);
113 *frames = ev->frames;
114 *subframes = ev->subframes;
115 *type = ev->type;
116 *size = ev->size;
117 return true;
118 } else {
119 return false;
124 /** Append an event to the buffer.
126 * \a timestamp must be >= the latest event in the buffer.
128 * \return true on success
130 bool
131 LV2EventBuffer::append(uint32_t frames,
132 uint32_t subframes,
133 uint16_t type,
134 uint16_t size,
135 const uint8_t* data)
137 #ifndef NDEBUG
138 if (lv2_event_is_valid(&_iter)) {
139 LV2_Event* last_event = lv2_event_get(&_iter, NULL);
140 assert(last_event->frames < frames
141 || (last_event->frames == frames && last_event->subframes <= subframes));
143 #endif
145 /*cout << "Appending event type " << type << ", size " << size
146 << " @ " << frames << "." << subframes << endl;
147 cout << "Buffer capacity " << _data->capacity << ", size " << _data->size << endl;*/
149 if (!lv2_event_write(&_iter, frames, subframes, type, size, data)) {
150 cerr << "ERROR: Failed to write event." << endl;
151 return false;
152 } else {
153 _latest_frames = frames;
154 _latest_subframes = subframes;
155 return true;
160 /** Append a buffer of events to the buffer.
162 * \a timestamp must be >= the latest event in the buffer.
164 * \return true on success
166 bool
167 LV2EventBuffer::append(const LV2_Event_Buffer* /*buf*/)
169 uint8_t** data = NULL;
170 bool ret = true;
172 LV2_Event_Iterator iter;
173 for (lv2_event_begin(&iter, _data); lv2_event_is_valid(&iter); lv2_event_increment(&iter)) {
174 LV2_Event* ev = lv2_event_get(&iter, data);
176 #ifndef NDEBUG
177 assert((ev->frames > _latest_frames)
178 || (ev->frames == _latest_frames
179 && ev->subframes >= _latest_subframes));
180 #endif
182 if (!(ret = append(ev->frames, ev->subframes, ev->type, ev->size, *data))) {
183 cerr << "ERROR: Failed to write event." << endl;
184 break;
187 _latest_frames = ev->frames;
188 _latest_subframes = ev->subframes;
191 return ret;
195 } // namespace ARDOUR