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.

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