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.

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