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.

758 lines
20KB

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