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.

1032 lines
30KB

  1. /*
  2. * Carla Bridge Plugin
  3. * Copyright (C) 2011-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 GPL.txt file
  16. */
  17. #include "CarlaPluginInternal.hpp"
  18. #if 1//ndef BUILD_BRIDGE
  19. #include <QtCore/QDir>
  20. #include <QtCore/QFile>
  21. #include <QtCore/QStringList>
  22. #include <QtCore/QTextStream>
  23. #define CARLA_BRIDGE_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \
  24. /* check argument count */ \
  25. if (argc != argcToCompare) \
  26. { \
  27. carla_stderr("BridgePlugin::%s() - argument count mismatch: %i != %i", __FUNCTION__, argc, argcToCompare); \
  28. return 1; \
  29. } \
  30. if (argc > 0) \
  31. { \
  32. /* check for nullness */ \
  33. if (! (types && typesToCompare)) \
  34. { \
  35. carla_stderr("BridgePlugin::%s() - argument types are null", __FUNCTION__); \
  36. return 1; \
  37. } \
  38. /* check argument types */ \
  39. if (std::strcmp(types, typesToCompare) != 0) \
  40. { \
  41. carla_stderr("BridgePlugin::%s() - argument types mismatch: '%s' != '%s'", __FUNCTION__, types, typesToCompare); \
  42. return 1; \
  43. } \
  44. }
  45. CARLA_BACKEND_START_NAMESPACE
  46. struct BridgeParamInfo {
  47. float value;
  48. CarlaString name;
  49. CarlaString unit;
  50. BridgeParamInfo()
  51. : value(0.0f) {}
  52. };
  53. class BridgePlugin : public CarlaPlugin
  54. {
  55. public:
  56. BridgePlugin(CarlaEngine* const engine, const unsigned int id, const BinaryType btype, const PluginType ptype)
  57. : CarlaPlugin(engine, id),
  58. fBinaryType(btype),
  59. fPluginType(ptype),
  60. fInitiated(false),
  61. fInitError(false),
  62. fSaved(false),
  63. fParams(nullptr)
  64. {
  65. carla_debug("BridgePlugin::BridgePlugin(%p, %i, %s, %s)", engine, id, BinaryType2Str(btype), PluginType2Str(ptype));
  66. kData->osc.thread.setMode(CarlaPluginThread::PLUGIN_THREAD_BRIDGE);
  67. }
  68. #if 0
  69. ~BridgePlugin()
  70. {
  71. carla_debug("BridgePlugin::~BridgePlugin()");
  72. if (osc.data.target)
  73. {
  74. osc_send_hide(&osc.data);
  75. osc_send_quit(&osc.data);
  76. osc.data.free();
  77. }
  78. if (osc.thread)
  79. {
  80. // Wait a bit first, try safe quit, then force kill
  81. if (osc.thread->isRunning() && ! osc.thread->wait(3000))
  82. {
  83. carla_stderr("Failed to properly stop Plugin Bridge thread");
  84. osc.thread->terminate();
  85. }
  86. delete osc.thread;
  87. }
  88. info.chunk.clear();
  89. }
  90. #endif
  91. // -------------------------------------------------------------------
  92. // Information (base)
  93. PluginType type() const
  94. {
  95. return fPluginType;
  96. }
  97. PluginCategory category() const
  98. {
  99. return fInfo.category;
  100. }
  101. long uniqueId()
  102. {
  103. return fInfo.uniqueId;
  104. }
  105. // -------------------------------------------------------------------
  106. // Information (count)
  107. uint32_t audioInCount()
  108. {
  109. return fInfo.aIns;
  110. }
  111. uint32_t audioOutCount()
  112. {
  113. return fInfo.aOuts;
  114. }
  115. uint32_t midiInCount()
  116. {
  117. return fInfo.mIns;
  118. }
  119. uint32_t midiOutCount()
  120. {
  121. return fInfo.mOuts;
  122. }
  123. #if 0
  124. // -------------------------------------------------------------------
  125. // Information (current data)
  126. int32_t chunkData(void** const dataPtr)
  127. {
  128. CARLA_ASSERT(dataPtr);
  129. if (! info.chunk.isEmpty())
  130. {
  131. *dataPtr = info.chunk.data();
  132. return info.chunk.size();
  133. }
  134. return 0;
  135. }
  136. // -------------------------------------------------------------------
  137. // Information (per-plugin data)
  138. double getParameterValue(const uint32_t parameterId)
  139. {
  140. CARLA_ASSERT(parameterId < param.count);
  141. return params[parameterId].value;
  142. }
  143. void getLabel(char* const strBuf)
  144. {
  145. if (info.label)
  146. strncpy(strBuf, info.label, STR_MAX);
  147. else
  148. CarlaPlugin::getLabel(strBuf);
  149. }
  150. void getMaker(char* const strBuf)
  151. {
  152. if (info.maker)
  153. strncpy(strBuf, info.maker, STR_MAX);
  154. else
  155. CarlaPlugin::getMaker(strBuf);
  156. }
  157. void getCopyright(char* const strBuf)
  158. {
  159. if (info.copyright)
  160. strncpy(strBuf, info.copyright, STR_MAX);
  161. else
  162. CarlaPlugin::getCopyright(strBuf);
  163. }
  164. void getRealName(char* const strBuf)
  165. {
  166. if (info.name)
  167. strncpy(strBuf, info.name, STR_MAX);
  168. else
  169. CarlaPlugin::getRealName(strBuf);
  170. }
  171. void getParameterName(const uint32_t parameterId, char* const strBuf)
  172. {
  173. CARLA_ASSERT(parameterId < param.count);
  174. strncpy(strBuf, params[parameterId].name.toUtf8().constData(), STR_MAX);
  175. }
  176. void getParameterUnit(const uint32_t parameterId, char* const strBuf)
  177. {
  178. CARLA_ASSERT(parameterId < param.count);
  179. strncpy(strBuf, params[parameterId].unit.toUtf8().constData(), STR_MAX);
  180. }
  181. void getGuiInfo(GuiType* const type, bool* const resizable)
  182. {
  183. if (m_hints & PLUGIN_HAS_GUI)
  184. *type = GUI_EXTERNAL_OSC;
  185. else
  186. *type = GUI_NONE;
  187. *resizable = false;
  188. }
  189. #endif
  190. // -------------------------------------------------------------------
  191. // Set data (internal stuff)
  192. int setOscPluginBridgeInfo(const PluginBridgeInfoType type, const int argc, const lo_arg* const* const argv, const char* const types)
  193. {
  194. carla_debug("setOscPluginBridgeInfo(%i, %i, %p, \"%s\")", type, argc, argv, types);
  195. #if 0
  196. switch (type)
  197. {
  198. case PluginBridgeAudioCount:
  199. {
  200. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "iii");
  201. const int32_t aIns = argv[0]->i;
  202. const int32_t aOuts = argv[1]->i;
  203. const int32_t aTotal = argv[2]->i;
  204. CARLA_ASSERT(aIns >= 0);
  205. CARLA_ASSERT(aOuts >= 0);
  206. CARLA_ASSERT(aIns + aOuts == aTotal);
  207. info.aIns = aIns;
  208. info.aOuts = aOuts;
  209. break;
  210. Q_UNUSED(aTotal);
  211. }
  212. case PluginBridgeMidiCount:
  213. {
  214. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "iii");
  215. const int32_t mIns = argv[0]->i;
  216. const int32_t mOuts = argv[1]->i;
  217. const int32_t mTotal = argv[2]->i;
  218. CARLA_ASSERT(mIns >= 0);
  219. CARLA_ASSERT(mOuts >= 0);
  220. CARLA_ASSERT(mIns + mOuts == mTotal);
  221. info.mIns = mIns;
  222. info.mOuts = mOuts;
  223. break;
  224. Q_UNUSED(mTotal);
  225. }
  226. case PluginBridgeParameterCount:
  227. {
  228. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "iii");
  229. const int32_t pIns = argv[0]->i;
  230. const int32_t pOuts = argv[1]->i;
  231. const int32_t pTotal = argv[2]->i;
  232. CARLA_ASSERT(pIns >= 0);
  233. CARLA_ASSERT(pOuts >= 0);
  234. CARLA_ASSERT(pIns + pOuts <= pTotal);
  235. // delete old data
  236. if (param.count > 0)
  237. {
  238. delete[] param.data;
  239. delete[] param.ranges;
  240. delete[] params;
  241. }
  242. // create new if needed
  243. const int32_t maxParams = x_engine->getOptions().maxParameters;
  244. param.count = (pTotal < maxParams) ? pTotal : 0;
  245. if (param.count > 0)
  246. {
  247. param.data = new ParameterData[param.count];
  248. param.ranges = new ParameterRanges[param.count];
  249. params = new BridgeParamInfo[param.count];
  250. }
  251. else
  252. {
  253. param.data = nullptr;
  254. param.ranges = nullptr;
  255. params = nullptr;
  256. }
  257. break;
  258. Q_UNUSED(pIns);
  259. Q_UNUSED(pOuts);
  260. }
  261. case PluginBridgeProgramCount:
  262. {
  263. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  264. const int32_t count = argv[0]->i;
  265. CARLA_ASSERT(count >= 0);
  266. // delete old programs
  267. if (prog.count > 0)
  268. {
  269. for (uint32_t i=0; i < prog.count; i++)
  270. {
  271. if (prog.names[i])
  272. free((void*)prog.names[i]);
  273. }
  274. delete[] prog.names;
  275. }
  276. prog.count = count;
  277. // create new if needed
  278. if (prog.count > 0)
  279. {
  280. prog.names = new const char* [prog.count];
  281. for (uint32_t i=0; i < prog.count; i++)
  282. prog.names[i] = nullptr;
  283. }
  284. else
  285. prog.names = nullptr;
  286. break;
  287. }
  288. case PluginBridgeMidiProgramCount:
  289. {
  290. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  291. const int32_t count = argv[0]->i;
  292. // delete old programs
  293. if (midiprog.count > 0)
  294. {
  295. for (uint32_t i=0; i < midiprog.count; i++)
  296. {
  297. if (midiprog.data[i].name)
  298. free((void*)midiprog.data[i].name);
  299. }
  300. delete[] midiprog.data;
  301. }
  302. // create new if needed
  303. midiprog.count = count;
  304. if (midiprog.count > 0)
  305. midiprog.data = new MidiProgramData[midiprog.count];
  306. else
  307. midiprog.data = nullptr;
  308. break;
  309. }
  310. case PluginBridgePluginInfo:
  311. {
  312. CARLA_BRIDGE_CHECK_OSC_TYPES(7, "iissssh");
  313. const int32_t category = argv[0]->i;
  314. const int32_t hints = argv[1]->i;
  315. const char* const name = (const char*)&argv[2]->s;
  316. const char* const label = (const char*)&argv[3]->s;
  317. const char* const maker = (const char*)&argv[4]->s;
  318. const char* const copyright = (const char*)&argv[5]->s;
  319. const int64_t uniqueId = argv[6]->h;
  320. CARLA_ASSERT(category >= 0);
  321. CARLA_ASSERT(hints >= 0);
  322. CARLA_ASSERT(name);
  323. CARLA_ASSERT(label);
  324. CARLA_ASSERT(maker);
  325. CARLA_ASSERT(copyright);
  326. m_hints = hints | PLUGIN_IS_BRIDGE;
  327. info.category = (PluginCategory)category;
  328. info.uniqueId = uniqueId;
  329. info.name = strdup(name);
  330. info.label = strdup(label);
  331. info.maker = strdup(maker);
  332. info.copyright = strdup(copyright);
  333. if (! m_name)
  334. m_name = x_engine->getUniquePluginName(name);
  335. break;
  336. }
  337. case PluginBridgeParameterInfo:
  338. {
  339. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "iss");
  340. const int32_t index = argv[0]->i;
  341. const char* const name = (const char*)&argv[1]->s;
  342. const char* const unit = (const char*)&argv[2]->s;
  343. CARLA_ASSERT(index >= 0 && index < (int32_t)param.count);
  344. CARLA_ASSERT(name);
  345. CARLA_ASSERT(unit);
  346. if (index >= 0 && index < (int32_t)param.count)
  347. {
  348. params[index].name = QString(name);
  349. params[index].unit = QString(unit);
  350. }
  351. break;
  352. }
  353. case PluginBridgeParameterData:
  354. {
  355. CARLA_BRIDGE_CHECK_OSC_TYPES(6, "iiiiii");
  356. const int32_t index = argv[0]->i;
  357. const int32_t type = argv[1]->i;
  358. const int32_t rindex = argv[2]->i;
  359. const int32_t hints = argv[3]->i;
  360. const int32_t channel = argv[4]->i;
  361. const int32_t cc = argv[5]->i;
  362. CARLA_ASSERT(index >= 0 && index < (int32_t)param.count);
  363. CARLA_ASSERT(type >= 0);
  364. CARLA_ASSERT(rindex >= 0);
  365. CARLA_ASSERT(hints >= 0);
  366. CARLA_ASSERT(channel >= 0 && channel < 16);
  367. CARLA_ASSERT(cc >= -1);
  368. if (index >= 0 && index < (int32_t)param.count)
  369. {
  370. param.data[index].type = (ParameterType)type;
  371. param.data[index].index = index;
  372. param.data[index].rindex = rindex;
  373. param.data[index].hints = hints;
  374. param.data[index].midiChannel = channel;
  375. param.data[index].midiCC = cc;
  376. }
  377. break;
  378. }
  379. case PluginBridgeParameterRanges:
  380. {
  381. CARLA_BRIDGE_CHECK_OSC_TYPES(7, "idddddd");
  382. const int32_t index = argv[0]->i;
  383. const double def = argv[1]->d;
  384. const double min = argv[2]->d;
  385. const double max = argv[3]->d;
  386. const double step = argv[4]->d;
  387. const double stepSmall = argv[5]->d;
  388. const double stepLarge = argv[6]->d;
  389. CARLA_ASSERT(index >= 0 && index < (int32_t)param.count);
  390. CARLA_ASSERT(min < max);
  391. CARLA_ASSERT(def >= min);
  392. CARLA_ASSERT(def <= max);
  393. if (index >= 0 && index < (int32_t)param.count)
  394. {
  395. param.ranges[index].def = def;
  396. param.ranges[index].min = min;
  397. param.ranges[index].max = max;
  398. param.ranges[index].step = step;
  399. param.ranges[index].stepSmall = stepSmall;
  400. param.ranges[index].stepLarge = stepLarge;
  401. params[index].value = def;
  402. }
  403. break;
  404. }
  405. case PluginBridgeProgramInfo:
  406. {
  407. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "is");
  408. const int32_t index = argv[0]->i;
  409. const char* const name = (const char*)&argv[1]->s;
  410. CARLA_ASSERT(index >= 0 && index < (int32_t)prog.count);
  411. CARLA_ASSERT(name);
  412. if (index >= 0 && index < (int32_t)prog.count)
  413. {
  414. if (prog.names[index])
  415. free((void*)prog.names[index]);
  416. prog.names[index] = strdup(name);
  417. }
  418. break;
  419. }
  420. case PluginBridgeMidiProgramInfo:
  421. {
  422. CARLA_BRIDGE_CHECK_OSC_TYPES(4, "iiis");
  423. const int32_t index = argv[0]->i;
  424. const int32_t bank = argv[1]->i;
  425. const int32_t program = argv[2]->i;
  426. const char* const name = (const char*)&argv[3]->s;
  427. CARLA_ASSERT(index >= 0 && index < (int32_t)midiprog.count);
  428. CARLA_ASSERT(bank >= 0);
  429. CARLA_ASSERT(program >= 0 && program < 128);
  430. CARLA_ASSERT(name);
  431. if (index >= 0 && index < (int32_t)midiprog.count)
  432. {
  433. if (midiprog.data[index].name)
  434. free((void*)midiprog.data[index].name);
  435. midiprog.data[index].bank = bank;
  436. midiprog.data[index].program = program;
  437. midiprog.data[index].name = strdup(name);
  438. }
  439. break;
  440. }
  441. case PluginBridgeConfigure:
  442. {
  443. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "ss");
  444. const char* const key = (const char*)&argv[0]->s;
  445. const char* const value = (const char*)&argv[1]->s;
  446. CARLA_ASSERT(key);
  447. CARLA_ASSERT(value);
  448. if (! (key && value))
  449. {
  450. // invalid
  451. pass();
  452. }
  453. else if (std::strcmp(key, CARLA_BRIDGE_MSG_HIDE_GUI) == 0)
  454. {
  455. x_engine->callback(CALLBACK_SHOW_GUI, m_id, 0, 0, 0.0, nullptr);
  456. }
  457. else if (std::strcmp(key, CARLA_BRIDGE_MSG_SAVED) == 0)
  458. {
  459. m_saved = true;
  460. }
  461. break;
  462. }
  463. case PluginBridgeSetParameterValue:
  464. {
  465. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "id");
  466. const int32_t index = argv[0]->i;
  467. const double value = argv[1]->d;
  468. CARLA_ASSERT(index != PARAMETER_NULL);
  469. setParameterValueByRIndex(index, value, false, true, true);
  470. break;
  471. }
  472. case PluginBridgeSetDefaultValue:
  473. {
  474. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "id");
  475. const int32_t index = argv[0]->i;
  476. const double value = argv[1]->d;
  477. CARLA_ASSERT(index >= 0 && index < (int32_t)param.count);
  478. if (index >= 0 && index < (int32_t)param.count)
  479. param.ranges[index].def = value;
  480. break;
  481. }
  482. case PluginBridgeSetProgram:
  483. {
  484. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  485. const int32_t index = argv[0]->i;
  486. CARLA_ASSERT(index < (int32_t)prog.count);
  487. setProgram(index, false, true, true, true);
  488. break;
  489. }
  490. case PluginBridgeSetMidiProgram:
  491. {
  492. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  493. const int32_t index = argv[0]->i;
  494. CARLA_ASSERT(index < (int32_t)midiprog.count);
  495. setMidiProgram(index, false, true, true, true);
  496. break;
  497. }
  498. case PluginBridgeSetCustomData:
  499. {
  500. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "sss");
  501. const char* const type = (const char*)&argv[0]->s;
  502. const char* const key = (const char*)&argv[1]->s;
  503. const char* const value = (const char*)&argv[2]->s;
  504. CARLA_ASSERT(type);
  505. CARLA_ASSERT(key);
  506. CARLA_ASSERT(value);
  507. setCustomData(type, key, value, false);
  508. break;
  509. }
  510. case PluginBridgeSetChunkData:
  511. {
  512. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "s");
  513. const char* const chunkFileChar = (const char*)&argv[0]->s;
  514. CARLA_ASSERT(chunkFileChar);
  515. QString chunkFileStr(chunkFileChar);
  516. #ifndef Q_OS_WIN
  517. // Using Wine, fix temp dir
  518. if (m_binary == BINARY_WIN32 || m_binary == BINARY_WIN64)
  519. {
  520. // Get WINEPREFIX
  521. QString wineDir;
  522. if (const char* const WINEPREFIX = getenv("WINEPREFIX"))
  523. wineDir = QString(WINEPREFIX);
  524. else
  525. wineDir = QDir::homePath() + "/.wine";
  526. QStringList chunkFileStrSplit1 = chunkFileStr.split(":/");
  527. QStringList chunkFileStrSplit2 = chunkFileStrSplit1.at(1).split("\\");
  528. QString wineDrive = chunkFileStrSplit1.at(0).toLower();
  529. QString wineTMP = chunkFileStrSplit2.at(0);
  530. QString baseName = chunkFileStrSplit2.at(1);
  531. chunkFileStr = wineDir;
  532. chunkFileStr += "/drive_";
  533. chunkFileStr += wineDrive;
  534. chunkFileStr += "/";
  535. chunkFileStr += wineTMP;
  536. chunkFileStr += "/";
  537. chunkFileStr += baseName;
  538. chunkFileStr = QDir::toNativeSeparators(chunkFileStr);
  539. }
  540. #endif
  541. QFile chunkFile(chunkFileStr);
  542. if (chunkFile.open(QIODevice::ReadOnly))
  543. {
  544. info.chunk = chunkFile.readAll();
  545. chunkFile.close();
  546. chunkFile.remove();
  547. }
  548. break;
  549. }
  550. case PluginBridgeUpdateNow:
  551. {
  552. m_initiated = true;
  553. break;
  554. }
  555. case PluginBridgeError:
  556. {
  557. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "s");
  558. const char* const error = (const char*)&argv[0]->s;
  559. CARLA_ASSERT(error);
  560. m_initiated = true;
  561. m_initError = true;
  562. x_engine->setLastError(error);
  563. break;
  564. }
  565. }
  566. #endif
  567. return 0;
  568. }
  569. #if 0
  570. // -------------------------------------------------------------------
  571. // Set data (plugin-specific stuff)
  572. void setParameterValue(const uint32_t parameterId, double value, const bool sendGui, const bool sendOsc, const bool sendCallback)
  573. {
  574. CARLA_ASSERT(parameterId < param.count);
  575. params[parameterId].value = fixParameterValue(value, param.ranges[parameterId]);
  576. CarlaPlugin::setParameterValue(parameterId, value, sendGui, sendOsc, sendCallback);
  577. }
  578. void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui)
  579. {
  580. CARLA_ASSERT(type);
  581. CARLA_ASSERT(key);
  582. CARLA_ASSERT(value);
  583. if (sendGui)
  584. {
  585. // TODO - if type is chunk|binary, store it in a file and send path instead
  586. QString cData;
  587. cData = type;
  588. cData += "·";
  589. cData += key;
  590. cData += "·";
  591. cData += value;
  592. osc_send_configure(&osc.data, CARLA_BRIDGE_MSG_SET_CUSTOM, cData.toUtf8().constData());
  593. }
  594. CarlaPlugin::setCustomData(type, key, value, sendGui);
  595. }
  596. void setChunkData(const char* const stringData)
  597. {
  598. CARLA_ASSERT(m_hints & PLUGIN_USES_CHUNKS);
  599. CARLA_ASSERT(stringData);
  600. QString filePath;
  601. filePath = QDir::tempPath();
  602. filePath += "/.CarlaChunk_";
  603. filePath += m_name;
  604. filePath = QDir::toNativeSeparators(filePath);
  605. QFile file(filePath);
  606. if (file.open(QIODevice::WriteOnly | QIODevice::Text))
  607. {
  608. QTextStream out(&file);
  609. out << stringData;
  610. file.close();
  611. osc_send_configure(&osc.data, CARLA_BRIDGE_MSG_SET_CHUNK, filePath.toUtf8().constData());
  612. }
  613. }
  614. // -------------------------------------------------------------------
  615. // Set gui stuff
  616. void showGui(const bool yesNo)
  617. {
  618. if (yesNo)
  619. osc_send_show(&osc.data);
  620. else
  621. osc_send_hide(&osc.data);
  622. }
  623. void idleGui()
  624. {
  625. if (! osc.thread->isRunning())
  626. carla_stderr("TESTING: Bridge has closed!");
  627. CarlaPlugin::idleGui();
  628. }
  629. // -------------------------------------------------------------------
  630. // Plugin state
  631. void prepareForSave()
  632. {
  633. m_saved = false;
  634. osc_send_configure(&osc.data, CARLA_BRIDGE_MSG_SAVE_NOW, "");
  635. for (int i=0; i < 200; i++)
  636. {
  637. if (m_saved)
  638. break;
  639. carla_msleep(50);
  640. }
  641. if (! m_saved)
  642. carla_stderr("BridgePlugin::prepareForSave() - Timeout while requesting save state");
  643. else
  644. carla_debug("BridgePlugin::prepareForSave() - success!");
  645. }
  646. // -------------------------------------------------------------------
  647. // Post-poned events
  648. void uiParameterChange(const uint32_t index, const double value)
  649. {
  650. CARLA_ASSERT(index < param.count);
  651. if (index >= param.count)
  652. return;
  653. if (! osc.data.target)
  654. return;
  655. osc_send_control(&osc.data, param.data[index].rindex, value);
  656. }
  657. void uiProgramChange(const uint32_t index)
  658. {
  659. CARLA_ASSERT(index < prog.count);
  660. if (index >= prog.count)
  661. return;
  662. if (! osc.data.target)
  663. return;
  664. osc_send_program(&osc.data, index);
  665. }
  666. void uiMidiProgramChange(const uint32_t index)
  667. {
  668. CARLA_ASSERT(index < midiprog.count);
  669. if (index >= midiprog.count)
  670. return;
  671. if (! osc.data.target)
  672. return;
  673. osc_send_midi_program(&osc.data, index);
  674. }
  675. void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo)
  676. {
  677. CARLA_ASSERT(channel < 16);
  678. CARLA_ASSERT(note < 128);
  679. CARLA_ASSERT(velo > 0 && velo < 128);
  680. if (! osc.data.target)
  681. return;
  682. uint8_t midiData[4] = { 0 };
  683. midiData[1] = MIDI_STATUS_NOTE_ON + channel;
  684. midiData[2] = note;
  685. midiData[3] = velo;
  686. osc_send_midi(&osc.data, midiData);
  687. }
  688. void uiNoteOff(const uint8_t channel, const uint8_t note)
  689. {
  690. CARLA_ASSERT(channel < 16);
  691. CARLA_ASSERT(note < 128);
  692. if (! osc.data.target)
  693. return;
  694. uint8_t midiData[4] = { 0 };
  695. midiData[1] = MIDI_STATUS_NOTE_OFF + channel;
  696. midiData[2] = note;
  697. osc_send_midi(&osc.data, midiData);
  698. }
  699. // -------------------------------------------------------------------
  700. // Cleanup
  701. void deleteBuffers()
  702. {
  703. carla_debug("BridgePlugin::delete_buffers() - start");
  704. if (param.count > 0)
  705. delete[] params;
  706. params = nullptr;
  707. CarlaPlugin::deleteBuffers();
  708. carla_debug("BridgePlugin::delete_buffers() - end");
  709. }
  710. // -------------------------------------------------------------------
  711. bool init(const char* const filename, const char* const name, const char* const label, const char* const bridgeBinary)
  712. {
  713. m_filename = strdup(filename);
  714. if (name)
  715. m_name = x_engine->getUniquePluginName(name);
  716. // register plugin now so we can receive OSC (and wait for it)
  717. x_engine->__bridgePluginRegister(m_id, this);
  718. osc.thread->setOscData(bridgeBinary, label, getPluginTypeString(m_type));
  719. osc.thread->start();
  720. for (int i=0; i < 200; i++)
  721. {
  722. if (m_initiated || osc.thread->isFinished())
  723. break;
  724. carla_msleep(50);
  725. }
  726. if (! m_initiated)
  727. {
  728. // unregister so it gets handled properly
  729. x_engine->__bridgePluginRegister(m_id, nullptr);
  730. osc.thread->terminate();
  731. x_engine->setLastError("Timeout while waiting for a response from plugin-bridge\n(or the plugin crashed on initialization?)");
  732. return false;
  733. }
  734. else if (m_initError)
  735. {
  736. // unregister so it gets handled properly
  737. x_engine->__bridgePluginRegister(m_id, nullptr);
  738. osc.thread->quit();
  739. // last error was set before
  740. return false;
  741. }
  742. return true;
  743. }
  744. #endif
  745. private:
  746. const BinaryType fBinaryType;
  747. const PluginType fPluginType;
  748. bool fInitiated;
  749. bool fInitError;
  750. bool fSaved;
  751. struct Info {
  752. uint32_t aIns, aOuts;
  753. uint32_t mIns, mOuts;
  754. PluginCategory category;
  755. long uniqueId;
  756. CarlaString name;
  757. CarlaString label;
  758. CarlaString maker;
  759. CarlaString copyright;
  760. //QByteArray chunk;
  761. Info()
  762. : aIns(0),
  763. aOuts(0),
  764. mIns(0),
  765. mOuts(0),
  766. category(PLUGIN_CATEGORY_NONE),
  767. uniqueId(0) {}
  768. } fInfo;
  769. BridgeParamInfo* fParams;
  770. };
  771. CARLA_BACKEND_END_NAMESPACE
  772. #endif // ! BUILD_BRIDGE
  773. CARLA_BACKEND_START_NAMESPACE
  774. CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, PluginType ptype, const char* const extra)
  775. {
  776. carla_debug("CarlaPlugin::newBridge({%p, \"%s\", \"%s\", \"%s\"}, %s, %s)", init.engine, init.filename, init.name, init.label, BinaryType2Str(btype), PluginType2Str(ptype));
  777. #if 1//ndef BUILD_BRIDGE
  778. if (extra == nullptr)
  779. {
  780. init.engine->setLastError("Bridge not possible, bridge-binary not found");
  781. return nullptr;
  782. }
  783. BridgePlugin* const plugin = new BridgePlugin(init.engine, init.id, btype, ptype);
  784. //if (! plugin->init(init.filename, init.name, init.label, (const char*)extra))
  785. {
  786. delete plugin;
  787. return nullptr;
  788. }
  789. plugin->reload();
  790. return plugin;
  791. #else
  792. init.engine->setLastError("Plugin bridge support not available");
  793. return nullptr;
  794. #endif
  795. }
  796. #if 1//ndef BUILD_BRIDGE
  797. // -------------------------------------------------------------------
  798. // Bridge Helper
  799. int CarlaPluginSetOscBridgeInfo(CarlaPlugin* const plugin, const PluginBridgeInfoType type,
  800. const int argc, const lo_arg* const* const argv, const char* const types)
  801. {
  802. return ((BridgePlugin*)plugin)->setOscPluginBridgeInfo(type, argc, argv, types);
  803. }
  804. #endif
  805. CARLA_BACKEND_END_NAMESPACE