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.

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