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.

1671 lines
43KB

  1. /*
  2. * Carla 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 "carla_lib_utils.hpp"
  19. #include <QtGui/QtEvents>
  20. CARLA_BACKEND_START_NAMESPACE
  21. // -------------------------------------------------------------------
  22. // fallback data
  23. static ParameterData paramDataNull;
  24. static ParameterRanges paramRangesNull;
  25. static MidiProgramData midiProgramDataNull;
  26. static CustomData customDataNull;
  27. // -------------------------------------------------------------------
  28. CarlaPlugin::CarlaPlugin(CarlaEngine* const engine, const unsigned short id)
  29. : m_id(id),
  30. x_engine(engine),
  31. x_client(nullptr),
  32. x_dryWet(1.0),
  33. x_volume(1.0),
  34. x_balanceLeft(-1.0),
  35. x_balanceRight(1.0)
  36. {
  37. CARLA_ASSERT(engine);
  38. CARLA_ASSERT(id < x_engine->maxPluginNumber());
  39. qDebug("CarlaPlugin::CarlaPlugin(%p, %i)", engine, id);
  40. m_type = PLUGIN_NONE;
  41. m_hints = 0;
  42. m_active = false;
  43. m_activeBefore = false;
  44. m_enabled = false;
  45. m_lib = nullptr;
  46. m_name = nullptr;
  47. m_filename = nullptr;
  48. // options
  49. m_ctrlInChannel = 0;
  50. m_fixedBufferSize = true;
  51. m_processHighPrecision = false;
  52. {
  53. const CarlaEngineOptions& options(x_engine->getOptions());
  54. m_processHighPrecision = options.processHighPrecision;
  55. if (options.processMode == PROCESS_MODE_CONTINUOUS_RACK)
  56. m_ctrlInChannel = m_id;
  57. }
  58. // latency
  59. m_latency = 0;
  60. m_latencyBuffers = nullptr;
  61. // Extra
  62. osc.data.path = nullptr;
  63. osc.data.source = nullptr;
  64. osc.data.target = nullptr;
  65. osc.thread = nullptr;
  66. }
  67. CarlaPlugin::~CarlaPlugin()
  68. {
  69. qDebug("CarlaPlugin::~CarlaPlugin()");
  70. // Remove client and ports
  71. if (x_client)
  72. {
  73. if (x_client->isActive())
  74. x_client->deactivate();
  75. removeClientPorts();
  76. delete x_client;
  77. }
  78. // Delete data
  79. deleteBuffers();
  80. // Unload DLL
  81. libClose();
  82. if (m_name)
  83. free((void*)m_name);
  84. if (m_filename)
  85. free((void*)m_filename);
  86. if (prog.count > 0)
  87. {
  88. for (uint32_t i=0; i < prog.count; i++)
  89. {
  90. if (prog.names[i])
  91. free((void*)prog.names[i]);
  92. }
  93. delete[] prog.names;
  94. }
  95. if (midiprog.count > 0)
  96. {
  97. for (uint32_t i=0; i < midiprog.count; i++)
  98. {
  99. if (midiprog.data[i].name)
  100. free((void*)midiprog.data[i].name);
  101. }
  102. delete[] midiprog.data;
  103. }
  104. if (custom.size() > 0)
  105. {
  106. for (size_t i=0; i < custom.size(); i++)
  107. {
  108. if (custom[i].key)
  109. free((void*)custom[i].key);
  110. if (custom[i].value)
  111. free((void*)custom[i].value);
  112. }
  113. custom.clear();
  114. }
  115. if (m_latencyBuffers)
  116. {
  117. for (uint32_t i=0; i < aIn.count; i++)
  118. delete[] m_latencyBuffers[i];
  119. delete[] m_latencyBuffers;
  120. }
  121. }
  122. // -------------------------------------------------------------------
  123. // Information (base)
  124. PluginType CarlaPlugin::type() const
  125. {
  126. return m_type;
  127. }
  128. unsigned short CarlaPlugin::id() const
  129. {
  130. return m_id;
  131. }
  132. unsigned int CarlaPlugin::hints() const
  133. {
  134. return m_hints;
  135. }
  136. bool CarlaPlugin::enabled() const
  137. {
  138. return m_enabled;
  139. }
  140. const char* CarlaPlugin::name() const
  141. {
  142. return m_name;
  143. }
  144. const char* CarlaPlugin::filename() const
  145. {
  146. return m_filename;
  147. }
  148. PluginCategory CarlaPlugin::category()
  149. {
  150. return PLUGIN_CATEGORY_NONE;
  151. }
  152. long CarlaPlugin::uniqueId()
  153. {
  154. return 0;
  155. }
  156. // -------------------------------------------------------------------
  157. // Information (count)
  158. uint32_t CarlaPlugin::audioInCount()
  159. {
  160. return aIn.count;
  161. }
  162. uint32_t CarlaPlugin::audioOutCount()
  163. {
  164. return aOut.count;
  165. }
  166. uint32_t CarlaPlugin::midiInCount()
  167. {
  168. return midi.portMin ? 1 : 0;
  169. }
  170. uint32_t CarlaPlugin::midiOutCount()
  171. {
  172. return midi.portMout ? 1 : 0;
  173. }
  174. uint32_t CarlaPlugin::parameterCount() const
  175. {
  176. return param.count;
  177. }
  178. uint32_t CarlaPlugin::parameterScalePointCount(const uint32_t parameterId)
  179. {
  180. CARLA_ASSERT(parameterId < param.count);
  181. return 0;
  182. }
  183. uint32_t CarlaPlugin::programCount() const
  184. {
  185. return prog.count;
  186. }
  187. uint32_t CarlaPlugin::midiProgramCount() const
  188. {
  189. return midiprog.count;
  190. }
  191. size_t CarlaPlugin::customDataCount() const
  192. {
  193. return custom.size();
  194. }
  195. // -------------------------------------------------------------------
  196. // Information (current data)
  197. int32_t CarlaPlugin::currentProgram() const
  198. {
  199. return prog.current;
  200. }
  201. int32_t CarlaPlugin::currentMidiProgram() const
  202. {
  203. return midiprog.current;
  204. }
  205. const ParameterData* CarlaPlugin::parameterData(const uint32_t parameterId) const
  206. {
  207. CARLA_ASSERT(parameterId < param.count);
  208. if (parameterId < param.count)
  209. return &param.data[parameterId];
  210. return &paramDataNull;
  211. }
  212. const ParameterRanges* CarlaPlugin::parameterRanges(const uint32_t parameterId) const
  213. {
  214. CARLA_ASSERT(parameterId < param.count);
  215. if (parameterId < param.count)
  216. return &param.ranges[parameterId];
  217. return &paramRangesNull;
  218. }
  219. bool CarlaPlugin::parameterIsOutput(const uint32_t parameterId) const
  220. {
  221. CARLA_ASSERT(parameterId < param.count);
  222. if (parameterId < param.count)
  223. return (param.data[parameterId].type == PARAMETER_OUTPUT);
  224. return false;
  225. }
  226. const MidiProgramData* CarlaPlugin::midiProgramData(const uint32_t index) const
  227. {
  228. CARLA_ASSERT(index < midiprog.count);
  229. if (index < midiprog.count)
  230. return &midiprog.data[index];
  231. return &midiProgramDataNull;
  232. }
  233. const CustomData* CarlaPlugin::customData(const size_t index) const
  234. {
  235. CARLA_ASSERT(index < custom.size());
  236. if (index < custom.size())
  237. return &custom[index];
  238. return &customDataNull;
  239. }
  240. int32_t CarlaPlugin::chunkData(void** const dataPtr)
  241. {
  242. CARLA_ASSERT(dataPtr);
  243. return 0;
  244. }
  245. // -------------------------------------------------------------------
  246. // Information (per-plugin data)
  247. double CarlaPlugin::getParameterValue(const uint32_t parameterId)
  248. {
  249. CARLA_ASSERT(parameterId < param.count);
  250. return 0.0;
  251. }
  252. double CarlaPlugin::getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId)
  253. {
  254. CARLA_ASSERT(parameterId < param.count);
  255. CARLA_ASSERT(scalePointId < parameterScalePointCount(parameterId));
  256. return 0.0;
  257. }
  258. void CarlaPlugin::getLabel(char* const strBuf)
  259. {
  260. *strBuf = 0;
  261. }
  262. void CarlaPlugin::getMaker(char* const strBuf)
  263. {
  264. *strBuf = 0;
  265. }
  266. void CarlaPlugin::getCopyright(char* const strBuf)
  267. {
  268. *strBuf = 0;
  269. }
  270. void CarlaPlugin::getRealName(char* const strBuf)
  271. {
  272. *strBuf = 0;;
  273. }
  274. void CarlaPlugin::getParameterName(const uint32_t parameterId, char* const strBuf)
  275. {
  276. CARLA_ASSERT(parameterId < param.count);
  277. *strBuf = 0;
  278. }
  279. void CarlaPlugin::getParameterSymbol(const uint32_t parameterId, char* const strBuf)
  280. {
  281. CARLA_ASSERT(parameterId < param.count);
  282. *strBuf = 0;
  283. }
  284. void CarlaPlugin::getParameterText(const uint32_t parameterId, char* const strBuf)
  285. {
  286. CARLA_ASSERT(parameterId < param.count);
  287. *strBuf = 0;
  288. }
  289. void CarlaPlugin::getParameterUnit(const uint32_t parameterId, char* const strBuf)
  290. {
  291. CARLA_ASSERT(parameterId < param.count);
  292. *strBuf = 0;
  293. }
  294. void CarlaPlugin::getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf)
  295. {
  296. CARLA_ASSERT(parameterId < param.count);
  297. CARLA_ASSERT(scalePointId < parameterScalePointCount(parameterId));
  298. *strBuf = 0;
  299. }
  300. void CarlaPlugin::getProgramName(const uint32_t index, char* const strBuf)
  301. {
  302. CARLA_ASSERT(index < prog.count);
  303. if (index < prog.count && prog.names[index])
  304. strncpy(strBuf, prog.names[index], STR_MAX);
  305. else
  306. *strBuf = 0;
  307. }
  308. void CarlaPlugin::getMidiProgramName(const uint32_t index, char* const strBuf)
  309. {
  310. CARLA_ASSERT(index < midiprog.count);
  311. if (index < midiprog.count && midiprog.data[index].name)
  312. strncpy(strBuf, midiprog.data[index].name, STR_MAX);
  313. else
  314. *strBuf = 0;
  315. }
  316. void CarlaPlugin::getParameterCountInfo(uint32_t* const ins, uint32_t* const outs, uint32_t* const total)
  317. {
  318. *ins = 0;
  319. *outs = 0;
  320. *total = param.count;
  321. for (uint32_t i=0; i < param.count; i++)
  322. {
  323. if (param.data[i].type == PARAMETER_INPUT)
  324. *ins += 1;
  325. else if (param.data[i].type == PARAMETER_OUTPUT)
  326. *outs += 1;
  327. }
  328. }
  329. void CarlaPlugin::getGuiInfo(GuiType* const type, bool* const resizable)
  330. {
  331. *type = GUI_NONE;
  332. *resizable = false;
  333. }
  334. // -------------------------------------------------------------------
  335. // Set data (internal stuff)
  336. void CarlaPlugin::setId(const unsigned short id)
  337. {
  338. m_id = id;
  339. if (x_engine->getOptions().processMode == PROCESS_MODE_CONTINUOUS_RACK)
  340. m_ctrlInChannel = id;
  341. }
  342. void CarlaPlugin::setEnabled(const bool yesNo)
  343. {
  344. m_enabled = yesNo;
  345. }
  346. void CarlaPlugin::setActive(const bool active, const bool sendOsc, const bool sendCallback)
  347. {
  348. m_active = active;
  349. double value = active ? 1.0 : 0.0;
  350. #ifndef BUILD_BRIDGE
  351. if (sendOsc)
  352. x_engine->osc_send_control_set_parameter_value(m_id, PARAMETER_ACTIVE, value);
  353. #else
  354. Q_UNUSED(sendOsc);
  355. #endif
  356. if (sendCallback)
  357. x_engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, m_id, PARAMETER_ACTIVE, 0, value, nullptr);
  358. #ifndef BUILD_BRIDGE
  359. else if (m_hints & PLUGIN_IS_BRIDGE)
  360. osc_send_control(&osc.data, PARAMETER_ACTIVE, value);
  361. #endif
  362. }
  363. void CarlaPlugin::setDryWet(double value, const bool sendOsc, const bool sendCallback)
  364. {
  365. CARLA_ASSERT(value >= 0.0 && value <= 1.0);
  366. if (value < 0.0)
  367. value = 0.0;
  368. else if (value > 1.0)
  369. value = 1.0;
  370. x_dryWet = value;
  371. #ifndef BUILD_BRIDGE
  372. if (sendOsc)
  373. x_engine->osc_send_control_set_parameter_value(m_id, PARAMETER_DRYWET, value);
  374. #else
  375. Q_UNUSED(sendOsc);
  376. #endif
  377. if (sendCallback)
  378. x_engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, m_id, PARAMETER_DRYWET, 0, value, nullptr);
  379. #ifndef BUILD_BRIDGE
  380. else if (m_hints & PLUGIN_IS_BRIDGE)
  381. osc_send_control(&osc.data, PARAMETER_DRYWET, value);
  382. #endif
  383. }
  384. void CarlaPlugin::setVolume(double value, const bool sendOsc, const bool sendCallback)
  385. {
  386. CARLA_ASSERT(value >= 0.0 && value <= 1.27);
  387. if (value < 0.0)
  388. value = 0.0;
  389. else if (value > 1.27)
  390. value = 1.27;
  391. x_volume = value;
  392. #ifndef BUILD_BRIDGE
  393. if (sendOsc)
  394. x_engine->osc_send_control_set_parameter_value(m_id, PARAMETER_VOLUME, value);
  395. #else
  396. Q_UNUSED(sendOsc);
  397. #endif
  398. if (sendCallback)
  399. x_engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, m_id, PARAMETER_VOLUME, 0, value, nullptr);
  400. #ifndef BUILD_BRIDGE
  401. else if (m_hints & PLUGIN_IS_BRIDGE)
  402. osc_send_control(&osc.data, PARAMETER_VOLUME, value);
  403. #endif
  404. }
  405. void CarlaPlugin::setBalanceLeft(double value, const bool sendOsc, const bool sendCallback)
  406. {
  407. CARLA_ASSERT(value >= -1.0 && value <= 1.0);
  408. if (value < -1.0)
  409. value = -1.0;
  410. else if (value > 1.0)
  411. value = 1.0;
  412. x_balanceLeft = value;
  413. #ifndef BUILD_BRIDGE
  414. if (sendOsc)
  415. x_engine->osc_send_control_set_parameter_value(m_id, PARAMETER_BALANCE_LEFT, value);
  416. #else
  417. Q_UNUSED(sendOsc);
  418. #endif
  419. if (sendCallback)
  420. x_engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, m_id, PARAMETER_BALANCE_LEFT, 0, value, nullptr);
  421. #ifndef BUILD_BRIDGE
  422. else if (m_hints & PLUGIN_IS_BRIDGE)
  423. osc_send_control(&osc.data, PARAMETER_BALANCE_LEFT, value);
  424. #endif
  425. }
  426. void CarlaPlugin::setBalanceRight(double value, const bool sendOsc, const bool sendCallback)
  427. {
  428. CARLA_ASSERT(value >= -1.0 && value <= 1.0);
  429. if (value < -1.0)
  430. value = -1.0;
  431. else if (value > 1.0)
  432. value = 1.0;
  433. x_balanceRight = value;
  434. #ifndef BUILD_BRIDGE
  435. if (sendOsc)
  436. x_engine->osc_send_control_set_parameter_value(m_id, PARAMETER_BALANCE_RIGHT, value);
  437. #else
  438. Q_UNUSED(sendOsc);
  439. #endif
  440. if (sendCallback)
  441. x_engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, m_id, PARAMETER_BALANCE_RIGHT, 0, value, nullptr);
  442. #ifndef BUILD_BRIDGE
  443. else if (m_hints & PLUGIN_IS_BRIDGE)
  444. osc_send_control(&osc.data, PARAMETER_BALANCE_RIGHT, value);
  445. #endif
  446. }
  447. #ifndef BUILD_BRIDGE
  448. int CarlaPlugin::setOscBridgeInfo(const PluginBridgeInfoType type, const int argc, const lo_arg* const* const argv, const char* const types)
  449. {
  450. return 1;
  451. Q_UNUSED(type);
  452. Q_UNUSED(argc);
  453. Q_UNUSED(argv);
  454. Q_UNUSED(types);
  455. }
  456. #endif
  457. // -------------------------------------------------------------------
  458. // Set data (plugin-specific stuff)
  459. void CarlaPlugin::setParameterValue(const uint32_t parameterId, double value, const bool sendGui, const bool sendOsc, const bool sendCallback)
  460. {
  461. CARLA_ASSERT(parameterId < param.count);
  462. if (sendGui)
  463. uiParameterChange(parameterId, value);
  464. #ifndef BUILD_BRIDGE
  465. if (sendOsc)
  466. x_engine->osc_send_control_set_parameter_value(m_id, parameterId, value);
  467. #else
  468. Q_UNUSED(sendOsc);
  469. #endif
  470. if (sendCallback)
  471. x_engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, m_id, parameterId, 0, value, nullptr);
  472. }
  473. void CarlaPlugin::setParameterValueByRIndex(const int32_t rindex, const double value, const bool sendGui, const bool sendOsc, const bool sendCallback)
  474. {
  475. CARLA_ASSERT(rindex >= PARAMETER_BALANCE_RIGHT && rindex != PARAMETER_NULL);
  476. if (rindex == PARAMETER_ACTIVE)
  477. return setActive(value > 0.0, sendOsc, sendCallback);
  478. if (rindex == PARAMETER_DRYWET)
  479. return setDryWet(value, sendOsc, sendCallback);
  480. if (rindex == PARAMETER_VOLUME)
  481. return setVolume(value, sendOsc, sendCallback);
  482. if (rindex == PARAMETER_BALANCE_LEFT)
  483. return setBalanceLeft(value, sendOsc, sendCallback);
  484. if (rindex == PARAMETER_BALANCE_RIGHT)
  485. return setBalanceRight(value, sendOsc, sendCallback);
  486. for (uint32_t i=0; i < param.count; i++)
  487. {
  488. if (param.data[i].rindex == rindex)
  489. return setParameterValue(i, value, sendGui, sendOsc, sendCallback);
  490. }
  491. }
  492. void CarlaPlugin::setParameterMidiChannel(const uint32_t parameterId, uint8_t channel, const bool sendOsc, const bool sendCallback)
  493. {
  494. CARLA_ASSERT(parameterId < param.count);
  495. CARLA_ASSERT(channel < 16);
  496. if (channel >= 16)
  497. channel = 16;
  498. param.data[parameterId].midiChannel = channel;
  499. #ifndef BUILD_BRIDGE
  500. if (sendOsc)
  501. x_engine->osc_send_control_set_parameter_midi_channel(m_id, parameterId, channel);
  502. #else
  503. Q_UNUSED(sendOsc);
  504. #endif
  505. if (sendCallback)
  506. x_engine->callback(CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED, m_id, parameterId, channel, 0.0, nullptr);
  507. }
  508. void CarlaPlugin::setParameterMidiCC(const uint32_t parameterId, int16_t cc, const bool sendOsc, const bool sendCallback)
  509. {
  510. CARLA_ASSERT(parameterId < param.count);
  511. CARLA_ASSERT(cc >= -1);
  512. if (cc < -1 || cc > 0x5F)
  513. cc = -1;
  514. param.data[parameterId].midiCC = cc;
  515. #ifndef BUILD_BRIDGE
  516. if (sendOsc)
  517. x_engine->osc_send_control_set_parameter_midi_cc(m_id, parameterId, cc);
  518. #else
  519. Q_UNUSED(sendOsc);
  520. #endif
  521. if (sendCallback)
  522. x_engine->callback(CALLBACK_PARAMETER_MIDI_CC_CHANGED, m_id, parameterId, cc, 0.0, nullptr);
  523. }
  524. void CarlaPlugin::setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui)
  525. {
  526. CARLA_ASSERT(type);
  527. CARLA_ASSERT(key);
  528. CARLA_ASSERT(value);
  529. if (! type)
  530. return qCritical("CarlaPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is invalid", type, key, value, bool2str(sendGui));
  531. if (! key)
  532. return qCritical("CarlaPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - key is null", type, key, value, bool2str(sendGui));
  533. if (! value)
  534. return qCritical("CarlaPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - value is null", type, key, value, bool2str(sendGui));
  535. bool saveData = true;
  536. if (strcmp(type, CUSTOM_DATA_STRING) == 0)
  537. {
  538. // Ignore some keys
  539. if (strncmp(key, "OSC:", 4) == 0 || strcmp(key, "guiVisible") == 0)
  540. saveData = false;
  541. else if (strcmp(key, CARLA_BRIDGE_MSG_SAVE_NOW) == 0 || strcmp(key, CARLA_BRIDGE_MSG_SET_CHUNK) == 0 || strcmp(key, CARLA_BRIDGE_MSG_SET_CUSTOM) == 0)
  542. saveData = false;
  543. }
  544. if (saveData)
  545. {
  546. // Check if we already have this key
  547. for (size_t i=0; i < custom.size(); i++)
  548. {
  549. if (strcmp(custom[i].key, key) == 0)
  550. {
  551. free((void*)custom[i].value);
  552. custom[i].value = strdup(value);
  553. return;
  554. }
  555. }
  556. // Otherwise store it
  557. CustomData newData;
  558. newData.type = strdup(type);
  559. newData.key = strdup(key);
  560. newData.value = strdup(value);
  561. custom.push_back(newData);
  562. }
  563. }
  564. void CarlaPlugin::setChunkData(const char* const stringData)
  565. {
  566. CARLA_ASSERT(stringData);
  567. }
  568. void CarlaPlugin::setProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block)
  569. {
  570. CARLA_ASSERT(index >= -1 && index < (int32_t)prog.count);
  571. if (index < -1)
  572. index = -1;
  573. else if (index > (int32_t)prog.count)
  574. return;
  575. prog.current = index;
  576. if (sendGui && index >= 0)
  577. uiProgramChange(index);
  578. // Change default parameter values
  579. if (index >= 0)
  580. {
  581. for (uint32_t i=0; i < param.count; i++)
  582. {
  583. param.ranges[i].def = getParameterValue(i);
  584. fixParameterValue(param.ranges[i].def, param.ranges[i]);
  585. #ifndef BUILD_BRIDGE
  586. if (sendOsc)
  587. {
  588. x_engine->osc_send_control_set_default_value(m_id, i, param.ranges[i].def);
  589. x_engine->osc_send_control_set_parameter_value(m_id, i, param.ranges[i].def);
  590. }
  591. #endif
  592. }
  593. }
  594. #ifndef BUILD_BRIDGE
  595. if (sendOsc)
  596. x_engine->osc_send_control_set_program(m_id, index);
  597. #else
  598. Q_UNUSED(sendOsc);
  599. #endif
  600. if (sendCallback)
  601. x_engine->callback(CALLBACK_PROGRAM_CHANGED, m_id, index, 0, 0.0, nullptr);
  602. Q_UNUSED(block);
  603. }
  604. void CarlaPlugin::setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block)
  605. {
  606. CARLA_ASSERT(index >= -1 && index < (int32_t)midiprog.count);
  607. if (index < -1)
  608. index = -1;
  609. else if (index > (int32_t)midiprog.count)
  610. return;
  611. midiprog.current = index;
  612. if (sendGui && index >= 0)
  613. uiMidiProgramChange(index);
  614. // Change default parameter values (sound banks never change defaults)
  615. if (index >= 0 && m_type != PLUGIN_GIG && m_type != PLUGIN_SF2 && m_type != PLUGIN_SFZ)
  616. {
  617. for (uint32_t i=0; i < param.count; i++)
  618. {
  619. param.ranges[i].def = getParameterValue(i);
  620. fixParameterValue(param.ranges[i].def, param.ranges[i]);
  621. #ifndef BUILD_BRIDGE
  622. if (sendOsc)
  623. {
  624. x_engine->osc_send_control_set_default_value(m_id, i, param.ranges[i].def);
  625. x_engine->osc_send_control_set_parameter_value(m_id, i, param.ranges[i].def);
  626. }
  627. #endif
  628. }
  629. }
  630. #ifndef BUILD_BRIDGE
  631. if (sendOsc)
  632. x_engine->osc_send_control_set_midi_program(m_id, index);
  633. #else
  634. Q_UNUSED(sendOsc);
  635. #endif
  636. if (sendCallback)
  637. x_engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, m_id, index, 0, 0.0, nullptr);
  638. Q_UNUSED(block);
  639. }
  640. void CarlaPlugin::setMidiProgramById(const uint32_t bank, const uint32_t program, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block)
  641. {
  642. for (uint32_t i=0; i < midiprog.count; i++)
  643. {
  644. if (midiprog.data[i].bank == bank && midiprog.data[i].program == program)
  645. return setMidiProgram(i, sendGui, sendOsc, sendCallback, block);
  646. }
  647. }
  648. // -------------------------------------------------------------------
  649. // Set gui stuff
  650. void CarlaPlugin::setGuiContainer(GuiContainer* const container)
  651. {
  652. Q_UNUSED(container);
  653. }
  654. void CarlaPlugin::showGui(const bool yesNo)
  655. {
  656. Q_UNUSED(yesNo);
  657. }
  658. void CarlaPlugin::idleGui()
  659. {
  660. if (! m_enabled)
  661. return;
  662. if (m_hints & PLUGIN_USES_SINGLE_THREAD)
  663. {
  664. // Process postponed events
  665. postEventsRun();
  666. // Update parameter outputs
  667. for (uint32_t i=0; i < param.count; i++)
  668. {
  669. if (param.data[i].type == PARAMETER_OUTPUT)
  670. uiParameterChange(i, getParameterValue(i));
  671. }
  672. }
  673. }
  674. // -------------------------------------------------------------------
  675. // Plugin state
  676. void CarlaPlugin::reload()
  677. {
  678. }
  679. void CarlaPlugin::reloadPrograms(const bool init)
  680. {
  681. Q_UNUSED(init);
  682. }
  683. void CarlaPlugin::prepareForSave()
  684. {
  685. }
  686. // -------------------------------------------------------------------
  687. // Plugin processing
  688. void CarlaPlugin::process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset)
  689. {
  690. Q_UNUSED(inBuffer);
  691. Q_UNUSED(outBuffer);
  692. Q_UNUSED(frames);
  693. Q_UNUSED(framesOffset);
  694. }
  695. void CarlaPlugin::bufferSizeChanged(const uint32_t newBufferSize)
  696. {
  697. Q_UNUSED(newBufferSize);
  698. }
  699. void CarlaPlugin::recreateLatencyBuffers()
  700. {
  701. if (m_latencyBuffers)
  702. {
  703. for (uint32_t i=0; i < aIn.count; i++)
  704. delete[] m_latencyBuffers[i];
  705. delete[] m_latencyBuffers;
  706. }
  707. if (aIn.count > 0 && m_latency > 0)
  708. {
  709. m_latencyBuffers = new float* [aIn.count];
  710. for (uint32_t i=0; i < aIn.count; i++)
  711. m_latencyBuffers[i] = new float [m_latency];
  712. }
  713. else
  714. m_latencyBuffers = nullptr;
  715. }
  716. // -------------------------------------------------------------------
  717. // OSC stuff
  718. void CarlaPlugin::registerToOscClient()
  719. {
  720. #ifndef BUILD_BRIDGE
  721. if (! x_engine->isOscControlRegistered())
  722. return;
  723. #else
  724. if (! x_engine->isOscBridgeRegistered())
  725. return;
  726. #endif
  727. #ifndef BUILD_BRIDGE
  728. x_engine->osc_send_control_add_plugin_start(m_id, m_name);
  729. #endif
  730. // Base data
  731. {
  732. char bufName[STR_MAX] = { 0 };
  733. char bufLabel[STR_MAX] = { 0 };
  734. char bufMaker[STR_MAX] = { 0 };
  735. char bufCopyright[STR_MAX] = { 0 };
  736. getRealName(bufName);
  737. getLabel(bufLabel);
  738. getMaker(bufMaker);
  739. getCopyright(bufCopyright);
  740. #ifdef BUILD_BRIDGE
  741. x_engine->osc_send_bridge_plugin_info(category(), m_hints, bufName, bufLabel, bufMaker, bufCopyright, uniqueId());
  742. #else
  743. x_engine->osc_send_control_set_plugin_data(m_id, m_type, category(), m_hints, bufName, bufLabel, bufMaker, bufCopyright, uniqueId());
  744. #endif
  745. }
  746. // Base count
  747. {
  748. uint32_t cIns, cOuts, cTotals;
  749. getParameterCountInfo(&cIns, &cOuts, &cTotals);
  750. #ifdef BUILD_BRIDGE
  751. x_engine->osc_send_bridge_audio_count(audioInCount(), audioOutCount(), audioInCount() + audioOutCount());
  752. x_engine->osc_send_bridge_midi_count(midiInCount(), midiOutCount(), midiInCount() + midiOutCount());
  753. x_engine->osc_send_bridge_parameter_count(cIns, cOuts, cTotals);
  754. #else
  755. x_engine->osc_send_control_set_plugin_ports(m_id, audioInCount(), audioOutCount(), midiInCount(), midiOutCount(), cIns, cOuts, cTotals);
  756. #endif
  757. }
  758. // Plugin Parameters
  759. if (param.count > 0 && param.count < x_engine->getOptions().maxParameters)
  760. {
  761. char bufName[STR_MAX], bufUnit[STR_MAX];
  762. for (uint32_t i=0; i < param.count; i++)
  763. {
  764. getParameterName(i, bufName);
  765. getParameterUnit(i, bufUnit);
  766. #ifdef BUILD_BRIDGE
  767. x_engine->osc_send_bridge_parameter_info(i, bufName, bufUnit);
  768. x_engine->osc_send_bridge_parameter_data(i, param.data[i].type, param.data[i].rindex, param.data[i].hints, param.data[i].midiChannel, param.data[i].midiCC);
  769. x_engine->osc_send_bridge_parameter_ranges(i, param.ranges[i].def, param.ranges[i].min, param.ranges[i].max, param.ranges[i].step, param.ranges[i].stepSmall, param.ranges[i].stepLarge);
  770. x_engine->osc_send_bridge_set_parameter_value(i, getParameterValue(i));
  771. #else
  772. x_engine->osc_send_control_set_parameter_data(m_id, i, param.data[i].type, param.data[i].hints, bufName, bufUnit, getParameterValue(i));
  773. x_engine->osc_send_control_set_parameter_ranges(m_id, i, param.ranges[i].min, param.ranges[i].max, param.ranges[i].def, param.ranges[i].step, param.ranges[i].stepSmall, param.ranges[i].stepLarge);
  774. x_engine->osc_send_control_set_parameter_midi_cc(m_id, i, param.data[i].midiCC);
  775. x_engine->osc_send_control_set_parameter_midi_channel(m_id, i, param.data[i].midiChannel);
  776. x_engine->osc_send_control_set_parameter_value(m_id, i, getParameterValue(i));
  777. #endif
  778. }
  779. }
  780. // Programs
  781. if (prog.count > 0)
  782. {
  783. #ifdef BUILD_BRIDGE
  784. x_engine->osc_send_bridge_program_count(prog.count);
  785. for (uint32_t i=0; i < prog.count; i++)
  786. x_engine->osc_send_bridge_program_info(i, prog.names[i]);
  787. x_engine->osc_send_bridge_set_program(prog.current);
  788. #else
  789. x_engine->osc_send_control_set_program_count(m_id, prog.count);
  790. for (uint32_t i=0; i < prog.count; i++)
  791. x_engine->osc_send_control_set_program_name(m_id, i, prog.names[i]);
  792. x_engine->osc_send_control_set_program(m_id, prog.current);
  793. #endif
  794. }
  795. // MIDI Programs
  796. if (midiprog.count > 0)
  797. {
  798. #ifdef BUILD_BRIDGE
  799. x_engine->osc_send_bridge_midi_program_count(midiprog.count);
  800. for (uint32_t i=0; i < midiprog.count; i++)
  801. x_engine->osc_send_bridge_midi_program_info(i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name);
  802. x_engine->osc_send_bridge_set_midi_program(prog.current);
  803. #else
  804. x_engine->osc_send_control_set_midi_program_count(m_id, midiprog.count);
  805. for (uint32_t i=0; i < midiprog.count; i++)
  806. x_engine->osc_send_control_set_midi_program_data(m_id, i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name);
  807. x_engine->osc_send_control_set_midi_program(m_id, midiprog.current);
  808. #endif
  809. }
  810. #ifndef BUILD_BRIDGE
  811. x_engine->osc_send_control_add_plugin_end(m_id);
  812. // Internal Parameters
  813. {
  814. x_engine->osc_send_control_set_parameter_value(m_id, PARAMETER_ACTIVE, m_active ? 1.0 : 0.0);
  815. x_engine->osc_send_control_set_parameter_value(m_id, PARAMETER_DRYWET, x_dryWet);
  816. x_engine->osc_send_control_set_parameter_value(m_id, PARAMETER_VOLUME, x_volume);
  817. x_engine->osc_send_control_set_parameter_value(m_id, PARAMETER_BALANCE_LEFT, x_balanceLeft);
  818. x_engine->osc_send_control_set_parameter_value(m_id, PARAMETER_BALANCE_RIGHT, x_balanceRight);
  819. }
  820. #endif
  821. }
  822. void CarlaPlugin::updateOscData(const lo_address source, const char* const url)
  823. {
  824. // FIXME - remove debug prints later
  825. qWarning("CarlaPlugin::updateOscData(%p, \"%s\")", source, url);
  826. const char* host;
  827. const char* port;
  828. const int proto = lo_address_get_protocol(source);
  829. osc.data.free();
  830. host = lo_address_get_hostname(source);
  831. port = lo_address_get_port(source);
  832. osc.data.source = lo_address_new_with_proto(proto, host, port);
  833. qWarning("CarlaPlugin::updateOscData() - source: host \"%s\", port \"%s\"", host, port);
  834. host = lo_url_get_hostname(url);
  835. port = lo_url_get_port(url);
  836. osc.data.path = lo_url_get_path(url);
  837. osc.data.target = lo_address_new_with_proto(proto, host, port);
  838. qWarning("CarlaPlugin::updateOscData() - target: host \"%s\", port \"%s\", path \"%s\"", host, port, osc.data.path);
  839. free((void*)host);
  840. free((void*)port);
  841. #ifndef BUILD_BRIDGE
  842. if (m_hints & PLUGIN_IS_BRIDGE)
  843. return;
  844. #endif
  845. osc_send_sample_rate(&osc.data, x_engine->getSampleRate());
  846. for (size_t i=0; i < custom.size(); i++)
  847. {
  848. // TODO
  849. //if (m_type == PLUGIN_LV2)
  850. //osc_send_lv2_transfer_event(&osc.data, getCustomDataTypeString(custom[i].type), /*custom[i].key,*/ custom[i].value);
  851. //else
  852. if (custom[i].type == CUSTOM_DATA_STRING)
  853. osc_send_configure(&osc.data, custom[i].key, custom[i].value);
  854. }
  855. if (prog.current >= 0)
  856. osc_send_program(&osc.data, prog.current);
  857. if (midiprog.current >= 0)
  858. {
  859. if (m_type == PLUGIN_DSSI)
  860. osc_send_program(&osc.data, midiprog.data[midiprog.current].bank, midiprog.data[midiprog.current].program);
  861. else
  862. osc_send_midi_program(&osc.data, midiprog.data[midiprog.current].bank, midiprog.data[midiprog.current].program);
  863. }
  864. for (uint32_t i=0; i < param.count; i++)
  865. osc_send_control(&osc.data, param.data[i].rindex, getParameterValue(i));
  866. qWarning("CarlaPlugin::updateOscData() - done");
  867. }
  868. void CarlaPlugin::freeOscData()
  869. {
  870. osc.data.free();
  871. }
  872. bool CarlaPlugin::waitForOscGuiShow()
  873. {
  874. qWarning("CarlaPlugin::waitForOscGuiShow()");
  875. // wait for UI 'update' call
  876. for (uint i=0, oscUiTimeout = x_engine->getOptions().oscUiTimeout; i < oscUiTimeout; i++)
  877. {
  878. if (osc.data.target)
  879. {
  880. qWarning("CarlaPlugin::waitForOscGuiShow() - got response, asking UI to show itself now");
  881. osc_send_show(&osc.data);
  882. return true;
  883. }
  884. else
  885. carla_msleep(100);
  886. }
  887. qWarning("CarlaPlugin::waitForOscGuiShow() - Timeout while waiting for UI to respond (waited %u msecs)", x_engine->getOptions().oscUiTimeout);
  888. return false;
  889. }
  890. // -------------------------------------------------------------------
  891. // MIDI events
  892. void CarlaPlugin::sendMidiSingleNote(const uint8_t channel, const uint8_t note, const uint8_t velo, const bool sendGui, const bool sendOsc, const bool sendCallback)
  893. {
  894. CARLA_ASSERT(channel < 16);
  895. CARLA_ASSERT(note < 128);
  896. CARLA_ASSERT(velo < 128);
  897. if (! m_active)
  898. return;
  899. engineMidiLock();
  900. for (unsigned short i=0; i < MAX_MIDI_EVENTS; i++)
  901. {
  902. if (extMidiNotes[i].channel < 0)
  903. {
  904. extMidiNotes[i].channel = channel;
  905. extMidiNotes[i].note = note;
  906. extMidiNotes[i].velo = velo;
  907. break;
  908. }
  909. }
  910. engineMidiUnlock();
  911. if (sendGui)
  912. {
  913. if (velo > 0)
  914. uiNoteOn(channel, note, velo);
  915. else
  916. uiNoteOff(channel, note);
  917. }
  918. #ifndef BUILD_BRIDGE
  919. if (sendOsc)
  920. {
  921. if (velo > 0)
  922. x_engine->osc_send_control_note_on(m_id, channel, note, velo);
  923. else
  924. x_engine->osc_send_control_note_off(m_id, channel, note);
  925. }
  926. #else
  927. Q_UNUSED(sendOsc);
  928. #endif
  929. if (sendCallback)
  930. x_engine->callback(velo ? CALLBACK_NOTE_ON : CALLBACK_NOTE_OFF, m_id, channel, note, velo, nullptr);
  931. }
  932. void CarlaPlugin::sendMidiAllNotesOff()
  933. {
  934. engineMidiLock();
  935. postEvents.mutex.lock();
  936. unsigned short postPad = 0;
  937. for (unsigned short i=0; i < MAX_POST_EVENTS; i++)
  938. {
  939. if (postEvents.data[i].type == PluginPostEventNull)
  940. {
  941. postPad = i;
  942. break;
  943. }
  944. }
  945. if (postPad == MAX_POST_EVENTS - 1)
  946. {
  947. qWarning("post-events buffer full, making room for all notes off now");
  948. postPad -= 128;
  949. }
  950. for (unsigned short i=0; i < 128; i++)
  951. {
  952. extMidiNotes[i].channel = m_ctrlInChannel;
  953. extMidiNotes[i].note = i;
  954. extMidiNotes[i].velo = 0;
  955. postEvents.data[i + postPad].type = PluginPostEventNoteOff;
  956. postEvents.data[i + postPad].value1 = m_ctrlInChannel;
  957. postEvents.data[i + postPad].value2 = i;
  958. postEvents.data[i + postPad].value3 = 0.0;
  959. }
  960. postEvents.mutex.unlock();
  961. engineMidiUnlock();
  962. }
  963. // -------------------------------------------------------------------
  964. // Post-poned events
  965. void CarlaPlugin::postponeEvent(const PluginPostEventType type, const int32_t value1, const int32_t value2, const double value3, const void* const cdata)
  966. {
  967. postEvents.mutex.lock();
  968. for (unsigned short i=0; i < MAX_POST_EVENTS; i++)
  969. {
  970. if (postEvents.data[i].type == PluginPostEventNull)
  971. {
  972. postEvents.data[i].type = type;
  973. postEvents.data[i].value1 = value1;
  974. postEvents.data[i].value2 = value2;
  975. postEvents.data[i].value3 = value3;
  976. postEvents.data[i].cdata = cdata;
  977. break;
  978. }
  979. }
  980. postEvents.mutex.unlock();
  981. }
  982. void CarlaPlugin::postEventsRun()
  983. {
  984. PluginPostEvent newPostEvents[MAX_POST_EVENTS];
  985. // Make a safe copy of events, and clear them
  986. postEvents.mutex.lock();
  987. memcpy(newPostEvents, postEvents.data, sizeof(PluginPostEvent)*MAX_POST_EVENTS);
  988. for (unsigned short i=0; i < MAX_POST_EVENTS; i++)
  989. postEvents.data[i].type = PluginPostEventNull;
  990. postEvents.mutex.unlock();
  991. // Handle events now
  992. for (uint32_t i=0; i < MAX_POST_EVENTS; i++)
  993. {
  994. const PluginPostEvent* const event = &newPostEvents[i];
  995. switch (event->type)
  996. {
  997. case PluginPostEventNull:
  998. break;
  999. case PluginPostEventDebug:
  1000. x_engine->callback(CALLBACK_DEBUG, m_id, event->value1, event->value2, event->value3, nullptr);
  1001. break;
  1002. case PluginPostEventParameterChange:
  1003. // Update UI
  1004. if (event->value1 >= 0)
  1005. uiParameterChange(event->value1, event->value3);
  1006. #ifndef BUILD_BRIDGE
  1007. // Update OSC control client
  1008. if (x_engine->isOscControlRegistered())
  1009. x_engine->osc_send_control_set_parameter_value(m_id, event->value1, event->value3);
  1010. #endif
  1011. // Update Host
  1012. x_engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, m_id, event->value1, 0, event->value3, nullptr);
  1013. break;
  1014. case PluginPostEventProgramChange:
  1015. // Update UI
  1016. if (event->value1 >= 0)
  1017. uiProgramChange(event->value1);
  1018. #ifndef BUILD_BRIDGE
  1019. // Update OSC control client
  1020. if (x_engine->isOscControlRegistered())
  1021. {
  1022. x_engine->osc_send_control_set_program(m_id, event->value1);
  1023. for (uint32_t j=0; j < param.count; j++)
  1024. x_engine->osc_send_control_set_default_value(m_id, j, param.ranges[j].def);
  1025. }
  1026. #endif
  1027. // Update Host
  1028. x_engine->callback(CALLBACK_PROGRAM_CHANGED, m_id, event->value1, 0, 0.0, nullptr);
  1029. break;
  1030. case PluginPostEventMidiProgramChange:
  1031. // Update UI
  1032. if (event->value1 >= 0)
  1033. uiMidiProgramChange(event->value1);
  1034. #ifndef BUILD_BRIDGE
  1035. // Update OSC control client
  1036. if (x_engine->isOscControlRegistered())
  1037. {
  1038. x_engine->osc_send_control_set_midi_program(m_id, event->value1);
  1039. for (uint32_t j=0; j < param.count; j++)
  1040. x_engine->osc_send_control_set_default_value(m_id, j, param.ranges[j].def);
  1041. }
  1042. #endif
  1043. // Update Host
  1044. x_engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, m_id, event->value1, 0, 0.0, nullptr);
  1045. break;
  1046. case PluginPostEventNoteOn:
  1047. // Update UI
  1048. uiNoteOn(event->value1, event->value2, rint(event->value3));
  1049. #ifndef BUILD_BRIDGE
  1050. // Update OSC control client
  1051. if (x_engine->isOscControlRegistered())
  1052. x_engine->osc_send_control_note_on(m_id, event->value1, event->value2, rint(event->value3));
  1053. #endif
  1054. // Update Host
  1055. x_engine->callback(CALLBACK_NOTE_ON, m_id, event->value1, event->value2, rint(event->value3), nullptr);
  1056. break;
  1057. case PluginPostEventNoteOff:
  1058. // Update UI
  1059. uiNoteOff(event->value1, event->value2);
  1060. #ifndef BUILD_BRIDGE
  1061. // Update OSC control client
  1062. if (x_engine->isOscControlRegistered())
  1063. x_engine->osc_send_control_note_off(m_id, event->value1, event->value2);
  1064. #endif
  1065. // Update Host
  1066. x_engine->callback(CALLBACK_NOTE_OFF, m_id, event->value1, event->value2, 0.0, nullptr);
  1067. break;
  1068. case PluginPostEventCustom:
  1069. // Handle custom event
  1070. postEventHandleCustom(event->value1, event->value2, event->value3, event->cdata);
  1071. break;
  1072. }
  1073. }
  1074. }
  1075. void CarlaPlugin::postEventHandleCustom(const int32_t value1, const int32_t value2, const double value3, const void* const cdata)
  1076. {
  1077. Q_UNUSED(value1);
  1078. Q_UNUSED(value2);
  1079. Q_UNUSED(value3);
  1080. Q_UNUSED(cdata);
  1081. }
  1082. void CarlaPlugin::uiParameterChange(const uint32_t index, const double value)
  1083. {
  1084. CARLA_ASSERT(index < param.count);
  1085. Q_UNUSED(value);
  1086. }
  1087. void CarlaPlugin::uiProgramChange(const uint32_t index)
  1088. {
  1089. CARLA_ASSERT(index < prog.count);
  1090. }
  1091. void CarlaPlugin::uiMidiProgramChange(const uint32_t index)
  1092. {
  1093. CARLA_ASSERT(index < midiprog.count);
  1094. }
  1095. void CarlaPlugin::uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo)
  1096. {
  1097. CARLA_ASSERT(channel < 16);
  1098. CARLA_ASSERT(note < 128);
  1099. CARLA_ASSERT(velo > 0 && velo < 128);
  1100. }
  1101. void CarlaPlugin::uiNoteOff(const uint8_t channel, const uint8_t note)
  1102. {
  1103. CARLA_ASSERT(channel < 16);
  1104. CARLA_ASSERT(note < 128);
  1105. }
  1106. // -------------------------------------------------------------------
  1107. // Cleanup
  1108. void CarlaPlugin::removeClientPorts()
  1109. {
  1110. qDebug("CarlaPlugin::removeClientPorts() - start");
  1111. for (uint32_t i=0; i < aIn.count; i++)
  1112. {
  1113. delete aIn.ports[i];
  1114. aIn.ports[i] = nullptr;
  1115. }
  1116. for (uint32_t i=0; i < aOut.count; i++)
  1117. {
  1118. delete aOut.ports[i];
  1119. aOut.ports[i] = nullptr;
  1120. }
  1121. if (midi.portMin)
  1122. {
  1123. delete midi.portMin;
  1124. midi.portMin = nullptr;
  1125. }
  1126. if (midi.portMout)
  1127. {
  1128. delete midi.portMout;
  1129. midi.portMout = nullptr;
  1130. }
  1131. if (param.portCin)
  1132. {
  1133. delete param.portCin;
  1134. param.portCin = nullptr;
  1135. }
  1136. if (param.portCout)
  1137. {
  1138. delete param.portCout;
  1139. param.portCout = nullptr;
  1140. }
  1141. qDebug("CarlaPlugin::removeClientPorts() - end");
  1142. }
  1143. void CarlaPlugin::initBuffers()
  1144. {
  1145. for (uint32_t i=0; i < aIn.count; i++)
  1146. {
  1147. if (aIn.ports[i])
  1148. aIn.ports[i]->initBuffer(x_engine);
  1149. }
  1150. for (uint32_t i=0; i < aOut.count; i++)
  1151. {
  1152. if (aOut.ports[i])
  1153. aOut.ports[i]->initBuffer(x_engine);
  1154. }
  1155. if (param.portCin)
  1156. param.portCin->initBuffer(x_engine);
  1157. if (param.portCout)
  1158. param.portCout->initBuffer(x_engine);
  1159. if (midi.portMin)
  1160. midi.portMin->initBuffer(x_engine);
  1161. if (midi.portMout)
  1162. midi.portMout->initBuffer(x_engine);
  1163. }
  1164. void CarlaPlugin::deleteBuffers()
  1165. {
  1166. qDebug("CarlaPlugin::deleteBuffers() - start");
  1167. if (aIn.count > 0)
  1168. {
  1169. delete[] aIn.ports;
  1170. delete[] aIn.rindexes;
  1171. }
  1172. if (aOut.count > 0)
  1173. {
  1174. delete[] aOut.ports;
  1175. delete[] aOut.rindexes;
  1176. }
  1177. if (param.count > 0)
  1178. {
  1179. delete[] param.data;
  1180. delete[] param.ranges;
  1181. }
  1182. aIn.count = 0;
  1183. aIn.ports = nullptr;
  1184. aIn.rindexes = nullptr;
  1185. aOut.count = 0;
  1186. aOut.ports = nullptr;
  1187. aOut.rindexes = nullptr;
  1188. param.count = 0;
  1189. param.data = nullptr;
  1190. param.ranges = nullptr;
  1191. param.portCin = nullptr;
  1192. param.portCout = nullptr;
  1193. qDebug("CarlaPlugin::deleteBuffers() - end");
  1194. }
  1195. // -------------------------------------------------------------------
  1196. // Library functions
  1197. bool CarlaPlugin::libOpen(const char* const filename)
  1198. {
  1199. m_lib = lib_open(filename);
  1200. return bool(m_lib);
  1201. }
  1202. bool CarlaPlugin::libClose()
  1203. {
  1204. if (m_lib)
  1205. return lib_close(m_lib);
  1206. return false;
  1207. }
  1208. void* CarlaPlugin::libSymbol(const char* const symbol)
  1209. {
  1210. if (m_lib)
  1211. return lib_symbol(m_lib, symbol);
  1212. return nullptr;
  1213. }
  1214. const char* CarlaPlugin::libError(const char* const filename)
  1215. {
  1216. return lib_error(filename);
  1217. }
  1218. // -------------------------------------------------------------------
  1219. // Locks
  1220. void CarlaPlugin::engineProcessLock()
  1221. {
  1222. x_engine->processLock();
  1223. }
  1224. void CarlaPlugin::engineProcessUnlock()
  1225. {
  1226. x_engine->processUnlock();
  1227. }
  1228. void CarlaPlugin::engineMidiLock()
  1229. {
  1230. x_engine->midiLock();
  1231. }
  1232. void CarlaPlugin::engineMidiUnlock()
  1233. {
  1234. x_engine->midiUnlock();
  1235. }
  1236. // -------------------------------------------------------------------
  1237. // CarlaPluginGUI
  1238. CarlaPluginGUI::CarlaPluginGUI(QWidget* const parent, Callback* const callback)
  1239. : QMainWindow(parent),
  1240. m_callback(callback)
  1241. {
  1242. qDebug("CarlaPluginGUI::CarlaPluginGUI(%p, %p", parent, callback);
  1243. CARLA_ASSERT(callback);
  1244. m_container = new GuiContainer(this);
  1245. setCentralWidget(m_container);
  1246. adjustSize();
  1247. m_container->setParent(this);
  1248. m_container->show();
  1249. m_resizable = true;
  1250. setNewSize(50, 50);
  1251. QMainWindow::setVisible(false);
  1252. }
  1253. CarlaPluginGUI::~CarlaPluginGUI()
  1254. {
  1255. qDebug("CarlaPluginGUI::~CarlaPluginGUI()");
  1256. CARLA_ASSERT(m_container);
  1257. // FIXME, automatically deleted by parent ?
  1258. delete m_container;
  1259. }
  1260. // -------------------------------------------------------------------
  1261. GuiContainer* CarlaPluginGUI::getContainer() const
  1262. {
  1263. return m_container;
  1264. }
  1265. WId CarlaPluginGUI::getWinId() const
  1266. {
  1267. return m_container->winId();
  1268. }
  1269. // -------------------------------------------------------------------
  1270. void CarlaPluginGUI::setNewSize(int width, int height)
  1271. {
  1272. qDebug("CarlaPluginGUI::setNewSize(%i, %i)", width, height);
  1273. if (width < 30)
  1274. width = 30;
  1275. if (height < 30)
  1276. height = 30;
  1277. if (m_resizable)
  1278. {
  1279. resize(width, height);
  1280. }
  1281. else
  1282. {
  1283. setFixedSize(width, height);
  1284. m_container->setFixedSize(width, height);
  1285. }
  1286. }
  1287. void CarlaPluginGUI::setResizable(bool resizable)
  1288. {
  1289. m_resizable = resizable;
  1290. setNewSize(width(), height());
  1291. #ifdef Q_OS_WIN
  1292. if (! resizable)
  1293. setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
  1294. #endif
  1295. }
  1296. void CarlaPluginGUI::setTitle(const char* const title)
  1297. {
  1298. CARLA_ASSERT(title);
  1299. setWindowTitle(QString("%1 (GUI)").arg(title));
  1300. }
  1301. void CarlaPluginGUI::setVisible(const bool yesNo)
  1302. {
  1303. qDebug("CarlaPluginGUI::setVisible(%s)", bool2str(yesNo));
  1304. if (yesNo)
  1305. {
  1306. if (! m_geometry.isNull())
  1307. restoreGeometry(m_geometry);
  1308. }
  1309. else
  1310. m_geometry = saveGeometry();
  1311. QMainWindow::setVisible(yesNo);
  1312. }
  1313. // -------------------------------------------------------------------
  1314. void CarlaPluginGUI::hideEvent(QHideEvent* const event)
  1315. {
  1316. qDebug("CarlaPluginGUI::hideEvent(%p)", event);
  1317. CARLA_ASSERT(event);
  1318. event->accept();
  1319. close();
  1320. }
  1321. void CarlaPluginGUI::closeEvent(QCloseEvent* const event)
  1322. {
  1323. qDebug("CarlaPluginGUI::closeEvent(%p)", event);
  1324. CARLA_ASSERT(event);
  1325. if (event->spontaneous())
  1326. {
  1327. if (m_callback)
  1328. m_callback->guiClosedCallback();
  1329. QMainWindow::closeEvent(event);
  1330. return;
  1331. }
  1332. event->ignore();
  1333. }
  1334. // -------------------------------------------------------------------
  1335. CARLA_BACKEND_END_NAMESPACE