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.

1622 lines
50KB

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