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.

881 lines
25KB

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