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.

CarlaPluginJuce.cpp 55KB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609
  1. /*
  2. * Carla Juce Plugin
  3. * Copyright (C) 2013-2020 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 doc/GPL.txt file.
  16. */
  17. #include "CarlaPluginInternal.hpp"
  18. #include "CarlaEngine.hpp"
  19. #ifdef USING_JUCE
  20. #include "CarlaBackendUtils.hpp"
  21. #include "CarlaMathUtils.hpp"
  22. #include "CarlaProcessUtils.hpp"
  23. #include "CarlaScopeUtils.hpp"
  24. #if defined(__clang__)
  25. # pragma clang diagnostic push
  26. # pragma clang diagnostic ignored "-Wfloat-equal"
  27. # pragma clang diagnostic ignored "-Wimplicit-int-float-conversion"
  28. #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  29. # pragma GCC diagnostic push
  30. # pragma GCC diagnostic ignored "-Wconversion"
  31. # pragma GCC diagnostic ignored "-Wdouble-promotion"
  32. # pragma GCC diagnostic ignored "-Weffc++"
  33. # pragma GCC diagnostic ignored "-Wfloat-equal"
  34. #endif
  35. #define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
  36. #include "AppConfig.h"
  37. #include "juce_audio_processors/juce_audio_processors.h"
  38. #include "juce_gui_basics/juce_gui_basics.h"
  39. #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
  40. # pragma GCC diagnostic pop
  41. #endif
  42. #include "JucePluginWindow.hpp"
  43. CARLA_BACKEND_START_NAMESPACE
  44. // -------------------------------------------------------------------------------------------------------------------
  45. // Fallback data
  46. static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 };
  47. // -------------------------------------------------------------------------------------------------------------------
  48. // find all available plugin audio ports
  49. static void findMaxTotalChannels(juce::AudioProcessor* const filter,
  50. const bool isAU, uint32_t& maxTotalIns, uint32_t& maxTotalOuts)
  51. {
  52. filter->enableAllBuses();
  53. if (isAU)
  54. {
  55. maxTotalIns = static_cast<uint32_t>(juce::jmax(0, filter->getTotalNumInputChannels()));
  56. maxTotalOuts = static_cast<uint32_t>(juce::jmax(0, filter->getTotalNumOutputChannels()));
  57. return;
  58. }
  59. const int numInputBuses = filter->getBusCount(true);
  60. const int numOutputBuses = filter->getBusCount(false);
  61. if (numInputBuses > 1 || numOutputBuses > 1)
  62. {
  63. maxTotalIns = maxTotalOuts = 0;
  64. for (int i = 0; i < numInputBuses; ++i)
  65. maxTotalIns += static_cast<uint32_t>(juce::jmax(0, filter->getChannelCountOfBus(true, i)));
  66. for (int i = 0; i < numOutputBuses; ++i)
  67. maxTotalOuts += static_cast<uint32_t>(juce::jmax(0, filter->getChannelCountOfBus(false, i)));
  68. }
  69. else
  70. {
  71. maxTotalIns = numInputBuses > 0
  72. ? static_cast<uint32_t>(juce::jmax(0, filter->getBus(true, 0)->getMaxSupportedChannels(64)))
  73. : 0;
  74. maxTotalOuts = numOutputBuses > 0
  75. ? static_cast<uint32_t>(juce::jmax(0, filter->getBus(false, 0)->getMaxSupportedChannels(64)))
  76. : 0;
  77. }
  78. }
  79. // -------------------------------------------------------------------------------------------------------------------
  80. class CarlaPluginJuce : public CarlaPlugin,
  81. private juce::AudioPlayHead,
  82. private juce::AudioProcessorListener
  83. {
  84. public:
  85. CarlaPluginJuce(CarlaEngine* const engine, const uint id)
  86. : CarlaPlugin(engine, id),
  87. fDesc(),
  88. fFormatManager(),
  89. fInstance(),
  90. fAudioBuffer(),
  91. fMidiBuffer(),
  92. fPosInfo(),
  93. fChunk(),
  94. fFormatName(),
  95. fWindow()
  96. {
  97. carla_debug("CarlaPluginJuce::CarlaPluginJuce(%p, %i)", engine, id);
  98. fMidiBuffer.ensureSize(2048);
  99. fMidiBuffer.clear();
  100. fPosInfo.resetToDefault();
  101. }
  102. ~CarlaPluginJuce() override
  103. {
  104. carla_debug("CarlaPluginJuce::~CarlaPluginJuce()");
  105. // close UI
  106. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  107. showCustomUI(false);
  108. pData->singleMutex.lock();
  109. pData->masterMutex.lock();
  110. if (pData->client != nullptr && pData->client->isActive())
  111. pData->client->deactivate(true);
  112. if (pData->active)
  113. {
  114. deactivate();
  115. pData->active = false;
  116. }
  117. fInstance = nullptr;
  118. clearBuffers();
  119. }
  120. // -------------------------------------------------------------------
  121. // Information (base)
  122. PluginType getType() const noexcept override
  123. {
  124. return getPluginTypeFromString(fDesc.pluginFormatName.toRawUTF8());
  125. }
  126. PluginCategory getCategory() const noexcept override
  127. {
  128. if (fDesc.isInstrument)
  129. return PLUGIN_CATEGORY_SYNTH;
  130. return getPluginCategoryFromName(fDesc.category.isNotEmpty()
  131. ? fDesc.category.toRawUTF8()
  132. : fDesc.name.toRawUTF8());
  133. }
  134. int64_t getUniqueId() const noexcept override
  135. {
  136. return fDesc.uid;
  137. }
  138. // -------------------------------------------------------------------
  139. // Information (count)
  140. // nothing
  141. // -------------------------------------------------------------------
  142. // Information (current data)
  143. std::size_t getChunkData(void** const dataPtr) noexcept override
  144. {
  145. CARLA_SAFE_ASSERT_RETURN(pData->options & PLUGIN_OPTION_USE_CHUNKS, 0);
  146. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, 0);
  147. CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr, 0);
  148. *dataPtr = nullptr;
  149. try {
  150. fChunk.reset();
  151. fInstance->getStateInformation(fChunk);
  152. } CARLA_SAFE_EXCEPTION_RETURN("CarlaPluginJuce::getChunkData", 0);
  153. if (const std::size_t size = fChunk.getSize())
  154. {
  155. *dataPtr = fChunk.getData();
  156. return size;
  157. }
  158. return 0;
  159. }
  160. // -------------------------------------------------------------------
  161. // Information (per-plugin data)
  162. uint getOptionsAvailable() const noexcept override
  163. {
  164. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, 0x0);
  165. uint options = 0x0;
  166. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  167. options |= PLUGIN_OPTION_USE_CHUNKS;
  168. if (fInstance->getNumPrograms() > 1)
  169. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  170. if (fInstance->acceptsMidi())
  171. {
  172. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  173. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  174. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  175. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  176. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  177. options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES;
  178. options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
  179. }
  180. return options;
  181. }
  182. float getParameterValue(const uint32_t parameterId) const noexcept override
  183. {
  184. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  185. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, 0.0f);
  186. return fInstance->getParameter(static_cast<int>(parameterId));
  187. }
  188. bool getLabel(char* const strBuf) const noexcept override
  189. {
  190. if (fDesc.pluginFormatName == "AU" || fDesc.pluginFormatName == "AudioUnit")
  191. std::strncpy(strBuf, fDesc.fileOrIdentifier.toRawUTF8(), STR_MAX);
  192. else
  193. std::strncpy(strBuf, fDesc.name.toRawUTF8(), STR_MAX);
  194. return true;
  195. }
  196. bool getMaker(char* const strBuf) const noexcept override
  197. {
  198. std::strncpy(strBuf, fDesc.manufacturerName.toRawUTF8(), STR_MAX);
  199. return true;
  200. }
  201. bool getCopyright(char* const strBuf) const noexcept override
  202. {
  203. return getMaker(strBuf);
  204. }
  205. bool getRealName(char* const strBuf) const noexcept override
  206. {
  207. std::strncpy(strBuf, fDesc.descriptiveName.toRawUTF8(), STR_MAX);
  208. return true;
  209. }
  210. bool getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
  211. {
  212. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  213. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, false);
  214. std::strncpy(strBuf, fInstance->getParameterName(static_cast<int>(parameterId), STR_MAX).toRawUTF8(), STR_MAX);
  215. return true;
  216. }
  217. bool getParameterText(const uint32_t parameterId, char* const strBuf) noexcept override
  218. {
  219. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  220. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, false);
  221. std::strncpy(strBuf, fInstance->getParameterText(static_cast<int>(parameterId), STR_MAX).toRawUTF8(), STR_MAX);
  222. return true;
  223. }
  224. bool getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
  225. {
  226. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  227. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, false);
  228. std::strncpy(strBuf, fInstance->getParameterLabel(static_cast<int>(parameterId)).toRawUTF8(), STR_MAX);
  229. return true;
  230. }
  231. // -------------------------------------------------------------------
  232. // Set data (state)
  233. // nothing
  234. // -------------------------------------------------------------------
  235. // Set data (internal stuff)
  236. void setName(const char* const newName) override
  237. {
  238. CarlaPlugin::setName(newName);
  239. if (fWindow == nullptr || pData->uiTitle.isNotEmpty())
  240. return;
  241. juce::String uiName(pData->name);
  242. uiName += " (GUI)";
  243. fWindow->setName(uiName);
  244. }
  245. // -------------------------------------------------------------------
  246. // Set data (plugin-specific stuff)
  247. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  248. {
  249. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  250. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  251. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  252. try {
  253. fInstance->setParameter(static_cast<int>(parameterId), value);
  254. } CARLA_SAFE_EXCEPTION("setParameter");
  255. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  256. }
  257. void setParameterValueRT(const uint32_t parameterId, const float value, const bool sendCallbackLater) noexcept override
  258. {
  259. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  260. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  261. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  262. try {
  263. fInstance->setParameter(static_cast<int>(parameterId), value);
  264. } CARLA_SAFE_EXCEPTION("setParameter(RT)");
  265. CarlaPlugin::setParameterValueRT(parameterId, fixedValue, sendCallbackLater);
  266. }
  267. void setChunkData(const void* const data, const std::size_t dataSize) override
  268. {
  269. CARLA_SAFE_ASSERT_RETURN(pData->options & PLUGIN_OPTION_USE_CHUNKS,);
  270. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  271. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  272. CARLA_SAFE_ASSERT_RETURN(dataSize > 0,);
  273. if (isJuceSaveFormat(data, dataSize))
  274. {
  275. const ScopedSingleProcessLocker spl(this, true);
  276. fInstance->setStateInformation(data, static_cast<int>(dataSize));
  277. }
  278. else
  279. {
  280. uint8_t* const dataCompat = (uint8_t*)std::malloc(dataSize + 160);
  281. CARLA_SAFE_ASSERT_RETURN(dataCompat != nullptr,);
  282. carla_stdout("NOTE: Loading plugin state in Carla JUCE/VST2 compatibility mode");
  283. std::memset(dataCompat, 0, 160);
  284. std::memcpy(dataCompat+160, data, dataSize);
  285. int32_t* const set = (int32_t*)dataCompat;
  286. set[0] = (int32_t)juce::ByteOrder::littleEndianInt("CcnK");
  287. set[2] = (int32_t)juce::ByteOrder::littleEndianInt("FBCh");
  288. set[3] = fxbSwap(1);
  289. set[39] = fxbSwap(static_cast<int32_t>(dataSize));
  290. {
  291. const ScopedSingleProcessLocker spl(this, true);
  292. fInstance->setStateInformation(dataCompat, static_cast<int>(dataSize+160));
  293. }
  294. std::free(dataCompat);
  295. }
  296. pData->updateParameterValues(this, true, true, false);
  297. }
  298. void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool doingInit) noexcept override
  299. {
  300. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  301. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);
  302. if (index >= 0)
  303. {
  304. const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
  305. try {
  306. fInstance->setCurrentProgram(index);
  307. } CARLA_SAFE_EXCEPTION("setCurrentProgram");
  308. }
  309. CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback, doingInit);
  310. }
  311. void setProgramRT(const uint32_t index, const bool sendCallbackLater) noexcept override
  312. {
  313. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  314. CARLA_SAFE_ASSERT_RETURN(index < pData->prog.count,);
  315. try {
  316. fInstance->setCurrentProgram(static_cast<int32_t>(index));
  317. } CARLA_SAFE_EXCEPTION("setCurrentProgram");
  318. CarlaPlugin::setProgramRT(index, sendCallbackLater);
  319. }
  320. // -------------------------------------------------------------------
  321. // Set ui stuff
  322. void setCustomUITitle(const char* const title) noexcept override
  323. {
  324. if (fWindow != nullptr)
  325. {
  326. try {
  327. fWindow->setName(title);
  328. } CARLA_SAFE_EXCEPTION("set custom ui title");
  329. }
  330. CarlaPlugin::setCustomUITitle(title);
  331. }
  332. void showCustomUI(const bool yesNo) override
  333. {
  334. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  335. carla_debug("CarlaPluginJuce::showCustomUI(%s)", bool2str(yesNo));
  336. if (yesNo)
  337. {
  338. if (juce::AudioProcessorEditor* const editor = fInstance->createEditorIfNeeded())
  339. {
  340. const EngineOptions& opts(pData->engine->getOptions());
  341. editor->setScaleFactor(opts.uiScale);
  342. if (fWindow == nullptr)
  343. {
  344. juce::String uiName;
  345. if (pData->uiTitle.isNotEmpty())
  346. {
  347. uiName = pData->uiTitle.buffer();
  348. }
  349. else
  350. {
  351. uiName = pData->name;
  352. uiName += " (GUI)";
  353. }
  354. fWindow = new JucePluginWindow(opts.frontendWinId);
  355. fWindow->setName(uiName);
  356. }
  357. fWindow->show(editor);
  358. fWindow->toFront(true);
  359. }
  360. }
  361. else
  362. {
  363. if (juce::AudioProcessorEditor* const editor = fInstance->getActiveEditor())
  364. delete editor;
  365. fWindow = nullptr;
  366. }
  367. }
  368. void uiIdle() override
  369. {
  370. if (fWindow != nullptr)
  371. {
  372. if (fWindow->wasClosedByUser())
  373. {
  374. showCustomUI(false);
  375. pData->engine->callback(true, true,
  376. ENGINE_CALLBACK_UI_STATE_CHANGED,
  377. pData->id,
  378. 0,
  379. 0, 0, 0.0f, nullptr);
  380. }
  381. }
  382. CarlaPlugin::uiIdle();
  383. }
  384. // -------------------------------------------------------------------
  385. // Plugin state
  386. void reload() override
  387. {
  388. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  389. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  390. carla_debug("CarlaPluginJuce::reload() - start");
  391. const EngineProcessMode processMode(pData->engine->getProccessMode());
  392. // Safely disable plugin for reload
  393. const ScopedDisabler sd(this);
  394. if (pData->active)
  395. deactivate();
  396. clearBuffers();
  397. uint32_t aIns, aOuts, mIns, mOuts, params;
  398. mIns = mOuts = 0;
  399. bool needsCtrlIn, needsCtrlOut;
  400. needsCtrlIn = needsCtrlOut = false;
  401. const bool isAU = fDesc.pluginFormatName == "AU" || fDesc.pluginFormatName == "AudioUnit";
  402. findMaxTotalChannels(fInstance.get(), isAU, aIns, aOuts);
  403. fInstance->refreshParameterList();
  404. params = static_cast<uint32_t>(std::max(fInstance->getNumParameters(), 0));
  405. if (fInstance->acceptsMidi())
  406. {
  407. mIns = 1;
  408. needsCtrlIn = true;
  409. }
  410. if (fInstance->producesMidi())
  411. {
  412. mOuts = 1;
  413. needsCtrlOut = true;
  414. }
  415. if (aIns > 0)
  416. {
  417. pData->audioIn.createNew(aIns);
  418. }
  419. if (aOuts > 0)
  420. {
  421. pData->audioOut.createNew(aOuts);
  422. needsCtrlIn = true;
  423. }
  424. if (params > 0)
  425. {
  426. pData->param.createNew(params, false);
  427. needsCtrlIn = true;
  428. }
  429. const uint portNameSize(pData->engine->getMaxPortNameSize());
  430. CarlaString portName;
  431. // Audio Ins
  432. for (uint32_t j=0; j < aIns; ++j)
  433. {
  434. portName.clear();
  435. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  436. {
  437. portName = pData->name;
  438. portName += ":";
  439. }
  440. if (aIns > 1)
  441. {
  442. portName += "input_";
  443. portName += CarlaString(j+1);
  444. }
  445. else
  446. portName += "input";
  447. portName.truncate(portNameSize);
  448. pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, j);
  449. pData->audioIn.ports[j].rindex = j;
  450. }
  451. // Audio Outs
  452. for (uint32_t j=0; j < aOuts; ++j)
  453. {
  454. portName.clear();
  455. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  456. {
  457. portName = pData->name;
  458. portName += ":";
  459. }
  460. if (aOuts > 1)
  461. {
  462. portName += "output_";
  463. portName += CarlaString(j+1);
  464. }
  465. else
  466. portName += "output";
  467. portName.truncate(portNameSize);
  468. pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, j);
  469. pData->audioOut.ports[j].rindex = j;
  470. }
  471. for (uint32_t j=0; j < params; ++j)
  472. {
  473. pData->param.data[j].type = PARAMETER_INPUT;
  474. pData->param.data[j].index = static_cast<int32_t>(j);
  475. pData->param.data[j].rindex = static_cast<int32_t>(j);
  476. float min, max, def, step, stepSmall, stepLarge;
  477. // TODO
  478. //const int numSteps(fInstance->getParameterNumSteps(static_cast<int>(j)));
  479. {
  480. min = 0.0f;
  481. max = 1.0f;
  482. step = 0.001f;
  483. stepSmall = 0.0001f;
  484. stepLarge = 0.1f;
  485. }
  486. pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  487. #ifndef BUILD_BRIDGE
  488. pData->param.data[j].hints |= PARAMETER_USES_CUSTOM_TEXT;
  489. #endif
  490. if (fInstance->isParameterAutomatable(static_cast<int>(j)))
  491. {
  492. pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
  493. if (fInstance->isMetaParameter(static_cast<int>(j)))
  494. pData->param.data[j].hints |= PARAMETER_CAN_BE_CV_CONTROLLED;
  495. }
  496. // FIXME?
  497. def = fInstance->getParameterDefaultValue(static_cast<int>(j));
  498. if (def < min)
  499. def = min;
  500. else if (def > max)
  501. def = max;
  502. pData->param.ranges[j].min = min;
  503. pData->param.ranges[j].max = max;
  504. pData->param.ranges[j].def = def;
  505. pData->param.ranges[j].step = step;
  506. pData->param.ranges[j].stepSmall = stepSmall;
  507. pData->param.ranges[j].stepLarge = stepLarge;
  508. }
  509. if (needsCtrlIn)
  510. {
  511. portName.clear();
  512. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  513. {
  514. portName = pData->name;
  515. portName += ":";
  516. }
  517. portName += "events-in";
  518. portName.truncate(portNameSize);
  519. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0);
  520. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  521. pData->event.cvSourcePorts = pData->client->createCVSourcePorts();
  522. #endif
  523. }
  524. if (needsCtrlOut)
  525. {
  526. portName.clear();
  527. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  528. {
  529. portName = pData->name;
  530. portName += ":";
  531. }
  532. portName += "events-out";
  533. portName.truncate(portNameSize);
  534. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, 0);
  535. }
  536. // plugin hints
  537. pData->hints = 0x0;
  538. pData->hints |= PLUGIN_NEEDS_FIXED_BUFFERS;
  539. if (fDesc.isInstrument)
  540. pData->hints |= PLUGIN_IS_SYNTH;
  541. if (fInstance->hasEditor())
  542. {
  543. pData->hints |= PLUGIN_HAS_CUSTOM_UI;
  544. pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD;
  545. }
  546. if (aOuts > 0 && (aIns == aOuts || aIns == 1))
  547. pData->hints |= PLUGIN_CAN_DRYWET;
  548. if (aOuts > 0)
  549. pData->hints |= PLUGIN_CAN_VOLUME;
  550. if (aOuts >= 2 && aOuts % 2 == 0)
  551. pData->hints |= PLUGIN_CAN_BALANCE;
  552. // extra plugin hints
  553. pData->extraHints = 0x0;
  554. if (mIns > 0)
  555. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  556. if (mOuts > 0)
  557. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
  558. fInstance->setPlayConfigDetails(static_cast<int>(aIns),
  559. static_cast<int>(aOuts),
  560. pData->engine->getSampleRate(),
  561. static_cast<int>(pData->engine->getBufferSize()));
  562. bufferSizeChanged(pData->engine->getBufferSize());
  563. reloadPrograms(true);
  564. if (pData->active)
  565. activate();
  566. carla_debug("CarlaPluginJuce::reload() - end");
  567. }
  568. void reloadPrograms(const bool doInit) override
  569. {
  570. carla_debug("CarlaPluginJuce::reloadPrograms(%s)", bool2str(doInit));
  571. const uint32_t oldCount = pData->prog.count;
  572. const int32_t current = pData->prog.current;
  573. // Delete old programs
  574. pData->prog.clear();
  575. // Query new programs
  576. const uint32_t newCount = (fInstance->getNumPrograms() > 0)
  577. ? static_cast<uint32_t>(fInstance->getNumPrograms())
  578. : 0;
  579. if (newCount > 0)
  580. {
  581. pData->prog.createNew(newCount);
  582. // Update names
  583. for (uint32_t i=0; i < newCount; ++i)
  584. pData->prog.names[i] = carla_strdup(fInstance->getProgramName(static_cast<int>(i)).toRawUTF8());
  585. }
  586. if (doInit)
  587. {
  588. if (newCount > 0)
  589. setProgram(0, false, false, false, true);
  590. }
  591. else
  592. {
  593. // Check if current program is invalid
  594. bool programChanged = false;
  595. if (newCount == oldCount+1)
  596. {
  597. // one program added, probably created by user
  598. pData->prog.current = static_cast<int32_t>(oldCount);
  599. programChanged = true;
  600. }
  601. else if (current < 0 && newCount > 0)
  602. {
  603. // programs exist now, but not before
  604. pData->prog.current = 0;
  605. programChanged = true;
  606. }
  607. else if (current >= 0 && newCount == 0)
  608. {
  609. // programs existed before, but not anymore
  610. pData->prog.current = -1;
  611. programChanged = true;
  612. }
  613. else if (current >= static_cast<int32_t>(newCount))
  614. {
  615. // current program > count
  616. pData->prog.current = 0;
  617. programChanged = true;
  618. }
  619. else
  620. {
  621. // no change
  622. pData->prog.current = current;
  623. }
  624. if (programChanged)
  625. {
  626. setProgram(pData->prog.current, true, true, true, false);
  627. }
  628. else
  629. {
  630. // Program was changed during update, re-set it
  631. if (pData->prog.current >= 0)
  632. fInstance->setCurrentProgram(pData->prog.current);
  633. }
  634. pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0, 0.0f, nullptr);
  635. }
  636. }
  637. // -------------------------------------------------------------------
  638. // Plugin processing
  639. void activate() noexcept override
  640. {
  641. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  642. try {
  643. fInstance->prepareToPlay(pData->engine->getSampleRate(), static_cast<int>(pData->engine->getBufferSize()));
  644. } catch(...) {}
  645. }
  646. void deactivate() noexcept override
  647. {
  648. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  649. try {
  650. fInstance->releaseResources();
  651. } catch(...) {}
  652. }
  653. void process(const float* const* const audioIn,
  654. float** const audioOut,
  655. const float* const* const cvIn,
  656. float**,
  657. const uint32_t frames) override
  658. {
  659. // --------------------------------------------------------------------------------------------------------
  660. // Check if active
  661. if (! pData->active)
  662. {
  663. // disable any output sound
  664. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  665. carla_zeroFloats(audioOut[i], frames);
  666. return;
  667. }
  668. // --------------------------------------------------------------------------------------------------------
  669. // Check if needs reset
  670. if (pData->needsReset)
  671. {
  672. fInstance->reset();
  673. pData->needsReset = false;
  674. }
  675. // --------------------------------------------------------------------------------------------------------
  676. // Event Input
  677. fMidiBuffer.clear();
  678. if (pData->event.portIn != nullptr)
  679. {
  680. // ----------------------------------------------------------------------------------------------------
  681. // MIDI Input (External)
  682. if (pData->extNotes.mutex.tryLock())
  683. {
  684. for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin2(); it.valid(); it.next())
  685. {
  686. const ExternalMidiNote& note(it.getValue(kExternalMidiNoteFallback));
  687. CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  688. uint8_t midiEvent[3];
  689. midiEvent[0] = uint8_t((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
  690. midiEvent[1] = note.note;
  691. midiEvent[2] = note.velo;
  692. fMidiBuffer.addEvent(midiEvent, 3, 0);
  693. }
  694. pData->extNotes.data.clear();
  695. pData->extNotes.mutex.unlock();
  696. } // End of MIDI Input (External)
  697. // ----------------------------------------------------------------------------------------------------
  698. // Event Input (System)
  699. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  700. bool allNotesOffSent = false;
  701. if (cvIn != nullptr && pData->event.cvSourcePorts != nullptr)
  702. pData->event.cvSourcePorts->initPortBuffers(cvIn, frames, false, pData->event.portIn);
  703. #endif
  704. for (uint32_t i=0, numEvents=pData->event.portIn->getEventCount(); i < numEvents; ++i)
  705. {
  706. EngineEvent& event(pData->event.portIn->getEvent(i));
  707. if (event.time >= frames)
  708. continue;
  709. switch (event.type)
  710. {
  711. case kEngineEventTypeNull:
  712. break;
  713. case kEngineEventTypeControl: {
  714. EngineControlEvent& ctrlEvent(event.ctrl);
  715. switch (ctrlEvent.type)
  716. {
  717. case kEngineControlEventTypeNull:
  718. break;
  719. case kEngineControlEventTypeParameter: {
  720. float value;
  721. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  722. // non-midi
  723. if (event.channel == kEngineEventNonMidiChannel)
  724. {
  725. const uint32_t k = ctrlEvent.param;
  726. CARLA_SAFE_ASSERT_CONTINUE(k < pData->param.count);
  727. ctrlEvent.handled = true;
  728. value = pData->param.getFinalUnnormalizedValue(k, ctrlEvent.normalizedValue);
  729. setParameterValueRT(k, value, true);
  730. continue;
  731. }
  732. // Control backend stuff
  733. if (event.channel == pData->ctrlChannel)
  734. {
  735. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
  736. {
  737. ctrlEvent.handled = true;
  738. value = ctrlEvent.normalizedValue;
  739. setDryWetRT(value, true);
  740. }
  741. else if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
  742. {
  743. ctrlEvent.handled = true;
  744. value = ctrlEvent.normalizedValue*127.0f/100.0f;
  745. setVolumeRT(value, true);
  746. }
  747. else if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
  748. {
  749. float left, right;
  750. value = ctrlEvent.normalizedValue/0.5f - 1.0f;
  751. if (value < 0.0f)
  752. {
  753. left = -1.0f;
  754. right = (value*2.0f)+1.0f;
  755. }
  756. else if (value > 0.0f)
  757. {
  758. left = (value*2.0f)-1.0f;
  759. right = 1.0f;
  760. }
  761. else
  762. {
  763. left = -1.0f;
  764. right = 1.0f;
  765. }
  766. ctrlEvent.handled = true;
  767. setBalanceLeftRT(left, true);
  768. setBalanceRightRT(right, true);
  769. }
  770. }
  771. #endif
  772. // Control plugin parameters
  773. uint32_t k;
  774. for (k=0; k < pData->param.count; ++k)
  775. {
  776. if (pData->param.data[k].midiChannel != event.channel)
  777. continue;
  778. if (pData->param.data[k].mappedControlIndex != ctrlEvent.param)
  779. continue;
  780. if (pData->param.data[k].type != PARAMETER_INPUT)
  781. continue;
  782. if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  783. continue;
  784. ctrlEvent.handled = true;
  785. value = pData->param.getFinalUnnormalizedValue(k, ctrlEvent.normalizedValue);
  786. setParameterValueRT(k, value, true);
  787. }
  788. if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param < MAX_MIDI_VALUE)
  789. {
  790. uint8_t midiData[3];
  791. midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  792. midiData[1] = uint8_t(ctrlEvent.param);
  793. midiData[2] = uint8_t(ctrlEvent.normalizedValue*127.0f);
  794. fMidiBuffer.addEvent(midiData, 3, static_cast<int>(event.time));
  795. }
  796. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  797. if (! ctrlEvent.handled)
  798. checkForMidiLearn(event);
  799. #endif
  800. break;
  801. } // case kEngineControlEventTypeParameter
  802. case kEngineControlEventTypeMidiBank:
  803. if ((pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) != 0)
  804. {
  805. uint8_t midiData[3];
  806. midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  807. midiData[1] = MIDI_CONTROL_BANK_SELECT;
  808. midiData[2] = 0;
  809. fMidiBuffer.addEvent(midiData, 3, static_cast<int>(event.time));
  810. midiData[1] = MIDI_CONTROL_BANK_SELECT__LSB;
  811. midiData[2] = uint8_t(ctrlEvent.normalizedValue*127.0f);
  812. fMidiBuffer.addEvent(midiData, 3, static_cast<int>(event.time));
  813. }
  814. break;
  815. case kEngineControlEventTypeMidiProgram:
  816. if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  817. {
  818. if (ctrlEvent.param < pData->prog.count)
  819. {
  820. setProgramRT(ctrlEvent.param, true);
  821. }
  822. }
  823. else if ((pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) != 0)
  824. {
  825. uint8_t midiData[3];
  826. midiData[0] = uint8_t(MIDI_STATUS_PROGRAM_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  827. midiData[1] = uint8_t(ctrlEvent.normalizedValue*127.0f);
  828. fMidiBuffer.addEvent(midiData, 2, static_cast<int>(event.time));
  829. }
  830. break;
  831. case kEngineControlEventTypeAllSoundOff:
  832. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  833. {
  834. uint8_t midiData[3];
  835. midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  836. midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  837. midiData[2] = 0;
  838. fMidiBuffer.addEvent(midiData, 3, static_cast<int>(event.time));
  839. }
  840. break;
  841. case kEngineControlEventTypeAllNotesOff:
  842. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  843. {
  844. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  845. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  846. {
  847. allNotesOffSent = true;
  848. postponeRtAllNotesOff();
  849. }
  850. #endif
  851. uint8_t midiData[3];
  852. midiData[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  853. midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  854. midiData[2] = 0;
  855. fMidiBuffer.addEvent(midiData, 3, static_cast<int>(event.time));
  856. }
  857. break;
  858. } // switch (ctrlEvent.type)
  859. break;
  860. } // case kEngineEventTypeControl
  861. case kEngineEventTypeMidi: {
  862. const EngineMidiEvent& midiEvent(event.midi);
  863. const uint8_t* const midiData(midiEvent.size > EngineMidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data);
  864. uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiData));
  865. if ((status == MIDI_STATUS_NOTE_OFF || status == MIDI_STATUS_NOTE_ON) && (pData->options & PLUGIN_OPTION_SKIP_SENDING_NOTES))
  866. continue;
  867. if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  868. continue;
  869. if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  870. continue;
  871. if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  872. continue;
  873. if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  874. continue;
  875. // Fix bad note-off
  876. if (status == MIDI_STATUS_NOTE_ON && midiData[2] == 0)
  877. status = MIDI_STATUS_NOTE_OFF;
  878. // put back channel in data
  879. uint8_t midiData2[midiEvent.size];
  880. midiData2[0] = uint8_t(status | (event.channel & MIDI_CHANNEL_BIT));
  881. std::memcpy(midiData2+1, midiData+1, static_cast<std::size_t>(midiEvent.size-1));
  882. fMidiBuffer.addEvent(midiData2, midiEvent.size, static_cast<int>(event.time));
  883. if (status == MIDI_STATUS_NOTE_ON)
  884. {
  885. pData->postponeNoteOnRtEvent(true, event.channel, midiData[1], midiData[2]);
  886. }
  887. else if (status == MIDI_STATUS_NOTE_OFF)
  888. {
  889. pData->postponeNoteOffRtEvent(true, event.channel, midiData[1]);
  890. }
  891. } break;
  892. } // switch (event.type)
  893. }
  894. pData->postRtEvents.trySplice();
  895. } // End of Event Input
  896. // --------------------------------------------------------------------------------------------------------
  897. // Set TimeInfo
  898. const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
  899. fPosInfo.isPlaying = timeInfo.playing;
  900. if (timeInfo.bbt.valid)
  901. {
  902. CARLA_SAFE_ASSERT_INT(timeInfo.bbt.bar > 0, timeInfo.bbt.bar);
  903. CARLA_SAFE_ASSERT_INT(timeInfo.bbt.beat > 0, timeInfo.bbt.beat);
  904. const double ppqBar = static_cast<double>(timeInfo.bbt.beatsPerBar) * (timeInfo.bbt.bar - 1);
  905. const double ppqBeat = static_cast<double>(timeInfo.bbt.beat - 1);
  906. const double ppqTick = timeInfo.bbt.tick / timeInfo.bbt.ticksPerBeat;
  907. fPosInfo.bpm = timeInfo.bbt.beatsPerMinute;
  908. fPosInfo.timeSigNumerator = static_cast<int>(timeInfo.bbt.beatsPerBar);
  909. fPosInfo.timeSigDenominator = static_cast<int>(timeInfo.bbt.beatType);
  910. fPosInfo.timeInSamples = static_cast<int64_t>(timeInfo.frame);
  911. fPosInfo.timeInSeconds = static_cast<double>(fPosInfo.timeInSamples)/pData->engine->getSampleRate();
  912. fPosInfo.ppqPosition = ppqBar + ppqBeat + ppqTick;
  913. fPosInfo.ppqPositionOfLastBarStart = ppqBar;
  914. }
  915. // --------------------------------------------------------------------------------------------------------
  916. // Process
  917. processSingle(audioIn, audioOut, frames);
  918. // --------------------------------------------------------------------------------------------------------
  919. #ifdef BUILD_BRIDGE_ALTERNATIVE_ARCH
  920. return;
  921. // unused
  922. (void)cvIn;
  923. #endif
  924. }
  925. bool processSingle(const float* const* const inBuffer, float** const outBuffer, const uint32_t frames)
  926. {
  927. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  928. if (pData->audioIn.count > 0)
  929. {
  930. CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
  931. }
  932. if (pData->audioOut.count > 0)
  933. {
  934. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  935. }
  936. // --------------------------------------------------------------------------------------------------------
  937. // Try lock, silence otherwise
  938. if (pData->engine->isOffline())
  939. {
  940. pData->singleMutex.lock();
  941. }
  942. else if (! pData->singleMutex.tryLock())
  943. {
  944. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  945. carla_zeroFloats(outBuffer[i], frames);
  946. return false;
  947. }
  948. // --------------------------------------------------------------------------------------------------------
  949. // Set audio in buffers
  950. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  951. fAudioBuffer.copyFrom(static_cast<int>(i), 0, inBuffer[i], static_cast<int>(frames));
  952. // --------------------------------------------------------------------------------------------------------
  953. // Run plugin
  954. fInstance->processBlock(fAudioBuffer, fMidiBuffer);
  955. // --------------------------------------------------------------------------------------------------------
  956. // Set audio out buffers
  957. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  958. carla_copyFloats(outBuffer[i], fAudioBuffer.getReadPointer(static_cast<int>(i)), frames);
  959. // --------------------------------------------------------------------------------------------------------
  960. // Midi out
  961. if (! fMidiBuffer.isEmpty())
  962. {
  963. if (pData->event.portOut != nullptr)
  964. {
  965. const uint8_t* midiEventData;
  966. int midiEventSize, midiEventPosition;
  967. for (juce::MidiBuffer::Iterator i(fMidiBuffer); i.getNextEvent(midiEventData, midiEventSize, midiEventPosition);)
  968. {
  969. CARLA_SAFE_ASSERT_BREAK(midiEventPosition >= 0 && midiEventPosition < static_cast<int>(frames));
  970. CARLA_SAFE_ASSERT_BREAK(midiEventSize > 0);
  971. if (! pData->event.portOut->writeMidiEvent(static_cast<uint32_t>(midiEventPosition), static_cast<uint8_t>(midiEventSize), midiEventData))
  972. break;
  973. }
  974. }
  975. fMidiBuffer.clear();
  976. }
  977. // --------------------------------------------------------------------------------------------------------
  978. pData->singleMutex.unlock();
  979. return true;
  980. }
  981. void bufferSizeChanged(const uint32_t newBufferSize) override
  982. {
  983. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  984. carla_debug("CarlaPluginJuce::bufferSizeChanged(%i)", newBufferSize);
  985. fAudioBuffer.setSize(static_cast<int>(std::max<uint32_t>(pData->audioIn.count, pData->audioOut.count)), static_cast<int>(newBufferSize));
  986. if (pData->active)
  987. {
  988. deactivate();
  989. activate();
  990. }
  991. }
  992. void sampleRateChanged(const double newSampleRate) override
  993. {
  994. CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
  995. carla_debug("CarlaPluginJuce::sampleRateChanged(%g)", newSampleRate);
  996. if (pData->active)
  997. {
  998. deactivate();
  999. activate();
  1000. }
  1001. }
  1002. // -------------------------------------------------------------------
  1003. // Plugin buffers
  1004. // nothing
  1005. // -------------------------------------------------------------------
  1006. // Post-poned UI Stuff
  1007. // nothing
  1008. // -------------------------------------------------------------------
  1009. void* getNativeHandle() const noexcept override
  1010. {
  1011. return (fInstance != nullptr) ? fInstance->getPlatformSpecificData() : nullptr;
  1012. }
  1013. // -------------------------------------------------------------------
  1014. protected:
  1015. void audioProcessorParameterChanged(juce::AudioProcessor*, int index, float value) override
  1016. {
  1017. CARLA_SAFE_ASSERT_RETURN(index >= 0,);
  1018. const uint32_t uindex(static_cast<uint32_t>(index));
  1019. const float fixedValue(pData->param.getFixedValue(uindex, value));
  1020. CarlaPlugin::setParameterValue(static_cast<uint32_t>(index), fixedValue, false, true, true);
  1021. }
  1022. void audioProcessorChanged(juce::AudioProcessor*) override
  1023. {
  1024. pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, 0, 0, 0, 0.0f, nullptr);
  1025. }
  1026. void audioProcessorParameterChangeGestureBegin(juce::AudioProcessor*, int index) override
  1027. {
  1028. CARLA_SAFE_ASSERT_RETURN(index >= 0,);
  1029. pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), true);
  1030. }
  1031. void audioProcessorParameterChangeGestureEnd(juce::AudioProcessor*, int index) override
  1032. {
  1033. CARLA_SAFE_ASSERT_RETURN(index >= 0,);
  1034. pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), false);
  1035. }
  1036. bool getCurrentPosition(CurrentPositionInfo& result) override
  1037. {
  1038. carla_copyStruct(result, fPosInfo);
  1039. return true;
  1040. }
  1041. // -------------------------------------------------------------------
  1042. public:
  1043. bool init(const CarlaPluginPtr plugin,
  1044. const char* const filename, const char* const name, const char* const label,
  1045. const int64_t uniqueId, const uint options, const char* const format)
  1046. {
  1047. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  1048. // ---------------------------------------------------------------
  1049. // first checks
  1050. if (pData->client != nullptr)
  1051. {
  1052. pData->engine->setLastError("Plugin client is already registered");
  1053. return false;
  1054. }
  1055. if (format == nullptr || format[0] == '\0')
  1056. {
  1057. pData->engine->setLastError("null format");
  1058. return false;
  1059. }
  1060. // AU requires label
  1061. if (std::strcmp(format, "AU") == 0)
  1062. {
  1063. if (label == nullptr || label[0] == '\0')
  1064. {
  1065. pData->engine->setLastError("null label");
  1066. return false;
  1067. }
  1068. }
  1069. juce::String fileOrIdentifier;
  1070. if (std::strcmp(format, "AU") == 0)
  1071. {
  1072. fileOrIdentifier = label;
  1073. }
  1074. else
  1075. {
  1076. // VST2 and VST3 require filename
  1077. if (filename == nullptr || filename[0] == '\0')
  1078. {
  1079. pData->engine->setLastError("null filename");
  1080. return false;
  1081. }
  1082. juce::String jfilename(filename);
  1083. #ifdef CARLA_OS_WIN
  1084. // Fix for wine usage
  1085. if (juce::File("Z:\\usr\\").isDirectory() && filename[0] == '/')
  1086. {
  1087. jfilename.replace("/", "\\");
  1088. jfilename = "Z:" + jfilename;
  1089. }
  1090. #endif
  1091. fileOrIdentifier = jfilename;
  1092. if (label != nullptr && label[0] != '\0')
  1093. fDesc.name = label;
  1094. }
  1095. /**/ if (std::strcmp(format, "AU") == 0)
  1096. {
  1097. #if JUCE_PLUGINHOST_AU
  1098. fFormatManager.addFormat(new juce::AudioUnitPluginFormat());
  1099. #endif
  1100. }
  1101. else if (std::strcmp(format, "VST2") == 0)
  1102. {
  1103. #if JUCE_PLUGINHOST_VST
  1104. fFormatManager.addFormat(new juce::VSTPluginFormat());
  1105. #endif
  1106. }
  1107. else if (std::strcmp(format, "VST3") == 0)
  1108. {
  1109. #if JUCE_PLUGINHOST_VST3
  1110. fFormatManager.addFormat(new juce::VST3PluginFormat());
  1111. #endif
  1112. }
  1113. else
  1114. {
  1115. fFormatManager.addDefaultFormats();
  1116. }
  1117. {
  1118. juce::OwnedArray<juce::PluginDescription> pluginDescriptions;
  1119. juce::KnownPluginList plist;
  1120. {
  1121. const ScopedAbortCatcher sac;
  1122. for (int i = 0; i < fFormatManager.getNumFormats(); ++i)
  1123. {
  1124. juce::AudioPluginFormat* const apformat = fFormatManager.getFormat(i);
  1125. CARLA_SAFE_ASSERT_CONTINUE(apformat != nullptr);
  1126. carla_debug("Trying to load '%s' plugin with format '%s'", fileOrIdentifier.toRawUTF8(), apformat->getName().toRawUTF8());
  1127. try {
  1128. plist.scanAndAddFile(fileOrIdentifier, true, pluginDescriptions, *apformat);
  1129. } CARLA_SAFE_EXCEPTION_CONTINUE("scanAndAddFile")
  1130. if (sac.wasTriggered())
  1131. {
  1132. carla_stderr("WARNING: Caught exception while scanning file, will not load this plugin");
  1133. pluginDescriptions.clearQuick(false);
  1134. break;
  1135. }
  1136. }
  1137. }
  1138. if (pluginDescriptions.size() == 0)
  1139. {
  1140. pData->engine->setLastError("Failed to get plugin description");
  1141. return false;
  1142. }
  1143. fDesc = *pluginDescriptions[0];
  1144. }
  1145. if (uniqueId != 0)
  1146. fDesc.uid = static_cast<int>(uniqueId);
  1147. juce::String error;
  1148. {
  1149. const ScopedAbortCatcher sac;
  1150. try {
  1151. fInstance = fFormatManager.createPluginInstance(fDesc,
  1152. pData->engine->getSampleRate(),
  1153. static_cast<int>(pData->engine->getBufferSize()),
  1154. error);
  1155. } CARLA_SAFE_EXCEPTION("createPluginInstance")
  1156. if (sac.wasTriggered())
  1157. {
  1158. fInstance = nullptr;
  1159. carla_stderr("WARNING: Caught exception while instantiating, will not load this plugin");
  1160. }
  1161. }
  1162. if (fInstance == nullptr)
  1163. {
  1164. pData->engine->setLastError(error.toRawUTF8());
  1165. return false;
  1166. }
  1167. fInstance->fillInPluginDescription(fDesc);
  1168. fInstance->setPlayHead(this);
  1169. fInstance->addListener(this);
  1170. fFormatName = format;
  1171. // ---------------------------------------------------------------
  1172. // get info
  1173. if (name != nullptr && name[0] != '\0')
  1174. pData->name = pData->engine->getUniquePluginName(name);
  1175. else
  1176. pData->name = pData->engine->getUniquePluginName(fInstance->getName().toRawUTF8());
  1177. if (filename != nullptr && filename[0] != '\0')
  1178. pData->filename = carla_strdup(filename);
  1179. // ---------------------------------------------------------------
  1180. // register client
  1181. pData->client = pData->engine->addClient(plugin);
  1182. if (pData->client == nullptr || ! pData->client->isOk())
  1183. {
  1184. pData->engine->setLastError("Failed to register plugin client");
  1185. return false;
  1186. }
  1187. // ---------------------------------------------------------------
  1188. // set options
  1189. pData->options = 0x0;
  1190. pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  1191. pData->options |= PLUGIN_OPTION_USE_CHUNKS;
  1192. if (fInstance->acceptsMidi())
  1193. {
  1194. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CONTROL_CHANGES))
  1195. pData->options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  1196. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CHANNEL_PRESSURE))
  1197. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  1198. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH))
  1199. pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  1200. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PITCHBEND))
  1201. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  1202. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_ALL_SOUND_OFF))
  1203. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  1204. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PROGRAM_CHANGES))
  1205. pData->options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES;
  1206. if (isPluginOptionInverseEnabled(options, PLUGIN_OPTION_SKIP_SENDING_NOTES))
  1207. pData->options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
  1208. }
  1209. if (fInstance->getNumPrograms() > 1 && ((pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) == 0))
  1210. {
  1211. if (isPluginOptionEnabled(options, PLUGIN_OPTION_MAP_PROGRAM_CHANGES))
  1212. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  1213. }
  1214. return true;
  1215. }
  1216. private:
  1217. juce::PluginDescription fDesc;
  1218. juce::AudioPluginFormatManager fFormatManager;
  1219. std::unique_ptr<juce::AudioPluginInstance> fInstance;
  1220. juce::AudioSampleBuffer fAudioBuffer;
  1221. juce::MidiBuffer fMidiBuffer;
  1222. CurrentPositionInfo fPosInfo;
  1223. juce::MemoryBlock fChunk;
  1224. juce::String fFormatName;
  1225. CarlaScopedPointer<JucePluginWindow> fWindow;
  1226. bool isJuceSaveFormat(const void* const data, const std::size_t dataSize)
  1227. {
  1228. if (fFormatName != "VST2")
  1229. return true;
  1230. if (dataSize < 160)
  1231. return false;
  1232. const int32_t* const set = (const int32_t*)data;
  1233. if (! compareMagic(set[0], "CcnK"))
  1234. return false;
  1235. if (! compareMagic(set[2], "FBCh") && ! compareMagic(set[2], "FJuc"))
  1236. return false;
  1237. if (fxbSwap(set[3]) > 1)
  1238. return false;
  1239. const int32_t chunkSize = fxbSwap(set[39]);
  1240. return static_cast<std::size_t>(chunkSize + 160) == dataSize;
  1241. }
  1242. static bool compareMagic(int32_t magic, const char* name) noexcept
  1243. {
  1244. return magic == (int32_t)juce::ByteOrder::littleEndianInt (name)
  1245. || magic == (int32_t)juce::ByteOrder::bigEndianInt (name);
  1246. }
  1247. static int32_t fxbSwap(const int32_t x) noexcept
  1248. {
  1249. return (int32_t)juce::ByteOrder::swapIfLittleEndian ((uint32_t) x);
  1250. }
  1251. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginJuce)
  1252. };
  1253. CARLA_BACKEND_END_NAMESPACE
  1254. #endif // USING_JUCE
  1255. // -------------------------------------------------------------------------------------------------------------------
  1256. CARLA_BACKEND_START_NAMESPACE
  1257. CarlaPluginPtr CarlaPlugin::newJuce(const Initializer& init, const char* const format)
  1258. {
  1259. carla_debug("CarlaPlugin::newJuce({%p, \"%s\", \"%s\", \"%s\", " P_INT64 "}, %s)",
  1260. init.engine, init.filename, init.name, init.label, init.uniqueId, format);
  1261. #ifdef USING_JUCE
  1262. std::shared_ptr<CarlaPluginJuce> plugin(new CarlaPluginJuce(init.engine, init.id));
  1263. if (! plugin->init(plugin, init.filename, init.name, init.label, init.uniqueId, init.options, format))
  1264. return nullptr;
  1265. return plugin;
  1266. #else
  1267. init.engine->setLastError("Juce-based plugin not available");
  1268. return nullptr;
  1269. // unused
  1270. (void)format;
  1271. #endif
  1272. }
  1273. CARLA_BACKEND_END_NAMESPACE
  1274. // -------------------------------------------------------------------------------------------------------------------