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.

320 lines
14KB

  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2019 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. #include "CarlaEngineOsc.hpp"
  18. #ifdef HAVE_LIBLO
  19. #include "CarlaBackendUtils.hpp"
  20. #include "CarlaEngine.hpp"
  21. #include "CarlaPlugin.hpp"
  22. CARLA_BACKEND_START_NAMESPACE
  23. // -----------------------------------------------------------------------
  24. void CarlaEngineOsc::sendCallback(const EngineCallbackOpcode action, const uint pluginId,
  25. const int value1, const int value2, const int value3,
  26. const float valuef, const char* const valueStr) const noexcept
  27. {
  28. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  29. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  30. carla_stdout("CarlaEngineOsc::sendCallback(%i:%s, %i, %i, %i, %i, %f, \"%s\")",
  31. action, EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3,
  32. static_cast<double>(valuef), valueStr);
  33. static const char* const kFakeNullString = "(null)";
  34. char targetPath[std::strlen(fControlDataTCP.path)+10];
  35. std::strcpy(targetPath, fControlDataTCP.path);
  36. std::strcat(targetPath, "/cb");
  37. try_lo_send(fControlDataTCP.target, targetPath, "iiiiifs",
  38. action, pluginId, value1, value2, value3, static_cast<double>(valuef),
  39. valueStr != nullptr ? valueStr : kFakeNullString);
  40. }
  41. void CarlaEngineOsc::sendPluginInit(const uint pluginId, const char* const pluginName) const noexcept
  42. {
  43. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  44. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  45. CARLA_SAFE_ASSERT_RETURN(pluginName != nullptr && pluginName[0] != '\0',);
  46. carla_stdout("CarlaEngineOsc::sendPluginInit(%i, \"%s\")", pluginId, pluginName);
  47. char targetPath[std::strlen(fControlDataTCP.path)+18];
  48. std::strcpy(targetPath, fControlDataTCP.path);
  49. std::strcat(targetPath, "/init");
  50. try_lo_send(fControlDataTCP.target, targetPath, "is", static_cast<int32_t>(pluginId), pluginName);
  51. }
  52. void CarlaEngineOsc::sendPluginInfo(const CarlaPlugin* const plugin) const noexcept
  53. {
  54. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  55. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  56. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  57. carla_stdout("CarlaEngineOsc::sendPluginInfo(%p)", plugin);
  58. char bufName[STR_MAX+1], bufLabel[STR_MAX+1], bufMaker[STR_MAX+1], bufCopyright[STR_MAX+1];
  59. carla_zeroChars(bufName, STR_MAX+1);
  60. carla_zeroChars(bufLabel, STR_MAX+1);
  61. carla_zeroChars(bufMaker, STR_MAX+1);
  62. carla_zeroChars(bufCopyright, STR_MAX+1);
  63. plugin->getRealName(bufName);
  64. plugin->getLabel(bufLabel);
  65. plugin->getMaker(bufMaker);
  66. plugin->getCopyright(bufCopyright);
  67. char targetPath[std::strlen(fControlDataTCP.path)+10];
  68. std::strcpy(targetPath, fControlDataTCP.path);
  69. std::strcat(targetPath, "/info");
  70. try_lo_send(fControlDataTCP.target, targetPath, "iiiihssss",
  71. static_cast<int32_t>(plugin->getId()),
  72. static_cast<int32_t>(plugin->getType()),
  73. static_cast<int32_t>(plugin->getCategory()),
  74. static_cast<int32_t>(plugin->getHints()),
  75. static_cast<int64_t>(plugin->getUniqueId()),
  76. bufName, bufLabel, bufMaker, bufCopyright);
  77. }
  78. void CarlaEngineOsc::sendPluginPortCount(const CarlaPlugin* const plugin) const noexcept
  79. {
  80. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  81. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  82. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  83. carla_stdout("CarlaEngineOsc::sendPluginInfo(%p)", plugin);
  84. uint32_t paramIns, paramOuts;
  85. plugin->getParameterCountInfo(paramIns, paramOuts);
  86. if (paramIns > 49)
  87. paramIns = 49;
  88. if (paramOuts > 49)
  89. paramOuts = 49;
  90. char targetPath[std::strlen(fControlDataTCP.path)+7];
  91. std::strcpy(targetPath, fControlDataTCP.path);
  92. std::strcat(targetPath, "/ports");
  93. try_lo_send(fControlDataTCP.target, targetPath, "iiiiiiii",
  94. static_cast<int32_t>(plugin->getId()),
  95. static_cast<int32_t>(plugin->getAudioInCount()),
  96. static_cast<int32_t>(plugin->getAudioOutCount()),
  97. static_cast<int32_t>(plugin->getMidiInCount()),
  98. static_cast<int32_t>(plugin->getMidiOutCount()),
  99. static_cast<int32_t>(paramIns),
  100. static_cast<int32_t>(paramOuts),
  101. static_cast<int32_t>(plugin->getParameterCount()));
  102. }
  103. void CarlaEngineOsc::sendPluginParameterInfo(const CarlaPlugin* const plugin, const uint32_t parameterId) const noexcept
  104. {
  105. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  106. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  107. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  108. carla_debug("CarlaEngineOsc::sendPluginInfo(%p, %u)", plugin, parameterId);
  109. char bufName[STR_MAX+1], bufUnit[STR_MAX+1];
  110. carla_zeroChars(bufName, STR_MAX+1);
  111. carla_zeroChars(bufUnit, STR_MAX+1);
  112. const ParameterData& paramData(plugin->getParameterData(parameterId));
  113. const ParameterRanges& paramRanges(plugin->getParameterRanges(parameterId));
  114. plugin->getParameterName(parameterId, bufName);
  115. plugin->getParameterUnit(parameterId, bufUnit);
  116. char targetPath[std::strlen(fControlDataTCP.path)+20];
  117. std::strcpy(targetPath, fControlDataTCP.path);
  118. std::strcat(targetPath, "/param");
  119. try_lo_send(fControlDataTCP.target, targetPath, "iiiiiissfffffff",
  120. static_cast<int32_t>(plugin->getId()), static_cast<int32_t>(parameterId),
  121. static_cast<int32_t>(paramData.type), static_cast<int32_t>(paramData.hints),
  122. static_cast<int32_t>(paramData.midiChannel), static_cast<int32_t>(paramData.midiCC),
  123. bufName, bufUnit,
  124. static_cast<double>(paramRanges.def),
  125. static_cast<double>(paramRanges.min),
  126. static_cast<double>(paramRanges.max),
  127. static_cast<double>(paramRanges.step),
  128. static_cast<double>(paramRanges.stepSmall),
  129. static_cast<double>(paramRanges.stepLarge),
  130. static_cast<double>(plugin->getParameterValue(parameterId)));
  131. }
  132. void CarlaEngineOsc::sendPluginInternalParameterValues(const CarlaPlugin* const plugin) const noexcept
  133. {
  134. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  135. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  136. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  137. carla_debug("CarlaEngineOsc::sendPluginInternalParameterValues(%p)", plugin);
  138. static_assert(PARAMETER_ACTIVE == -2 && PARAMETER_MAX == -9);
  139. double iparams[7];
  140. for (int32_t i = 0; i < 7; ++i)
  141. iparams[i] = plugin->getInternalParameterValue(PARAMETER_ACTIVE - i);
  142. char targetPath[std::strlen(fControlDataTCP.path)+18];
  143. std::strcpy(targetPath, fControlDataTCP.path);
  144. std::strcat(targetPath, "/iparams");
  145. try_lo_send(fControlDataTCP.target, targetPath, "ifffffff",
  146. static_cast<int32_t>(plugin->getId()),
  147. iparams[0], // PARAMETER_ACTIVE
  148. iparams[1], // PARAMETER_DRYWET
  149. iparams[2], // PARAMETER_VOLUME
  150. iparams[3], // PARAMETER_BALANCE_LEFT
  151. iparams[4], // PARAMETER_BALANCE_RIGHT
  152. iparams[5], // PARAMETER_PANNING
  153. iparams[6] // PARAMETER_CTRL_CHANNEL
  154. );
  155. }
  156. #if 0
  157. void CarlaEngineOsc::sendset_program_count(const uint pluginId, const uint32_t count) const noexcept
  158. {
  159. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  160. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  161. carla_debug("CarlaEngineOsc::sendset_program_count(%i, %i)", pluginId, count);
  162. char targetPath[std::strlen(fControlDataTCP.path)+19];
  163. std::strcpy(targetPath, fControlDataTCP.path);
  164. std::strcat(targetPath, "/set_program_count");
  165. try_lo_send(fControlDataTCP.target, targetPath, "ii", static_cast<int32_t>(pluginId), static_cast<int32_t>(count));
  166. }
  167. void CarlaEngineOsc::sendset_midi_program_count(const uint pluginId, const uint32_t count) const noexcept
  168. {
  169. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  170. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  171. carla_debug("CarlaEngineOsc::sendset_midi_program_count(%i, %i)", pluginId, count);
  172. char targetPath[std::strlen(fControlDataTCP.path)+24];
  173. std::strcpy(targetPath, fControlDataTCP.path);
  174. std::strcat(targetPath, "/set_midi_program_count");
  175. try_lo_send(fControlDataTCP.target, targetPath, "ii", static_cast<int32_t>(pluginId), static_cast<int32_t>(count));
  176. }
  177. void CarlaEngineOsc::sendset_program_name(const uint pluginId, const uint32_t index, const char* const name) const noexcept
  178. {
  179. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  180. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  181. CARLA_SAFE_ASSERT_RETURN(name != nullptr,);
  182. carla_debug("CarlaEngineOsc::sendset_program_name(%i, %i, \"%s\")", pluginId, index, name);
  183. char targetPath[std::strlen(fControlDataTCP.path)+18];
  184. std::strcpy(targetPath, fControlDataTCP.path);
  185. std::strcat(targetPath, "/set_program_name");
  186. try_lo_send(fControlDataTCP.target, targetPath, "iis", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), name);
  187. }
  188. void CarlaEngineOsc::sendset_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept
  189. {
  190. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  191. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  192. CARLA_SAFE_ASSERT_RETURN(name != nullptr,);
  193. carla_debug("CarlaEngineOsc::sendset_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name);
  194. char targetPath[std::strlen(fControlDataTCP.path)+23];
  195. std::strcpy(targetPath, fControlDataTCP.path);
  196. std::strcat(targetPath, "/set_midi_program_data");
  197. try_lo_send(fControlDataTCP.target, targetPath, "iiiis", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(bank), static_cast<int32_t>(program), name);
  198. }
  199. #endif
  200. // -----------------------------------------------------------------------
  201. void CarlaEngineOsc::sendPing() const noexcept
  202. {
  203. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  204. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  205. char targetPath[std::strlen(fControlDataTCP.path)+6];
  206. std::strcpy(targetPath, fControlDataTCP.path);
  207. std::strcat(targetPath, "/ping");
  208. try_lo_send(fControlDataTCP.target, targetPath, "");
  209. }
  210. void CarlaEngineOsc::sendExit() const noexcept
  211. {
  212. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  213. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  214. carla_debug("CarlaEngineOsc::sendExit()");
  215. char targetPath[std::strlen(fControlDataTCP.path)+6];
  216. std::strcpy(targetPath, fControlDataTCP.path);
  217. std::strcat(targetPath, "/exit");
  218. try_lo_send(fControlDataTCP.target, targetPath, "");
  219. }
  220. // -----------------------------------------------------------------------
  221. void CarlaEngineOsc::sendRuntimeInfo() const noexcept
  222. {
  223. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.path != nullptr && fControlDataUDP.path[0] != '\0',);
  224. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.target != nullptr,);
  225. carla_debug("CarlaEngineOsc::sendRuntimeInfo()");
  226. const EngineTimeInfo timeInfo(fEngine->getTimeInfo());
  227. char targetPath[std::strlen(fControlDataUDP.path)+18];
  228. std::strcpy(targetPath, fControlDataUDP.path);
  229. std::strcat(targetPath, "/runtime");
  230. try_lo_send(fControlDataUDP.target, targetPath, "fiihiiif",
  231. static_cast<double>(fEngine->getDSPLoad()),
  232. static_cast<int32_t>(fEngine->getTotalXruns()),
  233. timeInfo.playing ? 1 : 0,
  234. static_cast<int64_t>(timeInfo.frame),
  235. static_cast<int32_t>(timeInfo.bbt.bar),
  236. static_cast<int32_t>(timeInfo.bbt.beat),
  237. static_cast<int32_t>(timeInfo.bbt.tick),
  238. timeInfo.bbt.beatsPerMinute);
  239. }
  240. void CarlaEngineOsc::sendParameterValue(const uint pluginId, const uint32_t index, const float value) const noexcept
  241. {
  242. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.path != nullptr && fControlDataUDP.path[0] != '\0',);
  243. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.target != nullptr,);
  244. char targetPath[std::strlen(fControlDataUDP.path)+21];
  245. std::strcpy(targetPath, fControlDataUDP.path);
  246. std::strcat(targetPath, "/param");
  247. try_lo_send(fControlDataUDP.target, targetPath, "iif",
  248. static_cast<int32_t>(pluginId),
  249. index,
  250. static_cast<double>(value));
  251. }
  252. void CarlaEngineOsc::sendPeaks(const uint pluginId, const float peaks[4]) const noexcept
  253. {
  254. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.path != nullptr && fControlDataUDP.path[0] != '\0',);
  255. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.target != nullptr,);
  256. char targetPath[std::strlen(fControlDataUDP.path)+11];
  257. std::strcpy(targetPath, fControlDataUDP.path);
  258. std::strcat(targetPath, "/peaks");
  259. try_lo_send(fControlDataUDP.target, targetPath, "iffff", static_cast<int32_t>(pluginId),
  260. static_cast<double>(peaks[0]),
  261. static_cast<double>(peaks[1]),
  262. static_cast<double>(peaks[2]),
  263. static_cast<double>(peaks[3]));
  264. }
  265. // -----------------------------------------------------------------------
  266. CARLA_BACKEND_END_NAMESPACE
  267. #endif // HAVE_LIBLO