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.

341 lines
9.7KB

  1. /*
  2. * Copyright (c) 2012 Mark McCurry
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  19. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22. * DEALINGS IN THE SOFTWARE.
  23. */
  24. /**
  25. * @file rtosc.h
  26. * Functions handling messages and arguments
  27. */
  28. #ifndef RTOSC_H
  29. #define RTOSC_H
  30. #include <stdarg.h>
  31. #include <stdint.h>
  32. #include <stddef.h>
  33. #include <stdbool.h>
  34. #ifdef __cplusplus
  35. extern "C" {
  36. #endif
  37. typedef struct {
  38. int32_t len;
  39. uint8_t *data;
  40. } rtosc_blob_t;
  41. typedef union {
  42. int32_t i; //i,c,r
  43. char T; //I,T,F,N
  44. float f; //f
  45. double d; //d
  46. int64_t h; //h
  47. uint64_t t; //t
  48. uint8_t m[4];//m
  49. const char *s; //s,S
  50. rtosc_blob_t b; //b
  51. } rtosc_arg_t;
  52. /**
  53. * Write OSC message to fixed length buffer
  54. *
  55. * On error, buffer will be zeroed.
  56. * When buffer is NULL, the function returns the size of the buffer required to
  57. * store the message
  58. *
  59. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  60. * //Example messages
  61. * char buffer[128];
  62. * rtosc_message(buffer,128,"/path","TFI");
  63. * rtosc_message(buffer,128,"/path","s","foobar");
  64. * rtosc_message(buffer,128,"/path","i",128);
  65. * rtosc_message(buffer,128,"/path","f",128.0);
  66. * const char blob[4] = {'a','b','c','d'};
  67. * rtosc_message(buffer,128,"/path","b",4,blob);
  68. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  69. *
  70. * @param buffer Memory to write to
  71. * @param len Length of buffer
  72. * @param address OSC pattern to send message to
  73. * @param arguments String consisting of the types of the following arguments
  74. * @param ... OSC arguments to pass forward
  75. * @returns length of resulting message or zero if bounds exceeded
  76. */
  77. size_t rtosc_message(char *buffer,
  78. size_t len,
  79. const char *address,
  80. const char *arguments,
  81. ...);
  82. /**
  83. * @see rtosc_message()
  84. */
  85. size_t rtosc_vmessage(char *buffer,
  86. size_t len,
  87. const char *address,
  88. const char *arguments,
  89. va_list va);
  90. /**
  91. * @see rtosc_message()
  92. */
  93. size_t rtosc_amessage(char *buffer,
  94. size_t len,
  95. const char *address,
  96. const char *arguments,
  97. const rtosc_arg_t *args);
  98. /**
  99. * Returns the number of arguments found in a given message
  100. *
  101. * @param msg well formed OSC message
  102. * @returns number of arguments in message
  103. */
  104. unsigned rtosc_narguments(const char *msg);
  105. /**
  106. * @param msg well formed OSC message
  107. * @param i index of argument
  108. * @returns the type of the ith argument in msg
  109. */
  110. char rtosc_type(const char *msg, unsigned i);
  111. typedef struct {
  112. const char *type_pos;
  113. const uint8_t *value_pos;
  114. } rtosc_arg_itr_t;
  115. typedef struct {
  116. char type;
  117. rtosc_arg_t val;
  118. } rtosc_arg_val_t;
  119. typedef struct
  120. {
  121. //!< tolerance to when two floats or doubles are equal
  122. double float_tolerance;
  123. } rtosc_cmp_options;
  124. /**
  125. * Check if two arrays of rtosc_arg_val_t are equal
  126. *
  127. * @param opt Comparison options or NULL for default options
  128. * @return One if they are equal, zero if not
  129. */
  130. int rtosc_arg_vals_eq(rtosc_arg_val_t* lhs, rtosc_arg_val_t* rhs,
  131. size_t lsize, size_t rsize,
  132. const rtosc_cmp_options* opt);
  133. /**
  134. * Compare two arrays of rtosc_arg_val_t.
  135. * Whether an argument value is less or greater than another is computed
  136. * - using memcmp for blobs
  137. * - using strcmp for strings and identifiers
  138. * - using numerical comparison for all other types.
  139. * As an exception, the timestamp "immediately" is defined to be smaller than
  140. * every other timestamp.
  141. *
  142. * @param opt Comparison options or NULL for default options
  143. * @return An integer less than, equal to, or greater than zero if lhs is found,
  144. * respectively, to be less than, to match, or be greater than rhs.
  145. */
  146. int rtosc_arg_vals_cmp(rtosc_arg_val_t* lhs, rtosc_arg_val_t* rhs,
  147. size_t lsize, size_t rsize,
  148. const rtosc_cmp_options* opt);
  149. //! va_list container, required for passing va_list as pointers to functions
  150. typedef struct { va_list a; } rtosc_va_list_t;
  151. /**
  152. * Pack arguments into pre-allocated rtosc_arg_t array
  153. *
  154. * @param args Pre-allocated array; size must be greater or equal @p nargs
  155. * @param nargs Size of elements to pack
  156. * @param arg_str Rtosc string specifying the arguments' types
  157. * @param ap The parameters that shall be packed
  158. */
  159. void rtosc_v2args(rtosc_arg_t* args, size_t nargs,
  160. const char* arg_str, rtosc_va_list_t* ap);
  161. /**
  162. * Pack parameters into pre-allocated rtosc_arg_val-t array
  163. * @see rtosc_v2args
  164. */
  165. void rtosc_v2argvals(rtosc_arg_val_t* args, size_t nargs,
  166. const char* arg_str, va_list ap);
  167. /**
  168. * Pack parameters into pre-allocated rtosc_arg_val-t array
  169. * @see rtosc_v2args
  170. */
  171. void rtosc_2argvals(rtosc_arg_val_t* args, size_t nargs,
  172. const char* arg_str, ...);
  173. /**
  174. * Create an argument iterator for a message
  175. * @param msg OSC message
  176. * @returns an initialized iterator
  177. */
  178. rtosc_arg_itr_t rtosc_itr_begin(const char *msg);
  179. /**
  180. * Gets the next argument in a message
  181. * @param itr OSC message iterator
  182. * @returns a type value pair from the message
  183. */
  184. rtosc_arg_val_t rtosc_itr_next(rtosc_arg_itr_t *itr);
  185. /**
  186. * Determines if the iterator is at the end of the argument list
  187. * @param itr OSC message iterator
  188. * @returns 1 if there are no more elements, 0 otherwise
  189. */
  190. int rtosc_itr_end(rtosc_arg_itr_t itr);
  191. /**
  192. * Blob data may be safely written to
  193. * @param msg OSC message
  194. * @param i index of argument
  195. * @returns an argument by value via the rtosc_arg_t union
  196. */
  197. rtosc_arg_t rtosc_argument(const char *msg, unsigned i);
  198. /**
  199. * @param msg OSC message
  200. * @param len Message length upper bound
  201. * @returns the size of a message given a chunk of memory.
  202. */
  203. size_t rtosc_message_length(const char *msg, size_t len);
  204. typedef struct {
  205. char *data;
  206. size_t len;
  207. } ring_t;
  208. /**
  209. * Finds the length of the next message inside a ringbuffer structure.
  210. *
  211. * @param ring The addresses and lengths of the split buffer, in a compatible
  212. * format to jack's ringbuffer
  213. * @returns size of message stored in ring datastructure
  214. */
  215. size_t rtosc_message_ring_length(ring_t *ring);
  216. /**
  217. * Validate if an arbitrary byte sequence is an OSC message.
  218. * @param msg pointer to memory buffer
  219. * @param len length of buffer
  220. */
  221. bool rtosc_valid_message_p(const char *msg, size_t len);
  222. /**
  223. * @param OSC message
  224. * @returns the argument string of a given message
  225. */
  226. const char *rtosc_argument_string(const char *msg);
  227. /**
  228. * Generate a bundle from sub-messages
  229. *
  230. * @param buffer Destination buffer
  231. * @param len Length of buffer
  232. * @param tt OSC time tag
  233. * @param elms Number of sub messages
  234. * @param ... Messages
  235. * @returns length of generated bundle or zero on failure
  236. */
  237. size_t rtosc_bundle(char *buffer, size_t len, uint64_t tt, int elms, ...);
  238. /**
  239. * Find the elements in a bundle
  240. *
  241. * @param msg OSC bundle
  242. * @param len Upper bound on the length of the bundle
  243. * @returns The number of messages contained within the bundle
  244. */
  245. size_t rtosc_bundle_elements(const char *msg, size_t len);
  246. /**
  247. * Fetch a message within the bundle
  248. *
  249. * @param msg OSC bundle
  250. * @param i index of sub-message
  251. * @returns The ith message within the bundle
  252. */
  253. const char *rtosc_bundle_fetch(const char *msg, unsigned i);
  254. /**
  255. * Get the size of a particular bundle element
  256. *
  257. * @param msg OSC bundle
  258. * @param i Index of sub-message
  259. * @returns The size of the ith sub-message in bytes
  260. */
  261. size_t rtosc_bundle_size(const char *msg, unsigned i);
  262. /**
  263. * Test if the buffer contains a bundle
  264. *
  265. * @param msg OSC message
  266. * @returns true if message is a bundle
  267. */
  268. int rtosc_bundle_p(const char *msg);
  269. /**
  270. * @returns Time Tag for a bundle
  271. */
  272. uint64_t rtosc_bundle_timetag(const char *msg);
  273. /**
  274. * This is a non-compliant pattern matcher for dispatching OSC messages
  275. *
  276. * Overall the pattern specification is
  277. * (normal-path)(\#digit-specifier)?(/)?(:argument-restrictor)*
  278. *
  279. * @param pattern The pattern string stored in the Port
  280. * @param msg The OSC message to be matched
  281. * @param path_end if non-NULL, will point to where parsing stopped in the path
  282. * (in case of a match, *path_end is always '/' or '\0')
  283. * @returns true if a normal match and false if unmatched
  284. */
  285. bool rtosc_match(const char *pattern,
  286. const char *msg, const char** path_end);
  287. /**
  288. * Attempt to match a rtosc style path while ignoring arguments
  289. *
  290. * @param pattern rtosc pattern
  291. * @param msg a normal C string or a rtosc message
  292. * @param path_end if non-NULL, will point to where parsing stopped in the path
  293. * (in case of a match, *path_end is always '/' or '\0')
  294. */
  295. const char *rtosc_match_path(const char *pattern,
  296. const char *msg, const char** path_end);
  297. #ifdef __cplusplus
  298. };
  299. #endif
  300. #endif