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.

1582 lines
44KB

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