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();
45 cerr
<< "ERROR: LV2 event buffer of size 0 created." << endl
;
49 #ifdef NO_POSIX_MEMALIGN
50 _data
= (LV2_Event_Buffer
*)malloc(sizeof(LV2_Event_Buffer
) + capacity
);
51 int ret
= (_data
!= NULL
) ? 0 : -1;
53 int ret
= posix_memalign((void**)&_data
, 16, sizeof(LV2_Event_Buffer
) + capacity
);
57 cerr
<< "Failed to allocate event buffer. Aborting." << endl
;
61 _data
->event_count
= 0;
62 _data
->capacity
= (uint32_t)capacity
;
64 _data
->data
= reinterpret_cast<uint8_t*>(_data
+ 1);
70 LV2EventBuffer::~LV2EventBuffer()
76 /** Increment the read position by one event.
78 * \return true if increment was successful, or false if end of buffer reached.
81 LV2EventBuffer::increment() const
83 if (lv2_event_is_valid(&_iter
)) {
84 lv2_event_increment(&_iter
);
92 /** \return true iff the cursor is valid (ie get_event is safe)
95 LV2EventBuffer::is_valid() const
97 return lv2_event_is_valid(&_iter
);
101 /** Read an event from the current position in the buffer
103 * \return true if read was successful, or false if end of buffer reached
106 LV2EventBuffer::get_event(uint32_t* frames
,
110 uint8_t** data
) const
112 if (lv2_event_is_valid(&_iter
)) {
113 LV2_Event
* ev
= lv2_event_get(&_iter
, data
);
114 *frames
= ev
->frames
;
115 *subframes
= ev
->subframes
;
125 /** Append an event to the buffer.
127 * \a timestamp must be >= the latest event in the buffer.
129 * \return true on success
132 LV2EventBuffer::append(uint32_t frames
,
139 if (lv2_event_is_valid(&_iter
)) {
140 LV2_Event
* last_event
= lv2_event_get(&_iter
, NULL
);
141 assert(last_event
->frames
< frames
142 || (last_event
->frames
== frames
&& last_event
->subframes
<= subframes
));
146 /*cout << "Appending event type " << type << ", size " << size
147 << " @ " << frames << "." << subframes << endl;
148 cout << "Buffer capacity " << _data->capacity << ", size " << _data->size << endl;*/
150 if (!lv2_event_write(&_iter
, frames
, subframes
, type
, size
, data
)) {
151 cerr
<< "ERROR: Failed to write event." << endl
;
154 _latest_frames
= frames
;
155 _latest_subframes
= subframes
;
161 /** Append a buffer of events to the buffer.
163 * \a timestamp must be >= the latest event in the buffer.
165 * \return true on success
168 LV2EventBuffer::append(const LV2_Event_Buffer
* /*buf*/)
170 uint8_t** data
= NULL
;
173 LV2_Event_Iterator iter
;
174 for (lv2_event_begin(&iter
, _data
); lv2_event_is_valid(&iter
); lv2_event_increment(&iter
)) {
175 LV2_Event
* ev
= lv2_event_get(&iter
, data
);
178 assert((ev
->frames
> _latest_frames
)
179 || (ev
->frames
== _latest_frames
180 && ev
->subframes
>= _latest_subframes
));
183 if (!(ret
= append(ev
->frames
, ev
->subframes
, ev
->type
, ev
->size
, *data
))) {
184 cerr
<< "ERROR: Failed to write event." << endl
;
188 _latest_frames
= ev
->frames
;
189 _latest_subframes
= ev
->subframes
;
196 } // namespace ARDOUR