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.

2104 lines
59KB

  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 "CarlaPluginInternal.hpp"
  18. #include "CarlaLibUtils.hpp"
  19. #include "CarlaMIDI.h"
  20. #include <QtCore/QFile>
  21. #include <QtCore/QTextStream>
  22. //#include <QtGui/QtEvents>
  23. CARLA_BACKEND_START_NAMESPACE
  24. // -------------------------------------------------------------------
  25. // fallback data
  26. static const ParameterData kParameterDataNull;
  27. static const ParameterRanges kParameterRangesNull;
  28. static const MidiProgramData kMidiProgramDataNull;
  29. static const CustomData kCustomDataNull;
  30. // -------------------------------------------------------------------
  31. // Helpers
  32. CarlaEngine* CarlaPluginGetEngine(CarlaPlugin* const plugin)
  33. {
  34. return CarlaPluginProtectedData::getEngine(plugin);
  35. }
  36. CarlaEngineAudioPort* CarlaPluginGetAudioInPort(CarlaPlugin* const plugin, const uint32_t index)
  37. {
  38. return CarlaPluginProtectedData::getAudioInPort(plugin, index);
  39. }
  40. CarlaEngineAudioPort* CarlaPluginGetAudioOutPort(CarlaPlugin* const plugin, const uint32_t index)
  41. {
  42. return CarlaPluginProtectedData::getAudioOutPort(plugin, index);
  43. }
  44. // -------------------------------------------------------------------
  45. // Constructor and destructor
  46. CarlaPlugin::CarlaPlugin(CarlaEngine* const engine, const unsigned int id)
  47. : fId(id),
  48. fHints(0x0),
  49. fOptions(0x0),
  50. fEnabled(false),
  51. kData(new CarlaPluginProtectedData(engine, this))
  52. {
  53. CARLA_ASSERT(kData != nullptr);
  54. CARLA_ASSERT(engine != nullptr);
  55. CARLA_ASSERT(id < engine->maxPluginNumber());
  56. carla_debug("CarlaPlugin::CarlaPlugin(%p, %i)", engine, id);
  57. switch (engine->getProccessMode())
  58. {
  59. case PROCESS_MODE_SINGLE_CLIENT:
  60. case PROCESS_MODE_MULTIPLE_CLIENTS:
  61. CARLA_ASSERT(id < MAX_DEFAULT_PLUGINS);
  62. break;
  63. case PROCESS_MODE_CONTINUOUS_RACK:
  64. CARLA_ASSERT(id < MAX_RACK_PLUGINS);
  65. break;
  66. case PROCESS_MODE_PATCHBAY:
  67. CARLA_ASSERT(id < MAX_PATCHBAY_PLUGINS);
  68. break;
  69. case PROCESS_MODE_BRIDGE:
  70. CARLA_ASSERT(id == 0);
  71. break;
  72. }
  73. if (engine->getOptions().forceStereo)
  74. fOptions |= PLUGIN_OPTION_FORCE_STEREO;
  75. }
  76. CarlaPlugin::~CarlaPlugin()
  77. {
  78. carla_debug("CarlaPlugin::~CarlaPlugin()");
  79. // Remove client and ports
  80. if (kData->client != nullptr)
  81. {
  82. if (kData->client->isActive())
  83. kData->client->deactivate();
  84. // can't call virtual functions in destructor
  85. CarlaPlugin::deleteBuffers();
  86. delete kData->client;
  87. }
  88. if (kData->latencyBuffers != nullptr)
  89. {
  90. for (uint32_t i=0; i < kData->audioIn.count; i++)
  91. delete[] kData->latencyBuffers[i];
  92. delete[] kData->latencyBuffers;
  93. }
  94. for (auto it = kData->custom.begin(); it.valid(); it.next())
  95. {
  96. CustomData& cData(*it);
  97. CARLA_ASSERT(cData.type != nullptr);
  98. CARLA_ASSERT(cData.key != nullptr);
  99. CARLA_ASSERT(cData.value != nullptr);
  100. if (cData.type != nullptr)
  101. delete[] cData.type;
  102. if (cData.key != nullptr)
  103. delete[] cData.key;
  104. if (cData.value != nullptr)
  105. delete[] cData.value;
  106. }
  107. kData->prog.clear();
  108. kData->midiprog.clear();
  109. kData->custom.clear();
  110. // MUST have been unlocked before
  111. kData->masterMutex.unlock();
  112. kData->singleMutex.unlock();
  113. libClose();
  114. delete kData;
  115. }
  116. // -------------------------------------------------------------------
  117. // Information (base)
  118. uint32_t CarlaPlugin::latency() const
  119. {
  120. return kData->latency;
  121. }
  122. // -------------------------------------------------------------------
  123. // Information (count)
  124. uint32_t CarlaPlugin::audioInCount() const
  125. {
  126. return kData->audioIn.count;
  127. }
  128. uint32_t CarlaPlugin::audioOutCount() const
  129. {
  130. return kData->audioOut.count;
  131. }
  132. uint32_t CarlaPlugin::midiInCount() const
  133. {
  134. return (kData->extraHints & PLUGIN_HINT_HAS_MIDI_IN) ? 1 : 0;
  135. }
  136. uint32_t CarlaPlugin::midiOutCount() const
  137. {
  138. return (kData->extraHints & PLUGIN_HINT_HAS_MIDI_OUT) ? 1 : 0;
  139. }
  140. uint32_t CarlaPlugin::parameterCount() const
  141. {
  142. return kData->param.count;
  143. }
  144. uint32_t CarlaPlugin::parameterScalePointCount(const uint32_t parameterId) const
  145. {
  146. CARLA_ASSERT(parameterId < kData->param.count);
  147. return 0;
  148. // unused
  149. (void)parameterId;
  150. }
  151. uint32_t CarlaPlugin::programCount() const
  152. {
  153. return kData->prog.count;
  154. }
  155. uint32_t CarlaPlugin::midiProgramCount() const
  156. {
  157. return kData->midiprog.count;
  158. }
  159. uint32_t CarlaPlugin::customDataCount() const
  160. {
  161. return kData->custom.count();
  162. }
  163. // -------------------------------------------------------------------
  164. // Information (current data)
  165. int32_t CarlaPlugin::currentProgram() const
  166. {
  167. return kData->prog.current;
  168. }
  169. int32_t CarlaPlugin::currentMidiProgram() const
  170. {
  171. return kData->midiprog.current;
  172. }
  173. const ParameterData& CarlaPlugin::parameterData(const uint32_t parameterId) const
  174. {
  175. CARLA_ASSERT(parameterId < kData->param.count);
  176. return (parameterId < kData->param.count) ? kData->param.data[parameterId] : kParameterDataNull;
  177. }
  178. const ParameterRanges& CarlaPlugin::parameterRanges(const uint32_t parameterId) const
  179. {
  180. CARLA_ASSERT(parameterId < kData->param.count);
  181. return (parameterId < kData->param.count) ? kData->param.ranges[parameterId] : kParameterRangesNull;
  182. }
  183. bool CarlaPlugin::parameterIsOutput(const uint32_t parameterId) const
  184. {
  185. CARLA_ASSERT(parameterId < kData->param.count);
  186. return (parameterId < kData->param.count) ? (kData->param.data[parameterId].type == PARAMETER_OUTPUT) : false;
  187. }
  188. const MidiProgramData& CarlaPlugin::midiProgramData(const uint32_t index) const
  189. {
  190. CARLA_ASSERT(index < kData->midiprog.count);
  191. return (index < kData->midiprog.count) ? kData->midiprog.data[index] : kMidiProgramDataNull;
  192. }
  193. const CustomData& CarlaPlugin::customData(const size_t index) const
  194. {
  195. CARLA_ASSERT(index < kData->custom.count());
  196. return (index < kData->custom.count()) ? kData->custom.getAt(index) : kCustomDataNull;
  197. }
  198. int32_t CarlaPlugin::chunkData(void** const dataPtr)
  199. {
  200. CARLA_ASSERT(dataPtr != nullptr);
  201. return 0;
  202. // unused
  203. (void)dataPtr;
  204. }
  205. // -------------------------------------------------------------------
  206. // Information (per-plugin data)
  207. unsigned int CarlaPlugin::availableOptions()
  208. {
  209. return 0x0;
  210. }
  211. float CarlaPlugin::getParameterValue(const uint32_t parameterId)
  212. {
  213. CARLA_ASSERT(parameterId < parameterCount());
  214. return 0.0f;
  215. // unused
  216. (void)parameterId;
  217. }
  218. float CarlaPlugin::getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId)
  219. {
  220. CARLA_ASSERT(parameterId < parameterCount());
  221. CARLA_ASSERT(scalePointId < parameterScalePointCount(parameterId));
  222. return 0.0f;
  223. // unused
  224. (void)parameterId;
  225. (void)scalePointId;
  226. }
  227. void CarlaPlugin::getLabel(char* const strBuf)
  228. {
  229. *strBuf = 0;
  230. }
  231. void CarlaPlugin::getMaker(char* const strBuf)
  232. {
  233. *strBuf = 0;
  234. }
  235. void CarlaPlugin::getCopyright(char* const strBuf)
  236. {
  237. *strBuf = 0;
  238. }
  239. void CarlaPlugin::getRealName(char* const strBuf)
  240. {
  241. *strBuf = 0;
  242. }
  243. void CarlaPlugin::getParameterName(const uint32_t parameterId, char* const strBuf)
  244. {
  245. CARLA_ASSERT(parameterId < parameterCount());
  246. *strBuf = 0;
  247. return;
  248. // unused
  249. (void)parameterId;
  250. }
  251. void CarlaPlugin::getParameterSymbol(const uint32_t parameterId, char* const strBuf)
  252. {
  253. CARLA_ASSERT(parameterId < parameterCount());
  254. *strBuf = 0;
  255. return;
  256. // unused
  257. (void)parameterId;
  258. }
  259. void CarlaPlugin::getParameterText(const uint32_t parameterId, char* const strBuf)
  260. {
  261. CARLA_ASSERT(parameterId < parameterCount());
  262. *strBuf = 0;
  263. return;
  264. // unused
  265. (void)parameterId;
  266. }
  267. void CarlaPlugin::getParameterUnit(const uint32_t parameterId, char* const strBuf)
  268. {
  269. CARLA_ASSERT(parameterId < parameterCount());
  270. *strBuf = 0;
  271. return;
  272. // unused
  273. (void)parameterId;
  274. }
  275. void CarlaPlugin::getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf)
  276. {
  277. CARLA_ASSERT(parameterId < parameterCount());
  278. CARLA_ASSERT(scalePointId < parameterScalePointCount(parameterId));
  279. *strBuf = 0;
  280. return;
  281. // unused
  282. (void)parameterId;
  283. (void)scalePointId;
  284. }
  285. void CarlaPlugin::getProgramName(const uint32_t index, char* const strBuf)
  286. {
  287. CARLA_ASSERT(index < kData->prog.count);
  288. CARLA_ASSERT(kData->prog.names[index] != nullptr);
  289. if (index < kData->prog.count && kData->prog.names[index])
  290. std::strncpy(strBuf, kData->prog.names[index], STR_MAX);
  291. else
  292. *strBuf = 0;
  293. }
  294. void CarlaPlugin::getMidiProgramName(const uint32_t index, char* const strBuf)
  295. {
  296. CARLA_ASSERT(index < kData->midiprog.count);
  297. CARLA_ASSERT(kData->midiprog.data[index].name != nullptr);
  298. if (index < kData->midiprog.count && kData->midiprog.data[index].name)
  299. std::strncpy(strBuf, kData->midiprog.data[index].name, STR_MAX);
  300. else
  301. *strBuf = 0;
  302. }
  303. void CarlaPlugin::getParameterCountInfo(uint32_t* const ins, uint32_t* const outs, uint32_t* const total)
  304. {
  305. CARLA_ASSERT(ins != nullptr);
  306. CARLA_ASSERT(outs != nullptr);
  307. CARLA_ASSERT(total != nullptr);
  308. if (ins == nullptr || outs == nullptr || total == nullptr)
  309. return;
  310. *ins = 0;
  311. *outs = 0;
  312. *total = kData->param.count;
  313. for (uint32_t i=0; i < kData->param.count; i++)
  314. {
  315. if (kData->param.data[i].type == PARAMETER_INPUT)
  316. *ins += 1;
  317. else if (kData->param.data[i].type == PARAMETER_OUTPUT)
  318. *outs += 1;
  319. }
  320. }
  321. // -------------------------------------------------------------------
  322. // Set data (state)
  323. void CarlaPlugin::prepareForSave()
  324. {
  325. }
  326. const SaveState& CarlaPlugin::getSaveState()
  327. {
  328. static SaveState saveState;
  329. saveState.reset();
  330. prepareForSave();
  331. char strBuf[STR_MAX];
  332. // ----------------------------
  333. // Basic info
  334. switch (type())
  335. {
  336. case PLUGIN_INTERNAL:
  337. saveState.type = carla_strdup("Internal");
  338. break;
  339. case PLUGIN_LADSPA:
  340. saveState.type = carla_strdup("LADSPA");
  341. break;
  342. case PLUGIN_DSSI:
  343. saveState.type = carla_strdup("DSSI");
  344. break;
  345. case PLUGIN_LV2:
  346. saveState.type = carla_strdup("LV2");
  347. break;
  348. case PLUGIN_VST:
  349. saveState.type = carla_strdup("VST");
  350. break;
  351. case PLUGIN_GIG:
  352. saveState.type = carla_strdup("GIG");
  353. break;
  354. case PLUGIN_SF2:
  355. saveState.type = carla_strdup("SF2");
  356. break;
  357. case PLUGIN_SFZ:
  358. saveState.type = carla_strdup("SFZ");
  359. break;
  360. default:
  361. saveState.type = carla_strdup("Unknown");
  362. break;
  363. }
  364. getLabel(strBuf);
  365. saveState.name = carla_strdup(fName);
  366. saveState.label = carla_strdup(strBuf);
  367. saveState.binary = carla_strdup(fFilename);
  368. saveState.uniqueID = uniqueId();
  369. // ----------------------------
  370. // Internals
  371. saveState.active = kData->active;
  372. saveState.dryWet = kData->postProc.dryWet;
  373. saveState.volume = kData->postProc.volume;
  374. saveState.balanceLeft = kData->postProc.balanceLeft;
  375. saveState.balanceRight = kData->postProc.balanceRight;
  376. saveState.panning = kData->postProc.panning;
  377. saveState.ctrlChannel = kData->ctrlChannel;
  378. // ----------------------------
  379. // Current Program
  380. if (kData->prog.current >= 0)
  381. {
  382. saveState.currentProgramIndex = kData->prog.current;
  383. saveState.currentProgramName = carla_strdup(kData->prog.names[kData->prog.current]);
  384. }
  385. // ----------------------------
  386. // Current MIDI Program
  387. if (kData->midiprog.current >= 0)
  388. {
  389. const MidiProgramData& mpData = kData->midiprog.getCurrent();
  390. saveState.currentMidiBank = mpData.bank;
  391. saveState.currentMidiProgram = mpData.program;
  392. }
  393. // ----------------------------
  394. // Parameters
  395. float sampleRate = kData->engine->getSampleRate();
  396. for (uint32_t i=0, count=kData->param.count; i < count; i++)
  397. {
  398. const ParameterData& paramData = kData->param.data[i];
  399. if (paramData.type != PARAMETER_INPUT)
  400. continue;
  401. StateParameter* stateParameter(new StateParameter);
  402. stateParameter->index = paramData.index;
  403. stateParameter->midiCC = paramData.midiCC;
  404. stateParameter->midiChannel = paramData.midiChannel + 1;
  405. getParameterName(i, strBuf);
  406. stateParameter->name = carla_strdup(strBuf);
  407. getParameterSymbol(i, strBuf);
  408. stateParameter->symbol = carla_strdup(strBuf);;
  409. stateParameter->value = getParameterValue(i);
  410. if (paramData.hints & PARAMETER_USES_SAMPLERATE)
  411. stateParameter->value /= sampleRate;
  412. saveState.parameters.push_back(stateParameter);
  413. }
  414. // ----------------------------
  415. // Custom Data
  416. for (auto it = kData->custom.begin(); it.valid(); it.next())
  417. {
  418. const CustomData& cData(*it);
  419. if (cData.type == nullptr)
  420. continue;
  421. StateCustomData* stateCustomData(new StateCustomData);
  422. stateCustomData->type = carla_strdup(cData.type);
  423. stateCustomData->key = carla_strdup(cData.key);
  424. stateCustomData->value = carla_strdup(cData.value);
  425. saveState.customData.push_back(stateCustomData);
  426. }
  427. // ----------------------------
  428. // Chunk
  429. if (fOptions & PLUGIN_OPTION_USE_CHUNKS)
  430. {
  431. void* data = nullptr;
  432. const int32_t dataSize = chunkData(&data);
  433. if (data != nullptr && dataSize >= 4)
  434. {
  435. CarlaString chunkStr;
  436. chunkStr.importBinaryAsBase64((const uint8_t*)data, static_cast<size_t>(dataSize));
  437. saveState.chunk = carla_strdup(chunkStr);
  438. }
  439. }
  440. return saveState;
  441. }
  442. void CarlaPlugin::loadSaveState(const SaveState& saveState)
  443. {
  444. char strBuf[STR_MAX];
  445. // ---------------------------------------------------------------------
  446. // Part 1 - set custom data (except binary/chunks)
  447. for (auto it = saveState.customData.begin(); it != saveState.customData.end(); ++it)
  448. {
  449. const StateCustomData* const stateCustomData(*it);
  450. if (std::strcmp(stateCustomData->type, CUSTOM_DATA_CHUNK) != 0)
  451. setCustomData(stateCustomData->type, stateCustomData->key, stateCustomData->value, true);
  452. }
  453. // ---------------------------------------------------------------------
  454. // Part 2 - set program
  455. int32_t programId = -1;
  456. if (saveState.currentProgramName != nullptr)
  457. {
  458. getProgramName(saveState.currentProgramIndex, strBuf);
  459. // Program name matches
  460. if (std::strcmp(saveState.currentProgramName, strBuf) == 0)
  461. {
  462. programId = saveState.currentProgramIndex;
  463. }
  464. // index < count
  465. else if (saveState.currentProgramIndex < static_cast<int32_t>(kData->prog.count))
  466. {
  467. programId = saveState.currentProgramIndex;
  468. }
  469. // index not valid, try to find by name
  470. else
  471. {
  472. for (uint32_t i=0; i < kData->prog.count; i++)
  473. {
  474. getProgramName(i, strBuf);
  475. if (std::strcmp(saveState.currentProgramName, strBuf) == 0)
  476. {
  477. programId = i;
  478. break;
  479. }
  480. }
  481. }
  482. }
  483. // set program now, if valid
  484. if (programId >= 0)
  485. setProgram(programId, true, true, true);
  486. // ---------------------------------------------------------------------
  487. // Part 3 - set midi program
  488. if (saveState.currentMidiBank >= 0 && saveState.currentMidiProgram)
  489. setMidiProgramById(saveState.currentMidiBank, saveState.currentMidiProgram, true, true, true);
  490. // ---------------------------------------------------------------------
  491. // Part 4a - get plugin parameter symbols
  492. struct ParamSymbol {
  493. uint32_t index;
  494. const char* symbol;
  495. ParamSymbol()
  496. : index(0),
  497. symbol(nullptr) {}
  498. ParamSymbol(uint32_t index_, const char* symbol_)
  499. : index(index_),
  500. symbol(carla_strdup(symbol_)) {}
  501. void free()
  502. {
  503. if (symbol != nullptr)
  504. {
  505. delete[] symbol;
  506. symbol = nullptr;
  507. }
  508. }
  509. };
  510. QVector<ParamSymbol> paramSymbols;
  511. if (std::strcmp(saveState.type, "LADSPA") == 0 || std::strcmp(saveState.type, "LV2") == 0)
  512. {
  513. for (uint32_t i=0; i < kData->param.count; i++)
  514. {
  515. getParameterSymbol(i, strBuf);
  516. if (*strBuf != 0)
  517. {
  518. ParamSymbol paramSymbol(i, strBuf);
  519. paramSymbols.append(paramSymbol);
  520. }
  521. }
  522. }
  523. // ---------------------------------------------------------------------
  524. // Part 4b - set parameter values (carefully)
  525. float sampleRate = kData->engine->getSampleRate();
  526. for (auto it = saveState.parameters.begin(); it != saveState.parameters.end(); ++it)
  527. {
  528. StateParameter* stateParameter = *it;
  529. int32_t index = -1;
  530. if (std::strcmp(saveState.type, "LADSPA") == 0)
  531. {
  532. // Try to set by symbol, otherwise use index
  533. if (stateParameter->symbol != nullptr && *stateParameter->symbol != 0)
  534. {
  535. foreach (const ParamSymbol& paramSymbol, paramSymbols)
  536. {
  537. if (std::strcmp(stateParameter->symbol, paramSymbol.symbol) == 0)
  538. {
  539. index = paramSymbol.index;
  540. break;
  541. }
  542. }
  543. if (index == -1)
  544. index = stateParameter->index;
  545. }
  546. else
  547. index = stateParameter->index;
  548. }
  549. else if (std::strcmp(saveState.type, "LV2") == 0)
  550. {
  551. // Symbol only
  552. if (stateParameter->symbol != nullptr && *stateParameter->symbol != 0)
  553. {
  554. foreach (const ParamSymbol& paramSymbol, paramSymbols)
  555. {
  556. if (std::strcmp(stateParameter->symbol, paramSymbol.symbol) == 0)
  557. {
  558. index = paramSymbol.index;
  559. break;
  560. }
  561. }
  562. if (index == -1)
  563. carla_stderr("Failed to find LV2 parameter symbol for '%s')", stateParameter->symbol);
  564. }
  565. else
  566. carla_stderr("LV2 Plugin parameter '%s' has no symbol", stateParameter->name);
  567. }
  568. else
  569. {
  570. // Index only
  571. index = stateParameter->index;
  572. }
  573. // Now set parameter
  574. if (index >= 0 && index < static_cast<int32_t>(kData->param.count))
  575. {
  576. if (kData->param.data[index].hints & PARAMETER_USES_SAMPLERATE)
  577. stateParameter->value *= sampleRate;
  578. setParameterValue(index, stateParameter->value, true, true, true);
  579. setParameterMidiCC(index, stateParameter->midiCC, true, true);
  580. setParameterMidiChannel(index, stateParameter->midiChannel-1, true, true);
  581. }
  582. else
  583. carla_stderr("Could not set parameter data for '%s'", stateParameter->name);
  584. }
  585. // clear
  586. foreach (ParamSymbol paramSymbol, paramSymbols)
  587. paramSymbol.free();
  588. // ---------------------------------------------------------------------
  589. // Part 5 - set chunk data
  590. for (auto it = saveState.customData.begin(); it != saveState.customData.end(); ++it)
  591. {
  592. const StateCustomData* const stateCustomData(*it);
  593. if (std::strcmp(stateCustomData->type, CUSTOM_DATA_CHUNK) == 0)
  594. setCustomData(stateCustomData->type, stateCustomData->key, stateCustomData->value, true);
  595. }
  596. if (saveState.chunk != nullptr && (fOptions & PLUGIN_OPTION_USE_CHUNKS) != 0)
  597. setChunkData(saveState.chunk);
  598. // ---------------------------------------------------------------------
  599. // Part 6 - set internal stuff
  600. setDryWet(saveState.dryWet, true, true);
  601. setVolume(saveState.volume, true, true);
  602. setBalanceLeft(saveState.balanceLeft, true, true);
  603. setBalanceRight(saveState.balanceRight, true, true);
  604. setPanning(saveState.panning, true, true);
  605. setCtrlChannel(saveState.ctrlChannel, true, true);
  606. setActive(saveState.active, true, true);
  607. }
  608. bool CarlaPlugin::saveStateToFile(const char* const filename)
  609. {
  610. carla_debug("CarlaPlugin::saveStateToFile(\"%s\")", filename);
  611. CARLA_ASSERT(filename != nullptr);
  612. QFile file(filename);
  613. if (! file.open(QIODevice::WriteOnly | QIODevice::Text))
  614. return false;
  615. QTextStream out(&file);
  616. out << "<?xml version='1.0' encoding='UTF-8'?>\n";
  617. out << "<!DOCTYPE CARLA-PRESET>\n";
  618. out << "<CARLA-PRESET VERSION='1.0'>\n";
  619. out << getXMLFromSaveState(getSaveState());
  620. out << "</CARLA-PRESET>\n";
  621. file.close();
  622. return true;
  623. }
  624. bool CarlaPlugin::loadStateFromFile(const char* const filename)
  625. {
  626. carla_debug("CarlaPlugin::loadStateFromFile(\"%s\")", filename);
  627. CARLA_ASSERT(filename != nullptr);
  628. QFile file(filename);
  629. if (! file.open(QIODevice::ReadOnly | QIODevice::Text))
  630. return false;
  631. QDomDocument xml;
  632. xml.setContent(file.readAll());
  633. file.close();
  634. QDomNode xmlNode(xml.documentElement());
  635. if (xmlNode.toElement().tagName() != "CARLA-PRESET")
  636. {
  637. carla_stderr2("Not a valid Carla preset file");
  638. return false;
  639. }
  640. loadSaveState(getSaveStateDictFromXML(xmlNode));
  641. return true;
  642. }
  643. // -------------------------------------------------------------------
  644. // Set data (internal stuff)
  645. void CarlaPlugin::setId(const unsigned int id)
  646. {
  647. fId = id;
  648. if (kData->engine->getProccessMode() == PROCESS_MODE_CONTINUOUS_RACK)
  649. {
  650. CARLA_ASSERT(id < MAX_RACK_PLUGINS);
  651. if (id >= MAX_RACK_PLUGINS || kData->ctrlChannel == static_cast<int8_t>(id))
  652. return;
  653. kData->ctrlChannel = id;
  654. kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, PARAMETER_CTRL_CHANNEL, 0, id, nullptr);
  655. }
  656. }
  657. void CarlaPlugin::setOption(const unsigned int option, const bool yesNo)
  658. {
  659. if (yesNo)
  660. fOptions |= option;
  661. else
  662. fOptions &= ~option;
  663. }
  664. void CarlaPlugin::setEnabled(const bool yesNo)
  665. {
  666. fEnabled = yesNo;
  667. }
  668. void CarlaPlugin::setActive(const bool active, const bool sendOsc, const bool sendCallback)
  669. {
  670. if (kData->active == active)
  671. return;
  672. kData->active = active;
  673. const float value = active ? 1.0f : 0.0f;
  674. #ifndef BUILD_BRIDGE
  675. if (sendOsc)
  676. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_ACTIVE, value);
  677. #else
  678. // unused
  679. (void)sendOsc;
  680. #endif
  681. if (sendCallback)
  682. kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, PARAMETER_ACTIVE, 0, value, nullptr);
  683. #ifndef BUILD_BRIDGE
  684. else if (fHints & PLUGIN_IS_BRIDGE)
  685. osc_send_control(&kData->osc.data, PARAMETER_ACTIVE, value);
  686. #endif
  687. }
  688. void CarlaPlugin::setDryWet(const float value, const bool sendOsc, const bool sendCallback)
  689. {
  690. CARLA_ASSERT(value >= 0.0f && value <= 1.0f);
  691. const float fixedValue = carla_fixValue<float>(0.0f, 1.0f, value);
  692. if (kData->postProc.dryWet == fixedValue)
  693. return;
  694. kData->postProc.dryWet = fixedValue;
  695. #ifndef BUILD_BRIDGE
  696. if (sendOsc)
  697. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_DRYWET, fixedValue);
  698. #else
  699. // unused
  700. (void)sendOsc;
  701. #endif
  702. if (sendCallback)
  703. kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, PARAMETER_DRYWET, 0, fixedValue, nullptr);
  704. #ifndef BUILD_BRIDGE
  705. else if (fHints & PLUGIN_IS_BRIDGE)
  706. osc_send_control(&kData->osc.data, PARAMETER_DRYWET, fixedValue);
  707. #endif
  708. }
  709. void CarlaPlugin::setVolume(const float value, const bool sendOsc, const bool sendCallback)
  710. {
  711. CARLA_ASSERT(value >= 0.0f && value <= 1.27f);
  712. const float fixedValue = carla_fixValue<float>(0.0f, 1.27f, value);
  713. if (kData->postProc.volume == fixedValue)
  714. return;
  715. kData->postProc.volume = fixedValue;
  716. #ifndef BUILD_BRIDGE
  717. if (sendOsc)
  718. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_VOLUME, fixedValue);
  719. #else
  720. // unused
  721. (void)sendOsc;
  722. #endif
  723. if (sendCallback)
  724. kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, PARAMETER_VOLUME, 0, fixedValue, nullptr);
  725. #ifndef BUILD_BRIDGE
  726. else if (fHints & PLUGIN_IS_BRIDGE)
  727. osc_send_control(&kData->osc.data, PARAMETER_VOLUME, fixedValue);
  728. #endif
  729. }
  730. void CarlaPlugin::setBalanceLeft(const float value, const bool sendOsc, const bool sendCallback)
  731. {
  732. CARLA_ASSERT(value >= -1.0f && value <= 1.0f);
  733. const float fixedValue = carla_fixValue<float>(-1.0f, 1.0f, value);
  734. if (kData->postProc.balanceLeft == fixedValue)
  735. return;
  736. kData->postProc.balanceLeft = fixedValue;
  737. #ifndef BUILD_BRIDGE
  738. if (sendOsc)
  739. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_BALANCE_LEFT, fixedValue);
  740. #else
  741. // unused
  742. (void)sendOsc;
  743. #endif
  744. if (sendCallback)
  745. kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, PARAMETER_BALANCE_LEFT, 0, fixedValue, nullptr);
  746. #ifndef BUILD_BRIDGE
  747. else if (fHints & PLUGIN_IS_BRIDGE)
  748. osc_send_control(&kData->osc.data, PARAMETER_BALANCE_LEFT, fixedValue);
  749. #endif
  750. }
  751. void CarlaPlugin::setBalanceRight(const float value, const bool sendOsc, const bool sendCallback)
  752. {
  753. CARLA_ASSERT(value >= -1.0f && value <= 1.0f);
  754. const float fixedValue = carla_fixValue<float>(-1.0f, 1.0f, value);
  755. if (kData->postProc.balanceRight == fixedValue)
  756. return;
  757. kData->postProc.balanceRight = fixedValue;
  758. #ifndef BUILD_BRIDGE
  759. if (sendOsc)
  760. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_BALANCE_RIGHT, fixedValue);
  761. #else
  762. // unused
  763. (void)sendOsc;
  764. #endif
  765. if (sendCallback)
  766. kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, PARAMETER_BALANCE_RIGHT, 0, fixedValue, nullptr);
  767. #ifndef BUILD_BRIDGE
  768. else if (fHints & PLUGIN_IS_BRIDGE)
  769. osc_send_control(&kData->osc.data, PARAMETER_BALANCE_RIGHT, fixedValue);
  770. #endif
  771. }
  772. void CarlaPlugin::setPanning(const float value, const bool sendOsc, const bool sendCallback)
  773. {
  774. CARLA_ASSERT(value >= -1.0f && value <= 1.0f);
  775. const float fixedValue = carla_fixValue<float>(-1.0f, 1.0f, value);
  776. if (kData->postProc.panning == fixedValue)
  777. return;
  778. kData->postProc.panning = fixedValue;
  779. #ifndef BUILD_BRIDGE
  780. if (sendOsc)
  781. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_PANNING, fixedValue);
  782. #else
  783. // unused
  784. (void)sendOsc;
  785. #endif
  786. if (sendCallback)
  787. kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, PARAMETER_PANNING, 0, fixedValue, nullptr);
  788. #ifndef BUILD_BRIDGE
  789. else if (fHints & PLUGIN_IS_BRIDGE)
  790. osc_send_control(&kData->osc.data, PARAMETER_PANNING, fixedValue);
  791. #endif
  792. }
  793. void CarlaPlugin::setCtrlChannel(const int8_t channel, const bool sendOsc, const bool sendCallback)
  794. {
  795. if (kData->ctrlChannel == channel)
  796. return;
  797. kData->ctrlChannel = channel;
  798. #ifndef BUILD_BRIDGE
  799. const float ctrlf = channel;
  800. if (sendOsc)
  801. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_CTRL_CHANNEL, ctrlf);
  802. #else
  803. // unused
  804. (void)sendOsc;
  805. #endif
  806. if (sendCallback)
  807. kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, PARAMETER_CTRL_CHANNEL, 0, channel, nullptr);
  808. #ifndef BUILD_BRIDGE
  809. else if (fHints & PLUGIN_IS_BRIDGE)
  810. osc_send_control(&kData->osc.data, PARAMETER_CTRL_CHANNEL, ctrlf);
  811. #endif
  812. }
  813. // -------------------------------------------------------------------
  814. // Set data (plugin-specific stuff)
  815. void CarlaPlugin::setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback)
  816. {
  817. CARLA_ASSERT(parameterId < kData->param.count);
  818. if (sendGui)
  819. uiParameterChange(parameterId, value);
  820. #ifndef BUILD_BRIDGE
  821. if (sendOsc)
  822. kData->engine->osc_send_control_set_parameter_value(fId, parameterId, value);
  823. #else
  824. // unused
  825. (void)sendOsc;
  826. #endif
  827. if (sendCallback)
  828. kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, parameterId, 0, value, nullptr);
  829. #ifndef BUILD_BRIDGE
  830. else if (fHints & PLUGIN_IS_BRIDGE)
  831. osc_send_control(&kData->osc.data, parameterId, value);
  832. #endif
  833. }
  834. void CarlaPlugin::setParameterValueByRIndex(const int32_t rindex, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback)
  835. {
  836. CARLA_ASSERT(rindex > PARAMETER_MAX && rindex != PARAMETER_NULL);
  837. if (rindex <= PARAMETER_MAX)
  838. return;
  839. if (rindex == PARAMETER_NULL)
  840. return;
  841. if (rindex == PARAMETER_ACTIVE)
  842. return setActive((value > 0.0f), sendOsc, sendCallback);
  843. if (rindex == PARAMETER_DRYWET)
  844. return setDryWet(value, sendOsc, sendCallback);
  845. if (rindex == PARAMETER_VOLUME)
  846. return setVolume(value, sendOsc, sendCallback);
  847. if (rindex == PARAMETER_BALANCE_LEFT)
  848. return setBalanceLeft(value, sendOsc, sendCallback);
  849. if (rindex == PARAMETER_BALANCE_RIGHT)
  850. return setBalanceRight(value, sendOsc, sendCallback);
  851. if (rindex == PARAMETER_PANNING)
  852. return setPanning(value, sendOsc, sendCallback);
  853. if (rindex == PARAMETER_CTRL_CHANNEL)
  854. return setCtrlChannel(int8_t(value), sendOsc, sendCallback);
  855. for (uint32_t i=0; i < kData->param.count; i++)
  856. {
  857. if (kData->param.data[i].rindex == rindex)
  858. return setParameterValue(i, value, sendGui, sendOsc, sendCallback);
  859. }
  860. }
  861. void CarlaPlugin::setParameterMidiChannel(const uint32_t parameterId, uint8_t channel, const bool sendOsc, const bool sendCallback)
  862. {
  863. CARLA_ASSERT(parameterId < kData->param.count);
  864. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  865. if (channel >= MAX_MIDI_CHANNELS)
  866. channel = MAX_MIDI_CHANNELS;
  867. kData->param.data[parameterId].midiChannel = channel;
  868. #ifndef BUILD_BRIDGE
  869. if (sendOsc)
  870. kData->engine->osc_send_control_set_parameter_midi_channel(fId, parameterId, channel);
  871. #else
  872. // unused
  873. (void)sendOsc;
  874. #endif
  875. if (sendCallback)
  876. kData->engine->callback(CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED, fId, parameterId, channel, 0.0f, nullptr);
  877. #ifndef BUILD_BRIDGE
  878. else if (fHints & PLUGIN_IS_BRIDGE)
  879. {} // TODO
  880. #endif
  881. }
  882. void CarlaPlugin::setParameterMidiCC(const uint32_t parameterId, int16_t cc, const bool sendOsc, const bool sendCallback)
  883. {
  884. CARLA_ASSERT(parameterId < kData->param.count);
  885. CARLA_ASSERT(cc >= -1);
  886. if (cc < -1 || cc > 0x5F)
  887. cc = -1;
  888. kData->param.data[parameterId].midiCC = cc;
  889. #ifndef BUILD_BRIDGE
  890. if (sendOsc)
  891. kData->engine->osc_send_control_set_parameter_midi_cc(fId, parameterId, cc);
  892. #else
  893. // unused
  894. (void)sendOsc;
  895. #endif
  896. if (sendCallback)
  897. kData->engine->callback(CALLBACK_PARAMETER_MIDI_CC_CHANGED, fId, parameterId, cc, 0.0f, nullptr);
  898. #ifndef BUILD_BRIDGE
  899. else if (fHints & PLUGIN_IS_BRIDGE)
  900. {} // TODO
  901. #endif
  902. }
  903. void CarlaPlugin::setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui)
  904. {
  905. CARLA_ASSERT(type != nullptr);
  906. CARLA_ASSERT(key != nullptr);
  907. CARLA_ASSERT(value != nullptr);
  908. if (type == nullptr)
  909. return carla_stderr2("CarlaPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is null", type, key, value, bool2str(sendGui));
  910. if (key == nullptr)
  911. return carla_stderr2("CarlaPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - key is null", type, key, value, bool2str(sendGui));
  912. if (value == nullptr)
  913. return carla_stderr2("CarlaPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - value is null", type, key, value, bool2str(sendGui));
  914. bool saveData = true;
  915. if (std::strcmp(type, CUSTOM_DATA_STRING) == 0)
  916. {
  917. // Ignore some keys
  918. if (std::strncmp(key, "OSC:", 4) == 0 || std::strcmp(key, "guiVisible") == 0)
  919. saveData = false;
  920. //else if (std::strcmp(key, CARLA_BRIDGE_MSG_SAVE_NOW) == 0 || std::strcmp(key, CARLA_BRIDGE_MSG_SET_CHUNK) == 0 || std::strcmp(key, CARLA_BRIDGE_MSG_SET_CUSTOM) == 0)
  921. // saveData = false;
  922. }
  923. if (saveData)
  924. {
  925. // Check if we already have this key
  926. for (auto it = kData->custom.begin(); it.valid(); it.next())
  927. {
  928. CustomData& cData(*it);
  929. CARLA_ASSERT(cData.type != nullptr);
  930. CARLA_ASSERT(cData.key != nullptr);
  931. CARLA_ASSERT(cData.value != nullptr);
  932. if (std::strcmp(cData.key, key) == 0)
  933. {
  934. if (cData.value != nullptr)
  935. delete[] cData.value;
  936. cData.value = carla_strdup(value);
  937. return;
  938. }
  939. }
  940. // Otherwise store it
  941. CustomData newData;
  942. newData.type = carla_strdup(type);
  943. newData.key = carla_strdup(key);
  944. newData.value = carla_strdup(value);
  945. kData->custom.append(newData);
  946. }
  947. }
  948. void CarlaPlugin::setChunkData(const char* const stringData)
  949. {
  950. CARLA_ASSERT(stringData != nullptr);
  951. return;
  952. // unused
  953. (void)stringData;
  954. }
  955. void CarlaPlugin::setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback)
  956. {
  957. CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->prog.count));
  958. if (index > static_cast<int32_t>(kData->prog.count))
  959. return;
  960. const int32_t fixedIndex = carla_fixValue<int32_t>(-1, kData->prog.count, index);
  961. kData->prog.current = fixedIndex;
  962. // Change default parameter values
  963. if (fixedIndex >= 0)
  964. {
  965. if (sendGui)
  966. uiProgramChange(fixedIndex);
  967. for (uint32_t i=0; i < kData->param.count; i++)
  968. {
  969. // FIXME?
  970. kData->param.ranges[i].def = getParameterValue(i);
  971. kData->param.ranges[i].fixDefault();
  972. if (sendOsc)
  973. {
  974. #ifndef BUILD_BRIDGE
  975. kData->engine->osc_send_control_set_default_value(fId, i, kData->param.ranges[i].def);
  976. kData->engine->osc_send_control_set_parameter_value(fId, i, kData->param.ranges[i].def);
  977. #endif
  978. }
  979. }
  980. }
  981. #ifndef BUILD_BRIDGE
  982. if (sendOsc)
  983. kData->engine->osc_send_control_set_program(fId, fixedIndex);
  984. #endif
  985. if (sendCallback)
  986. kData->engine->callback(CALLBACK_PROGRAM_CHANGED, fId, fixedIndex, 0, 0.0f, nullptr);
  987. }
  988. void CarlaPlugin::setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback)
  989. {
  990. CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->midiprog.count));
  991. if (index > static_cast<int32_t>(kData->midiprog.count))
  992. return;
  993. const int32_t fixedIndex = carla_fixValue<int32_t>(-1, kData->midiprog.count, index);
  994. kData->midiprog.current = fixedIndex;
  995. if (fixedIndex >= 0)
  996. {
  997. if (sendGui)
  998. uiMidiProgramChange(fixedIndex);
  999. // Change default parameter values (sound banks never change defaults)
  1000. #ifndef BUILD_BRIDGE // FIXME
  1001. if (type() != PLUGIN_GIG && type() != PLUGIN_SF2 && type() != PLUGIN_SFZ)
  1002. #endif
  1003. {
  1004. for (uint32_t i=0; i < kData->param.count; i++)
  1005. {
  1006. // FIXME?
  1007. kData->param.ranges[i].def = getParameterValue(i);
  1008. kData->param.ranges[i].fixDefault();
  1009. if (sendOsc)
  1010. {
  1011. #ifndef BUILD_BRIDGE
  1012. kData->engine->osc_send_control_set_default_value(fId, i, kData->param.ranges[i].def);
  1013. kData->engine->osc_send_control_set_parameter_value(fId, i, kData->param.ranges[i].def);
  1014. #endif
  1015. }
  1016. }
  1017. }
  1018. }
  1019. #ifndef BUILD_BRIDGE
  1020. if (sendOsc)
  1021. kData->engine->osc_send_control_set_midi_program(fId, fixedIndex);
  1022. #endif
  1023. if (sendCallback)
  1024. kData->engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, fId, fixedIndex, 0, 0.0f, nullptr);
  1025. }
  1026. void CarlaPlugin::setMidiProgramById(const uint32_t bank, const uint32_t program, const bool sendGui, const bool sendOsc, const bool sendCallback)
  1027. {
  1028. for (uint32_t i=0; i < kData->midiprog.count; i++)
  1029. {
  1030. if (kData->midiprog.data[i].bank == bank && kData->midiprog.data[i].program == program)
  1031. return setMidiProgram(i, sendGui, sendOsc, sendCallback);
  1032. }
  1033. }
  1034. // -------------------------------------------------------------------
  1035. // Set gui stuff
  1036. void CarlaPlugin::showGui(const bool yesNo)
  1037. {
  1038. return;
  1039. // unused
  1040. (void)yesNo;
  1041. }
  1042. void CarlaPlugin::idleGui()
  1043. {
  1044. if (! fEnabled)
  1045. return;
  1046. if (fHints & PLUGIN_HAS_SINGLE_THREAD)
  1047. {
  1048. // Process postponed events
  1049. postRtEventsRun();
  1050. // Update parameter outputs
  1051. for (uint32_t i=0; i < kData->param.count; i++)
  1052. {
  1053. if (kData->param.data[i].type == PARAMETER_OUTPUT)
  1054. uiParameterChange(i, getParameterValue(i));
  1055. }
  1056. }
  1057. }
  1058. // -------------------------------------------------------------------
  1059. // Plugin state
  1060. void CarlaPlugin::reload()
  1061. {
  1062. }
  1063. void CarlaPlugin::reloadPrograms(const bool)
  1064. {
  1065. }
  1066. // -------------------------------------------------------------------
  1067. // Plugin processing
  1068. void CarlaPlugin::process(float** const, float** const, const uint32_t)
  1069. {
  1070. }
  1071. void CarlaPlugin::bufferSizeChanged(const uint32_t)
  1072. {
  1073. }
  1074. void CarlaPlugin::sampleRateChanged(const double)
  1075. {
  1076. }
  1077. void CarlaPlugin::recreateLatencyBuffers()
  1078. {
  1079. if (kData->latencyBuffers != nullptr)
  1080. {
  1081. for (uint32_t i=0; i < kData->audioIn.count; i++)
  1082. {
  1083. CARLA_ASSERT(kData->latencyBuffers[i] != nullptr);
  1084. if (kData->latencyBuffers[i] != nullptr)
  1085. delete[] kData->latencyBuffers[i];
  1086. }
  1087. delete[] kData->latencyBuffers;
  1088. kData->latencyBuffers = nullptr;
  1089. }
  1090. if (kData->audioIn.count > 0 && kData->latency > 0)
  1091. {
  1092. kData->latencyBuffers = new float*[kData->audioIn.count];
  1093. for (uint32_t i=0; i < kData->audioIn.count; i++)
  1094. {
  1095. kData->latencyBuffers[i] = new float[kData->latency];
  1096. carla_zeroFloat(kData->latencyBuffers[i], kData->latency);
  1097. }
  1098. }
  1099. }
  1100. bool CarlaPlugin::tryLock()
  1101. {
  1102. return kData->masterMutex.tryLock();
  1103. }
  1104. void CarlaPlugin::unlock()
  1105. {
  1106. kData->masterMutex.unlock();
  1107. }
  1108. // -------------------------------------------------------------------
  1109. // OSC stuff
  1110. void CarlaPlugin::registerToOscClient()
  1111. {
  1112. #ifdef BUILD_BRIDGE
  1113. if (! kData->engine->isOscBridgeRegistered())
  1114. return;
  1115. #else
  1116. if (! kData->engine->isOscControlRegistered())
  1117. return;
  1118. #endif
  1119. #ifndef BUILD_BRIDGE
  1120. kData->engine->osc_send_control_add_plugin_start(fId, fName);
  1121. #endif
  1122. // Base data
  1123. {
  1124. char bufName[STR_MAX] = { 0 };
  1125. char bufLabel[STR_MAX] = { 0 };
  1126. char bufMaker[STR_MAX] = { 0 };
  1127. char bufCopyright[STR_MAX] = { 0 };
  1128. getRealName(bufName);
  1129. getLabel(bufLabel);
  1130. getMaker(bufMaker);
  1131. getCopyright(bufCopyright);
  1132. #ifdef BUILD_BRIDGE
  1133. kData->engine->osc_send_bridge_plugin_info(category(), fHints, bufName, bufLabel, bufMaker, bufCopyright, uniqueId());
  1134. #else
  1135. kData->engine->osc_send_control_set_plugin_data(fId, type(), category(), fHints, bufName, bufLabel, bufMaker, bufCopyright, uniqueId());
  1136. #endif
  1137. }
  1138. // Base count
  1139. {
  1140. uint32_t cIns, cOuts, cTotals;
  1141. getParameterCountInfo(&cIns, &cOuts, &cTotals);
  1142. #ifdef BUILD_BRIDGE
  1143. kData->engine->osc_send_bridge_audio_count(audioInCount(), audioOutCount(), audioInCount() + audioOutCount());
  1144. kData->engine->osc_send_bridge_midi_count(midiInCount(), midiOutCount(), midiInCount() + midiOutCount());
  1145. kData->engine->osc_send_bridge_parameter_count(cIns, cOuts, cTotals);
  1146. #else
  1147. kData->engine->osc_send_control_set_plugin_ports(fId, audioInCount(), audioOutCount(), midiInCount(), midiOutCount(), cIns, cOuts, cTotals);
  1148. #endif
  1149. }
  1150. // Plugin Parameters
  1151. if (kData->param.count > 0 && kData->param.count < kData->engine->getOptions().maxParameters)
  1152. {
  1153. char bufName[STR_MAX], bufUnit[STR_MAX];
  1154. for (uint32_t i=0; i < kData->param.count; i++)
  1155. {
  1156. getParameterName(i, bufName);
  1157. getParameterUnit(i, bufUnit);
  1158. const ParameterData& paramData(kData->param.data[i]);
  1159. const ParameterRanges& paramRanges(kData->param.ranges[i]);
  1160. #ifdef BUILD_BRIDGE
  1161. kData->engine->osc_send_bridge_parameter_info(i, bufName, bufUnit);
  1162. kData->engine->osc_send_bridge_parameter_data(i, paramData.type, paramData.rindex, paramData.hints, paramData.midiChannel, paramData.midiCC);
  1163. kData->engine->osc_send_bridge_parameter_ranges(i, paramRanges.def, paramRanges.min, paramRanges.max, paramRanges.step, paramRanges.stepSmall, paramRanges.stepLarge);
  1164. kData->engine->osc_send_bridge_set_parameter_value(i, getParameterValue(i));
  1165. #else
  1166. kData->engine->osc_send_control_set_parameter_data(fId, i, paramData.type, paramData.hints, bufName, bufUnit, getParameterValue(i));
  1167. kData->engine->osc_send_control_set_parameter_ranges(fId, i, paramRanges.min, paramRanges.max, paramRanges.def, paramRanges.step, paramRanges.stepSmall, paramRanges.stepLarge);
  1168. kData->engine->osc_send_control_set_parameter_midi_cc(fId, i, paramData.midiCC);
  1169. kData->engine->osc_send_control_set_parameter_midi_channel(fId, i, paramData.midiChannel);
  1170. kData->engine->osc_send_control_set_parameter_value(fId, i, getParameterValue(i));
  1171. #endif
  1172. }
  1173. }
  1174. // Programs
  1175. if (kData->prog.count > 0)
  1176. {
  1177. #ifdef BUILD_BRIDGE
  1178. kData->engine->osc_send_bridge_program_count(kData->prog.count);
  1179. for (uint32_t i=0; i < kData->prog.count; i++)
  1180. kData->engine->osc_send_bridge_program_info(i, kData->prog.names[i]);
  1181. kData->engine->osc_send_bridge_set_program(kData->prog.current);
  1182. #else
  1183. kData->engine->osc_send_control_set_program_count(fId, kData->prog.count);
  1184. for (uint32_t i=0; i < kData->prog.count; i++)
  1185. kData->engine->osc_send_control_set_program_name(fId, i, kData->prog.names[i]);
  1186. kData->engine->osc_send_control_set_program(fId, kData->prog.current);
  1187. #endif
  1188. }
  1189. // MIDI Programs
  1190. if (kData->midiprog.count > 0)
  1191. {
  1192. #ifdef BUILD_BRIDGE
  1193. kData->engine->osc_send_bridge_midi_program_count(kData->midiprog.count);
  1194. for (uint32_t i=0; i < kData->midiprog.count; i++)
  1195. {
  1196. const MidiProgramData& mpData(kData->midiprog.data[i]);
  1197. kData->engine->osc_send_bridge_midi_program_info(i, mpData.bank, mpData.program, mpData.name);
  1198. }
  1199. kData->engine->osc_send_bridge_set_midi_program(kData->midiprog.current);
  1200. #else
  1201. kData->engine->osc_send_control_set_midi_program_count(fId, kData->midiprog.count);
  1202. for (uint32_t i=0; i < kData->midiprog.count; i++)
  1203. {
  1204. const MidiProgramData& mpData(kData->midiprog.data[i]);
  1205. kData->engine->osc_send_control_set_midi_program_data(fId, i, mpData.bank, mpData.program, mpData.name);
  1206. }
  1207. kData->engine->osc_send_control_set_midi_program(fId, kData->midiprog.current);
  1208. #endif
  1209. }
  1210. #ifndef BUILD_BRIDGE
  1211. kData->engine->osc_send_control_add_plugin_end(fId);
  1212. // Internal Parameters
  1213. {
  1214. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_ACTIVE, kData->active ? 1.0 : 0.0);
  1215. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_DRYWET, kData->postProc.dryWet);
  1216. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_VOLUME, kData->postProc.volume);
  1217. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_BALANCE_LEFT, kData->postProc.balanceLeft);
  1218. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_BALANCE_RIGHT, kData->postProc.balanceRight);
  1219. kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_PANNING, kData->postProc.panning);
  1220. }
  1221. #endif
  1222. }
  1223. void CarlaPlugin::updateOscData(const lo_address& source, const char* const url)
  1224. {
  1225. // FIXME - remove debug prints later
  1226. carla_stdout("CarlaPlugin::updateOscData(%p, \"%s\")", source, url);
  1227. kData->osc.data.free();
  1228. const int proto = lo_address_get_protocol(source);
  1229. {
  1230. const char* host = lo_address_get_hostname(source);
  1231. const char* port = lo_address_get_port(source);
  1232. kData->osc.data.source = lo_address_new_with_proto(proto, host, port);
  1233. carla_stdout("CarlaPlugin::updateOscData() - source: host \"%s\", port \"%s\"", host, port);
  1234. }
  1235. {
  1236. char* host = lo_url_get_hostname(url);
  1237. char* port = lo_url_get_port(url);
  1238. kData->osc.data.path = carla_strdup_free(lo_url_get_path(url));
  1239. kData->osc.data.target = lo_address_new_with_proto(proto, host, port);
  1240. carla_stdout("CarlaPlugin::updateOscData() - target: host \"%s\", port \"%s\", path \"%s\"", host, port, kData->osc.data.path);
  1241. std::free(host);
  1242. std::free(port);
  1243. }
  1244. #ifndef BUILD_BRIDGE
  1245. if (fHints & PLUGIN_IS_BRIDGE)
  1246. return;
  1247. #endif
  1248. osc_send_sample_rate(&kData->osc.data, kData->engine->getSampleRate());
  1249. for (auto it = kData->custom.begin(); it.valid(); it.next())
  1250. {
  1251. const CustomData& cData(*it);
  1252. CARLA_ASSERT(cData.type != nullptr);
  1253. CARLA_ASSERT(cData.key != nullptr);
  1254. CARLA_ASSERT(cData.value != nullptr);
  1255. #ifdef WANT_LV2
  1256. if (type() == PLUGIN_LV2)
  1257. osc_send_lv2_transfer_event(&kData->osc.data, 0, cData.type, cData.value);
  1258. else
  1259. #endif
  1260. if (std::strcmp(cData.type, CUSTOM_DATA_STRING) == 0)
  1261. osc_send_configure(&kData->osc.data, cData.key, cData.value);
  1262. }
  1263. if (kData->prog.current >= 0)
  1264. osc_send_program(&kData->osc.data, kData->prog.current);
  1265. if (kData->midiprog.current >= 0)
  1266. {
  1267. const MidiProgramData& curMidiProg(kData->midiprog.getCurrent());
  1268. if (type() == PLUGIN_DSSI)
  1269. osc_send_program(&kData->osc.data, curMidiProg.bank, curMidiProg.program);
  1270. else
  1271. osc_send_midi_program(&kData->osc.data, curMidiProg.bank, curMidiProg.program);
  1272. }
  1273. for (uint32_t i=0; i < kData->param.count; i++)
  1274. osc_send_control(&kData->osc.data, kData->param.data[i].rindex, getParameterValue(i));
  1275. carla_stdout("CarlaPlugin::updateOscData() - done");
  1276. }
  1277. void CarlaPlugin::freeOscData()
  1278. {
  1279. kData->osc.data.free();
  1280. }
  1281. bool CarlaPlugin::waitForOscGuiShow()
  1282. {
  1283. carla_stdout("CarlaPlugin::waitForOscGuiShow()");
  1284. uint i=0, oscUiTimeout = kData->engine->getOptions().oscUiTimeout;
  1285. // wait for UI 'update' call
  1286. for (; i < oscUiTimeout; i++)
  1287. {
  1288. if (kData->osc.data.target != nullptr)
  1289. {
  1290. carla_stdout("CarlaPlugin::waitForOscGuiShow() - got response, asking UI to show itself now");
  1291. osc_send_show(&kData->osc.data);
  1292. return true;
  1293. }
  1294. else
  1295. carla_msleep(100);
  1296. }
  1297. carla_stdout("CarlaPlugin::waitForOscGuiShow() - Timeout while waiting for UI to respond (waited %u msecs)", oscUiTimeout);
  1298. return false;
  1299. }
  1300. // -------------------------------------------------------------------
  1301. // MIDI events
  1302. void CarlaPlugin::sendMidiSingleNote(const uint8_t channel, const uint8_t note, const uint8_t velo, const bool sendGui, const bool sendOsc, const bool sendCallback)
  1303. {
  1304. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  1305. CARLA_ASSERT(note < MAX_MIDI_NOTE);
  1306. CARLA_ASSERT(velo < MAX_MIDI_VALUE);
  1307. if (! kData->active)
  1308. return;
  1309. ExternalMidiNote extNote;
  1310. extNote.channel = channel;
  1311. extNote.note = note;
  1312. extNote.velo = velo;
  1313. kData->extNotes.append(extNote);
  1314. if (sendGui)
  1315. {
  1316. if (velo > 0)
  1317. uiNoteOn(channel, note, velo);
  1318. else
  1319. uiNoteOff(channel, note);
  1320. }
  1321. #ifndef BUILD_BRIDGE
  1322. if (sendOsc)
  1323. {
  1324. if (velo > 0)
  1325. kData->engine->osc_send_control_note_on(fId, channel, note, velo);
  1326. else
  1327. kData->engine->osc_send_control_note_off(fId, channel, note);
  1328. }
  1329. #else
  1330. // unused
  1331. (void)sendOsc;
  1332. #endif
  1333. if (sendCallback)
  1334. kData->engine->callback((velo > 0) ? CALLBACK_NOTE_ON : CALLBACK_NOTE_OFF, fId, channel, note, velo, nullptr);
  1335. }
  1336. void CarlaPlugin::sendMidiAllNotesOff()
  1337. {
  1338. if (kData->ctrlChannel < 0 || kData->ctrlChannel >= MAX_MIDI_CHANNELS)
  1339. return;
  1340. PluginPostRtEvent postEvent;
  1341. postEvent.type = kPluginPostRtEventNoteOff;
  1342. postEvent.value1 = kData->ctrlChannel;
  1343. postEvent.value2 = 0;
  1344. postEvent.value3 = 0.0f;
  1345. for (unsigned short i=0; i < MAX_MIDI_NOTE; i++)
  1346. {
  1347. postEvent.value2 = i;
  1348. kData->postRtEvents.appendRT(postEvent);
  1349. }
  1350. }
  1351. // -------------------------------------------------------------------
  1352. // Post-poned events
  1353. void CarlaPlugin::postponeRtEvent(const PluginPostRtEventType type, const int32_t value1, const int32_t value2, const float value3)
  1354. {
  1355. PluginPostRtEvent event;
  1356. event.type = type;
  1357. event.value1 = value1;
  1358. event.value2 = value2;
  1359. event.value3 = value3;
  1360. kData->postRtEvents.appendRT(event);
  1361. }
  1362. void CarlaPlugin::postRtEventsRun()
  1363. {
  1364. const CarlaMutex::ScopedLocker sl(&kData->postRtEvents.mutex);
  1365. while (! kData->postRtEvents.data.isEmpty())
  1366. {
  1367. const PluginPostRtEvent& event = kData->postRtEvents.data.getFirst(true);
  1368. switch (event.type)
  1369. {
  1370. case kPluginPostRtEventNull:
  1371. break;
  1372. case kPluginPostRtEventDebug:
  1373. kData->engine->callback(CALLBACK_DEBUG, fId, event.value1, event.value2, event.value3, nullptr);
  1374. break;
  1375. case kPluginPostRtEventParameterChange:
  1376. // Update UI
  1377. if (event.value1 >= 0)
  1378. uiParameterChange(event.value1, event.value3);
  1379. #ifndef BUILD_BRIDGE
  1380. // Update OSC control client
  1381. if (kData->engine->isOscControlRegistered())
  1382. kData->engine->osc_send_control_set_parameter_value(fId, event.value1, event.value3);
  1383. #endif
  1384. // Update Host
  1385. kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, event.value1, 0, event.value3, nullptr);
  1386. break;
  1387. case kPluginPostRtEventProgramChange:
  1388. // Update UI
  1389. if (event.value1 >= 0)
  1390. uiProgramChange(event.value1);
  1391. #ifndef BUILD_BRIDGE
  1392. // Update OSC control client
  1393. if (kData->engine->isOscControlRegistered())
  1394. {
  1395. kData->engine->osc_send_control_set_program(fId, event.value1);
  1396. for (uint32_t j=0; j < kData->param.count; j++)
  1397. kData->engine->osc_send_control_set_default_value(fId, j, kData->param.ranges[j].def);
  1398. }
  1399. #endif
  1400. // Update Host
  1401. kData->engine->callback(CALLBACK_PROGRAM_CHANGED, fId, event.value1, 0, 0.0, nullptr);
  1402. break;
  1403. case kPluginPostRtEventMidiProgramChange:
  1404. // Update UI
  1405. if (event.value1 >= 0)
  1406. uiMidiProgramChange(event.value1);
  1407. #ifndef BUILD_BRIDGE
  1408. // Update OSC control client
  1409. if (kData->engine->isOscControlRegistered())
  1410. {
  1411. kData->engine->osc_send_control_set_midi_program(fId, event.value1);
  1412. for (uint32_t j=0; j < kData->param.count; j++)
  1413. kData->engine->osc_send_control_set_default_value(fId, j, kData->param.ranges[j].def);
  1414. }
  1415. #endif
  1416. // Update Host
  1417. kData->engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, fId, event.value1, 0, 0.0, nullptr);
  1418. break;
  1419. case kPluginPostRtEventNoteOn:
  1420. // Update UI
  1421. uiNoteOn(event.value1, event.value2, int(event.value3));
  1422. #ifndef BUILD_BRIDGE
  1423. // Update OSC control client
  1424. if (kData->engine->isOscControlRegistered())
  1425. kData->engine->osc_send_control_note_on(fId, event.value1, event.value2, int(event.value3));
  1426. #endif
  1427. // Update Host
  1428. kData->engine->callback(CALLBACK_NOTE_ON, fId, event.value1, event.value2, int(event.value3), nullptr);
  1429. break;
  1430. case kPluginPostRtEventNoteOff:
  1431. // Update UI
  1432. uiNoteOff(event.value1, event.value2);
  1433. #ifndef BUILD_BRIDGE
  1434. // Update OSC control client
  1435. if (kData->engine->isOscControlRegistered())
  1436. kData->engine->osc_send_control_note_off(fId, event.value1, event.value2);
  1437. #endif
  1438. // Update Host
  1439. kData->engine->callback(CALLBACK_NOTE_OFF, fId, event.value1, event.value2, 0.0, nullptr);
  1440. break;
  1441. }
  1442. }
  1443. }
  1444. void CarlaPlugin::uiParameterChange(const uint32_t index, const float value)
  1445. {
  1446. CARLA_ASSERT(index < parameterCount());
  1447. return;
  1448. // unused
  1449. (void)index;
  1450. (void)value;
  1451. }
  1452. void CarlaPlugin::uiProgramChange(const uint32_t index)
  1453. {
  1454. CARLA_ASSERT(index < programCount());
  1455. return;
  1456. // unused
  1457. (void)index;
  1458. }
  1459. void CarlaPlugin::uiMidiProgramChange(const uint32_t index)
  1460. {
  1461. CARLA_ASSERT(index < midiProgramCount());
  1462. return;
  1463. // unused
  1464. (void)index;
  1465. }
  1466. void CarlaPlugin::uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo)
  1467. {
  1468. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  1469. CARLA_ASSERT(note < MAX_MIDI_NOTE);
  1470. CARLA_ASSERT(velo > 0 && velo < MAX_MIDI_VALUE);
  1471. return;
  1472. // unused
  1473. (void)channel;
  1474. (void)note;
  1475. (void)velo;
  1476. }
  1477. void CarlaPlugin::uiNoteOff(const uint8_t channel, const uint8_t note)
  1478. {
  1479. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  1480. CARLA_ASSERT(note < MAX_MIDI_NOTE);
  1481. return;
  1482. // unused
  1483. (void)channel;
  1484. (void)note;
  1485. }
  1486. // -------------------------------------------------------------------
  1487. // Cleanup
  1488. void CarlaPlugin::initBuffers()
  1489. {
  1490. kData->audioIn.initBuffers(kData->engine);
  1491. kData->audioOut.initBuffers(kData->engine);
  1492. kData->event.initBuffers(kData->engine);
  1493. }
  1494. void CarlaPlugin::deleteBuffers()
  1495. {
  1496. carla_debug("CarlaPlugin::deleteBuffers() - start");
  1497. kData->audioIn.clear();
  1498. kData->audioOut.clear();
  1499. kData->param.clear();
  1500. kData->event.clear();
  1501. carla_debug("CarlaPlugin::deleteBuffers() - end");
  1502. }
  1503. // -------------------------------------------------------------------
  1504. // Library functions
  1505. bool CarlaPlugin::libOpen(const char* const filename)
  1506. {
  1507. kData->lib = lib_open(filename);
  1508. return bool(kData->lib);
  1509. }
  1510. bool CarlaPlugin::libClose()
  1511. {
  1512. if (kData->lib == nullptr)
  1513. return false;
  1514. const bool ret = lib_close(kData->lib);
  1515. kData->lib = nullptr;
  1516. return ret;
  1517. }
  1518. void* CarlaPlugin::libSymbol(const char* const symbol)
  1519. {
  1520. return lib_symbol(kData->lib, symbol);
  1521. }
  1522. const char* CarlaPlugin::libError(const char* const filename)
  1523. {
  1524. return lib_error(filename);
  1525. }
  1526. // -------------------------------------------------------------------
  1527. // Scoped Disabler
  1528. CarlaPlugin::ScopedDisabler::ScopedDisabler(CarlaPlugin* const plugin)
  1529. : kPlugin(plugin)
  1530. {
  1531. carla_debug("CarlaPlugin::ScopedDisabler(%p)", plugin);
  1532. CARLA_ASSERT(plugin != nullptr);
  1533. plugin->kData->masterMutex.lock();
  1534. if (plugin->fEnabled)
  1535. plugin->fEnabled = false;
  1536. if (plugin->kData->client->isActive())
  1537. plugin->kData->client->deactivate();
  1538. }
  1539. CarlaPlugin::ScopedDisabler::~ScopedDisabler()
  1540. {
  1541. carla_debug("CarlaPlugin::~ScopedDisabler()");
  1542. kPlugin->fEnabled = true;
  1543. kPlugin->kData->client->activate();
  1544. kPlugin->kData->masterMutex.unlock();
  1545. }
  1546. // -------------------------------------------------------------------
  1547. // Scoped Process Locker
  1548. CarlaPlugin::ScopedProcessLocker::ScopedProcessLocker(CarlaPlugin* const plugin, const bool block)
  1549. : kPlugin(plugin),
  1550. kBlock(block)
  1551. {
  1552. carla_debug("CarlaPlugin::ScopedProcessLocker(%p, %s)", plugin, bool2str(block));
  1553. CARLA_ASSERT(plugin != nullptr);
  1554. if (block)
  1555. plugin->kData->singleMutex.lock();
  1556. }
  1557. CarlaPlugin::ScopedProcessLocker::~ScopedProcessLocker()
  1558. {
  1559. carla_debug("CarlaPlugin::~ScopedProcessLocker()");
  1560. if (kBlock)
  1561. {
  1562. if (kPlugin->kData->singleMutex.wasTryLockCalled())
  1563. kPlugin->kData->needsReset = true;
  1564. kPlugin->kData->singleMutex.unlock();
  1565. }
  1566. }
  1567. // -------------------------------------------------------------------
  1568. // CarlaPluginGUI
  1569. #if 0
  1570. CarlaPluginGUI::CarlaPluginGUI(QWidget* const parent, Callback* const callback)
  1571. : QMainWindow(parent),
  1572. kCallback(callback)
  1573. {
  1574. carla_debug("CarlaPluginGUI::CarlaPluginGUI(%p)", parent);
  1575. //CARLA_ASSERT(callback);
  1576. //m_container = new GuiContainer(this);
  1577. //setCentralWidget(m_container);
  1578. //adjustSize();
  1579. //m_container->setParent(this);
  1580. //m_container->show();
  1581. //m_resizable = true;
  1582. //setNewSize(50, 50);
  1583. QMainWindow::setVisible(false);
  1584. }
  1585. CarlaPluginGUI::~CarlaPluginGUI()
  1586. {
  1587. carla_debug("CarlaPluginGUI::~CarlaPluginGUI()");
  1588. //CARLA_ASSERT(m_container);
  1589. // FIXME, automatically deleted by parent ?
  1590. //delete m_container;
  1591. }
  1592. #endif
  1593. #if 0
  1594. // -------------------------------------------------------------------
  1595. GuiContainer* CarlaPluginGUI::getContainer() const
  1596. {
  1597. return m_container;
  1598. }
  1599. WId CarlaPluginGUI::getWinId() const
  1600. {
  1601. return m_container->winId();
  1602. }
  1603. // -------------------------------------------------------------------
  1604. void CarlaPluginGUI::setNewSize(int width, int height)
  1605. {
  1606. carla_debug("CarlaPluginGUI::setNewSize(%i, %i)", width, height);
  1607. if (width < 30)
  1608. width = 30;
  1609. if (height < 30)
  1610. height = 30;
  1611. if (m_resizable)
  1612. {
  1613. resize(width, height);
  1614. }
  1615. else
  1616. {
  1617. setFixedSize(width, height);
  1618. m_container->setFixedSize(width, height);
  1619. }
  1620. }
  1621. void CarlaPluginGUI::setResizable(bool resizable)
  1622. {
  1623. m_resizable = resizable;
  1624. setNewSize(width(), height());
  1625. #ifdef Q_OS_WIN
  1626. if (! resizable)
  1627. setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
  1628. #endif
  1629. }
  1630. void CarlaPluginGUI::setTitle(const char* const title)
  1631. {
  1632. CARLA_ASSERT(title);
  1633. setWindowTitle(QString("%1 (GUI)").arg(title));
  1634. }
  1635. void CarlaPluginGUI::setVisible(const bool yesNo)
  1636. {
  1637. carla_debug("CarlaPluginGUI::setVisible(%s)", bool2str(yesNo));
  1638. if (yesNo)
  1639. {
  1640. if (! m_geometry.isNull())
  1641. restoreGeometry(m_geometry);
  1642. }
  1643. else
  1644. m_geometry = saveGeometry();
  1645. QMainWindow::setVisible(yesNo);
  1646. }
  1647. // -------------------------------------------------------------------
  1648. void CarlaPluginGUI::hideEvent(QHideEvent* const event)
  1649. {
  1650. carla_debug("CarlaPluginGUI::hideEvent(%p)", event);
  1651. CARLA_ASSERT(event);
  1652. event->accept();
  1653. close();
  1654. }
  1655. void CarlaPluginGUI::closeEvent(QCloseEvent* const event)
  1656. {
  1657. carla_debug("CarlaPluginGUI::closeEvent(%p)", event);
  1658. CARLA_ASSERT(event);
  1659. if (event->spontaneous())
  1660. {
  1661. if (m_callback)
  1662. m_callback->guiClosedCallback();
  1663. QMainWindow::closeEvent(event);
  1664. return;
  1665. }
  1666. event->ignore();
  1667. }
  1668. #endif
  1669. // -------------------------------------------------------------------
  1670. CARLA_BACKEND_END_NAMESPACE