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.

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