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.

1565 lines
43KB

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