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.

353 lines
12KB

  1. /*
  2. * Carla OSC utils
  3. * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the GPL.txt file
  16. */
  17. #ifndef __CARLA_OSC_UTILS_HPP__
  18. #define __CARLA_OSC_UTILS_HPP__
  19. #include "CarlaJuceUtils.hpp"
  20. #include <lo/lo.h>
  21. // -------------------------------------------------
  22. struct CarlaOscData {
  23. const char* path;
  24. lo_address source;
  25. lo_address target;
  26. CarlaOscData()
  27. : path(nullptr),
  28. source(nullptr),
  29. target(nullptr) {}
  30. ~CarlaOscData()
  31. {
  32. free();
  33. }
  34. void free()
  35. {
  36. if (path != nullptr)
  37. {
  38. delete[] path;
  39. path = nullptr;
  40. }
  41. if (source != nullptr)
  42. {
  43. lo_address_free(source);
  44. source = nullptr;
  45. }
  46. if (target != nullptr)
  47. {
  48. lo_address_free(target);
  49. target = nullptr;
  50. }
  51. }
  52. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(CarlaOscData)
  53. };
  54. // -------------------------------------------------
  55. static inline
  56. void osc_send_configure(const CarlaOscData* const oscData, const char* const key, const char* const value)
  57. {
  58. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  59. CARLA_ASSERT(key != nullptr);
  60. CARLA_ASSERT(value != nullptr);
  61. carla_debug("osc_send_configure(path:\"%s\", \"%s\", \"%s\")", oscData->path, key, value);
  62. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && key != nullptr && value != nullptr)
  63. {
  64. char targetPath[std::strlen(oscData->path)+11];
  65. std::strcpy(targetPath, oscData->path);
  66. std::strcat(targetPath, "/configure");
  67. lo_send(oscData->target, targetPath, "ss", key, value);
  68. }
  69. }
  70. static inline
  71. void osc_send_control(const CarlaOscData* const oscData, const int32_t index, const float value)
  72. {
  73. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  74. CARLA_ASSERT(index != -1); // -1 == PARAMETER_NULL
  75. carla_debug("osc_send_control(path:\"%s\", %i, %f)", oscData->path, index, value);
  76. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && index != -1)
  77. {
  78. char targetPath[std::strlen(oscData->path)+9];
  79. std::strcpy(targetPath, oscData->path);
  80. std::strcat(targetPath, "/control");
  81. lo_send(oscData->target, targetPath, "if", index, value);
  82. }
  83. }
  84. static inline
  85. void osc_send_program(const CarlaOscData* const oscData, const int32_t index)
  86. {
  87. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  88. CARLA_ASSERT(index >= 0);
  89. carla_debug("osc_send_program(path:\"%s\", %i)", oscData->path, index);
  90. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && index >= 0)
  91. {
  92. char targetPath[std::strlen(oscData->path)+9];
  93. std::strcpy(targetPath, oscData->path);
  94. std::strcat(targetPath, "/program");
  95. lo_send(oscData->target, targetPath, "i", index);
  96. }
  97. }
  98. static inline
  99. void osc_send_program(const CarlaOscData* const oscData, const int32_t bank, const int32_t program)
  100. {
  101. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  102. CARLA_ASSERT(program >= 0);
  103. CARLA_ASSERT(bank >= 0);
  104. carla_debug("osc_send_program(path:\"%s\", %i, %i)", oscData->path, bank, program);
  105. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && bank >= 0 && program >= 0)
  106. {
  107. char targetPath[std::strlen(oscData->path)+9];
  108. std::strcpy(targetPath, oscData->path);
  109. std::strcat(targetPath, "/program");
  110. lo_send(oscData->target, targetPath, "ii", bank, program);
  111. }
  112. }
  113. static inline
  114. void osc_send_midi_program(const CarlaOscData* const oscData, const int32_t index)
  115. {
  116. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  117. CARLA_ASSERT(index >= 0);
  118. carla_debug("osc_send_midi_program(path:\"%s\", %i)", oscData->path, index);
  119. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && index >= 0)
  120. {
  121. char targetPath[std::strlen(oscData->path)+14];
  122. std::strcpy(targetPath, oscData->path);
  123. std::strcat(targetPath, "/midi-program");
  124. lo_send(oscData->target, targetPath, "i", index);
  125. }
  126. }
  127. static inline
  128. void osc_send_midi_program(const CarlaOscData* const oscData, const int32_t bank, const int32_t program)
  129. {
  130. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  131. CARLA_ASSERT(program >= 0);
  132. CARLA_ASSERT(bank >= 0);
  133. carla_debug("osc_send_midi_program(path:\"%s\", %i, %i)", oscData->path, bank, program);
  134. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && bank >= 0 && program >= 0)
  135. {
  136. char targetPath[std::strlen(oscData->path)+14];
  137. std::strcpy(targetPath, oscData->path);
  138. std::strcat(targetPath, "/midi-program");
  139. lo_send(oscData->target, targetPath, "ii", bank, program);
  140. }
  141. }
  142. static inline
  143. void osc_send_midi(const CarlaOscData* const oscData, const uint8_t buf[4])
  144. {
  145. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  146. CARLA_ASSERT(buf[0] == 0);
  147. CARLA_ASSERT(buf[1] != 0);
  148. carla_debug("osc_send_midi(path:\"%s\", 0x%X, %03u, %03u)", oscData->path, buf[1], buf[2], buf[3]);
  149. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && buf[0] == 0 && buf[1] != 0)
  150. {
  151. char targetPath[std::strlen(oscData->path)+6];
  152. std::strcpy(targetPath, oscData->path);
  153. std::strcat(targetPath, "/midi");
  154. lo_send(oscData->target, targetPath, "m", buf);
  155. }
  156. }
  157. static inline
  158. void osc_send_sample_rate(const CarlaOscData* const oscData, const float sampleRate)
  159. {
  160. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  161. CARLA_ASSERT(sampleRate > 0.0f);
  162. carla_debug("osc_send_sample_rate(path:\"%s\", %f)", oscData->path, sampleRate);
  163. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && sampleRate > 0.0f)
  164. {
  165. char targetPath[std::strlen(oscData->path)+13];
  166. std::strcpy(targetPath, oscData->path);
  167. std::strcat(targetPath, "/sample-rate");
  168. lo_send(oscData->target, targetPath, "f", sampleRate);
  169. }
  170. }
  171. #ifdef BUILD_BRIDGE
  172. static inline
  173. void osc_send_update(const CarlaOscData* const oscData, const char* const url)
  174. {
  175. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  176. CARLA_ASSERT(url != nullptr);
  177. carla_debug("osc_send_update(path:\"%s\", \"%s\")", oscData->path, url);
  178. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && url != nullptr)
  179. {
  180. char targetPath[std::strlen(oscData->path)+8];
  181. std::strcpy(targetPath, oscData->path);
  182. std::strcat(targetPath, "/update");
  183. lo_send(oscData->target, targetPath, "s", url);
  184. }
  185. }
  186. static inline
  187. void osc_send_exiting(const CarlaOscData* const oscData)
  188. {
  189. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  190. carla_debug("osc_send_exiting(path:\"%s\")", oscData->path);
  191. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr)
  192. {
  193. char targetPath[std::strlen(oscData->path)+9];
  194. std::strcpy(targetPath, oscData->path);
  195. std::strcat(targetPath, "/exiting");
  196. lo_send(oscData->target, targetPath, "");
  197. }
  198. }
  199. #endif
  200. static inline
  201. void osc_send_show(const CarlaOscData* const oscData)
  202. {
  203. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  204. carla_debug("osc_send_show(path:\"%s\")", oscData->path);
  205. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr)
  206. {
  207. char targetPath[std::strlen(oscData->path)+6];
  208. std::strcpy(targetPath, oscData->path);
  209. std::strcat(targetPath, "/show");
  210. lo_send(oscData->target, targetPath, "");
  211. }
  212. }
  213. static inline
  214. void osc_send_hide(const CarlaOscData* const oscData)
  215. {
  216. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  217. carla_debug("osc_send_hide(path:\"%s\")", oscData->path);
  218. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr)
  219. {
  220. char targetPath[std::strlen(oscData->path)+6];
  221. std::strcpy(targetPath, oscData->path);
  222. std::strcat(targetPath, "/hide");
  223. lo_send(oscData->target, targetPath, "");
  224. }
  225. }
  226. static inline
  227. void osc_send_quit(const CarlaOscData* const oscData)
  228. {
  229. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  230. carla_debug("osc_send_quit(path:\"%s\")", oscData->path);
  231. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr)
  232. {
  233. char targetPath[std::strlen(oscData->path)+6];
  234. std::strcpy(targetPath, oscData->path);
  235. std::strcat(targetPath, "/quit");
  236. lo_send(oscData->target, targetPath, "");
  237. }
  238. }
  239. // -------------------------------------------------
  240. #ifdef BUILD_BRIDGE_PLUGIN
  241. static inline
  242. void osc_send_bridge_update(const CarlaOscData* const oscData, const char* const url)
  243. {
  244. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  245. CARLA_ASSERT(url != nullptr);
  246. carla_debug("osc_send_bridge_update(path:\"%s\", \"%s\")", oscData->path, url);
  247. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && url != nullptr)
  248. {
  249. char targetPath[std::strlen(oscData->path)+15];
  250. std::strcpy(targetPath, oscData->path);
  251. std::strcat(targetPath, "/bridge_update");
  252. lo_send(oscData->target, targetPath, "s", url);
  253. }
  254. }
  255. static inline
  256. void osc_send_bridge_error(const CarlaOscData* const oscData, const char* const error)
  257. {
  258. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  259. CARLA_ASSERT(error != nullptr);
  260. carla_debug("osc_send_bridge_error(path:\"%s\", \"%s\")", oscData->path, error);
  261. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && error != nullptr)
  262. {
  263. char targetPath[std::strlen(oscData->path)+14];
  264. std::strcpy(targetPath, oscData->path);
  265. std::strcat(targetPath, "/bridge_error");
  266. lo_send(oscData->target, targetPath, "s", error);
  267. }
  268. }
  269. #endif
  270. #if defined(BRIDGE_LV2) || defined(WANT_LV2)
  271. static inline
  272. void osc_send_lv2_atom_transfer(const CarlaOscData* const oscData, const int32_t portIndex, const char* const atomBuf)
  273. {
  274. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  275. CARLA_ASSERT(portIndex >= 0);
  276. CARLA_ASSERT(atomBuf != nullptr);
  277. carla_debug("osc_send_lv2_atom_transfer(path:\"%s\", %i, <atomBuf:%p>)", oscData->path, portIndex, atomBuf);
  278. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && portIndex >= 0 && atomBuf != nullptr)
  279. {
  280. char targetPath[std::strlen(oscData->path)+19];
  281. std::strcpy(targetPath, oscData->path);
  282. std::strcat(targetPath, "/lv2_atom_transfer");
  283. lo_send(oscData->target, targetPath, "is", portIndex, atomBuf);
  284. }
  285. }
  286. static inline
  287. void osc_send_lv2_urid_map(const CarlaOscData* const oscData, const uint32_t urid, const char* const uri)
  288. {
  289. CARLA_ASSERT(oscData != nullptr && oscData->path != nullptr);
  290. CARLA_ASSERT(urid > 0);
  291. CARLA_ASSERT(uri != nullptr);
  292. carla_debug("osc_send_lv2_urid_map(path:\"%s\", %i, \"%s\")", oscData->path, urid, uri);
  293. if (oscData != nullptr && oscData->path != nullptr && oscData->target != nullptr && urid > 0 && uri != nullptr)
  294. {
  295. char targetPath[std::strlen(oscData->path)+14];
  296. std::strcpy(targetPath, oscData->path);
  297. std::strcat(targetPath, "/lv2_urid_map");
  298. lo_send(oscData->target, targetPath, "is", urid, uri);
  299. }
  300. }
  301. #endif
  302. // -------------------------------------------------
  303. #endif // __CARLA_OSC_UTILS_HPP__