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.

1720 lines
53KB

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