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.

1024 lines
29KB

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