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.

322 lines
12KB

  1. /*
  2. * Carla OSC utils
  3. * Copyright (C) 2012-2014 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 doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_OSC_UTILS_HPP_INCLUDED
  18. #define CARLA_OSC_UTILS_HPP_INCLUDED
  19. #include "CarlaUtils.hpp"
  20. #include <lo/lo.h>
  21. #define try_lo_send(...) \
  22. try { \
  23. lo_send(__VA_ARGS__); \
  24. } CARLA_SAFE_EXCEPTION("lo_send");
  25. // -----------------------------------------------------------------------
  26. struct CarlaOscData {
  27. const char* path;
  28. lo_address source;
  29. lo_address target;
  30. CarlaOscData() noexcept
  31. : path(nullptr),
  32. source(nullptr),
  33. target(nullptr) {}
  34. ~CarlaOscData() noexcept
  35. {
  36. free();
  37. }
  38. void free() noexcept
  39. {
  40. if (path != nullptr)
  41. {
  42. delete[] path;
  43. path = nullptr;
  44. }
  45. if (source != nullptr)
  46. {
  47. try {
  48. lo_address_free(source);
  49. } catch(...) {}
  50. source = nullptr;
  51. }
  52. if (target != nullptr)
  53. {
  54. try {
  55. lo_address_free(target);
  56. } catch(...) {}
  57. target = nullptr;
  58. }
  59. }
  60. CARLA_PREVENT_HEAP_ALLOCATION
  61. CARLA_DECLARE_NON_COPY_STRUCT(CarlaOscData)
  62. };
  63. // -----------------------------------------------------------------------
  64. static inline
  65. void osc_send_configure(const CarlaOscData& oscData, const char* const key, const char* const value) noexcept
  66. {
  67. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  68. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  69. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  70. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  71. carla_debug("osc_send_configure(path:\"%s\", \"%s\", \"%s\")", oscData.path, key, value);
  72. char targetPath[std::strlen(oscData.path)+11];
  73. std::strcpy(targetPath, oscData.path);
  74. std::strcat(targetPath, "/configure");
  75. try_lo_send(oscData.target, targetPath, "ss", key, value);
  76. }
  77. static inline
  78. void osc_send_control(const CarlaOscData& oscData, const int32_t index, const float value) noexcept
  79. {
  80. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  81. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  82. CARLA_SAFE_ASSERT_RETURN(index != -1,); // -1 == PARAMETER_NULL
  83. carla_debug("osc_send_control(path:\"%s\", %i, %f)", oscData.path, index, value);
  84. char targetPath[std::strlen(oscData.path)+9];
  85. std::strcpy(targetPath, oscData.path);
  86. std::strcat(targetPath, "/control");
  87. try_lo_send(oscData.target, targetPath, "if", index, value);
  88. }
  89. static inline
  90. void osc_send_program(const CarlaOscData& oscData, const uint32_t index) noexcept
  91. {
  92. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  93. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  94. carla_debug("osc_send_program(path:\"%s\", %u)", oscData.path, index);
  95. char targetPath[std::strlen(oscData.path)+9];
  96. std::strcpy(targetPath, oscData.path);
  97. std::strcat(targetPath, "/program");
  98. try_lo_send(oscData.target, targetPath, "i", static_cast<int32_t>(index));
  99. }
  100. static inline
  101. void osc_send_program(const CarlaOscData& oscData, const uint32_t bank, const uint32_t program) noexcept
  102. {
  103. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  104. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  105. carla_debug("osc_send_program(path:\"%s\", %u, %u)", oscData.path, bank, program);
  106. char targetPath[std::strlen(oscData.path)+9];
  107. std::strcpy(targetPath, oscData.path);
  108. std::strcat(targetPath, "/program");
  109. try_lo_send(oscData.target, targetPath, "ii", static_cast<int32_t>(bank), static_cast<int32_t>(program));
  110. }
  111. static inline
  112. void osc_send_midi_program(const CarlaOscData& oscData, const uint32_t index) noexcept
  113. {
  114. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  115. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  116. carla_debug("osc_send_midi_program(path:\"%s\", %u)", oscData.path, index);
  117. char targetPath[std::strlen(oscData.path)+14];
  118. std::strcpy(targetPath, oscData.path);
  119. std::strcat(targetPath, "/midi-program");
  120. try_lo_send(oscData.target, targetPath, "i", static_cast<int32_t>(index));
  121. }
  122. static inline
  123. void osc_send_midi_program(const CarlaOscData& oscData, const uint32_t bank, const uint32_t program) noexcept
  124. {
  125. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  126. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  127. carla_debug("osc_send_midi_program(path:\"%s\", %u, %u)", oscData.path, bank, program);
  128. char targetPath[std::strlen(oscData.path)+14];
  129. std::strcpy(targetPath, oscData.path);
  130. std::strcat(targetPath, "/midi-program");
  131. try_lo_send(oscData.target, targetPath, "ii", static_cast<int32_t>(bank), static_cast<int32_t>(program));
  132. }
  133. static inline
  134. void osc_send_midi(const CarlaOscData& oscData, const uint8_t buf[4]) noexcept
  135. {
  136. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  137. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  138. CARLA_SAFE_ASSERT_RETURN(buf[0] == 0,);
  139. CARLA_SAFE_ASSERT_RETURN(buf[1] != 0,);
  140. carla_debug("osc_send_midi(path:\"%s\", port:%u, {0x%X, %03u, %03u})", oscData.path, buf[0], buf[1], buf[2], buf[3]);
  141. char targetPath[std::strlen(oscData.path)+6];
  142. std::strcpy(targetPath, oscData.path);
  143. std::strcat(targetPath, "/midi");
  144. try_lo_send(oscData.target, targetPath, "m", buf);
  145. }
  146. static inline
  147. void osc_send_sample_rate(const CarlaOscData& oscData, const float sampleRate) noexcept
  148. {
  149. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  150. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  151. CARLA_SAFE_ASSERT_RETURN(sampleRate > 0.0f,);
  152. carla_debug("osc_send_sample_rate(path:\"%s\", %f)", oscData.path, sampleRate);
  153. char targetPath[std::strlen(oscData.path)+13];
  154. std::strcpy(targetPath, oscData.path);
  155. std::strcat(targetPath, "/sample-rate");
  156. try_lo_send(oscData.target, targetPath, "f", sampleRate);
  157. }
  158. #ifdef BUILD_BRIDGE
  159. static inline
  160. void osc_send_update(const CarlaOscData& oscData, const char* const url) noexcept
  161. {
  162. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  163. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  164. CARLA_SAFE_ASSERT_RETURN(url != nullptr && url[0] != '\0',);
  165. carla_debug("osc_send_update(path:\"%s\", \"%s\")", oscData.path, url);
  166. char targetPath[std::strlen(oscData.path)+8];
  167. std::strcpy(targetPath, oscData.path);
  168. std::strcat(targetPath, "/update");
  169. try_lo_send(oscData.target, targetPath, "s", url);
  170. }
  171. static inline
  172. void osc_send_exiting(const CarlaOscData& oscData) noexcept
  173. {
  174. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  175. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  176. carla_debug("osc_send_exiting(path:\"%s\")", oscData.path);
  177. char targetPath[std::strlen(oscData.path)+9];
  178. std::strcpy(targetPath, oscData.path);
  179. std::strcat(targetPath, "/exiting");
  180. try_lo_send(oscData.target, targetPath, "");
  181. }
  182. #endif
  183. static inline
  184. void osc_send_show(const CarlaOscData& oscData) noexcept
  185. {
  186. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  187. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  188. carla_debug("osc_send_show(path:\"%s\")", oscData.path);
  189. char targetPath[std::strlen(oscData.path)+6];
  190. std::strcpy(targetPath, oscData.path);
  191. std::strcat(targetPath, "/show");
  192. try_lo_send(oscData.target, targetPath, "");
  193. }
  194. static inline
  195. void osc_send_hide(const CarlaOscData& oscData) noexcept
  196. {
  197. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  198. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  199. carla_debug("osc_send_hide(path:\"%s\")", oscData.path);
  200. char targetPath[std::strlen(oscData.path)+6];
  201. std::strcpy(targetPath, oscData.path);
  202. std::strcat(targetPath, "/hide");
  203. try_lo_send(oscData.target, targetPath, "");
  204. }
  205. static inline
  206. void osc_send_quit(const CarlaOscData& oscData) noexcept
  207. {
  208. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  209. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  210. carla_debug("osc_send_quit(path:\"%s\")", oscData.path);
  211. char targetPath[std::strlen(oscData.path)+6];
  212. std::strcpy(targetPath, oscData.path);
  213. std::strcat(targetPath, "/quit");
  214. try_lo_send(oscData.target, targetPath, "");
  215. }
  216. // -----------------------------------------------------------------------
  217. #ifdef BUILD_BRIDGE_PLUGIN
  218. static inline
  219. void osc_send_bridge_update(const CarlaOscData& oscData, const char* const url) noexcept
  220. {
  221. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  222. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  223. CARLA_SAFE_ASSERT_RETURN(url != nullptr && url[0] != '\0',);
  224. carla_debug("osc_send_bridge_update(path:\"%s\", \"%s\")", oscData.path, url);
  225. char targetPath[std::strlen(oscData.path)+19];
  226. std::strcpy(targetPath, oscData.path);
  227. std::strcat(targetPath, "/bridge_update_now");
  228. try_lo_send(oscData.target, targetPath, "s", url);
  229. }
  230. static inline
  231. void osc_send_bridge_error(const CarlaOscData& oscData, const char* const error) noexcept
  232. {
  233. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  234. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  235. CARLA_SAFE_ASSERT_RETURN(error != nullptr && error[0] != '\0',);
  236. carla_debug("osc_send_bridge_error(path:\"%s\", \"%s\")", oscData.path, error);
  237. char targetPath[std::strlen(oscData.path)+14];
  238. std::strcpy(targetPath, oscData.path);
  239. std::strcat(targetPath, "/bridge_error");
  240. try_lo_send(oscData.target, targetPath, "s", error);
  241. }
  242. #endif
  243. #if defined(BRIDGE_LV2) || defined(WANT_LV2)
  244. static inline
  245. void osc_send_lv2_atom_transfer(const CarlaOscData& oscData, const uint32_t portIndex, const char* const atomBuf) noexcept
  246. {
  247. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  248. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  249. CARLA_SAFE_ASSERT_RETURN(atomBuf != nullptr && atomBuf[0] != '\0',);
  250. carla_debug("osc_send_lv2_atom_transfer(path:\"%s\", %u, <atomBuf:%p>)", oscData.path, portIndex, atomBuf);
  251. char targetPath[std::strlen(oscData.path)+19];
  252. std::strcpy(targetPath, oscData.path);
  253. std::strcat(targetPath, "/lv2_atom_transfer");
  254. try_lo_send(oscData.target, targetPath, "is", static_cast<int32_t>(portIndex), atomBuf);
  255. }
  256. static inline
  257. void osc_send_lv2_urid_map(const CarlaOscData& oscData, const uint32_t urid, const char* const uri) noexcept
  258. {
  259. CARLA_SAFE_ASSERT_RETURN(oscData.path != nullptr && oscData.path[0] != '\0',);
  260. CARLA_SAFE_ASSERT_RETURN(oscData.target != nullptr,);
  261. CARLA_SAFE_ASSERT_RETURN(urid != 0,);
  262. CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0',);
  263. carla_debug("osc_send_lv2_urid_map(path:\"%s\", %u, \"%s\")", oscData.path, urid, uri);
  264. char targetPath[std::strlen(oscData.path)+14];
  265. std::strcpy(targetPath, oscData.path);
  266. std::strcat(targetPath, "/lv2_urid_map");
  267. try_lo_send(oscData.target, targetPath, "is", static_cast<int32_t>(urid), uri);
  268. }
  269. #endif
  270. // -----------------------------------------------------------------------
  271. #endif // CARLA_OSC_UTILS_HPP_INCLUDED