Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

atom-helpers.h 6.1KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. // lv2_atom_helpers.h
  2. //
  3. /****************************************************************************
  4. Copyright (C) 2005-2013, rncbc aka Rui Nuno Capela. All rights reserved.
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License along
  14. with this program; if not, write to the Free Software Foundation, Inc.,
  15. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  16. *****************************************************************************/
  17. /* Helper functions for LV2 atom:Sequence event buffer.
  18. *
  19. * tentatively adapted from:
  20. *
  21. * - lv2_evbuf.h,c - An abstract/opaque LV2 event buffer implementation.
  22. *
  23. * - event-helpers.h - Helper functions for the LV2 Event extension.
  24. * <http://lv2plug.in/ns/ext/event>
  25. *
  26. * Copyright 2008-2012 David Robillard <http://drobilla.net>
  27. */
  28. #ifndef LV2_ATOM_HELPERS_H
  29. #define LV2_ATOM_HELPERS_H
  30. #include <stdint.h>
  31. #include <stdbool.h>
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <assert.h>
  35. #include "atom.h"
  36. #ifdef __cplusplus
  37. extern "C" {
  38. #endif
  39. // An abstract/opaque LV2 atom:Sequence buffer.
  40. //
  41. typedef
  42. struct _LV2_Atom_Buffer
  43. {
  44. uint32_t capacity;
  45. uint32_t chunk_type;
  46. uint32_t sequence_type;
  47. LV2_Atom_Sequence atoms;
  48. } LV2_Atom_Buffer;
  49. // Pad a size to 64 bits (for LV2 atom:Sequence event sizes).
  50. //
  51. static inline
  52. uint32_t lv2_atom_buffer_pad_size ( uint32_t size )
  53. {
  54. return (size + 7) & (~7);
  55. }
  56. // Clear and initialize an existing LV2 atom:Sequenece buffer.
  57. //
  58. static inline
  59. void lv2_atom_buffer_reset ( LV2_Atom_Buffer *buf, bool input )
  60. {
  61. if (input) {
  62. buf->atoms.atom.size = sizeof(LV2_Atom_Sequence_Body);
  63. buf->atoms.atom.type = buf->sequence_type;
  64. } else {
  65. buf->atoms.atom.size = buf->capacity;
  66. buf->atoms.atom.type = buf->chunk_type;
  67. }
  68. }
  69. // Allocate a new, empty LV2 atom:Sequence buffer.
  70. //
  71. static inline
  72. LV2_Atom_Buffer *lv2_atom_buffer_new (
  73. uint32_t capacity, uint32_t chunk_type, uint32_t sequence_type, bool input )
  74. {
  75. LV2_Atom_Buffer *buf = (LV2_Atom_Buffer *)
  76. malloc(sizeof(LV2_Atom_Buffer) + sizeof(LV2_Atom_Sequence) + capacity);
  77. buf->capacity = capacity;
  78. buf->chunk_type = chunk_type;
  79. buf->sequence_type = sequence_type;
  80. lv2_atom_buffer_reset(buf, input);
  81. return buf;
  82. }
  83. // Free an LV2 atom:Sequenece buffer allocated with lv2_atome_buffer_new.
  84. //
  85. static inline
  86. void lv2_atom_buffer_free ( LV2_Atom_Buffer *buf )
  87. {
  88. free(buf);
  89. }
  90. // Return the total padded size of events stored in a LV2 atom:Sequence buffer.
  91. //
  92. static inline
  93. uint32_t lv2_atom_buffer_get_size ( LV2_Atom_Buffer *buf )
  94. {
  95. if (buf->atoms.atom.type == buf->sequence_type)
  96. return buf->atoms.atom.size - uint32_t(sizeof(LV2_Atom_Sequence_Body));
  97. else
  98. return 0;
  99. }
  100. // Return the actual LV2 atom:Sequence implementation.
  101. //
  102. static inline
  103. LV2_Atom_Sequence *lv2_atom_buffer_get_sequence ( LV2_Atom_Buffer *buf )
  104. {
  105. return &buf->atoms;
  106. }
  107. // An iterator over an atom:Sequence buffer.
  108. //
  109. typedef
  110. struct _LV2_Atom_Buffer_Iterator
  111. {
  112. LV2_Atom_Buffer *buf;
  113. uint32_t offset;
  114. } LV2_Atom_Buffer_Iterator;
  115. // Reset an iterator to point to the start of an LV2 atom:Sequence buffer.
  116. //
  117. static inline
  118. bool lv2_atom_buffer_begin (
  119. LV2_Atom_Buffer_Iterator *iter, LV2_Atom_Buffer *buf )
  120. {
  121. iter->buf = buf;
  122. iter->offset = 0;
  123. return (buf->atoms.atom.size > 0);
  124. }
  125. // Reset an iterator to point to the end of an LV2 atom:Sequence buffer.
  126. //
  127. static inline
  128. bool lv2_atom_buffer_end (
  129. LV2_Atom_Buffer_Iterator *iter, LV2_Atom_Buffer *buf )
  130. {
  131. iter->buf = buf;
  132. iter->offset = lv2_atom_buffer_pad_size(lv2_atom_buffer_get_size(buf));
  133. return (iter->offset < buf->capacity - sizeof(LV2_Atom_Event));
  134. }
  135. // Check if a LV2 atom:Sequenece buffer iterator is valid.
  136. //
  137. static inline
  138. bool lv2_atom_buffer_is_valid ( LV2_Atom_Buffer_Iterator *iter )
  139. {
  140. return iter->offset < lv2_atom_buffer_get_size(iter->buf);
  141. }
  142. // Advance a LV2 atom:Sequenece buffer iterator forward one event.
  143. //
  144. static inline
  145. bool lv2_atom_buffer_increment ( LV2_Atom_Buffer_Iterator *iter )
  146. {
  147. if (!lv2_atom_buffer_is_valid(iter))
  148. return false;
  149. LV2_Atom_Buffer *buf = iter->buf;
  150. LV2_Atom_Sequence *atoms = &buf->atoms;
  151. uint32_t size = ((LV2_Atom_Event *) ((char *)
  152. LV2_ATOM_CONTENTS(LV2_Atom_Sequence, atoms) + iter->offset))->body.size;
  153. iter->offset += lv2_atom_buffer_pad_size(uint32_t(sizeof(LV2_Atom_Event)) + size);
  154. return true;
  155. }
  156. // Get the event currently pointed at a LV2 atom:Sequence buffer iterator.
  157. //
  158. static inline
  159. LV2_Atom_Event *lv2_atom_buffer_get (
  160. LV2_Atom_Buffer_Iterator *iter, uint8_t **data )
  161. {
  162. if (!lv2_atom_buffer_is_valid(iter))
  163. return NULL;
  164. LV2_Atom_Buffer *buf = iter->buf;
  165. LV2_Atom_Sequence *atoms = &buf->atoms;
  166. LV2_Atom_Event *ev = (LV2_Atom_Event *) ((char *)
  167. LV2_ATOM_CONTENTS(LV2_Atom_Sequence, atoms) + iter->offset);
  168. *data = (uint8_t *) LV2_ATOM_BODY(&ev->body);
  169. return ev;
  170. }
  171. // Write an event at a LV2 atom:Sequence buffer iterator.
  172. static inline
  173. bool lv2_atom_buffer_write (
  174. LV2_Atom_Buffer_Iterator *iter,
  175. uint32_t frames,
  176. uint32_t /*subframes*/,
  177. uint32_t type,
  178. uint32_t size,
  179. const uint8_t *data )
  180. {
  181. LV2_Atom_Buffer *buf = iter->buf;
  182. LV2_Atom_Sequence *atoms = &buf->atoms;
  183. if (buf->capacity - sizeof(LV2_Atom) - atoms->atom.size
  184. < sizeof(LV2_Atom_Event) + size)
  185. return false;
  186. LV2_Atom_Event *ev = (LV2_Atom_Event*) ((char *)
  187. LV2_ATOM_CONTENTS(LV2_Atom_Sequence, atoms) + iter->offset);
  188. ev->time.frames = frames;
  189. ev->body.type = type;
  190. ev->body.size = size;
  191. memcpy(LV2_ATOM_BODY(&ev->body), data, size);
  192. size = lv2_atom_buffer_pad_size(uint32_t(sizeof(LV2_Atom_Event)) + size);
  193. atoms->atom.size += size;
  194. iter->offset += size;
  195. return true;
  196. }
  197. #ifdef __cplusplus
  198. } /* extern "C" */
  199. #endif
  200. #endif // LV2_ATOM_HELPERS_H
  201. // end of lv2_atom_helpers.h