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.

319 lines
11KB

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