Collection of tools useful for audio production
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.

1722 lines
53KB

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