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.

1667 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 unsigned 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. // Change default parameter values (sound banks never change defaults)
  630. if (index >= 0 && type() != PLUGIN_GIG && type() != PLUGIN_SF2 && type() != PLUGIN_SFZ)
  631. {
  632. for (uint32_t i=0; i < fData->param.count; i++)
  633. {
  634. fData->param.ranges[i].def = getParameterValue(i);
  635. fData->param.ranges[i].fixDefault();
  636. #ifndef BUILD_BRIDGE
  637. if (sendOsc)
  638. {
  639. fData->engine->osc_send_control_set_default_value(fData->id, i, fData->param.ranges[i].def);
  640. fData->engine->osc_send_control_set_parameter_value(fData->id, i, fData->param.ranges[i].def);
  641. }
  642. #endif
  643. }
  644. }
  645. #ifndef BUILD_BRIDGE
  646. if (sendOsc)
  647. fData->engine->osc_send_control_set_midi_program(fData->id, index);
  648. #else
  649. Q_UNUSED(sendOsc);
  650. #endif
  651. if (sendCallback)
  652. fData->engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, fData->id, index, 0, 0.0, nullptr);
  653. }
  654. void CarlaPlugin::setMidiProgramById(const uint32_t bank, const uint32_t program, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block)
  655. {
  656. for (uint32_t i=0; i < fData->midiprog.count; i++)
  657. {
  658. if (fData->midiprog.data[i].bank == bank && fData->midiprog.data[i].program == program)
  659. return setMidiProgram(i, sendGui, sendOsc, sendCallback, block);
  660. }
  661. }
  662. // -------------------------------------------------------------------
  663. // Set gui stuff
  664. void CarlaPlugin::showGui(const bool yesNo)
  665. {
  666. Q_UNUSED(yesNo);
  667. }
  668. void CarlaPlugin::idleGui()
  669. {
  670. if (! fData->enabled)
  671. return;
  672. if (fData->hints & PLUGIN_USES_SINGLE_THREAD)
  673. {
  674. // Process postponed events
  675. postEventsRun();
  676. // Update parameter outputs
  677. for (uint32_t i=0; i < fData->param.count; i++)
  678. {
  679. if (fData->param.data[i].type == PARAMETER_OUTPUT)
  680. uiParameterChange(i, getParameterValue(i));
  681. }
  682. }
  683. }
  684. // -------------------------------------------------------------------
  685. // Plugin state
  686. void CarlaPlugin::reload()
  687. {
  688. }
  689. void CarlaPlugin::reloadPrograms(const bool)
  690. {
  691. }
  692. void CarlaPlugin::prepareForSave()
  693. {
  694. }
  695. // -------------------------------------------------------------------
  696. // Plugin processing
  697. void CarlaPlugin::process(float** const, float** const, const uint32_t, const uint32_t)
  698. {
  699. }
  700. void CarlaPlugin::bufferSizeChanged(const uint32_t)
  701. {
  702. }
  703. void CarlaPlugin::sampleRateChanged(const double)
  704. {
  705. }
  706. void CarlaPlugin::recreateLatencyBuffers()
  707. {
  708. if (fData->latencyBuffers)
  709. {
  710. for (uint32_t i=0; i < fData->audioIn.count; i++)
  711. delete[] fData->latencyBuffers[i];
  712. delete[] fData->latencyBuffers;
  713. }
  714. if (fData->audioIn.count > 0 && fData->latency > 0)
  715. {
  716. fData->latencyBuffers = new float*[fData->audioIn.count];
  717. for (uint32_t i=0; i < fData->audioIn.count; i++)
  718. fData->latencyBuffers[i] = new float[fData->latency];
  719. }
  720. else
  721. fData->latencyBuffers = nullptr;
  722. }
  723. // -------------------------------------------------------------------
  724. // OSC stuff
  725. void CarlaPlugin::registerToOscClient()
  726. {
  727. #ifndef BUILD_BRIDGE
  728. if (! fData->engine->isOscControlRegistered())
  729. return;
  730. #else
  731. if (! fData->engine->isOscBridgeRegistered())
  732. return;
  733. #endif
  734. #ifndef BUILD_BRIDGE
  735. fData->engine->osc_send_control_add_plugin_start(fData->id, fData->name);
  736. #endif
  737. // Base data
  738. {
  739. char bufName[STR_MAX] = { 0 };
  740. char bufLabel[STR_MAX] = { 0 };
  741. char bufMaker[STR_MAX] = { 0 };
  742. char bufCopyright[STR_MAX] = { 0 };
  743. getRealName(bufName);
  744. getLabel(bufLabel);
  745. getMaker(bufMaker);
  746. getCopyright(bufCopyright);
  747. #ifdef BUILD_BRIDGE
  748. fData->engine->osc_send_bridge_plugin_info(category(), fData->hints, bufName, bufLabel, bufMaker, bufCopyright, uniqueId());
  749. #else
  750. fData->engine->osc_send_control_set_plugin_data(fData->id, type(), category(), fData->hints, bufName, bufLabel, bufMaker, bufCopyright, uniqueId());
  751. #endif
  752. }
  753. // Base count
  754. {
  755. uint32_t cIns, cOuts, cTotals;
  756. getParameterCountInfo(&cIns, &cOuts, &cTotals);
  757. #ifdef BUILD_BRIDGE
  758. fData->engine->osc_send_bridge_audio_count(audioInCount(), audioOutCount(), audioInCount() + audioOutCount());
  759. fData->engine->osc_send_bridge_midi_count(midiInCount(), midiOutCount(), midiInCount() + midiOutCount());
  760. fData->engine->osc_send_bridge_parameter_count(cIns, cOuts, cTotals);
  761. #else
  762. fData->engine->osc_send_control_set_plugin_ports(fData->id, audioInCount(), audioOutCount(), midiInCount(), midiOutCount(), cIns, cOuts, cTotals);
  763. #endif
  764. }
  765. // Plugin Parameters
  766. if (fData->param.count > 0 && fData->param.count < fData->engine->getOptions().maxParameters)
  767. {
  768. char bufName[STR_MAX], bufUnit[STR_MAX];
  769. for (uint32_t i=0; i < fData->param.count; i++)
  770. {
  771. getParameterName(i, bufName);
  772. getParameterUnit(i, bufUnit);
  773. #ifdef BUILD_BRIDGE
  774. fData->engine->osc_send_bridge_parameter_info(i, bufName, bufUnit);
  775. fData->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);
  776. fData->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);
  777. fData->engine->osc_send_bridge_set_parameter_value(i, getParameterValue(i));
  778. #else
  779. 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));
  780. 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);
  781. fData->engine->osc_send_control_set_parameter_midi_cc(fData->id, i, fData->param.data[i].midiCC);
  782. fData->engine->osc_send_control_set_parameter_midi_channel(fData->id, i, fData->param.data[i].midiChannel);
  783. fData->engine->osc_send_control_set_parameter_value(fData->id, i, getParameterValue(i));
  784. #endif
  785. }
  786. }
  787. // Programs
  788. if (fData->prog.count > 0)
  789. {
  790. #ifdef BUILD_BRIDGE
  791. fData->engine->osc_send_bridge_program_count(fData->prog.count);
  792. for (uint32_t i=0; i < fData->prog.count; i++)
  793. fData->engine->osc_send_bridge_program_info(i, fData->prog.names[i]);
  794. fData->engine->osc_send_bridge_set_program(fData->prog.current);
  795. #else
  796. fData->engine->osc_send_control_set_program_count(fData->id, fData->prog.count);
  797. for (uint32_t i=0; i < fData->prog.count; i++)
  798. fData->engine->osc_send_control_set_program_name(fData->id, i, fData->prog.names[i]);
  799. fData->engine->osc_send_control_set_program(fData->id, fData->prog.current);
  800. #endif
  801. }
  802. // MIDI Programs
  803. if (fData->midiprog.count > 0)
  804. {
  805. #ifdef BUILD_BRIDGE
  806. x_engine->osc_send_bridge_midi_program_count(midiprog.count);
  807. for (uint32_t i=0; i < midiprog.count; i++)
  808. x_engine->osc_send_bridge_midi_program_info(i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name);
  809. x_engine->osc_send_bridge_set_midi_program(prog.current);
  810. #else
  811. fData->engine->osc_send_control_set_midi_program_count(fData->id, fData->midiprog.count);
  812. for (uint32_t i=0; i < fData->midiprog.count; i++)
  813. 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);
  814. fData->engine->osc_send_control_set_midi_program(fData->id, fData->midiprog.current);
  815. #endif
  816. }
  817. #ifndef BUILD_BRIDGE
  818. fData->engine->osc_send_control_add_plugin_end(fData->id);
  819. // Internal Parameters
  820. {
  821. fData->engine->osc_send_control_set_parameter_value(fData->id, PARAMETER_ACTIVE, fData->active ? 1.0 : 0.0);
  822. fData->engine->osc_send_control_set_parameter_value(fData->id, PARAMETER_DRYWET, fData->postProc.dryWet);
  823. fData->engine->osc_send_control_set_parameter_value(fData->id, PARAMETER_VOLUME, fData->postProc.volume);
  824. fData->engine->osc_send_control_set_parameter_value(fData->id, PARAMETER_BALANCE_LEFT, fData->postProc.balanceLeft);
  825. fData->engine->osc_send_control_set_parameter_value(fData->id, PARAMETER_BALANCE_RIGHT, fData->postProc.balanceRight);
  826. fData->engine->osc_send_control_set_parameter_value(fData->id, PARAMETER_PANNING, fData->postProc.panning);
  827. }
  828. #endif
  829. }
  830. void CarlaPlugin::updateOscData(const lo_address& source, const char* const url)
  831. {
  832. // FIXME - remove debug prints later
  833. qWarning("CarlaPlugin::updateOscData(%p, \"%s\")", source, url);
  834. const char* host;
  835. const char* port;
  836. const int proto = lo_address_get_protocol(source);
  837. fData->osc.data.free();
  838. host = lo_address_get_hostname(source);
  839. port = lo_address_get_port(source);
  840. fData->osc.data.source = lo_address_new_with_proto(proto, host, port);
  841. qWarning("CarlaPlugin::updateOscData() - source: host \"%s\", port \"%s\"", host, port);
  842. host = lo_url_get_hostname(url);
  843. port = lo_url_get_port(url);
  844. fData->osc.data.path = lo_url_get_path(url);
  845. fData->osc.data.target = lo_address_new_with_proto(proto, host, port);
  846. qWarning("CarlaPlugin::updateOscData() - target: host \"%s\", port \"%s\", path \"%s\"", host, port, fData->osc.data.path);
  847. free((void*)host);
  848. free((void*)port);
  849. #ifndef BUILD_BRIDGE
  850. if (fData->hints & PLUGIN_IS_BRIDGE)
  851. return;
  852. #endif
  853. osc_send_sample_rate(&fData->osc.data, fData->engine->getSampleRate());
  854. #if 0
  855. for (size_t i=0; i < fData->custom.count(); i++)
  856. {
  857. // TODO
  858. //if (m_type == PLUGIN_LV2)
  859. //osc_send_lv2_transfer_event(&osc.data, getCustomDataTypeString(custom[i].type), /*custom[i].key,*/ custom[i].value);
  860. //else
  861. if (custom[i].type == CUSTOM_DATA_STRING)
  862. osc_send_configure(&osc.data, custom[i].key, custom[i].value);
  863. }
  864. #endif
  865. if (fData->prog.current >= 0)
  866. osc_send_program(&fData->osc.data, fData->prog.current);
  867. if (fData->midiprog.current >= 0)
  868. {
  869. const MidiProgramData& curMidiProg(fData->midiprog.getCurrent());
  870. if (type() == PLUGIN_DSSI)
  871. osc_send_program(&fData->osc.data, curMidiProg.bank, curMidiProg.program);
  872. else
  873. osc_send_midi_program(&fData->osc.data, curMidiProg.bank, curMidiProg.program);
  874. }
  875. for (uint32_t i=0; i < fData->param.count; i++)
  876. osc_send_control(&fData->osc.data, fData->param.data[i].rindex, getParameterValue(i));
  877. qWarning("CarlaPlugin::updateOscData() - done");
  878. }
  879. void CarlaPlugin::freeOscData()
  880. {
  881. fData->osc.data.free();
  882. }
  883. bool CarlaPlugin::waitForOscGuiShow()
  884. {
  885. qWarning("CarlaPlugin::waitForOscGuiShow()");
  886. // wait for UI 'update' call
  887. for (uint i=0, oscUiTimeout = fData->engine->getOptions().oscUiTimeout; i < oscUiTimeout; i++)
  888. {
  889. if (fData->osc.data.target)
  890. {
  891. qWarning("CarlaPlugin::waitForOscGuiShow() - got response, asking UI to show itself now");
  892. osc_send_show(&fData->osc.data);
  893. return true;
  894. }
  895. else
  896. carla_msleep(100);
  897. }
  898. qWarning("CarlaPlugin::waitForOscGuiShow() - Timeout while waiting for UI to respond (waited %u msecs)", fData->engine->getOptions().oscUiTimeout);
  899. return false;
  900. }
  901. #if 0
  902. // -------------------------------------------------------------------
  903. // MIDI events
  904. void CarlaPlugin::sendMidiSingleNote(const uint8_t channel, const uint8_t note, const uint8_t velo, const bool sendGui, const bool sendOsc, const bool sendCallback)
  905. {
  906. CARLA_ASSERT(channel < 16);
  907. CARLA_ASSERT(note < 128);
  908. CARLA_ASSERT(velo < 128);
  909. if (! m_active)
  910. return;
  911. engineMidiLock();
  912. for (unsigned short i=0; i < MAX_MIDI_EVENTS; i++)
  913. {
  914. if (extMidiNotes[i].channel < 0)
  915. {
  916. extMidiNotes[i].channel = channel;
  917. extMidiNotes[i].note = note;
  918. extMidiNotes[i].velo = velo;
  919. break;
  920. }
  921. }
  922. engineMidiUnlock();
  923. if (sendGui)
  924. {
  925. if (velo > 0)
  926. uiNoteOn(channel, note, velo);
  927. else
  928. uiNoteOff(channel, note);
  929. }
  930. #ifndef BUILD_BRIDGE
  931. if (sendOsc)
  932. {
  933. if (velo > 0)
  934. x_engine->osc_send_control_note_on(m_id, channel, note, velo);
  935. else
  936. x_engine->osc_send_control_note_off(m_id, channel, note);
  937. }
  938. #else
  939. Q_UNUSED(sendOsc);
  940. #endif
  941. if (sendCallback)
  942. x_engine->callback(velo ? CALLBACK_NOTE_ON : CALLBACK_NOTE_OFF, m_id, channel, note, velo, nullptr);
  943. }
  944. void CarlaPlugin::sendMidiAllNotesOff()
  945. {
  946. engineMidiLock();
  947. postEvents.mutex.lock();
  948. unsigned short postPad = 0;
  949. for (unsigned short i=0; i < MAX_POST_EVENTS; i++)
  950. {
  951. if (postEvents.data[i].type == PluginPostEventNull)
  952. {
  953. postPad = i;
  954. break;
  955. }
  956. }
  957. if (postPad == MAX_POST_EVENTS - 1)
  958. {
  959. qWarning("post-events buffer full, making room for all notes off now");
  960. postPad -= 128;
  961. }
  962. for (unsigned short i=0; i < 128; i++)
  963. {
  964. extMidiNotes[i].channel = m_ctrlInChannel;
  965. extMidiNotes[i].note = i;
  966. extMidiNotes[i].velo = 0;
  967. postEvents.data[i + postPad].type = PluginPostEventNoteOff;
  968. postEvents.data[i + postPad].value1 = m_ctrlInChannel;
  969. postEvents.data[i + postPad].value2 = i;
  970. postEvents.data[i + postPad].value3 = 0.0;
  971. }
  972. postEvents.mutex.unlock();
  973. engineMidiUnlock();
  974. }
  975. #endif
  976. // -------------------------------------------------------------------
  977. // Post-poned events
  978. void CarlaPlugin::postponeEvent(const PluginPostRtEventType type, const int32_t value1, const int32_t value2, const double value3)
  979. {
  980. PluginPostRtEvent event;
  981. event.type = type;
  982. event.value1 = value1;
  983. event.value2 = value2;
  984. event.value3 = value3;
  985. fData->postRtEvents.append(event);
  986. }
  987. #if 0
  988. void CarlaPlugin::postEventsRun()
  989. {
  990. PluginPostEvent newPostEvents[MAX_POST_EVENTS];
  991. // Make a safe copy of events, and clear them
  992. postEvents.mutex.lock();
  993. memcpy(newPostEvents, postEvents.data, sizeof(PluginPostEvent)*MAX_POST_EVENTS);
  994. for (unsigned short i=0; i < MAX_POST_EVENTS; i++)
  995. postEvents.data[i].type = PluginPostEventNull;
  996. postEvents.mutex.unlock();
  997. // Handle events now
  998. for (uint32_t i=0; i < MAX_POST_EVENTS; i++)
  999. {
  1000. const PluginPostEvent* const event = &newPostEvents[i];
  1001. switch (event->type)
  1002. {
  1003. case PluginPostEventNull:
  1004. break;
  1005. case PluginPostEventDebug:
  1006. x_engine->callback(CALLBACK_DEBUG, m_id, event->value1, event->value2, event->value3, nullptr);
  1007. break;
  1008. case PluginPostEventParameterChange:
  1009. // Update UI
  1010. if (event->value1 >= 0)
  1011. uiParameterChange(event->value1, event->value3);
  1012. #ifndef BUILD_BRIDGE
  1013. // Update OSC control client
  1014. if (x_engine->isOscControlRegistered())
  1015. x_engine->osc_send_control_set_parameter_value(m_id, event->value1, event->value3);
  1016. #endif
  1017. // Update Host
  1018. x_engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, m_id, event->value1, 0, event->value3, nullptr);
  1019. break;
  1020. case PluginPostEventProgramChange:
  1021. // Update UI
  1022. if (event->value1 >= 0)
  1023. uiProgramChange(event->value1);
  1024. #ifndef BUILD_BRIDGE
  1025. // Update OSC control client
  1026. if (x_engine->isOscControlRegistered())
  1027. {
  1028. x_engine->osc_send_control_set_program(m_id, event->value1);
  1029. for (uint32_t j=0; j < param.count; j++)
  1030. x_engine->osc_send_control_set_default_value(m_id, j, param.ranges[j].def);
  1031. }
  1032. #endif
  1033. // Update Host
  1034. x_engine->callback(CALLBACK_PROGRAM_CHANGED, m_id, event->value1, 0, 0.0, nullptr);
  1035. break;
  1036. case PluginPostEventMidiProgramChange:
  1037. // Update UI
  1038. if (event->value1 >= 0)
  1039. uiMidiProgramChange(event->value1);
  1040. #ifndef BUILD_BRIDGE
  1041. // Update OSC control client
  1042. if (x_engine->isOscControlRegistered())
  1043. {
  1044. x_engine->osc_send_control_set_midi_program(m_id, event->value1);
  1045. for (uint32_t j=0; j < param.count; j++)
  1046. x_engine->osc_send_control_set_default_value(m_id, j, param.ranges[j].def);
  1047. }
  1048. #endif
  1049. // Update Host
  1050. x_engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, m_id, event->value1, 0, 0.0, nullptr);
  1051. break;
  1052. case PluginPostEventNoteOn:
  1053. // Update UI
  1054. uiNoteOn(event->value1, event->value2, rint(event->value3));
  1055. #ifndef BUILD_BRIDGE
  1056. // Update OSC control client
  1057. if (x_engine->isOscControlRegistered())
  1058. x_engine->osc_send_control_note_on(m_id, event->value1, event->value2, rint(event->value3));
  1059. #endif
  1060. // Update Host
  1061. x_engine->callback(CALLBACK_NOTE_ON, m_id, event->value1, event->value2, rint(event->value3), nullptr);
  1062. break;
  1063. case PluginPostEventNoteOff:
  1064. // Update UI
  1065. uiNoteOff(event->value1, event->value2);
  1066. #ifndef BUILD_BRIDGE
  1067. // Update OSC control client
  1068. if (x_engine->isOscControlRegistered())
  1069. x_engine->osc_send_control_note_off(m_id, event->value1, event->value2);
  1070. #endif
  1071. // Update Host
  1072. x_engine->callback(CALLBACK_NOTE_OFF, m_id, event->value1, event->value2, 0.0, nullptr);
  1073. break;
  1074. case PluginPostEventCustom:
  1075. // Handle custom event
  1076. postEventHandleCustom(event->value1, event->value2, event->value3, event->cdata);
  1077. break;
  1078. }
  1079. }
  1080. }
  1081. #endif
  1082. void CarlaPlugin::uiParameterChange(const uint32_t index, const double value)
  1083. {
  1084. CARLA_ASSERT(index < parameterCount());
  1085. return;
  1086. // unused
  1087. Q_UNUSED(index);
  1088. Q_UNUSED(value);
  1089. }
  1090. void CarlaPlugin::uiProgramChange(const uint32_t index)
  1091. {
  1092. CARLA_ASSERT(index < programCount());
  1093. return;
  1094. // unused
  1095. Q_UNUSED(index);
  1096. }
  1097. void CarlaPlugin::uiMidiProgramChange(const uint32_t index)
  1098. {
  1099. CARLA_ASSERT(index < midiProgramCount());
  1100. return;
  1101. // unused
  1102. Q_UNUSED(index);
  1103. }
  1104. void CarlaPlugin::uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo)
  1105. {
  1106. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  1107. CARLA_ASSERT(note < MAX_MIDI_NOTE);
  1108. CARLA_ASSERT(velo > 0 && velo < MAX_MIDI_VALUE);
  1109. return;
  1110. // unused
  1111. Q_UNUSED(channel);
  1112. Q_UNUSED(note);
  1113. Q_UNUSED(velo);
  1114. }
  1115. void CarlaPlugin::uiNoteOff(const uint8_t channel, const uint8_t note)
  1116. {
  1117. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  1118. CARLA_ASSERT(note < MAX_MIDI_NOTE);
  1119. return;
  1120. // unused
  1121. Q_UNUSED(channel);
  1122. Q_UNUSED(note);
  1123. }
  1124. // -------------------------------------------------------------------
  1125. // Cleanup
  1126. void CarlaPlugin::removeClientPorts()
  1127. {
  1128. qDebug("CarlaPlugin::removeClientPorts() - start");
  1129. for (uint32_t i=0; i < fData->audioIn.count; i++)
  1130. {
  1131. delete fData->audioIn.ports[i].port;
  1132. fData->audioIn.ports[i].port = nullptr;
  1133. }
  1134. for (uint32_t i=0; i < fData->audioOut.count; i++)
  1135. {
  1136. delete fData->audioOut.ports[i].port;
  1137. fData->audioOut.ports[i].port = nullptr;
  1138. }
  1139. if (fData->event.portIn)
  1140. {
  1141. delete fData->event.portIn;
  1142. fData->event.portIn = nullptr;
  1143. }
  1144. if (fData->event.portOut)
  1145. {
  1146. delete fData->event.portOut;
  1147. fData->event.portOut = nullptr;
  1148. }
  1149. qDebug("CarlaPlugin::removeClientPorts() - end");
  1150. }
  1151. void CarlaPlugin::initBuffers()
  1152. {
  1153. for (uint32_t i=0; i < fData->audioIn.count; i++)
  1154. {
  1155. if (fData->audioIn.ports[i].port)
  1156. fData->audioIn.ports[i].port->initBuffer(fData->engine);
  1157. }
  1158. for (uint32_t i=0; i < fData->audioOut.count; i++)
  1159. {
  1160. if (fData->audioOut.ports[i].port)
  1161. fData->audioOut.ports[i].port->initBuffer(fData->engine);
  1162. }
  1163. if (fData->event.portIn)
  1164. fData->event.portIn->initBuffer(fData->engine);
  1165. if (fData->event.portOut)
  1166. fData->event.portOut->initBuffer(fData->engine);
  1167. }
  1168. void CarlaPlugin::deleteBuffers()
  1169. {
  1170. qDebug("CarlaPlugin::deleteBuffers() - start");
  1171. if (fData->audioIn.count > 0)
  1172. {
  1173. fData->audioIn.free();
  1174. }
  1175. if (fData->audioOut.count > 0)
  1176. {
  1177. fData->audioOut.free();
  1178. }
  1179. if (fData->param.count > 0)
  1180. {
  1181. delete[] fData->param.data;
  1182. delete[] fData->param.ranges;
  1183. }
  1184. fData->audioIn.count = 0;
  1185. fData->audioIn.ports = nullptr;
  1186. fData->audioOut.count = 0;
  1187. fData->audioOut.ports = nullptr;
  1188. fData->param.count = 0;
  1189. fData->param.data = nullptr;
  1190. fData->param.ranges = nullptr;
  1191. fData->event.portIn = nullptr;
  1192. fData->event.portOut = nullptr;
  1193. qDebug("CarlaPlugin::deleteBuffers() - end");
  1194. }
  1195. // -------------------------------------------------------------------
  1196. // Library functions
  1197. bool CarlaPlugin::libOpen(const char* const filename)
  1198. {
  1199. fData->lib = lib_open(filename);
  1200. return bool(fData->lib);
  1201. }
  1202. bool CarlaPlugin::libClose()
  1203. {
  1204. const bool ret = lib_close(fData->lib);
  1205. fData->lib = nullptr;
  1206. return ret;
  1207. }
  1208. void* CarlaPlugin::libSymbol(const char* const symbol)
  1209. {
  1210. return lib_symbol(fData->lib, symbol);
  1211. }
  1212. const char* CarlaPlugin::libError(const char* const filename)
  1213. {
  1214. return lib_error(filename);
  1215. }
  1216. #if 0
  1217. // -------------------------------------------------------------------
  1218. // Locks
  1219. void CarlaPlugin::engineProcessLock()
  1220. {
  1221. x_engine->processLock();
  1222. }
  1223. void CarlaPlugin::engineProcessUnlock()
  1224. {
  1225. x_engine->processUnlock();
  1226. }
  1227. void CarlaPlugin::engineMidiLock()
  1228. {
  1229. x_engine->midiLock();
  1230. }
  1231. void CarlaPlugin::engineMidiUnlock()
  1232. {
  1233. x_engine->midiUnlock();
  1234. }
  1235. // -------------------------------------------------------------------
  1236. // CarlaPluginGUI
  1237. CarlaPluginGUI::CarlaPluginGUI(QWidget* const parent, Callback* const callback)
  1238. : QMainWindow(parent),
  1239. m_callback(callback)
  1240. {
  1241. qDebug("CarlaPluginGUI::CarlaPluginGUI(%p, %p", parent, callback);
  1242. CARLA_ASSERT(callback);
  1243. m_container = new GuiContainer(this);
  1244. setCentralWidget(m_container);
  1245. adjustSize();
  1246. m_container->setParent(this);
  1247. m_container->show();
  1248. m_resizable = true;
  1249. setNewSize(50, 50);
  1250. QMainWindow::setVisible(false);
  1251. }
  1252. CarlaPluginGUI::~CarlaPluginGUI()
  1253. {
  1254. qDebug("CarlaPluginGUI::~CarlaPluginGUI()");
  1255. CARLA_ASSERT(m_container);
  1256. // FIXME, automatically deleted by parent ?
  1257. delete m_container;
  1258. }
  1259. // -------------------------------------------------------------------
  1260. GuiContainer* CarlaPluginGUI::getContainer() const
  1261. {
  1262. return m_container;
  1263. }
  1264. WId CarlaPluginGUI::getWinId() const
  1265. {
  1266. return m_container->winId();
  1267. }
  1268. // -------------------------------------------------------------------
  1269. void CarlaPluginGUI::setNewSize(int width, int height)
  1270. {
  1271. qDebug("CarlaPluginGUI::setNewSize(%i, %i)", width, height);
  1272. if (width < 30)
  1273. width = 30;
  1274. if (height < 30)
  1275. height = 30;
  1276. if (m_resizable)
  1277. {
  1278. resize(width, height);
  1279. }
  1280. else
  1281. {
  1282. setFixedSize(width, height);
  1283. m_container->setFixedSize(width, height);
  1284. }
  1285. }
  1286. void CarlaPluginGUI::setResizable(bool resizable)
  1287. {
  1288. m_resizable = resizable;
  1289. setNewSize(width(), height());
  1290. #ifdef Q_OS_WIN
  1291. if (! resizable)
  1292. setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
  1293. #endif
  1294. }
  1295. void CarlaPluginGUI::setTitle(const char* const title)
  1296. {
  1297. CARLA_ASSERT(title);
  1298. setWindowTitle(QString("%1 (GUI)").arg(title));
  1299. }
  1300. void CarlaPluginGUI::setVisible(const bool yesNo)
  1301. {
  1302. qDebug("CarlaPluginGUI::setVisible(%s)", bool2str(yesNo));
  1303. if (yesNo)
  1304. {
  1305. if (! m_geometry.isNull())
  1306. restoreGeometry(m_geometry);
  1307. }
  1308. else
  1309. m_geometry = saveGeometry();
  1310. QMainWindow::setVisible(yesNo);
  1311. }
  1312. // -------------------------------------------------------------------
  1313. void CarlaPluginGUI::hideEvent(QHideEvent* const event)
  1314. {
  1315. qDebug("CarlaPluginGUI::hideEvent(%p)", event);
  1316. CARLA_ASSERT(event);
  1317. event->accept();
  1318. close();
  1319. }
  1320. void CarlaPluginGUI::closeEvent(QCloseEvent* const event)
  1321. {
  1322. qDebug("CarlaPluginGUI::closeEvent(%p)", event);
  1323. CARLA_ASSERT(event);
  1324. if (event->spontaneous())
  1325. {
  1326. if (m_callback)
  1327. m_callback->guiClosedCallback();
  1328. QMainWindow::closeEvent(event);
  1329. return;
  1330. }
  1331. event->ignore();
  1332. }
  1333. #endif
  1334. // -------------------------------------------------------------------
  1335. CARLA_BACKEND_END_NAMESPACE