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.

296 lines
13KB

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