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.

1731 lines
54KB

  1. /*
  2. * Carla Native Plugin
  3. * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * 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 COPYING file
  16. */
  17. #include "carla_plugin.hpp"
  18. #include "carla_native.h"
  19. CARLA_BACKEND_START_NAMESPACE
  20. #if 0
  21. struct NativePluginMidiData {
  22. uint32_t count;
  23. uint32_t* indexes;
  24. CarlaEngineMidiPort** ports;
  25. NativePluginMidiData()
  26. : count(0),
  27. indexes(nullptr),
  28. ports(nullptr) {}
  29. };
  30. #endif
  31. class NativePlugin : public CarlaPlugin
  32. {
  33. public:
  34. NativePlugin(CarlaEngine* const engine, const int id)
  35. : CarlaPlugin(engine, id)
  36. {
  37. qDebug("NativePlugin::NativePlugin(%p, %i)", engine, id);
  38. #if 0
  39. descriptor = nullptr;
  40. handle = h2 = nullptr;
  41. host.handle = this;
  42. host.get_buffer_size = carla_host_get_buffer_size;
  43. host.get_sample_rate = carla_host_get_sample_rate;
  44. host.get_time_info = carla_host_get_time_info;
  45. host.write_midi_event = carla_host_write_midi_event;
  46. host.ui_parameter_changed = carla_host_ui_parameter_changed;
  47. host.ui_custom_data_changed = carla_host_ui_custom_data_changed;
  48. host.ui_closed = carla_host_ui_closed;
  49. isProcessing = false;
  50. midiEventCount = 0;
  51. memset(midiEvents, 0, sizeof(::MidiEvent) * MAX_MIDI_EVENTS * 2);
  52. #endif
  53. }
  54. #if 0
  55. ~NativePlugin()
  56. {
  57. qDebug("NativePlugin::~NativePlugin()");
  58. if (descriptor)
  59. {
  60. if (descriptor->deactivate && m_activeBefore)
  61. {
  62. if (handle)
  63. descriptor->deactivate(handle);
  64. if (h2)
  65. descriptor->deactivate(h2);
  66. }
  67. if (descriptor->cleanup)
  68. {
  69. if (handle)
  70. descriptor->cleanup(handle);
  71. if (h2)
  72. descriptor->cleanup(h2);
  73. }
  74. }
  75. }
  76. // -------------------------------------------------------------------
  77. // Information (base)
  78. PluginCategory category()
  79. {
  80. CARLA_ASSERT(descriptor);
  81. if (descriptor)
  82. return static_cast<PluginCategory>(descriptor->category);
  83. return getPluginCategoryFromName(m_name);
  84. }
  85. // -------------------------------------------------------------------
  86. // Information (count)
  87. uint32_t midiInCount()
  88. {
  89. return mIn.count;
  90. }
  91. uint32_t midiOutCount()
  92. {
  93. return mOut.count;
  94. }
  95. uint32_t parameterScalePointCount(const uint32_t parameterId)
  96. {
  97. CARLA_ASSERT(descriptor);
  98. CARLA_ASSERT(handle);
  99. CARLA_ASSERT(parameterId < param.count);
  100. if (descriptor && handle && parameterId < param.count && descriptor->get_parameter_info)
  101. {
  102. const ::Parameter* const param = descriptor->get_parameter_info(handle, parameterId);
  103. if (param)
  104. return param->scalePointCount;
  105. }
  106. return 0;
  107. }
  108. // -------------------------------------------------------------------
  109. // Information (per-plugin data)
  110. double getParameterValue(const uint32_t parameterId)
  111. {
  112. CARLA_ASSERT(descriptor);
  113. CARLA_ASSERT(handle);
  114. CARLA_ASSERT(parameterId < param.count);
  115. if (descriptor && handle && parameterId < param.count && descriptor->get_parameter_value)
  116. return descriptor->get_parameter_value(handle, parameterId);
  117. return 0.0;
  118. }
  119. double getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId)
  120. {
  121. CARLA_ASSERT(descriptor);
  122. CARLA_ASSERT(handle);
  123. CARLA_ASSERT(parameterId < param.count);
  124. CARLA_ASSERT(scalePointId < parameterScalePointCount(parameterId));
  125. if (descriptor && handle && parameterId < param.count && descriptor->get_parameter_info)
  126. {
  127. const ::Parameter* const param = descriptor->get_parameter_info(handle, parameterId);
  128. if (param && scalePointId < param->scalePointCount && param->scalePoints)
  129. {
  130. const ::ParameterScalePoint* const scalePoint = &param->scalePoints[scalePointId];
  131. if (scalePoint)
  132. return scalePoint->value;
  133. }
  134. }
  135. return 0.0;
  136. }
  137. void getLabel(char* const strBuf)
  138. {
  139. CARLA_ASSERT(descriptor);
  140. if (descriptor && descriptor->label)
  141. strncpy(strBuf, descriptor->label, STR_MAX);
  142. else
  143. CarlaPlugin::getLabel(strBuf);
  144. }
  145. void getMaker(char* const strBuf)
  146. {
  147. CARLA_ASSERT(descriptor);
  148. if (descriptor && descriptor->maker)
  149. strncpy(strBuf, descriptor->maker, STR_MAX);
  150. else
  151. CarlaPlugin::getMaker(strBuf);
  152. }
  153. void getCopyright(char* const strBuf)
  154. {
  155. CARLA_ASSERT(descriptor);
  156. if (descriptor && descriptor->copyright)
  157. strncpy(strBuf, descriptor->copyright, STR_MAX);
  158. else
  159. CarlaPlugin::getCopyright(strBuf);
  160. }
  161. void getRealName(char* const strBuf)
  162. {
  163. CARLA_ASSERT(descriptor);
  164. if (descriptor && descriptor->name)
  165. strncpy(strBuf, descriptor->name, STR_MAX);
  166. else
  167. CarlaPlugin::getRealName(strBuf);
  168. }
  169. void getParameterName(const uint32_t parameterId, char* const strBuf)
  170. {
  171. CARLA_ASSERT(descriptor);
  172. CARLA_ASSERT(handle);
  173. CARLA_ASSERT(parameterId < param.count);
  174. if (descriptor && handle && parameterId < param.count && descriptor->get_parameter_info)
  175. {
  176. const ::Parameter* const param = descriptor->get_parameter_info(handle, parameterId);
  177. if (param && param->name)
  178. {
  179. strncpy(strBuf, param->name, STR_MAX);
  180. return;
  181. }
  182. }
  183. CarlaPlugin::getParameterName(parameterId, strBuf);
  184. }
  185. void getParameterText(const uint32_t parameterId, char* const strBuf)
  186. {
  187. CARLA_ASSERT(descriptor);
  188. CARLA_ASSERT(handle);
  189. CARLA_ASSERT(parameterId < param.count);
  190. if (descriptor && handle && parameterId < param.count && descriptor->get_parameter_text)
  191. {
  192. const char* const text = descriptor->get_parameter_text(handle, parameterId);
  193. if (text)
  194. {
  195. strncpy(strBuf, text, STR_MAX);
  196. return;
  197. }
  198. }
  199. CarlaPlugin::getParameterText(parameterId, strBuf);
  200. }
  201. void getParameterUnit(const uint32_t parameterId, char* const strBuf)
  202. {
  203. CARLA_ASSERT(descriptor);
  204. CARLA_ASSERT(handle);
  205. CARLA_ASSERT(parameterId < param.count);
  206. if (descriptor && handle && parameterId < param.count && descriptor->get_parameter_info)
  207. {
  208. const ::Parameter* const param = descriptor->get_parameter_info(handle, parameterId);
  209. if (param && param->unit)
  210. {
  211. strncpy(strBuf, param->unit, STR_MAX);
  212. return;
  213. }
  214. }
  215. CarlaPlugin::getParameterUnit(parameterId, strBuf);
  216. }
  217. void getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf)
  218. {
  219. CARLA_ASSERT(descriptor);
  220. CARLA_ASSERT(handle);
  221. CARLA_ASSERT(parameterId < param.count);
  222. CARLA_ASSERT(scalePointId < parameterScalePointCount(parameterId));
  223. if (descriptor && handle && parameterId < param.count && descriptor->get_parameter_info)
  224. {
  225. const ::Parameter* const param = descriptor->get_parameter_info(handle, parameterId);
  226. if (param && scalePointId < param->scalePointCount && param->scalePoints)
  227. {
  228. const ::ParameterScalePoint* const scalePoint = &param->scalePoints[scalePointId];
  229. if (scalePoint && scalePoint->label)
  230. {
  231. strncpy(strBuf, scalePoint->label, STR_MAX);
  232. return;
  233. }
  234. }
  235. }
  236. CarlaPlugin::getParameterScalePointLabel(parameterId, scalePointId, strBuf);
  237. }
  238. void getGuiInfo(GuiType* const type, bool* const resizable)
  239. {
  240. *type = GUI_EXTERNAL_LV2; // FIXME, should be as _PLUGIN
  241. *resizable = false;
  242. }
  243. // -------------------------------------------------------------------
  244. // Set data (plugin-specific stuff)
  245. void setParameterValue(const uint32_t parameterId, double value, const bool sendGui, const bool sendOsc, const bool sendCallback)
  246. {
  247. CARLA_ASSERT(descriptor);
  248. CARLA_ASSERT(handle);
  249. CARLA_ASSERT(parameterId < param.count);
  250. if (descriptor && handle && parameterId < param.count)
  251. {
  252. fixParameterValue(value, param.ranges[parameterId]);
  253. descriptor->set_parameter_value(handle, param.data[parameterId].rindex, value);
  254. if (h2) descriptor->set_parameter_value(h2, param.data[parameterId].rindex, value);
  255. }
  256. CarlaPlugin::setParameterValue(parameterId, value, sendGui, sendOsc, sendCallback);
  257. }
  258. void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui)
  259. {
  260. CARLA_ASSERT(descriptor);
  261. CARLA_ASSERT(handle);
  262. CARLA_ASSERT(type);
  263. CARLA_ASSERT(key);
  264. CARLA_ASSERT(value);
  265. if (! type)
  266. return qCritical("NativePlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is not string", type, key, value, bool2str(sendGui));
  267. if (! key)
  268. return qCritical("NativePlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - key is null", type, key, value, bool2str(sendGui));
  269. if (! value)
  270. return qCritical("Nativelugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - value is null", type, key, value, bool2str(sendGui));
  271. if (descriptor && handle)
  272. {
  273. if (descriptor->set_custom_data)
  274. {
  275. descriptor->set_custom_data(handle, key, value);
  276. if (h2) descriptor->set_custom_data(h2, key, value);
  277. }
  278. // FIXME - only if gui was started before
  279. if (sendGui && descriptor->ui_set_custom_data)
  280. descriptor->ui_set_custom_data(handle, key, value);
  281. }
  282. CarlaPlugin::setCustomData(type, key, value, sendGui);
  283. }
  284. void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block)
  285. {
  286. CARLA_ASSERT(descriptor);
  287. CARLA_ASSERT(handle);
  288. CARLA_ASSERT(index >= -1 && index < (int32_t)midiprog.count);
  289. if (index < -1)
  290. index = -1;
  291. else if (index > (int32_t)midiprog.count)
  292. return;
  293. if (descriptor && handle && index >= 0)
  294. {
  295. if (x_engine->isOffline())
  296. {
  297. const CarlaEngine::ScopedLocker m(x_engine, block);
  298. descriptor->set_midi_program(handle, midiprog.data[index].bank, midiprog.data[index].program);
  299. if (h2) descriptor->set_midi_program(h2, midiprog.data[index].bank, midiprog.data[index].program);
  300. }
  301. else
  302. {
  303. const ScopedDisabler m(this, block);
  304. descriptor->set_midi_program(handle, midiprog.data[index].bank, midiprog.data[index].program);
  305. if (h2) descriptor->set_midi_program(h2, midiprog.data[index].bank, midiprog.data[index].program);
  306. }
  307. }
  308. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, block);
  309. }
  310. // -------------------------------------------------------------------
  311. // Set gui stuff
  312. void showGui(const bool yesNo)
  313. {
  314. CARLA_ASSERT(descriptor);
  315. CARLA_ASSERT(handle);
  316. if (descriptor && handle && descriptor->ui_show)
  317. descriptor->ui_show(handle, yesNo);
  318. }
  319. void idleGui()
  320. {
  321. // FIXME - this should not be called if there's no GUI!
  322. CARLA_ASSERT(descriptor);
  323. CARLA_ASSERT(handle);
  324. if (descriptor && handle && descriptor->ui_idle)
  325. descriptor->ui_idle(handle);
  326. }
  327. // -------------------------------------------------------------------
  328. // Plugin state
  329. void reload()
  330. {
  331. qDebug("NativePlugin::reload() - start");
  332. CARLA_ASSERT(descriptor);
  333. const ProcessMode processMode(x_engine->getOptions().processMode);
  334. // Safely disable plugin for reload
  335. const ScopedDisabler m(this);
  336. if (x_client->isActive())
  337. x_client->deactivate();
  338. // Remove client ports
  339. removeClientPorts();
  340. // Delete old data
  341. deleteBuffers();
  342. uint32_t aIns, aOuts, mIns, mOuts, params, j;
  343. aIns = aOuts = mIns = mOuts = params = 0;
  344. const double sampleRate = x_engine->getSampleRate();
  345. aIns = descriptor->audioIns;
  346. aOuts = descriptor->audioOuts;
  347. mIns = descriptor->midiIns;
  348. mOuts = descriptor->midiOuts;
  349. params = descriptor->get_parameter_count ? descriptor->get_parameter_count(handle) : 0;
  350. bool forcedStereoIn, forcedStereoOut;
  351. forcedStereoIn = forcedStereoOut = false;
  352. if (x_engine->getOptions().forceStereo && (aIns == 1 || aOuts == 1) && mIns <= 1 && mOuts <= 1 && ! h2)
  353. {
  354. h2 = descriptor->instantiate(descriptor, &host);
  355. if (aIns == 1)
  356. {
  357. aIns = 2;
  358. forcedStereoIn = true;
  359. }
  360. if (aOuts == 1)
  361. {
  362. aOuts = 2;
  363. forcedStereoOut = true;
  364. }
  365. }
  366. if (aIns > 0)
  367. {
  368. aIn.ports = new CarlaEngineAudioPort*[aIns];
  369. aIn.rindexes = new uint32_t[aIns];
  370. }
  371. if (aOuts > 0)
  372. {
  373. aOut.ports = new CarlaEngineAudioPort*[aOuts];
  374. aOut.rindexes = new uint32_t[aOuts];
  375. }
  376. if (mIns > 0)
  377. {
  378. mIn.ports = new CarlaEngineMidiPort*[mIns];
  379. mIn.indexes = new uint32_t[mIns];
  380. }
  381. if (mOuts > 0)
  382. {
  383. mOut.ports = new CarlaEngineMidiPort*[mOuts];
  384. mOut.indexes = new uint32_t[mOuts];
  385. }
  386. if (params > 0)
  387. {
  388. param.data = new ParameterData[params];
  389. param.ranges = new ParameterRanges[params];
  390. }
  391. const int portNameSize = x_engine->maxPortNameSize() - 2;
  392. char portName[portNameSize];
  393. bool needsCtrlIn = false;
  394. bool needsCtrlOut = false;
  395. // Audio Ins
  396. for (j=0; j < descriptor->audioIns; j++)
  397. {
  398. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  399. sprintf(portName, "%s:input_%02i", m_name, j+1);
  400. else
  401. sprintf(portName, "input_%02i", j+1);
  402. aIn.ports[j] = (CarlaEngineAudioPort*)x_client->addPort(CarlaEnginePortTypeAudio, portName, true);
  403. aIn.rindexes[j] = j;
  404. if (forcedStereoIn)
  405. {
  406. strcat(portName, "_");
  407. aIn.ports[1] = (CarlaEngineAudioPort*)x_client->addPort(CarlaEnginePortTypeAudio, portName, true);
  408. aIn.rindexes[1] = j;
  409. }
  410. }
  411. // Audio Outs
  412. for (j=0; j < descriptor->audioOuts; j++)
  413. {
  414. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  415. sprintf(portName, "%s:output_%02i", m_name, j+1);
  416. else
  417. sprintf(portName, "output_%02i", j+1);
  418. qDebug("Audio Out #%i", j);
  419. aOut.ports[j] = (CarlaEngineAudioPort*)x_client->addPort(CarlaEnginePortTypeAudio, portName, false);
  420. aOut.rindexes[j] = j;
  421. needsCtrlIn = true;
  422. if (forcedStereoOut)
  423. {
  424. strcat(portName, "_");
  425. aOut.ports[1] = (CarlaEngineAudioPort*)x_client->addPort(CarlaEnginePortTypeAudio, portName, false);
  426. aOut.rindexes[1] = j;
  427. }
  428. }
  429. // MIDI Input
  430. for (j=0; j < mIns; j++)
  431. {
  432. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  433. sprintf(portName, "%s:midi-in_%02i", m_name, j+1);
  434. else
  435. sprintf(portName, "midi-in_%02i", j+1);
  436. mIn.ports[j] = (CarlaEngineMidiPort*)x_client->addPort(CarlaEnginePortTypeMIDI, portName, true);
  437. mIn.indexes[j] = j;
  438. }
  439. // MIDI Output
  440. for (j=0; j < mOuts; j++)
  441. {
  442. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  443. sprintf(portName, "%s:midi-out_%02i", m_name, j+1);
  444. else
  445. sprintf(portName, "midi-out_%02i", j+1);
  446. mOut.ports[j] = (CarlaEngineMidiPort*)x_client->addPort(CarlaEnginePortTypeMIDI, portName, false);
  447. mOut.indexes[j] = j;
  448. }
  449. for (j=0; j < params; j++)
  450. {
  451. if (! descriptor->get_parameter_info)
  452. break;
  453. const ::Parameter* const paramInfo = descriptor->get_parameter_info(handle, j);
  454. //const uint32_t paramHints = param->hints;
  455. //const bool paramOutput = paramHins;
  456. param.data[j].index = j;
  457. param.data[j].rindex = j;
  458. param.data[j].hints = 0;
  459. param.data[j].midiChannel = 0;
  460. param.data[j].midiCC = -1;
  461. double min, max, def, step, stepSmall, stepLarge;
  462. // min value
  463. min = paramInfo->ranges.min;
  464. // max value
  465. max = paramInfo->ranges.max;
  466. if (min > max)
  467. max = min;
  468. else if (max < min)
  469. min = max;
  470. if (max - min == 0.0)
  471. {
  472. qWarning("Broken plugin parameter: max - min == 0");
  473. max = min + 0.1;
  474. }
  475. // default value
  476. def = paramInfo->ranges.def;
  477. if (def < min)
  478. def = min;
  479. else if (def > max)
  480. def = max;
  481. if (paramInfo->hints & ::PARAMETER_USES_SAMPLE_RATE)
  482. {
  483. min *= sampleRate;
  484. max *= sampleRate;
  485. def *= sampleRate;
  486. param.data[j].hints |= PARAMETER_USES_SAMPLERATE;
  487. }
  488. if (paramInfo->hints & ::PARAMETER_IS_BOOLEAN)
  489. {
  490. step = max - min;
  491. stepSmall = step;
  492. stepLarge = step;
  493. param.data[j].hints |= PARAMETER_IS_BOOLEAN;
  494. }
  495. else if (paramInfo->hints & ::PARAMETER_IS_INTEGER)
  496. {
  497. step = 1.0;
  498. stepSmall = 1.0;
  499. stepLarge = 10.0;
  500. param.data[j].hints |= PARAMETER_IS_INTEGER;
  501. }
  502. else
  503. {
  504. double range = max - min;
  505. step = range/100.0;
  506. stepSmall = range/1000.0;
  507. stepLarge = range/10.0;
  508. }
  509. if (paramInfo->hints & ::PARAMETER_IS_OUTPUT)
  510. {
  511. param.data[j].type = PARAMETER_OUTPUT;
  512. needsCtrlOut = true;
  513. }
  514. else
  515. {
  516. param.data[j].type = PARAMETER_INPUT;
  517. needsCtrlIn = true;
  518. }
  519. // extra parameter hints
  520. if (paramInfo->hints & ::PARAMETER_IS_ENABLED)
  521. param.data[j].hints |= PARAMETER_IS_ENABLED;
  522. if (paramInfo->hints & ::PARAMETER_IS_AUTOMABLE)
  523. param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
  524. if (paramInfo->hints & ::PARAMETER_IS_LOGARITHMIC)
  525. param.data[j].hints |= PARAMETER_IS_LOGARITHMIC;
  526. if (paramInfo->hints & ::PARAMETER_USES_SCALEPOINTS)
  527. param.data[j].hints |= PARAMETER_USES_SCALEPOINTS;
  528. if (paramInfo->hints & ::PARAMETER_USES_CUSTOM_TEXT)
  529. param.data[j].hints |= PARAMETER_USES_CUSTOM_TEXT;
  530. param.ranges[j].min = min;
  531. param.ranges[j].max = max;
  532. param.ranges[j].def = def;
  533. param.ranges[j].step = step;
  534. param.ranges[j].stepSmall = stepSmall;
  535. param.ranges[j].stepLarge = stepLarge;
  536. }
  537. if (needsCtrlIn)
  538. {
  539. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  540. {
  541. strcpy(portName, m_name);
  542. strcat(portName, ":control-in");
  543. }
  544. else
  545. strcpy(portName, "control-in");
  546. param.portCin = (CarlaEngineControlPort*)x_client->addPort(CarlaEnginePortTypeControl, portName, true);
  547. }
  548. if (needsCtrlOut)
  549. {
  550. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  551. {
  552. strcpy(portName, m_name);
  553. strcat(portName, ":control-out");
  554. }
  555. else
  556. strcpy(portName, "control-out");
  557. param.portCout = (CarlaEngineControlPort*)x_client->addPort(CarlaEnginePortTypeControl, portName, false);
  558. }
  559. aIn.count = aIns;
  560. aOut.count = aOuts;
  561. mIn.count = mIns;
  562. mOut.count = mOuts;
  563. param.count = params;
  564. // plugin checks
  565. m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE | PLUGIN_CAN_FORCE_STEREO);
  566. if (aOuts > 0 && (aIns == aOuts || aIns == 1))
  567. m_hints |= PLUGIN_CAN_DRYWET;
  568. if (aOuts > 0)
  569. m_hints |= PLUGIN_CAN_VOLUME;
  570. if (aOuts >= 2 && aOuts%2 == 0)
  571. m_hints |= PLUGIN_CAN_BALANCE;
  572. if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0) && mIns <= 1 && mOuts <= 1)
  573. m_hints |= PLUGIN_CAN_FORCE_STEREO;
  574. // native plugin hints
  575. if (descriptor->hints & ::PLUGIN_IS_SYNTH)
  576. m_hints |= PLUGIN_IS_SYNTH;
  577. if (descriptor->hints & ::PLUGIN_HAS_GUI)
  578. m_hints |= PLUGIN_HAS_GUI;
  579. if (descriptor->hints & ::PLUGIN_USES_SINGLE_THREAD)
  580. m_hints |= PLUGIN_USES_SINGLE_THREAD;
  581. reloadPrograms(true);
  582. x_client->activate();
  583. qDebug("NativePlugin::reload() - end");
  584. }
  585. void reloadPrograms(const bool init)
  586. {
  587. qDebug("NativePlugin::reloadPrograms(%s)", bool2str(init));
  588. uint32_t i, oldCount = midiprog.count;
  589. // Delete old programs
  590. if (midiprog.count > 0)
  591. {
  592. for (i=0; i < midiprog.count; i++)
  593. {
  594. if (midiprog.data[i].name)
  595. free((void*)midiprog.data[i].name);
  596. }
  597. delete[] midiprog.data;
  598. }
  599. midiprog.count = (descriptor->get_midi_program_count && descriptor->get_midi_program_info) ? descriptor->get_midi_program_count(handle) : 0;
  600. midiprog.data = nullptr;
  601. if (midiprog.count > 0)
  602. midiprog.data = new MidiProgramData[midiprog.count];
  603. // Update data
  604. for (i=0; i < midiprog.count; i++)
  605. {
  606. const ::MidiProgram* const mpDesc = descriptor->get_midi_program_info(handle, i);
  607. CARLA_ASSERT(mpDesc);
  608. CARLA_ASSERT(mpDesc->name);
  609. midiprog.data[i].bank = mpDesc->bank;
  610. midiprog.data[i].program = mpDesc->program;
  611. midiprog.data[i].name = strdup(mpDesc->name);
  612. }
  613. // Update OSC Names
  614. if (x_engine->isOscControlRegistered())
  615. {
  616. x_engine->osc_send_control_set_midi_program_count(m_id, midiprog.count);
  617. for (i=0; i < midiprog.count; i++)
  618. x_engine->osc_send_control_set_midi_program_data(m_id, i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name);
  619. }
  620. if (init)
  621. {
  622. if (midiprog.count > 0)
  623. setMidiProgram(0, false, false, false, true);
  624. }
  625. else
  626. {
  627. x_engine->callback(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0, nullptr);
  628. // Check if current program is invalid
  629. bool programChanged = false;
  630. if (midiprog.count == oldCount+1)
  631. {
  632. // one midi program added, probably created by user
  633. midiprog.current = oldCount;
  634. programChanged = true;
  635. }
  636. else if (midiprog.current >= (int32_t)midiprog.count)
  637. {
  638. // current midi program > count
  639. midiprog.current = 0;
  640. programChanged = true;
  641. }
  642. else if (midiprog.current < 0 && midiprog.count > 0)
  643. {
  644. // programs exist now, but not before
  645. midiprog.current = 0;
  646. programChanged = true;
  647. }
  648. else if (midiprog.current >= 0 && midiprog.count == 0)
  649. {
  650. // programs existed before, but not anymore
  651. midiprog.current = -1;
  652. programChanged = true;
  653. }
  654. if (programChanged)
  655. setMidiProgram(midiprog.current, true, true, true, true);
  656. }
  657. }
  658. // -------------------------------------------------------------------
  659. // Plugin processing
  660. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset)
  661. {
  662. uint32_t i, k;
  663. double aInsPeak[2] = { 0.0 };
  664. double aOutsPeak[2] = { 0.0 };
  665. // reset MIDI
  666. midiEventCount = 0;
  667. memset(midiEvents, 0, sizeof(::MidiEvent) * MAX_MIDI_EVENTS * 2);
  668. CARLA_PROCESS_CONTINUE_CHECK;
  669. // --------------------------------------------------------------------------------------------------------
  670. // Input VU
  671. if (aIn.count > 0 && x_engine->getOptions().processMode != PROCESS_MODE_CONTINUOUS_RACK)
  672. {
  673. if (aIn.count == 1)
  674. {
  675. for (k=0; k < frames; k++)
  676. {
  677. if (std::abs(inBuffer[0][k]) > aInsPeak[0])
  678. aInsPeak[0] = std::abs(inBuffer[0][k]);
  679. }
  680. }
  681. else if (aIn.count > 1)
  682. {
  683. for (k=0; k < frames; k++)
  684. {
  685. if (std::abs(inBuffer[0][k]) > aInsPeak[0])
  686. aInsPeak[0] = std::abs(inBuffer[0][k]);
  687. if (std::abs(inBuffer[1][k]) > aInsPeak[1])
  688. aInsPeak[1] = std::abs(inBuffer[1][k]);
  689. }
  690. }
  691. }
  692. CARLA_PROCESS_CONTINUE_CHECK;
  693. // --------------------------------------------------------------------------------------------------------
  694. // Parameters Input [Automation]
  695. if (param.portCin && m_active && m_activeBefore)
  696. {
  697. bool allNotesOffSent = false;
  698. const CarlaEngineControlEvent* cinEvent;
  699. uint32_t time, nEvents = param.portCin->getEventCount();
  700. uint32_t nextBankId = 0;
  701. if (midiprog.current >= 0 && midiprog.count > 0)
  702. nextBankId = midiprog.data[midiprog.current].bank;
  703. for (i=0; i < nEvents; i++)
  704. {
  705. cinEvent = param.portCin->getEvent(i);
  706. if (! cinEvent)
  707. continue;
  708. time = cinEvent->time - framesOffset;
  709. if (time >= frames)
  710. continue;
  711. // Control change
  712. switch (cinEvent->type)
  713. {
  714. case CarlaEngineNullEvent:
  715. break;
  716. case CarlaEngineParameterChangeEvent:
  717. {
  718. double value;
  719. // Control backend stuff
  720. if (cinEvent->channel == m_ctrlInChannel)
  721. {
  722. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(cinEvent->parameter) && (m_hints & PLUGIN_CAN_DRYWET) > 0)
  723. {
  724. value = cinEvent->value;
  725. setDryWet(value, false, false);
  726. postponeEvent(PluginPostEventParameterChange, PARAMETER_DRYWET, 0, value);
  727. continue;
  728. }
  729. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(cinEvent->parameter) && (m_hints & PLUGIN_CAN_VOLUME) > 0)
  730. {
  731. value = cinEvent->value*127/100;
  732. setVolume(value, false, false);
  733. postponeEvent(PluginPostEventParameterChange, PARAMETER_VOLUME, 0, value);
  734. continue;
  735. }
  736. if (MIDI_IS_CONTROL_BALANCE(cinEvent->parameter) && (m_hints & PLUGIN_CAN_BALANCE) > 0)
  737. {
  738. double left, right;
  739. value = cinEvent->value/0.5 - 1.0;
  740. if (value < 0.0)
  741. {
  742. left = -1.0;
  743. right = (value*2)+1.0;
  744. }
  745. else if (value > 0.0)
  746. {
  747. left = (value*2)-1.0;
  748. right = 1.0;
  749. }
  750. else
  751. {
  752. left = -1.0;
  753. right = 1.0;
  754. }
  755. setBalanceLeft(left, false, false);
  756. setBalanceRight(right, false, false);
  757. postponeEvent(PluginPostEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  758. postponeEvent(PluginPostEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  759. continue;
  760. }
  761. }
  762. // Control plugin parameters
  763. for (k=0; k < param.count; k++)
  764. {
  765. if (param.data[k].midiChannel != cinEvent->channel)
  766. continue;
  767. if (param.data[k].midiCC != cinEvent->parameter)
  768. continue;
  769. if (param.data[k].type != PARAMETER_INPUT)
  770. continue;
  771. if (param.data[k].hints & PARAMETER_IS_AUTOMABLE)
  772. {
  773. if (param.data[k].hints & PARAMETER_IS_BOOLEAN)
  774. {
  775. value = cinEvent->value < 0.5 ? param.ranges[k].min : param.ranges[k].max;
  776. }
  777. else
  778. {
  779. value = cinEvent->value * (param.ranges[k].max - param.ranges[k].min) + param.ranges[k].min;
  780. if (param.data[k].hints & PARAMETER_IS_INTEGER)
  781. value = rint(value);
  782. }
  783. setParameterValue(k, value, false, false, false);
  784. postponeEvent(PluginPostEventParameterChange, k, 0, value);
  785. }
  786. }
  787. break;
  788. }
  789. case CarlaEngineMidiBankChangeEvent:
  790. if (cinEvent->channel == m_ctrlInChannel)
  791. nextBankId = rint(cinEvent->value);
  792. break;
  793. case CarlaEngineMidiProgramChangeEvent:
  794. if (cinEvent->channel == m_ctrlInChannel)
  795. {
  796. uint32_t nextProgramId = rint(cinEvent->value);
  797. for (k=0; k < midiprog.count; k++)
  798. {
  799. if (midiprog.data[k].bank == nextBankId && midiprog.data[k].program == nextProgramId)
  800. {
  801. setMidiProgram(k, false, false, false, false);
  802. postponeEvent(PluginPostEventMidiProgramChange, k, 0, 0.0);
  803. break;
  804. }
  805. }
  806. }
  807. break;
  808. case CarlaEngineAllSoundOffEvent:
  809. if (cinEvent->channel == m_ctrlInChannel)
  810. {
  811. if (mIn.count > 0 && ! allNotesOffSent)
  812. sendMidiAllNotesOff();
  813. if (descriptor->deactivate)
  814. {
  815. descriptor->deactivate(handle);
  816. if (h2) descriptor->deactivate(h2);
  817. }
  818. if (descriptor->activate)
  819. {
  820. descriptor->activate(handle);
  821. if (h2) descriptor->activate(h2);
  822. }
  823. postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 0.0);
  824. postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 1.0);
  825. allNotesOffSent = true;
  826. }
  827. break;
  828. case CarlaEngineAllNotesOffEvent:
  829. if (cinEvent->channel == m_ctrlInChannel)
  830. {
  831. if (mIn.count > 0 && ! allNotesOffSent)
  832. sendMidiAllNotesOff();
  833. allNotesOffSent = true;
  834. }
  835. break;
  836. }
  837. }
  838. } // End of Parameters Input
  839. CARLA_PROCESS_CONTINUE_CHECK;
  840. // --------------------------------------------------------------------------------------------------------
  841. // MIDI Input
  842. if (mIn.count > 0 && m_active && m_activeBefore)
  843. {
  844. // ----------------------------------------------------------------------------------------------------
  845. // MIDI Input (External)
  846. {
  847. engineMidiLock();
  848. for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++)
  849. {
  850. if (extMidiNotes[i].channel < 0)
  851. break;
  852. ::MidiEvent* const midiEvent = &midiEvents[midiEventCount];
  853. memset(midiEvent, 0, sizeof(::MidiEvent));
  854. midiEvent->data[0] = uint8_t(extMidiNotes[i].velo ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) + extMidiNotes[i].channel;
  855. midiEvent->data[1] = extMidiNotes[i].note;
  856. midiEvent->data[2] = extMidiNotes[i].velo;
  857. extMidiNotes[i].channel = -1; // mark as invalid
  858. midiEventCount += 1;
  859. }
  860. engineMidiUnlock();
  861. } // End of MIDI Input (External)
  862. CARLA_PROCESS_CONTINUE_CHECK;
  863. // ----------------------------------------------------------------------------------------------------
  864. // MIDI Input (System)
  865. for (i=0; i < mIn.count; i++)
  866. {
  867. if (! mIn.ports[i])
  868. continue;
  869. const CarlaEngineMidiEvent* minEvent;
  870. uint32_t time, nEvents = mIn.ports[i]->getEventCount();
  871. for (k=0; k < nEvents && midiEventCount < MAX_MIDI_EVENTS; k++)
  872. {
  873. minEvent = mIn.ports[i]->getEvent(k);
  874. if (! minEvent)
  875. continue;
  876. time = minEvent->time - framesOffset;
  877. if (time >= frames)
  878. continue;
  879. uint8_t status = minEvent->data[0];
  880. uint8_t channel = status & 0x0F;
  881. // Fix bad note-off
  882. if (MIDI_IS_STATUS_NOTE_ON(status) && minEvent->data[2] == 0)
  883. status -= 0x10;
  884. ::MidiEvent* const midiEvent = &midiEvents[midiEventCount];
  885. memset(midiEvent, 0, sizeof(::MidiEvent));
  886. midiEvent->port = i;
  887. midiEvent->time = minEvent->time;
  888. if (MIDI_IS_STATUS_NOTE_OFF(status))
  889. {
  890. uint8_t note = minEvent->data[1];
  891. midiEvent->data[0] = status;
  892. midiEvent->data[1] = note;
  893. postponeEvent(PluginPostEventNoteOff, channel, note, 0.0);
  894. }
  895. else if (MIDI_IS_STATUS_NOTE_ON(status))
  896. {
  897. uint8_t note = minEvent->data[1];
  898. uint8_t velo = minEvent->data[2];
  899. midiEvent->data[0] = status;
  900. midiEvent->data[1] = note;
  901. midiEvent->data[2] = velo;
  902. postponeEvent(PluginPostEventNoteOn, channel, note, velo);
  903. }
  904. else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status))
  905. {
  906. uint8_t note = minEvent->data[1];
  907. uint8_t pressure = minEvent->data[2];
  908. midiEvent->data[0] = status;
  909. midiEvent->data[1] = note;
  910. midiEvent->data[2] = pressure;
  911. }
  912. else if (MIDI_IS_STATUS_AFTERTOUCH(status))
  913. {
  914. uint8_t pressure = minEvent->data[1];
  915. midiEvent->data[0] = status;
  916. midiEvent->data[1] = pressure;
  917. }
  918. else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status))
  919. {
  920. uint8_t lsb = minEvent->data[1];
  921. uint8_t msb = minEvent->data[2];
  922. midiEvent->data[0] = status;
  923. midiEvent->data[1] = lsb;
  924. midiEvent->data[2] = msb;
  925. }
  926. else
  927. continue;
  928. midiEventCount += 1;
  929. }
  930. } // End of MIDI Input (System)
  931. } // End of MIDI Input
  932. CARLA_PROCESS_CONTINUE_CHECK;
  933. // --------------------------------------------------------------------------------------------------------
  934. // Plugin processing
  935. uint32_t midiEventCountBefore = midiEventCount;
  936. if (m_active)
  937. {
  938. if (! m_activeBefore)
  939. {
  940. if (mIn.count > 0)
  941. {
  942. for (k=0; k < MAX_MIDI_CHANNELS; k++)
  943. {
  944. memset(&midiEvents[k], 0, sizeof(::MidiEvent));
  945. midiEvents[k].data[0] = MIDI_STATUS_CONTROL_CHANGE + k;
  946. midiEvents[k].data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  947. memset(&midiEvents[k*2], 0, sizeof(::MidiEvent));
  948. midiEvents[k*2].data[0] = MIDI_STATUS_CONTROL_CHANGE + k;
  949. midiEvents[k*2].data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  950. }
  951. midiEventCount = MAX_MIDI_CHANNELS*2;
  952. }
  953. if (descriptor->activate)
  954. {
  955. descriptor->activate(handle);
  956. if (h2) descriptor->activate(h2);
  957. }
  958. }
  959. isProcessing = true;
  960. if (h2)
  961. {
  962. descriptor->process(handle, inBuffer? &inBuffer[0] : nullptr, outBuffer? &outBuffer[0] : nullptr, frames, midiEventCountBefore, midiEvents);
  963. descriptor->process(h2, inBuffer? &inBuffer[1] : nullptr, outBuffer? &outBuffer[1] : nullptr, frames, midiEventCountBefore, midiEvents);
  964. }
  965. else
  966. descriptor->process(handle, inBuffer, outBuffer, frames, midiEventCountBefore, midiEvents);
  967. isProcessing = false;
  968. }
  969. else
  970. {
  971. if (m_activeBefore)
  972. {
  973. if (descriptor->deactivate)
  974. {
  975. descriptor->deactivate(handle);
  976. if (h2) descriptor->deactivate(h2);
  977. }
  978. }
  979. }
  980. CARLA_PROCESS_CONTINUE_CHECK;
  981. // --------------------------------------------------------------------------------------------------------
  982. // Post-processing (dry/wet, volume and balance)
  983. if (m_active)
  984. {
  985. bool do_drywet = (m_hints & PLUGIN_CAN_DRYWET) > 0 && x_dryWet != 1.0;
  986. bool do_volume = (m_hints & PLUGIN_CAN_VOLUME) > 0 && x_volume != 1.0;
  987. bool do_balance = (m_hints & PLUGIN_CAN_BALANCE) > 0 && (x_balanceLeft != -1.0 || x_balanceRight != 1.0);
  988. double bal_rangeL, bal_rangeR;
  989. float bufValue, oldBufLeft[do_balance ? frames : 0];
  990. for (i=0; i < aOut.count; i++)
  991. {
  992. // Dry/Wet
  993. if (do_drywet)
  994. {
  995. for (k=0; k < frames; k++)
  996. {
  997. bufValue = (aIn.count == 1) ? inBuffer[0][k] : inBuffer[i][k];
  998. outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(bufValue*(1.0-x_dryWet));
  999. }
  1000. }
  1001. // Balance
  1002. if (do_balance)
  1003. {
  1004. if (i%2 == 0)
  1005. memcpy(&oldBufLeft, outBuffer[i], sizeof(float)*frames);
  1006. bal_rangeL = (x_balanceLeft+1.0)/2;
  1007. bal_rangeR = (x_balanceRight+1.0)/2;
  1008. for (k=0; k < frames; k++)
  1009. {
  1010. if (i%2 == 0)
  1011. {
  1012. // left output
  1013. outBuffer[i][k] = oldBufLeft[k]*(1.0-bal_rangeL);
  1014. outBuffer[i][k] += outBuffer[i+1][k]*(1.0-bal_rangeR);
  1015. }
  1016. else
  1017. {
  1018. // right
  1019. outBuffer[i][k] = outBuffer[i][k]*bal_rangeR;
  1020. outBuffer[i][k] += oldBufLeft[k]*bal_rangeL;
  1021. }
  1022. }
  1023. }
  1024. // Volume
  1025. if (do_volume)
  1026. {
  1027. for (k=0; k < frames; k++)
  1028. outBuffer[i][k] *= x_volume;
  1029. }
  1030. // Output VU
  1031. if (x_engine->getOptions().processMode != PROCESS_MODE_CONTINUOUS_RACK)
  1032. {
  1033. for (k=0; i < 2 && k < frames; k++)
  1034. {
  1035. if (std::abs(outBuffer[i][k]) > aOutsPeak[i])
  1036. aOutsPeak[i] = std::abs(outBuffer[i][k]);
  1037. }
  1038. }
  1039. }
  1040. }
  1041. else
  1042. {
  1043. // disable any output sound if not active
  1044. for (i=0; i < aOut.count; i++)
  1045. carla_zeroF(outBuffer[i], frames);
  1046. aOutsPeak[0] = 0.0;
  1047. aOutsPeak[1] = 0.0;
  1048. } // End of Post-processing
  1049. CARLA_PROCESS_CONTINUE_CHECK;
  1050. // --------------------------------------------------------------------------------------------------------
  1051. // MIDI Output
  1052. if (mOut.count > 0 && m_active)
  1053. {
  1054. uint8_t data[3] = { 0 };
  1055. for (uint32_t i = midiEventCountBefore; i < midiEventCount; i++)
  1056. {
  1057. data[0] = midiEvents[i].data[0];
  1058. data[1] = midiEvents[i].data[1];
  1059. data[2] = midiEvents[i].data[2];
  1060. // Fix bad note-off
  1061. if (MIDI_IS_STATUS_NOTE_ON(data[0]) && data[2] == 0)
  1062. data[0] -= 0x10;
  1063. const uint32_t port = midiEvents[i].port;
  1064. if (port < mOut.count)
  1065. mOut.ports[port]->writeEvent(midiEvents[i].time, data, 3);
  1066. }
  1067. } // End of MIDI Output
  1068. // --------------------------------------------------------------------------------------------------------
  1069. // Control Output
  1070. if (param.portCout && m_active)
  1071. {
  1072. double value, valueControl;
  1073. for (k=0; k < param.count; k++)
  1074. {
  1075. if (param.data[k].type == PARAMETER_OUTPUT)
  1076. {
  1077. value = descriptor->get_parameter_value(handle, param.data[k].rindex);
  1078. if (param.data[k].midiCC > 0)
  1079. {
  1080. valueControl = (value - param.ranges[k].min) / (param.ranges[k].max - param.ranges[k].min);
  1081. param.portCout->writeEvent(CarlaEngineParameterChangeEvent, framesOffset, param.data[k].midiChannel, param.data[k].midiCC, valueControl);
  1082. }
  1083. }
  1084. }
  1085. } // End of Control Output
  1086. CARLA_PROCESS_CONTINUE_CHECK;
  1087. // --------------------------------------------------------------------------------------------------------
  1088. // Peak Values
  1089. x_engine->setInputPeak(m_id, 0, aInsPeak[0]);
  1090. x_engine->setInputPeak(m_id, 1, aInsPeak[1]);
  1091. x_engine->setOutputPeak(m_id, 0, aOutsPeak[0]);
  1092. x_engine->setOutputPeak(m_id, 1, aOutsPeak[1]);
  1093. m_activeBefore = m_active;
  1094. }
  1095. // -------------------------------------------------------------------
  1096. // Cleanup
  1097. void removeClientPorts()
  1098. {
  1099. qDebug("NativePlugin::removeClientPorts() - start");
  1100. for (uint32_t i=0; i < mIn.count; i++)
  1101. {
  1102. delete mIn.ports[i];
  1103. mIn.ports[i] = nullptr;
  1104. }
  1105. for (uint32_t i=0; i < mOut.count; i++)
  1106. {
  1107. delete mOut.ports[i];
  1108. mOut.ports[i] = nullptr;
  1109. }
  1110. CarlaPlugin::removeClientPorts();
  1111. qDebug("NativePlugin::removeClientPorts() - end");
  1112. }
  1113. void initBuffers()
  1114. {
  1115. for (uint32_t i=0; i < mIn.count; i++)
  1116. {
  1117. if (mIn.ports[i])
  1118. mIn.ports[i]->initBuffer(x_engine);
  1119. }
  1120. for (uint32_t i=0; i < mOut.count; i++)
  1121. {
  1122. if (mOut.ports[i])
  1123. mOut.ports[i]->initBuffer(x_engine);
  1124. }
  1125. CarlaPlugin::initBuffers();
  1126. }
  1127. void deleteBuffers()
  1128. {
  1129. qDebug("NativePlugin::deleteBuffers() - start");
  1130. if (mIn.count > 0)
  1131. {
  1132. delete[] mIn.ports;
  1133. delete[] mIn.indexes;
  1134. }
  1135. if (mOut.count > 0)
  1136. {
  1137. delete[] mOut.ports;
  1138. delete[] mOut.indexes;
  1139. }
  1140. mIn.count = 0;
  1141. mIn.ports = nullptr;
  1142. mIn.indexes = nullptr;
  1143. mOut.count = 0;
  1144. mOut.ports = nullptr;
  1145. mOut.indexes = nullptr;
  1146. CarlaPlugin::deleteBuffers();
  1147. qDebug("NativePlugin::deleteBuffers() - end");
  1148. }
  1149. // -------------------------------------------------------------------
  1150. uint32_t handleGetBufferSize()
  1151. {
  1152. return x_engine->getBufferSize();
  1153. }
  1154. double handleGetSampleRate()
  1155. {
  1156. return x_engine->getSampleRate();
  1157. }
  1158. const TimeInfo* handleGetTimeInfo()
  1159. {
  1160. // TODO
  1161. return nullptr;
  1162. }
  1163. bool handleWriteMidiEvent(MidiEvent* event)
  1164. {
  1165. CARLA_ASSERT(m_enabled);
  1166. CARLA_ASSERT(mOut.count > 0);
  1167. CARLA_ASSERT(isProcessing);
  1168. CARLA_ASSERT(event);
  1169. if (! m_enabled)
  1170. return false;
  1171. if (mOut.count == 0)
  1172. return false;
  1173. if (! isProcessing)
  1174. {
  1175. qCritical("NativePlugin::handleWriteMidiEvent(%p) - received MIDI out events outside audio thread, ignoring", event);
  1176. return false;
  1177. }
  1178. if (midiEventCount >= MAX_MIDI_EVENTS*2)
  1179. return false;
  1180. memcpy(&midiEvents[midiEventCount], event, sizeof(::MidiEvent));
  1181. midiEventCount += 1;
  1182. return true;
  1183. }
  1184. void handleUiParameterChanged(uint32_t index, float value)
  1185. {
  1186. setParameterValue(index, value, false, true, true);
  1187. }
  1188. void handleUiCustomDataChanged(const char* key, const char* value)
  1189. {
  1190. setCustomData(CUSTOM_DATA_STRING, key, value, false);
  1191. }
  1192. void handleUiClosed()
  1193. {
  1194. x_engine->callback(CALLBACK_SHOW_GUI, m_id, 0, 0, 0.0, nullptr);
  1195. }
  1196. // -------------------------------------------------------------------
  1197. static uint32_t carla_host_get_buffer_size(HostHandle handle)
  1198. {
  1199. CARLA_ASSERT(handle);
  1200. return ((NativePlugin*)handle)->handleGetBufferSize();
  1201. }
  1202. static double carla_host_get_sample_rate(HostHandle handle)
  1203. {
  1204. CARLA_ASSERT(handle);
  1205. return ((NativePlugin*)handle)->handleGetSampleRate();
  1206. }
  1207. static const TimeInfo* carla_host_get_time_info(HostHandle handle)
  1208. {
  1209. CARLA_ASSERT(handle);
  1210. return ((NativePlugin*)handle)->handleGetTimeInfo();
  1211. }
  1212. static bool carla_host_write_midi_event(HostHandle handle, MidiEvent* event)
  1213. {
  1214. CARLA_ASSERT(handle);
  1215. return ((NativePlugin*)handle)->handleWriteMidiEvent(event);
  1216. }
  1217. static void carla_host_ui_parameter_changed(HostHandle handle, uint32_t index, float value)
  1218. {
  1219. CARLA_ASSERT(handle);
  1220. ((NativePlugin*)handle)->handleUiParameterChanged(index, value);
  1221. }
  1222. static void carla_host_ui_custom_data_changed(HostHandle handle, const char* key, const char* value)
  1223. {
  1224. CARLA_ASSERT(handle);
  1225. ((NativePlugin*)handle)->handleUiCustomDataChanged(key, value);
  1226. }
  1227. static void carla_host_ui_closed(HostHandle handle)
  1228. {
  1229. CARLA_ASSERT(handle);
  1230. ((NativePlugin*)handle)->handleUiClosed();
  1231. }
  1232. // -------------------------------------------------------------------
  1233. #endif
  1234. static size_t getPluginCount()
  1235. {
  1236. maybeFirstInit();
  1237. return pluginDescriptors.size();
  1238. }
  1239. static const PluginDescriptor* getPlugin(const size_t index)
  1240. {
  1241. maybeFirstInit();
  1242. CARLA_ASSERT(index < pluginDescriptors.size());
  1243. if (index < pluginDescriptors.size())
  1244. return pluginDescriptors[index];
  1245. return nullptr;
  1246. }
  1247. static void registerPlugin(const PluginDescriptor* desc)
  1248. {
  1249. pluginDescriptors.push_back(desc);
  1250. }
  1251. static void maybeFirstInit()
  1252. {
  1253. if (! firstInit)
  1254. return;
  1255. firstInit = false;
  1256. carla_register_native_plugin_bypass();
  1257. carla_register_native_plugin_midiSplit();
  1258. carla_register_native_plugin_midiThrough();
  1259. carla_register_native_plugin_3BandEQ();
  1260. carla_register_native_plugin_3BandSplitter();
  1261. carla_register_native_plugin_PingPongPan();
  1262. #ifdef WANT_ZYNADDSUBFX
  1263. carla_register_native_plugin_zynaddsubfx();
  1264. #endif
  1265. }
  1266. #if 0
  1267. // -------------------------------------------------------------------
  1268. bool init(const char* const name, const char* const label)
  1269. {
  1270. // ---------------------------------------------------------------
  1271. // initialize native-plugins descriptors
  1272. maybeFirstInit();
  1273. // ---------------------------------------------------------------
  1274. // get descriptor that matches label
  1275. for (size_t i=0; i < pluginDescriptors.size(); i++)
  1276. {
  1277. descriptor = pluginDescriptors[i];
  1278. if (! descriptor)
  1279. break;
  1280. if (descriptor->label && strcmp(descriptor->label, label) == 0)
  1281. break;
  1282. descriptor = nullptr;
  1283. }
  1284. if (! descriptor)
  1285. {
  1286. x_engine->setLastError("Invalid internal plugin");
  1287. return false;
  1288. }
  1289. // ---------------------------------------------------------------
  1290. // get info
  1291. if (name)
  1292. m_name = x_engine->getUniquePluginName(name);
  1293. else
  1294. m_name = x_engine->getUniquePluginName(descriptor->name);
  1295. // ---------------------------------------------------------------
  1296. // register client
  1297. x_client = x_engine->addClient(this);
  1298. if (! x_client->isOk())
  1299. {
  1300. x_engine->setLastError("Failed to register plugin client");
  1301. return false;
  1302. }
  1303. // ---------------------------------------------------------------
  1304. // initialize plugin
  1305. handle = descriptor->instantiate(descriptor, &host);
  1306. if (! handle)
  1307. {
  1308. x_engine->setLastError("Plugin failed to initialize");
  1309. return false;
  1310. }
  1311. return true;
  1312. }
  1313. #endif
  1314. private:
  1315. #if 0
  1316. const PluginDescriptor* descriptor;
  1317. PluginHandle handle, h2;
  1318. HostDescriptor host;
  1319. bool isProcessing;
  1320. NativePluginMidiData mIn;
  1321. NativePluginMidiData mOut;
  1322. uint32_t midiEventCount;
  1323. ::MidiEvent midiEvents[MAX_MIDI_EVENTS*2];
  1324. #endif
  1325. static bool firstInit;
  1326. static std::vector<const PluginDescriptor*> pluginDescriptors;
  1327. };
  1328. bool NativePlugin::firstInit = true;
  1329. std::vector<const PluginDescriptor*> NativePlugin::pluginDescriptors;
  1330. // -----------------------------------------------------------------------
  1331. #if 0
  1332. CarlaPlugin* CarlaPlugin::newNative(const initializer& init)
  1333. {
  1334. qDebug("CarlaPlugin::newNative(%p, \"%s\", \"%s\", \"%s\")", init.engine, init.filename, init.name, init.label);
  1335. short id = init.engine->getNewPluginId();
  1336. if (id < 0 || id > init.engine->maxPluginNumber())
  1337. {
  1338. init.engine->setLastError("Maximum number of plugins reached");
  1339. return nullptr;
  1340. }
  1341. NativePlugin* const plugin = new NativePlugin(init.engine, id);
  1342. if (! plugin->init(init.name, init.label))
  1343. {
  1344. delete plugin;
  1345. return nullptr;
  1346. }
  1347. plugin->reload();
  1348. if (init.engine->getOptions().processMode == PROCESS_MODE_CONTINUOUS_RACK)
  1349. {
  1350. if (! (plugin->hints() & PLUGIN_CAN_FORCE_STEREO))
  1351. {
  1352. init.engine->setLastError("Carla's rack mode can only work with Mono or Stereo Internal plugins, sorry!");
  1353. delete plugin;
  1354. return nullptr;
  1355. }
  1356. }
  1357. plugin->registerToOscClient();
  1358. return plugin;
  1359. }
  1360. #endif
  1361. // -----------------------------------------------------------------------
  1362. size_t CarlaPlugin::getNativePluginCount()
  1363. {
  1364. return NativePlugin::getPluginCount();
  1365. }
  1366. const PluginDescriptor* CarlaPlugin::getNativePluginDescriptor(const size_t index)
  1367. {
  1368. return NativePlugin::getPlugin(index);
  1369. }
  1370. // -----------------------------------------------------------------------
  1371. CARLA_BACKEND_END_NAMESPACE
  1372. void carla_register_native_plugin(const PluginDescriptor* desc)
  1373. {
  1374. CARLA_BACKEND_USE_NAMESPACE
  1375. NativePlugin::registerPlugin(desc);
  1376. }