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.

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