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.

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