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.

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