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.

368 lines
16KB

  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. static const char* const kNullString = "";
  24. // -----------------------------------------------------------------------
  25. void CarlaEngineOsc::sendCallback(const EngineCallbackOpcode action, const uint pluginId,
  26. const int value1, const int value2, const int value3,
  27. const float valuef, const char* const valueStr) const noexcept
  28. {
  29. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  30. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  31. carla_stdout("CarlaEngineOsc::sendCallback(%i:%s, %i, %i, %i, %i, %f, \"%s\")",
  32. action, EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3,
  33. static_cast<double>(valuef), valueStr);
  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 : kNullString);
  40. }
  41. void CarlaEngineOsc::sendPluginInfo(const CarlaPlugin* const plugin) 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(plugin != nullptr,);
  46. carla_stdout("CarlaEngineOsc::sendPluginInfo(%p)", plugin);
  47. char bufRealName[STR_MAX+1], bufLabel[STR_MAX+1], bufMaker[STR_MAX+1], bufCopyright[STR_MAX+1];
  48. carla_zeroChars(bufRealName, STR_MAX+1);
  49. carla_zeroChars(bufLabel, STR_MAX+1);
  50. carla_zeroChars(bufMaker, STR_MAX+1);
  51. carla_zeroChars(bufCopyright, STR_MAX+1);
  52. plugin->getRealName(bufRealName);
  53. plugin->getLabel(bufLabel);
  54. plugin->getMaker(bufMaker);
  55. plugin->getCopyright(bufCopyright);
  56. const char* name = plugin->getName();
  57. const char* filename = plugin->getFilename();
  58. const char* iconName = plugin->getIconName();
  59. if (name == nullptr)
  60. name = kNullString;
  61. if (filename == nullptr)
  62. filename = kNullString;
  63. if (iconName == nullptr)
  64. iconName = kNullString;
  65. char targetPath[std::strlen(fControlDataTCP.path)+10];
  66. std::strcpy(targetPath, fControlDataTCP.path);
  67. std::strcat(targetPath, "/info");
  68. try_lo_send(fControlDataTCP.target, targetPath, "iiiihiisssssss",
  69. static_cast<int32_t>(plugin->getId()),
  70. static_cast<int32_t>(plugin->getType()),
  71. static_cast<int32_t>(plugin->getCategory()),
  72. static_cast<int32_t>(plugin->getHints()),
  73. static_cast<int64_t>(plugin->getUniqueId()),
  74. static_cast<int64_t>(plugin->getOptionsAvailable()),
  75. static_cast<int64_t>(plugin->getOptionsEnabled()),
  76. name, filename, iconName,
  77. bufRealName, bufLabel, bufMaker, bufCopyright);
  78. }
  79. void CarlaEngineOsc::sendPluginPortCount(const CarlaPlugin* const plugin) const noexcept
  80. {
  81. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  82. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  83. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  84. carla_stdout("CarlaEngineOsc::sendPluginPortCount(%p)", plugin);
  85. uint32_t paramIns, paramOuts;
  86. plugin->getParameterCountInfo(paramIns, paramOuts);
  87. if (paramIns > 49)
  88. paramIns = 49;
  89. if (paramOuts > 49)
  90. paramOuts = 49;
  91. char targetPath[std::strlen(fControlDataTCP.path)+7];
  92. std::strcpy(targetPath, fControlDataTCP.path);
  93. std::strcat(targetPath, "/ports");
  94. try_lo_send(fControlDataTCP.target, targetPath, "iiiiiiii",
  95. static_cast<int32_t>(plugin->getId()),
  96. static_cast<int32_t>(plugin->getAudioInCount()),
  97. static_cast<int32_t>(plugin->getAudioOutCount()),
  98. static_cast<int32_t>(plugin->getMidiInCount()),
  99. static_cast<int32_t>(plugin->getMidiOutCount()),
  100. static_cast<int32_t>(paramIns),
  101. static_cast<int32_t>(paramOuts),
  102. static_cast<int32_t>(plugin->getParameterCount()));
  103. }
  104. void CarlaEngineOsc::sendPluginParameterInfo(const CarlaPlugin* const plugin, const uint32_t index) const noexcept
  105. {
  106. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  107. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  108. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  109. carla_debug("CarlaEngineOsc::sendPluginParameterInfo(%p, %u)", plugin, index);
  110. char bufName[STR_MAX+1], bufUnit[STR_MAX+1];
  111. carla_zeroChars(bufName, STR_MAX+1);
  112. carla_zeroChars(bufUnit, STR_MAX+1);
  113. const ParameterData& paramData(plugin->getParameterData(index));
  114. const ParameterRanges& paramRanges(plugin->getParameterRanges(index));
  115. plugin->getParameterName(index, bufName);
  116. plugin->getParameterUnit(index, bufUnit);
  117. char targetPath[std::strlen(fControlDataTCP.path)+20];
  118. std::strcpy(targetPath, fControlDataTCP.path);
  119. std::strcat(targetPath, "/param");
  120. try_lo_send(fControlDataTCP.target, targetPath, "iiiiiissfffffff",
  121. static_cast<int32_t>(plugin->getId()), static_cast<int32_t>(index),
  122. static_cast<int32_t>(paramData.type), static_cast<int32_t>(paramData.hints),
  123. static_cast<int32_t>(paramData.midiChannel), static_cast<int32_t>(paramData.midiCC),
  124. bufName, bufUnit,
  125. static_cast<double>(paramRanges.def),
  126. static_cast<double>(paramRanges.min),
  127. static_cast<double>(paramRanges.max),
  128. static_cast<double>(paramRanges.step),
  129. static_cast<double>(paramRanges.stepSmall),
  130. static_cast<double>(paramRanges.stepLarge),
  131. static_cast<double>(plugin->getParameterValue(index)));
  132. }
  133. void CarlaEngineOsc::sendPluginDataCount(const CarlaPlugin* const plugin) const noexcept
  134. {
  135. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  136. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  137. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  138. carla_stdout("CarlaEngineOsc::sendPluginDataCount(%p)", plugin);
  139. char targetPath[std::strlen(fControlDataTCP.path)+7];
  140. std::strcpy(targetPath, fControlDataTCP.path);
  141. std::strcat(targetPath, "/count");
  142. try_lo_send(fControlDataTCP.target, targetPath, "iiiiii",
  143. static_cast<int32_t>(plugin->getId()),
  144. static_cast<int32_t>(plugin->getProgramCount()),
  145. static_cast<int32_t>(plugin->getMidiProgramCount()),
  146. static_cast<int32_t>(plugin->getCustomDataCount()),
  147. static_cast<int32_t>(plugin->getCurrentProgram()),
  148. static_cast<int32_t>(plugin->getCurrentMidiProgram()));
  149. }
  150. void CarlaEngineOsc::sendPluginProgramCount(const CarlaPlugin* const plugin) const noexcept
  151. {
  152. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  153. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  154. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  155. carla_stdout("CarlaEngineOsc::sendPluginDataCount(%p)", plugin);
  156. char targetPath[std::strlen(fControlDataTCP.path)+7];
  157. std::strcpy(targetPath, fControlDataTCP.path);
  158. std::strcat(targetPath, "/pcount");
  159. try_lo_send(fControlDataTCP.target, targetPath, "iii",
  160. static_cast<int32_t>(plugin->getId()),
  161. static_cast<int32_t>(plugin->getProgramCount()),
  162. static_cast<int32_t>(plugin->getMidiProgramCount()));
  163. }
  164. void CarlaEngineOsc::sendPluginProgram(const CarlaPlugin* const plugin, const uint32_t index) const noexcept
  165. {
  166. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  167. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  168. carla_stdout("CarlaEngineOsc::sendPluginProgram(%p, %u)", plugin, index);
  169. char strBuf[STR_MAX+1];
  170. carla_zeroChars(strBuf, STR_MAX+1);
  171. plugin->getProgramName(index, strBuf);
  172. char targetPath[std::strlen(fControlDataTCP.path)+6];
  173. std::strcpy(targetPath, fControlDataTCP.path);
  174. std::strcat(targetPath, "/prog");
  175. try_lo_send(fControlDataTCP.target, targetPath, "iis",
  176. static_cast<int32_t>(plugin->getId()), static_cast<int32_t>(index), strBuf);
  177. }
  178. void CarlaEngineOsc::sendPluginMidiProgram(const CarlaPlugin* const plugin, const uint32_t index) const noexcept
  179. {
  180. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  181. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  182. carla_stdout("CarlaEngineOsc::sendPluginProgram(%p, %u)", plugin, index);
  183. const MidiProgramData& mpdata(plugin->getMidiProgramData(index));
  184. CARLA_SAFE_ASSERT_RETURN(mpdata.name != nullptr,);
  185. char targetPath[std::strlen(fControlDataTCP.path)+7];
  186. std::strcpy(targetPath, fControlDataTCP.path);
  187. std::strcat(targetPath, "/mprog");
  188. try_lo_send(fControlDataTCP.target, targetPath, "iiiis",
  189. static_cast<int32_t>(plugin->getId()),
  190. static_cast<int32_t>(index),
  191. static_cast<int32_t>(mpdata.bank), static_cast<int32_t>(mpdata.program), mpdata.name);
  192. }
  193. void CarlaEngineOsc::sendPluginCustomData(const CarlaPlugin* const plugin, const uint32_t index) const noexcept
  194. {
  195. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  196. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  197. carla_stdout("CarlaEngineOsc::sendPluginCustomData(%p, %u)", plugin, index);
  198. const CustomData& cdata(plugin->getCustomData(index));
  199. CARLA_SAFE_ASSERT_RETURN(cdata.isValid(),);
  200. char targetPath[std::strlen(fControlDataTCP.path)+7];
  201. std::strcpy(targetPath, fControlDataTCP.path);
  202. std::strcat(targetPath, "/cdata");
  203. try_lo_send(fControlDataTCP.target, targetPath, "iisss",
  204. static_cast<int32_t>(plugin->getId()),
  205. static_cast<int32_t>(index),
  206. cdata.type, cdata.key, cdata.value);
  207. }
  208. void CarlaEngineOsc::sendPluginInternalParameterValues(const CarlaPlugin* const plugin) const noexcept
  209. {
  210. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  211. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  212. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  213. carla_debug("CarlaEngineOsc::sendPluginInternalParameterValues(%p)", plugin);
  214. static_assert(PARAMETER_ACTIVE == -2 && PARAMETER_MAX == -9, "Incorrect data");
  215. double iparams[7];
  216. for (int32_t i = 0; i < 7; ++i)
  217. iparams[i] = plugin->getInternalParameterValue(PARAMETER_ACTIVE - i);
  218. char targetPath[std::strlen(fControlDataTCP.path)+18];
  219. std::strcpy(targetPath, fControlDataTCP.path);
  220. std::strcat(targetPath, "/iparams");
  221. try_lo_send(fControlDataTCP.target, targetPath, "ifffffff",
  222. static_cast<int32_t>(plugin->getId()),
  223. iparams[0], // PARAMETER_ACTIVE
  224. iparams[1], // PARAMETER_DRYWET
  225. iparams[2], // PARAMETER_VOLUME
  226. iparams[3], // PARAMETER_BALANCE_LEFT
  227. iparams[4], // PARAMETER_BALANCE_RIGHT
  228. iparams[5], // PARAMETER_PANNING
  229. iparams[6] // PARAMETER_CTRL_CHANNEL
  230. );
  231. }
  232. // -----------------------------------------------------------------------
  233. void CarlaEngineOsc::sendPing() const noexcept
  234. {
  235. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  236. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  237. char targetPath[std::strlen(fControlDataTCP.path)+6];
  238. std::strcpy(targetPath, fControlDataTCP.path);
  239. std::strcat(targetPath, "/ping");
  240. try_lo_send(fControlDataTCP.target, targetPath, "");
  241. }
  242. void CarlaEngineOsc::sendResponse(const int messageId, const char* const error) const noexcept
  243. {
  244. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  245. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  246. carla_debug("CarlaEngineOsc::sendResponse()");
  247. char targetPath[std::strlen(fControlDataTCP.path)+6];
  248. std::strcpy(targetPath, fControlDataTCP.path);
  249. std::strcat(targetPath, "/resp");
  250. try_lo_send(fControlDataTCP.target, targetPath, "is", messageId, error);
  251. }
  252. void CarlaEngineOsc::sendExit() const noexcept
  253. {
  254. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.path != nullptr && fControlDataTCP.path[0] != '\0',);
  255. CARLA_SAFE_ASSERT_RETURN(fControlDataTCP.target != nullptr,);
  256. carla_debug("CarlaEngineOsc::sendExit()");
  257. char targetPath[std::strlen(fControlDataTCP.path)+6];
  258. std::strcpy(targetPath, fControlDataTCP.path);
  259. std::strcat(targetPath, "/exit");
  260. try_lo_send(fControlDataTCP.target, targetPath, "");
  261. }
  262. // -----------------------------------------------------------------------
  263. void CarlaEngineOsc::sendRuntimeInfo() const noexcept
  264. {
  265. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.path != nullptr && fControlDataUDP.path[0] != '\0',);
  266. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.target != nullptr,);
  267. const EngineTimeInfo timeInfo(fEngine->getTimeInfo());
  268. char targetPath[std::strlen(fControlDataUDP.path)+18];
  269. std::strcpy(targetPath, fControlDataUDP.path);
  270. std::strcat(targetPath, "/runtime");
  271. try_lo_send(fControlDataUDP.target, targetPath, "fiihiiif",
  272. static_cast<double>(fEngine->getDSPLoad()),
  273. static_cast<int32_t>(fEngine->getTotalXruns()),
  274. timeInfo.playing ? 1 : 0,
  275. static_cast<int64_t>(timeInfo.frame),
  276. static_cast<int32_t>(timeInfo.bbt.bar),
  277. static_cast<int32_t>(timeInfo.bbt.beat),
  278. static_cast<int32_t>(timeInfo.bbt.tick),
  279. timeInfo.bbt.beatsPerMinute);
  280. }
  281. void CarlaEngineOsc::sendParameterValue(const uint pluginId, const uint32_t index, const float value) const noexcept
  282. {
  283. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.path != nullptr && fControlDataUDP.path[0] != '\0',);
  284. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.target != nullptr,);
  285. char targetPath[std::strlen(fControlDataUDP.path)+21];
  286. std::strcpy(targetPath, fControlDataUDP.path);
  287. std::strcat(targetPath, "/param");
  288. try_lo_send(fControlDataUDP.target, targetPath, "iif",
  289. static_cast<int32_t>(pluginId),
  290. index,
  291. static_cast<double>(value));
  292. }
  293. void CarlaEngineOsc::sendPeaks(const uint pluginId, const float peaks[4]) const noexcept
  294. {
  295. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.path != nullptr && fControlDataUDP.path[0] != '\0',);
  296. CARLA_SAFE_ASSERT_RETURN(fControlDataUDP.target != nullptr,);
  297. char targetPath[std::strlen(fControlDataUDP.path)+11];
  298. std::strcpy(targetPath, fControlDataUDP.path);
  299. std::strcat(targetPath, "/peaks");
  300. try_lo_send(fControlDataUDP.target, targetPath, "iffff", static_cast<int32_t>(pluginId),
  301. static_cast<double>(peaks[0]),
  302. static_cast<double>(peaks[1]),
  303. static_cast<double>(peaks[2]),
  304. static_cast<double>(peaks[3]));
  305. }
  306. // -----------------------------------------------------------------------
  307. CARLA_BACKEND_END_NAMESPACE
  308. #endif // HAVE_LIBLO