Collection of tools useful for audio production
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.

942 lines
27KB

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