2 Copyright (C) 2009 Paul Davis
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)
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
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 #define __STDC_LIMIT_MACROS 1
23 #include "lv2ext/lv2_event.h"
24 #include "lv2ext/lv2_event_helpers.h"
25 #include "ardour/lv2_event_buffer.h"
32 /** Allocate a new event buffer.
33 * \a capacity is in bytes (not number of events).
35 LV2EventBuffer::LV2EventBuffer(size_t capacity)
37 , _latest_subframes(0)
39 if (capacity > UINT32_MAX) {
40 cerr << "Event buffer size " << capacity << " too large, aborting." << endl;
41 throw std::bad_alloc();
44 #ifdef NO_POSIX_MEMALIGN
45 _data = (LV2_Event_Buffer*)malloc(sizeof(LV2_Event_Buffer) + capacity);
46 int ret = (_data != NULL) ? 0 : -1;
48 int ret = posix_memalign((void**)&_data, 16, sizeof(LV2_Event_Buffer) + capacity);
52 cerr << "Failed to allocate event buffer. Aborting." << endl;
56 _data->event_count = 0;
57 _data->capacity = (uint32_t)capacity;
59 _data->data = reinterpret_cast<uint8_t*>(_data + 1);
65 LV2EventBuffer::~LV2EventBuffer()
71 /** Increment the read position by one event.
73 * \return true if increment was successful, or false if end of buffer reached.
76 LV2EventBuffer::increment() const
78 if (lv2_event_is_valid(&_iter)) {
79 lv2_event_increment(&_iter);
87 /** \return true iff the cursor is valid (ie get_event is safe)
90 LV2EventBuffer::is_valid() const
92 return lv2_event_is_valid(&_iter);
96 /** Read an event from the current position in the buffer
98 * \return true if read was successful, or false if end of buffer reached
101 LV2EventBuffer::get_event(uint32_t* frames,
105 uint8_t** data) const
107 if (lv2_event_is_valid(&_iter)) {
108 LV2_Event* ev = lv2_event_get(&_iter, data);
109 *frames = ev->frames;
110 *subframes = ev->subframes;
120 /** Append an event to the buffer.
122 * \a timestamp must be >= the latest event in the buffer.
124 * \return true on success
127 LV2EventBuffer::append(uint32_t frames,
134 if (lv2_event_is_valid(&_iter)) {
135 LV2_Event* last_event = lv2_event_get(&_iter, NULL);
136 assert(last_event->frames < frames
137 || (last_event->frames == frames && last_event->subframes <= subframes));
141 /*cout << "Appending event type " << type << ", size " << size
142 << " @ " << frames << "." << subframes << endl;*/
144 if (!lv2_event_write(&_iter, frames, subframes, type, size, data)) {
145 cerr << "ERROR: Failed to write event." << endl;
148 _latest_frames = frames;
149 _latest_subframes = subframes;
155 /** Append a buffer of events to the buffer.
157 * \a timestamp must be >= the latest event in the buffer.
159 * \return true on success
162 LV2EventBuffer::append(const LV2_Event_Buffer* buf)
164 uint8_t** data = NULL;
167 LV2_Event_Iterator iter;
168 for (lv2_event_begin(&iter, _data); lv2_event_is_valid(&iter); lv2_event_increment(&iter)) {
169 LV2_Event* ev = lv2_event_get(&iter, data);
172 assert((ev->frames > _latest_frames)
173 || (ev->frames == _latest_frames
174 && ev->subframes >= _latest_subframes));
177 if (!(ret = append(ev->frames, ev->subframes, ev->type, ev->size, *data))) {
178 cerr << "ERROR: Failed to write event." << endl;
182 _latest_frames = ev->frames;
183 _latest_subframes = ev->subframes;
190 } // namespace ARDOUR