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.

1598 lines
44KB

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