Audio plugin host https://kx.studio/carla
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.

1725 lines
55KB

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