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.

1719 lines
54KB

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