Make MIDI region `automation' respect the automation mode so that it is
[ardour.git] / libs / ardour / lv2ext / lv2_event_helpers.h
1 /* lv2_event_helpers.h - Helper functions for the LV2 events extension.
2  *
3  * Copyright (C) 2008 Dave Robillard <dave@drobilla.net>
4  *
5  * This header is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published
7  * by the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This header 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 Lesser General Public
13  * License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this header; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA
18  */
19
20 #ifndef LV2_EVENT_HELPERS_H
21 #define LV2_EVENT_HELPERS_H
22
23 #include <stdint.h>
24 #include <stdbool.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <assert.h>
28 #include "lv2_event.h"
29
30 /** @file
31  * This header defines some helper functions for the the LV2 events extension
32  * with URI <http://lv2plug.in/ns/ext/event> ('lv2ev').
33  *
34  * These functions are provided for convenience only, use of them is not
35  * required for supporting lv2ev (i.e. the events extension is defined by the
36  * raw buffer format described in lv2_event.h and NOT by this API).
37  *
38  * Note that these functions are all static inline which basically means:
39  * do not take the address of these functions. */
40
41
42 /** Pad a size to 64 bits (for event sizes) */
43 static inline uint16_t
44 lv2_event_pad_size(uint16_t size)
45 {
46         return (size + 7) & (~7);
47 }
48
49
50 /** Initialize (empty, reset..) an existing event buffer.
51  * The contents of buf are ignored entirely and overwritten, except capacity
52  * which is unmodified. */
53 static inline void
54 lv2_event_buffer_reset(LV2_Event_Buffer* buf, uint16_t stamp_type, uint8_t *data)
55 {
56         buf->data = data;
57         buf->header_size = sizeof(LV2_Event_Buffer);
58         buf->stamp_type = stamp_type;
59         buf->event_count = 0;
60         buf->size = 0;
61 }
62
63
64 /** Allocate a new, empty event buffer. */
65 static inline LV2_Event_Buffer*
66 lv2_event_buffer_new(uint32_t capacity, uint16_t stamp_type)
67 {
68         LV2_Event_Buffer* buf = (LV2_Event_Buffer*)malloc(sizeof(LV2_Event_Buffer) + capacity);
69         if (buf != NULL) {
70                 buf->capacity = capacity;
71                 lv2_event_buffer_reset(buf, stamp_type, (uint8_t *)(buf + 1));
72                 return buf;
73         } else {
74                 return NULL;
75         }
76 }
77
78
79 /** An iterator over an LV2_Event_Buffer.
80  *
81  * Multiple simultaneous read iterators over a single buffer is fine,
82  * but changing the buffer invalidates all iterators (e.g. RW Lock). */
83 typedef struct {
84         LV2_Event_Buffer* buf;
85         uint32_t          offset;
86 } LV2_Event_Iterator;
87
88
89 /** Reset an iterator to point to the start of @a buf.
90  * @return True if @a iter is valid, otherwise false (buffer is empty) */
91 static inline bool
92 lv2_event_begin(LV2_Event_Iterator* iter,
93                 LV2_Event_Buffer*   buf)
94 {
95         iter->buf = buf;
96         iter->offset = 0;
97         return (buf->size > 0);
98 }
99
100
101 /** Check if @a iter is valid..
102  * @return True if @a iter is valid, otherwise false (past end of buffer) */
103 static inline bool
104 lv2_event_is_valid(LV2_Event_Iterator* iter)
105 {
106         return (iter->offset < iter->buf->size);
107 }
108
109
110 /** Advance @a iter forward one event.
111  * @a iter must be valid.
112  * @return True if @a iter is valid, otherwise false (reached end of buffer) */
113 static inline bool
114 lv2_event_increment(LV2_Event_Iterator* iter)
115 {
116         assert(lv2_event_is_valid(iter));
117
118         LV2_Event* const ev = (LV2_Event*)(
119                         (uint8_t*)iter->buf->data + iter->offset);
120
121         iter->offset += lv2_event_pad_size(sizeof(LV2_Event) + ev->size);       
122         
123         return true;
124 }
125
126
127 /** Dereference an event iterator (get the event currently pointed at).
128  * @a iter must be valid.
129  * @a data if non-NULL, will be set to point to the contents of the event
130  *         returned.
131  * @return A Pointer to the event @a iter is currently pointing at, or NULL
132  *         if the end of the buffer is reached (in which case @a data is
133  *         also set to NULL). */
134 static inline LV2_Event*
135 lv2_event_get(LV2_Event_Iterator* iter,
136               uint8_t**           data)
137 {
138         assert(lv2_event_is_valid(iter));
139
140         LV2_Event* const ev = (LV2_Event*)(
141                         (uint8_t*)iter->buf->data + iter->offset);
142
143         if (data)
144                 *data = (uint8_t*)ev + sizeof(LV2_Event);
145
146         return ev;
147 }
148
149
150 /** Write an event at @a iter.
151  * The event (if any) pointed to by @iter will be overwritten, and @a iter
152  * incremented to point to the following event (i.e. several calls to this
153  * function can be done in sequence without twiddling iter in-between).
154  * @return True if event was written, otherwise false (buffer is full). */
155 static inline bool
156 lv2_event_write(LV2_Event_Iterator* iter,
157                 uint32_t            frames,
158                 uint32_t            subframes,
159                 uint16_t            type,
160                 uint16_t            size,
161                 const uint8_t*      data)
162 {
163         if (iter->buf->capacity - iter->buf->size < sizeof(LV2_Event) + size)
164                 return false;
165
166         LV2_Event* const ev = (LV2_Event*)(
167                         (uint8_t*)iter->buf->data + iter->offset);
168         
169         ev->frames = frames;
170         ev->subframes = subframes;
171         ev->type = type;
172         ev->size = size;
173         memcpy((uint8_t*)ev + sizeof(LV2_Event), data, size);
174         ++iter->buf->event_count;
175         
176         size = lv2_event_pad_size(sizeof(LV2_Event) + size);
177         iter->buf->size += size;
178         iter->offset    += size;
179         
180         return true;
181 }
182
183
184 /** Reserve space for an event in the buffer and return a pointer to
185     the memory where the caller can write the event data, or NULL if there
186     is not enough room in the buffer. */
187 static inline uint8_t*
188 lv2_event_reserve(LV2_Event_Iterator* iter,
189                   uint32_t frames,
190                   uint32_t subframes,
191                   uint16_t type,
192                   uint16_t size) 
193 {
194         size = lv2_event_pad_size(size);
195         if (iter->buf->capacity - iter->buf->size < sizeof(LV2_Event) + size)
196                 return NULL;
197
198         LV2_Event* const ev = (LV2_Event*)((uint8_t*)iter->buf->data + 
199                                            iter->offset);
200         
201         ev->frames = frames;
202         ev->subframes = subframes;
203         ev->type = type;
204         ev->size = size;
205         ++iter->buf->event_count;
206         
207         size = lv2_event_pad_size(sizeof(LV2_Event) + size);
208         iter->buf->size += size;
209         iter->offset    += size;
210         
211         return (uint8_t*)ev + sizeof(LV2_Event);
212 }
213
214
215 /** Write an event at @a iter.
216  * The event (if any) pointed to by @iter will be overwritten, and @a iter
217  * incremented to point to the following event (i.e. several calls to this
218  * function can be done in sequence without twiddling iter in-between).
219  * @return True if event was written, otherwise false (buffer is full). */
220 static inline bool
221 lv2_event_write_event(LV2_Event_Iterator* iter,
222                       const LV2_Event*    ev,
223                       const uint8_t*      data)
224 {
225         if (iter->buf->capacity - iter->buf->size < sizeof(LV2_Event) + ev->size)
226                 return false;
227
228         LV2_Event* const write_ev = (LV2_Event*)(
229                         (uint8_t*)iter->buf->data + iter->offset);
230         
231         *write_ev = *ev;
232         memcpy((uint8_t*)write_ev + sizeof(LV2_Event), data, ev->size);
233         ++iter->buf->event_count;
234         
235         const uint16_t size = lv2_event_pad_size(sizeof(LV2_Event) + ev->size);
236         iter->buf->size += size;
237         iter->offset    += size;
238         
239         return true;
240 }
241
242 #endif // LV2_EVENT_HELPERS_H
243