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.

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