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.

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