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.

1636 lines
51KB

  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 = h2 = 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 | PLUGIN_CAN_FORCE_STEREO);
  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. if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0) && mIns <= 1 && mOuts <= 1)
  566. m_hints |= PLUGIN_CAN_FORCE_STEREO;
  567. m_hints |= getPluginHintsFromNative(descriptor->hints);
  568. reloadPrograms(true);
  569. x_client->activate();
  570. qDebug("NativePlugin::reload() - end");
  571. }
  572. void reloadPrograms(const bool init)
  573. {
  574. qDebug("NativePlugin::reloadPrograms(%s)", bool2str(init));
  575. uint32_t i, oldCount = midiprog.count;
  576. // Delete old programs
  577. if (midiprog.count > 0)
  578. {
  579. for (i=0; i < midiprog.count; i++)
  580. {
  581. if (midiprog.data[i].name)
  582. free((void*)midiprog.data[i].name);
  583. }
  584. delete[] midiprog.data;
  585. }
  586. midiprog.count = 0;
  587. midiprog.data = nullptr;
  588. // Query new programs
  589. midiprog.count = descriptor->midiProgramCount;
  590. if (midiprog.count > 0)
  591. midiprog.data = new midi_program_t[midiprog.count];
  592. // Update data
  593. for (i=0; i < midiprog.count; i++)
  594. {
  595. const MidiProgram* const mpDesc = &descriptor->midiPrograms[i];
  596. Q_ASSERT(mpDesc->program < 128);
  597. Q_ASSERT(mpDesc->name);
  598. midiprog.data[i].bank = mpDesc->bank;
  599. midiprog.data[i].program = mpDesc->program;
  600. midiprog.data[i].name = strdup(mpDesc->name);
  601. }
  602. #ifndef BUILD_BRIDGE
  603. // Update OSC Names
  604. if (x_engine->isOscControllerRegisted())
  605. {
  606. x_engine->osc_send_control_set_midi_program_count(m_id, midiprog.count);
  607. for (i=0; i < midiprog.count; i++)
  608. x_engine->osc_send_control_set_midi_program_data(m_id, i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name);
  609. }
  610. #endif
  611. if (init)
  612. {
  613. if (midiprog.count > 0)
  614. setMidiProgram(0, false, false, false, true);
  615. }
  616. else
  617. {
  618. x_engine->callback(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0);
  619. // Check if current program is invalid
  620. bool programChanged = false;
  621. if (midiprog.count == oldCount+1)
  622. {
  623. // one midi program added, probably created by user
  624. midiprog.current = oldCount;
  625. programChanged = true;
  626. }
  627. else if (midiprog.current >= (int32_t)midiprog.count)
  628. {
  629. // current midi program > count
  630. midiprog.current = 0;
  631. programChanged = true;
  632. }
  633. else if (midiprog.current < 0 && midiprog.count > 0)
  634. {
  635. // programs exist now, but not before
  636. midiprog.current = 0;
  637. programChanged = true;
  638. }
  639. else if (midiprog.current >= 0 && midiprog.count == 0)
  640. {
  641. // programs existed before, but not anymore
  642. midiprog.current = -1;
  643. programChanged = true;
  644. }
  645. if (programChanged)
  646. setMidiProgram(midiprog.current, true, true, true, true);
  647. }
  648. }
  649. // -------------------------------------------------------------------
  650. // Plugin processing
  651. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset)
  652. {
  653. uint32_t i, k;
  654. double aInsPeak[2] = { 0.0 };
  655. double aOutsPeak[2] = { 0.0 };
  656. // reset MIDI
  657. midiEventCount = 0;
  658. memset(midiEvents, 0, sizeof(::MidiEvent) * MAX_MIDI_EVENTS * 2);
  659. CARLA_PROCESS_CONTINUE_CHECK;
  660. // --------------------------------------------------------------------------------------------------------
  661. // Input VU
  662. if (aIn.count > 0)
  663. {
  664. if (aIn.count == 1)
  665. {
  666. for (k=0; k < frames; k++)
  667. {
  668. if (abs(inBuffer[0][k]) > aInsPeak[0])
  669. aInsPeak[0] = abs(inBuffer[0][k]);
  670. }
  671. }
  672. else if (aIn.count > 1)
  673. {
  674. for (k=0; k < frames; k++)
  675. {
  676. if (abs(inBuffer[0][k]) > aInsPeak[0])
  677. aInsPeak[0] = abs(inBuffer[0][k]);
  678. if (abs(inBuffer[1][k]) > aInsPeak[1])
  679. aInsPeak[1] = abs(inBuffer[1][k]);
  680. }
  681. }
  682. }
  683. CARLA_PROCESS_CONTINUE_CHECK;
  684. // --------------------------------------------------------------------------------------------------------
  685. // Parameters Input [Automation]
  686. if (param.portCin && m_active && m_activeBefore)
  687. {
  688. bool allNotesOffSent = false;
  689. const CarlaEngineControlEvent* cinEvent;
  690. uint32_t time, nEvents = param.portCin->getEventCount();
  691. uint32_t nextBankId = 0;
  692. if (midiprog.current >= 0 && midiprog.count > 0)
  693. nextBankId = midiprog.data[midiprog.current].bank;
  694. for (i=0; i < nEvents; i++)
  695. {
  696. cinEvent = param.portCin->getEvent(i);
  697. if (! cinEvent)
  698. continue;
  699. time = cinEvent->time - framesOffset;
  700. if (time >= frames)
  701. continue;
  702. // Control change
  703. switch (cinEvent->type)
  704. {
  705. case CarlaEngineEventNull:
  706. break;
  707. case CarlaEngineEventControlChange:
  708. {
  709. double value;
  710. // Control backend stuff
  711. if (cinEvent->channel == m_ctrlInChannel)
  712. {
  713. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(cinEvent->controller) && (m_hints & PLUGIN_CAN_DRYWET) > 0)
  714. {
  715. value = cinEvent->value;
  716. setDryWet(value, false, false);
  717. postponeEvent(PluginPostEventParameterChange, PARAMETER_DRYWET, 0, value);
  718. continue;
  719. }
  720. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(cinEvent->controller) && (m_hints & PLUGIN_CAN_VOLUME) > 0)
  721. {
  722. value = cinEvent->value*127/100;
  723. setVolume(value, false, false);
  724. postponeEvent(PluginPostEventParameterChange, PARAMETER_VOLUME, 0, value);
  725. continue;
  726. }
  727. if (MIDI_IS_CONTROL_BALANCE(cinEvent->controller) && (m_hints & PLUGIN_CAN_BALANCE) > 0)
  728. {
  729. double left, right;
  730. value = cinEvent->value/0.5 - 1.0;
  731. if (value < 0.0)
  732. {
  733. left = -1.0;
  734. right = (value*2)+1.0;
  735. }
  736. else if (value > 0.0)
  737. {
  738. left = (value*2)-1.0;
  739. right = 1.0;
  740. }
  741. else
  742. {
  743. left = -1.0;
  744. right = 1.0;
  745. }
  746. setBalanceLeft(left, false, false);
  747. setBalanceRight(right, false, false);
  748. postponeEvent(PluginPostEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  749. postponeEvent(PluginPostEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  750. continue;
  751. }
  752. }
  753. // Control plugin parameters
  754. for (k=0; k < param.count; k++)
  755. {
  756. if (param.data[k].midiChannel != cinEvent->channel)
  757. continue;
  758. if (param.data[k].midiCC != cinEvent->controller)
  759. continue;
  760. if (param.data[k].type != PARAMETER_INPUT)
  761. continue;
  762. if (param.data[k].hints & PARAMETER_IS_AUTOMABLE)
  763. {
  764. if (param.data[k].hints & PARAMETER_IS_BOOLEAN)
  765. {
  766. value = cinEvent->value < 0.5 ? param.ranges[k].min : param.ranges[k].max;
  767. }
  768. else
  769. {
  770. value = cinEvent->value * (param.ranges[k].max - param.ranges[k].min) + param.ranges[k].min;
  771. if (param.data[k].hints & PARAMETER_IS_INTEGER)
  772. value = rint(value);
  773. }
  774. setParameterValue(k, value, false, false, false);
  775. postponeEvent(PluginPostEventParameterChange, k, 0, value);
  776. }
  777. }
  778. break;
  779. }
  780. case CarlaEngineEventMidiBankChange:
  781. if (cinEvent->channel == m_ctrlInChannel)
  782. nextBankId = rint(cinEvent->value);
  783. break;
  784. case CarlaEngineEventMidiProgramChange:
  785. if (cinEvent->channel == m_ctrlInChannel)
  786. {
  787. uint32_t nextProgramId = rint(cinEvent->value);
  788. for (k=0; k < midiprog.count; k++)
  789. {
  790. if (midiprog.data[k].bank == nextBankId && midiprog.data[k].program == nextProgramId)
  791. {
  792. setMidiProgram(k, false, false, false, false);
  793. postponeEvent(PluginPostEventMidiProgramChange, k, 0, 0.0);
  794. break;
  795. }
  796. }
  797. }
  798. break;
  799. case CarlaEngineEventAllSoundOff:
  800. if (cinEvent->channel == m_ctrlInChannel)
  801. {
  802. if (mIn.count > 0 && ! allNotesOffSent)
  803. sendMidiAllNotesOff();
  804. if (descriptor->deactivate)
  805. {
  806. descriptor->deactivate(handle);
  807. //if (h2) ldescriptor->deactivate(h2);
  808. }
  809. if (descriptor->activate)
  810. {
  811. descriptor->activate(handle);
  812. //if (h2) ldescriptor->activate(h2);
  813. }
  814. allNotesOffSent = true;
  815. }
  816. break;
  817. case CarlaEngineEventAllNotesOff:
  818. if (cinEvent->channel == m_ctrlInChannel)
  819. {
  820. if (mIn.count > 0 && ! allNotesOffSent)
  821. sendMidiAllNotesOff();
  822. allNotesOffSent = true;
  823. }
  824. break;
  825. }
  826. }
  827. } // End of Parameters Input
  828. CARLA_PROCESS_CONTINUE_CHECK;
  829. // --------------------------------------------------------------------------------------------------------
  830. // MIDI Input
  831. if (mIn.count > 0 && m_active && m_activeBefore)
  832. {
  833. // ----------------------------------------------------------------------------------------------------
  834. // MIDI Input (External)
  835. {
  836. engineMidiLock();
  837. for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++)
  838. {
  839. if (extMidiNotes[i].channel < 0)
  840. break;
  841. ::MidiEvent* const midiEvent = &midiEvents[midiEventCount];
  842. memset(midiEvent, 0, sizeof(::MidiEvent));
  843. midiEvent->data[0] = uint8_t(extMidiNotes[i].velo ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) + extMidiNotes[i].channel;
  844. midiEvent->data[1] = extMidiNotes[i].note;
  845. midiEvent->data[2] = extMidiNotes[i].velo;
  846. midiEvent->size = 3;
  847. extMidiNotes[i].channel = -1; // mark as invalid
  848. midiEventCount += 1;
  849. }
  850. engineMidiUnlock();
  851. } // End of MIDI Input (External)
  852. CARLA_PROCESS_CONTINUE_CHECK;
  853. // ----------------------------------------------------------------------------------------------------
  854. // MIDI Input (System)
  855. for (i=0; i < mIn.count; i++)
  856. {
  857. if (! mIn.ports[i])
  858. continue;
  859. const CarlaEngineMidiEvent* minEvent;
  860. uint32_t time, nEvents = mIn.ports[i]->getEventCount();
  861. for (k=0; k < nEvents && midiEventCount < MAX_MIDI_EVENTS; k++)
  862. {
  863. minEvent = mIn.ports[i]->getEvent(k);
  864. if (! minEvent)
  865. continue;
  866. time = minEvent->time - framesOffset;
  867. if (time >= frames)
  868. continue;
  869. uint8_t status = minEvent->data[0];
  870. uint8_t channel = status & 0x0F;
  871. // Fix bad note-off
  872. if (MIDI_IS_STATUS_NOTE_ON(status) && minEvent->data[2] == 0)
  873. status -= 0x10;
  874. ::MidiEvent* const midiEvent = &midiEvents[midiEventCount];
  875. memset(midiEvent, 0, sizeof(::MidiEvent));
  876. midiEvent->portOffset = i;
  877. midiEvent->time = minEvent->time;
  878. midiEvent->size = minEvent->size;
  879. if (MIDI_IS_STATUS_NOTE_OFF(status))
  880. {
  881. uint8_t note = minEvent->data[1];
  882. midiEvent->data[0] = status;
  883. midiEvent->data[1] = note;
  884. postponeEvent(PluginPostEventNoteOff, channel, note, 0.0);
  885. }
  886. else if (MIDI_IS_STATUS_NOTE_ON(status))
  887. {
  888. uint8_t note = minEvent->data[1];
  889. uint8_t velo = minEvent->data[2];
  890. midiEvent->data[0] = status;
  891. midiEvent->data[1] = note;
  892. midiEvent->data[2] = velo;
  893. postponeEvent(PluginPostEventNoteOn, channel, note, velo);
  894. }
  895. else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status))
  896. {
  897. uint8_t note = minEvent->data[1];
  898. uint8_t pressure = minEvent->data[2];
  899. midiEvent->data[0] = status;
  900. midiEvent->data[1] = note;
  901. midiEvent->data[2] = pressure;
  902. }
  903. else if (MIDI_IS_STATUS_AFTERTOUCH(status))
  904. {
  905. uint8_t pressure = minEvent->data[1];
  906. midiEvent->data[0] = status;
  907. midiEvent->data[1] = pressure;
  908. }
  909. else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status))
  910. {
  911. uint8_t lsb = minEvent->data[1];
  912. uint8_t msb = minEvent->data[2];
  913. midiEvent->data[0] = status;
  914. midiEvent->data[1] = lsb;
  915. midiEvent->data[2] = msb;
  916. }
  917. else
  918. continue;
  919. midiEventCount += 1;
  920. }
  921. } // End of MIDI Input (System)
  922. } // End of MIDI Input
  923. CARLA_PROCESS_CONTINUE_CHECK;
  924. // --------------------------------------------------------------------------------------------------------
  925. // Plugin processing
  926. uint32_t midiEventCountBefore = midiEventCount;
  927. if (m_active)
  928. {
  929. if (! m_activeBefore)
  930. {
  931. if (mIn.count > 0 && m_ctrlInChannel >= 0 && m_ctrlInChannel < 16)
  932. {
  933. memset(&midiEvents[0], 0, sizeof(::MidiEvent));
  934. midiEvents[0].data[0] = MIDI_STATUS_CONTROL_CHANGE + m_ctrlInChannel;
  935. midiEvents[0].data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  936. midiEvents[0].size = 2;
  937. memset(&midiEvents[1], 0, sizeof(::MidiEvent));
  938. midiEvents[1].data[0] = MIDI_STATUS_CONTROL_CHANGE + m_ctrlInChannel;
  939. midiEvents[1].data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  940. midiEvents[1].size = 2;
  941. midiEventCount = 2;
  942. }
  943. if (descriptor->activate)
  944. {
  945. descriptor->activate(handle);
  946. //if (h2) descriptor->activate(h2);
  947. }
  948. }
  949. isProcessing = true;
  950. descriptor->process(handle, inBuffer, outBuffer, frames, midiEventCountBefore, midiEvents);
  951. //if (h2) descriptor->process(h2, inBuffer, outBuffer, frames, midiEventCount, midiEvents);
  952. isProcessing = false;
  953. }
  954. else
  955. {
  956. if (m_activeBefore)
  957. {
  958. if (descriptor->deactivate)
  959. {
  960. descriptor->deactivate(handle);
  961. //if (h2) descriptor->deactivate(h2);
  962. }
  963. }
  964. }
  965. CARLA_PROCESS_CONTINUE_CHECK;
  966. // --------------------------------------------------------------------------------------------------------
  967. // Post-processing (dry/wet, volume and balance)
  968. if (m_active)
  969. {
  970. bool do_drywet = (m_hints & PLUGIN_CAN_DRYWET) > 0 && x_dryWet != 1.0;
  971. bool do_volume = (m_hints & PLUGIN_CAN_VOLUME) > 0 && x_volume != 1.0;
  972. bool do_balance = (m_hints & PLUGIN_CAN_BALANCE) > 0 && (x_balanceLeft != -1.0 || x_balanceRight != 1.0);
  973. double bal_rangeL, bal_rangeR;
  974. float oldBufLeft[do_balance ? frames : 0];
  975. for (i=0; i < aOut.count; i++)
  976. {
  977. // Dry/Wet
  978. if (do_drywet)
  979. {
  980. for (k=0; k < frames; k++)
  981. {
  982. if (aOut.count == 1)
  983. outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[0][k]*(1.0-x_dryWet));
  984. else
  985. outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(inBuffer[i][k]*(1.0-x_dryWet));
  986. }
  987. }
  988. // Balance
  989. if (do_balance)
  990. {
  991. if (i%2 == 0)
  992. memcpy(&oldBufLeft, outBuffer[i], sizeof(float)*frames);
  993. bal_rangeL = (x_balanceLeft+1.0)/2;
  994. bal_rangeR = (x_balanceRight+1.0)/2;
  995. for (k=0; k < frames; k++)
  996. {
  997. if (i%2 == 0)
  998. {
  999. // left output
  1000. outBuffer[i][k] = oldBufLeft[k]*(1.0-bal_rangeL);
  1001. outBuffer[i][k] += outBuffer[i+1][k]*(1.0-bal_rangeR);
  1002. }
  1003. else
  1004. {
  1005. // right
  1006. outBuffer[i][k] = outBuffer[i][k]*bal_rangeR;
  1007. outBuffer[i][k] += oldBufLeft[k]*bal_rangeL;
  1008. }
  1009. }
  1010. }
  1011. // Volume
  1012. if (do_volume)
  1013. {
  1014. for (k=0; k < frames; k++)
  1015. outBuffer[i][k] *= x_volume;
  1016. }
  1017. // Output VU
  1018. for (k=0; i < 2 && k < frames; k++)
  1019. {
  1020. if (abs(outBuffer[i][k]) > aOutsPeak[i])
  1021. aOutsPeak[i] = abs(outBuffer[i][k]);
  1022. }
  1023. }
  1024. }
  1025. else
  1026. {
  1027. // disable any output sound if not active
  1028. for (i=0; i < aOut.count; i++)
  1029. memset(outBuffer[i], 0.0f, sizeof(float)*frames);
  1030. aOutsPeak[0] = 0.0;
  1031. aOutsPeak[1] = 0.0;
  1032. } // End of Post-processing
  1033. CARLA_PROCESS_CONTINUE_CHECK;
  1034. // --------------------------------------------------------------------------------------------------------
  1035. // MIDI Output
  1036. if (mOut.count > 0 && m_active)
  1037. {
  1038. uint8_t data[3] = { 0 };
  1039. for (uint32_t i = midiEventCountBefore; i < midiEventCount; i++)
  1040. {
  1041. data[0] = midiEvents[i].data[0];
  1042. data[1] = midiEvents[i].data[1];
  1043. data[2] = midiEvents[i].data[2];
  1044. // Fix bad note-off
  1045. if (MIDI_IS_STATUS_NOTE_ON(data[0]) && data[2] == 0)
  1046. data[0] -= 0x10;
  1047. const uint32_t portOffset = midiEvents[i].portOffset;
  1048. if (portOffset < mOut.count)
  1049. mOut.ports[portOffset]->writeEvent(midiEvents[i].time, data, 3);
  1050. }
  1051. } // End of MIDI Output
  1052. // --------------------------------------------------------------------------------------------------------
  1053. // Control Output
  1054. if (param.portCout && m_active)
  1055. {
  1056. double value, valueControl;
  1057. for (k=0; k < param.count; k++)
  1058. {
  1059. if (param.data[k].type == PARAMETER_OUTPUT)
  1060. {
  1061. value = descriptor->get_parameter_value(handle, param.data[k].rindex);
  1062. if (param.data[k].midiCC > 0)
  1063. {
  1064. valueControl = (value - param.ranges[k].min) / (param.ranges[k].max - param.ranges[k].min);
  1065. param.portCout->writeEvent(CarlaEngineEventControlChange, framesOffset, param.data[k].midiChannel, param.data[k].midiCC, valueControl);
  1066. }
  1067. }
  1068. }
  1069. } // End of Control Output
  1070. CARLA_PROCESS_CONTINUE_CHECK;
  1071. // --------------------------------------------------------------------------------------------------------
  1072. // Peak Values
  1073. x_engine->setInputPeak(m_id, 0, aInsPeak[0]);
  1074. x_engine->setInputPeak(m_id, 1, aInsPeak[1]);
  1075. x_engine->setOutputPeak(m_id, 0, aOutsPeak[0]);
  1076. x_engine->setOutputPeak(m_id, 1, aOutsPeak[1]);
  1077. m_activeBefore = m_active;
  1078. }
  1079. // -------------------------------------------------------------------
  1080. // Cleanup
  1081. void removeClientPorts()
  1082. {
  1083. qDebug("NativePlugin::removeClientPorts() - start");
  1084. for (uint32_t i=0; i < mIn.count; i++)
  1085. {
  1086. delete mIn.ports[i];
  1087. mIn.ports[i] = nullptr;
  1088. }
  1089. for (uint32_t i=0; i < mOut.count; i++)
  1090. {
  1091. delete mOut.ports[i];
  1092. mOut.ports[i] = nullptr;
  1093. }
  1094. CarlaPlugin::removeClientPorts();
  1095. qDebug("NativePlugin::removeClientPorts() - end");
  1096. }
  1097. void initBuffers()
  1098. {
  1099. uint32_t i;
  1100. for (i=0; i < mIn.count; i++)
  1101. {
  1102. if (mIn.ports[i])
  1103. mIn.ports[i]->initBuffer(x_engine);
  1104. }
  1105. for (i=0; i < mOut.count; i++)
  1106. {
  1107. if (mOut.ports[i])
  1108. mOut.ports[i]->initBuffer(x_engine);
  1109. }
  1110. CarlaPlugin::initBuffers();
  1111. }
  1112. void deleteBuffers()
  1113. {
  1114. qDebug("NativePlugin::deleteBuffers() - start");
  1115. if (mIn.count > 0)
  1116. {
  1117. delete[] mIn.ports;
  1118. delete[] mIn.rindexes;
  1119. }
  1120. if (mOut.count > 0)
  1121. {
  1122. delete[] mOut.ports;
  1123. delete[] mOut.rindexes;
  1124. }
  1125. mIn.count = 0;
  1126. mIn.ports = nullptr;
  1127. mIn.rindexes = nullptr;
  1128. mOut.count = 0;
  1129. mOut.ports = nullptr;
  1130. mOut.rindexes = nullptr;
  1131. CarlaPlugin::deleteBuffers();
  1132. qDebug("NativePlugin::deleteBuffers() - end");
  1133. }
  1134. // -------------------------------------------------------------------
  1135. uint32_t handleGetBufferSize()
  1136. {
  1137. return x_engine->getBufferSize();
  1138. }
  1139. double handleGetSampleRate()
  1140. {
  1141. return x_engine->getSampleRate();
  1142. }
  1143. const TimeInfo* handleGetTimeInfo()
  1144. {
  1145. // TODO
  1146. return nullptr;
  1147. }
  1148. bool handleWriteMidiEvent(MidiEvent* event)
  1149. {
  1150. Q_ASSERT(m_enabled);
  1151. Q_ASSERT(mOut.count > 0);
  1152. Q_ASSERT(isProcessing);
  1153. Q_ASSERT(event);
  1154. if (! m_enabled)
  1155. return false;
  1156. if (mOut.count == 0)
  1157. return false;
  1158. if (! isProcessing)
  1159. {
  1160. qCritical("NativePlugin::handleWriteMidiEvent(%p) - received MIDI out events outside audio thread, ignoring", event);
  1161. return false;
  1162. }
  1163. if (midiEventCount >= MAX_MIDI_EVENTS*2)
  1164. return false;
  1165. memcpy(&midiEvents[midiEventCount], event, sizeof(::MidiEvent));
  1166. midiEventCount += 1;
  1167. return true;
  1168. }
  1169. static uint32_t carla_host_get_buffer_size(HostHandle handle)
  1170. {
  1171. Q_ASSERT(handle);
  1172. return ((NativePlugin*)handle)->handleGetBufferSize();
  1173. }
  1174. static double carla_host_get_sample_rate(HostHandle handle)
  1175. {
  1176. Q_ASSERT(handle);
  1177. return ((NativePlugin*)handle)->handleGetSampleRate();
  1178. }
  1179. static const TimeInfo* carla_host_get_time_info(HostHandle handle)
  1180. {
  1181. Q_ASSERT(handle);
  1182. return ((NativePlugin*)handle)->handleGetTimeInfo();
  1183. }
  1184. static bool carla_host_write_midi_event(HostHandle handle, MidiEvent* event)
  1185. {
  1186. Q_ASSERT(handle);
  1187. return ((NativePlugin*)handle)->handleWriteMidiEvent(event);
  1188. }
  1189. // -------------------------------------------------------------------
  1190. static size_t getPluginCount()
  1191. {
  1192. return pluginDescriptors.size();
  1193. }
  1194. static const PluginDescriptor* getPlugin(size_t index)
  1195. {
  1196. Q_ASSERT(index < pluginDescriptors.size());
  1197. if (index < pluginDescriptors.size())
  1198. return pluginDescriptors[index];
  1199. return nullptr;
  1200. }
  1201. static void registerPlugin(const PluginDescriptor* desc)
  1202. {
  1203. pluginDescriptors.push_back(desc);
  1204. }
  1205. // -------------------------------------------------------------------
  1206. bool init(const char* const name, const char* const label)
  1207. {
  1208. // ---------------------------------------------------------------
  1209. // get descriptor that matches label
  1210. for (size_t i=0; i < pluginDescriptors.size(); i++)
  1211. {
  1212. descriptor = pluginDescriptors[i];
  1213. if (! descriptor)
  1214. break;
  1215. if (strcmp(descriptor->label, label) == 0)
  1216. break;
  1217. descriptor = nullptr;
  1218. }
  1219. if (! descriptor)
  1220. {
  1221. setLastError("Invalid internal plugin");
  1222. return false;
  1223. }
  1224. scopedInitliazer.initializeIfNeeded(descriptor);
  1225. // ---------------------------------------------------------------
  1226. // initialize plugin
  1227. handle = descriptor->instantiate((struct _PluginDescriptor*)descriptor, &host);
  1228. if (! handle)
  1229. {
  1230. setLastError("Plugin failed to initialize");
  1231. return false;
  1232. }
  1233. // ---------------------------------------------------------------
  1234. // get info
  1235. if (name)
  1236. m_name = x_engine->getUniqueName(name);
  1237. else
  1238. m_name = x_engine->getUniqueName(descriptor->name);
  1239. // ---------------------------------------------------------------
  1240. // register client
  1241. x_client = x_engine->addClient(this);
  1242. if (! x_client->isOk())
  1243. {
  1244. setLastError("Failed to register plugin client");
  1245. return false;
  1246. }
  1247. return true;
  1248. }
  1249. private:
  1250. const PluginDescriptor* descriptor;
  1251. PluginHandle handle, h2;
  1252. HostDescriptor host;
  1253. bool isProcessing;
  1254. NativePluginMidiData mIn;
  1255. NativePluginMidiData mOut;
  1256. uint32_t midiEventCount;
  1257. ::MidiEvent midiEvents[MAX_MIDI_EVENTS*2];
  1258. static std::vector<const PluginDescriptor*> pluginDescriptors;
  1259. };
  1260. std::vector<const PluginDescriptor*> NativePlugin::pluginDescriptors;
  1261. CarlaPlugin* CarlaPlugin::newNative(const initializer& init)
  1262. {
  1263. qDebug("CarlaPlugin::newNative(%p, \"%s\", \"%s\", \"%s\")", init.engine, init.filename, init.name, init.label);
  1264. short id = init.engine->getNewPluginId();
  1265. if (id < 0 || id > CarlaEngine::maxPluginNumber())
  1266. {
  1267. setLastError("Maximum number of plugins reached");
  1268. return nullptr;
  1269. }
  1270. NativePlugin* const plugin = new NativePlugin(init.engine, id);
  1271. if (! plugin->init(init.name, init.label))
  1272. {
  1273. delete plugin;
  1274. return nullptr;
  1275. }
  1276. plugin->reload();
  1277. if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK)
  1278. {
  1279. if (! plugin->hints() & PLUGIN_CAN_FORCE_STEREO)
  1280. {
  1281. setLastError("Carla's rack mode can only work with Mono or Stereo Internal plugins, sorry!");
  1282. delete plugin;
  1283. return nullptr;
  1284. }
  1285. }
  1286. plugin->registerToOsc();
  1287. return plugin;
  1288. }
  1289. size_t CarlaPlugin::getNativePluginCount()
  1290. {
  1291. return NativePlugin::getPluginCount();
  1292. }
  1293. const PluginDescriptor* CarlaPlugin::getNativePlugin(size_t index)
  1294. {
  1295. return NativePlugin::getPlugin(index);
  1296. }
  1297. CARLA_BACKEND_END_NAMESPACE
  1298. void carla_register_native_plugin(const PluginDescriptor* desc)
  1299. {
  1300. CarlaBackend::NativePlugin::registerPlugin(desc);
  1301. }