Audio plugin host https://kx.studio/carla
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.

1669 lines
45KB

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