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.

1733 lines
54KB

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