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
44KB

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