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.

JucePlugin.cpp 24KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824
  1. /*
  2. * Carla Juce Plugin
  3. * Copyright (C) 2013-2014 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 HAVE_JUCE
  20. #include "CarlaBackendUtils.hpp"
  21. #include "JucePluginWindow.hpp"
  22. #include "juce_audio_processors.h"
  23. // TODO - use setPlayConfigDetails
  24. using namespace juce;
  25. CARLA_BACKEND_START_NAMESPACE
  26. class JucePlugin : public CarlaPlugin
  27. {
  28. public:
  29. JucePlugin(CarlaEngine* const engine, const uint id)
  30. : CarlaPlugin(engine, id),
  31. fInstance(nullptr),
  32. fAudioBuffer(1, 0)
  33. {
  34. carla_debug("JucePlugin::JucePlugin(%p, %i)", engine, id);
  35. fMidiBuffer.ensureSize(2048);
  36. fMidiBuffer.clear();
  37. }
  38. ~JucePlugin() override
  39. {
  40. carla_debug("JucePlugin::~JucePlugin()");
  41. // close UI
  42. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  43. showCustomUI(false);
  44. pData->singleMutex.lock();
  45. pData->masterMutex.lock();
  46. if (pData->client != nullptr && pData->client->isActive())
  47. pData->client->deactivate();
  48. if (pData->active)
  49. {
  50. deactivate();
  51. pData->active = false;
  52. }
  53. if (fInstance != nullptr)
  54. {
  55. delete fInstance;
  56. fInstance = nullptr;
  57. }
  58. clearBuffers();
  59. }
  60. // -------------------------------------------------------------------
  61. // Information (base)
  62. PluginType getType() const noexcept override
  63. {
  64. PluginType type = PLUGIN_NONE;
  65. try {
  66. type = getPluginTypeFromString(fDesc.pluginFormatName.toRawUTF8());
  67. } catch(...) {}
  68. return type;
  69. }
  70. PluginCategory getCategory() const noexcept override
  71. {
  72. PluginCategory category = PLUGIN_CATEGORY_NONE;
  73. try {
  74. category = getPluginCategoryFromName(fDesc.category.toRawUTF8());
  75. } catch(...) {}
  76. return category;
  77. }
  78. long getUniqueId() const noexcept override
  79. {
  80. return fDesc.uid;
  81. }
  82. // -------------------------------------------------------------------
  83. // Information (count)
  84. // nothing
  85. // -------------------------------------------------------------------
  86. // Information (current data)
  87. // nothing
  88. // -------------------------------------------------------------------
  89. // Information (per-plugin data)
  90. unsigned int getOptionsAvailable() const noexcept override
  91. {
  92. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, 0x0);
  93. unsigned int options = 0x0;
  94. //options |= PLUGIN_OPTION_FIXED_BUFFERS;
  95. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  96. //options |= PLUGIN_OPTION_USE_CHUNKS;
  97. if (fInstance->acceptsMidi())
  98. {
  99. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  100. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  101. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  102. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  103. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  104. }
  105. return options;
  106. }
  107. float getParameterValue(const uint32_t parameterId) const noexcept override
  108. {
  109. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  110. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, 0.0f);
  111. return fInstance->getParameter(static_cast<int>(parameterId));
  112. }
  113. void getLabel(char* const strBuf) const noexcept override
  114. {
  115. std::strncpy(strBuf, fDesc.name.toRawUTF8(), STR_MAX);
  116. }
  117. void getMaker(char* const strBuf) const noexcept override
  118. {
  119. std::strncpy(strBuf, fDesc.manufacturerName.toRawUTF8(), STR_MAX);
  120. }
  121. void getCopyright(char* const strBuf) const noexcept override
  122. {
  123. getMaker(strBuf);
  124. }
  125. void getRealName(char* const strBuf) const noexcept override
  126. {
  127. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  128. std::strncpy(strBuf, fInstance->getName().toRawUTF8(), STR_MAX);
  129. }
  130. void getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
  131. {
  132. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  133. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  134. std::strncpy(strBuf, fInstance->getParameterName(static_cast<int>(parameterId)).toRawUTF8(), STR_MAX);
  135. }
  136. void getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
  137. {
  138. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  139. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  140. std::strncpy(strBuf, fInstance->getParameterLabel(static_cast<int>(parameterId)).toRawUTF8(), STR_MAX);
  141. }
  142. // -------------------------------------------------------------------
  143. // Set data (state)
  144. // nothing
  145. // -------------------------------------------------------------------
  146. // Set data (internal stuff)
  147. void setName(const char* const newName) override
  148. {
  149. CarlaPlugin::setName(newName);
  150. if (fWindow != nullptr)
  151. {
  152. String uiName(pData->name);
  153. uiName += " (JUCE GUI)";
  154. fWindow->setName(uiName);
  155. }
  156. }
  157. // -------------------------------------------------------------------
  158. // Set data (plugin-specific stuff)
  159. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  160. {
  161. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  162. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  163. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  164. fInstance->setParameter(static_cast<int>(parameterId), value);
  165. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  166. }
  167. // -------------------------------------------------------------------
  168. // Set ui stuff
  169. void showCustomUI(const bool yesNo) override
  170. {
  171. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  172. #ifdef CARLA_OS_LINUX
  173. const MessageManagerLock mmLock;
  174. #endif
  175. if (yesNo)
  176. {
  177. if (fWindow == nullptr)
  178. {
  179. String uiName(pData->name);
  180. uiName += " (JUCE GUI)";
  181. fWindow = new JucePluginWindow();
  182. fWindow->setName(uiName);
  183. }
  184. if (AudioProcessorEditor* const editor = fInstance->createEditorIfNeeded())
  185. fWindow->show(editor);
  186. }
  187. else
  188. {
  189. if (fWindow != nullptr)
  190. fWindow->hide();
  191. if (AudioProcessorEditor* const editor = fInstance->getActiveEditor())
  192. delete editor;
  193. fWindow = nullptr;
  194. }
  195. }
  196. void idle() override
  197. {
  198. if (fWindow != nullptr)
  199. {
  200. if (fWindow->wasClosedByUser())
  201. {
  202. showCustomUI(false);
  203. pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr);
  204. }
  205. }
  206. CarlaPlugin::idle();
  207. }
  208. // -------------------------------------------------------------------
  209. // Plugin state
  210. void reload() override
  211. {
  212. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  213. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  214. carla_debug("VstPlugin::reload() - start");
  215. const EngineProcessMode processMode(pData->engine->getProccessMode());
  216. // Safely disable plugin for reload
  217. const ScopedDisabler sd(this);
  218. if (pData->active)
  219. deactivate();
  220. clearBuffers();
  221. fInstance->refreshParameterList();
  222. uint32_t aIns, aOuts, mIns, mOuts, params;
  223. aIns = aOuts = mIns = mOuts = params = 0;
  224. bool needsCtrlIn, needsCtrlOut;
  225. needsCtrlIn = needsCtrlOut = false;
  226. aIns = (fInstance->getNumInputChannels() > 0) ? static_cast<uint32_t>(fInstance->getNumInputChannels()) : 0;
  227. aOuts = (fInstance->getNumOutputChannels() > 0) ? static_cast<uint32_t>(fInstance->getNumOutputChannels()) : 0;
  228. params = (fInstance->getNumParameters() > 0) ? static_cast<uint32_t>(fInstance->getNumParameters()) : 0;
  229. if (fInstance->acceptsMidi())
  230. {
  231. mIns = 1;
  232. needsCtrlIn = true;
  233. }
  234. if (fInstance->producesMidi())
  235. {
  236. mOuts = 1;
  237. needsCtrlOut = true;
  238. }
  239. if (aIns > 0)
  240. {
  241. pData->audioIn.createNew(aIns);
  242. }
  243. if (aOuts > 0)
  244. {
  245. pData->audioOut.createNew(aOuts);
  246. needsCtrlIn = true;
  247. }
  248. if (params > 0)
  249. {
  250. pData->param.createNew(params, false);
  251. needsCtrlIn = true;
  252. }
  253. const uint portNameSize(pData->engine->getMaxPortNameSize());
  254. CarlaString portName;
  255. // Audio Ins
  256. for (uint32_t j=0; j < aIns; ++j)
  257. {
  258. portName.clear();
  259. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  260. {
  261. portName = pData->name;
  262. portName += ":";
  263. }
  264. if (aIns > 1)
  265. {
  266. portName += "input_";
  267. portName += CarlaString(j+1);
  268. }
  269. else
  270. portName += "input";
  271. portName.truncate(portNameSize);
  272. pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true);
  273. pData->audioIn.ports[j].rindex = j;
  274. }
  275. // Audio Outs
  276. for (uint32_t j=0; j < aOuts; ++j)
  277. {
  278. portName.clear();
  279. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  280. {
  281. portName = pData->name;
  282. portName += ":";
  283. }
  284. if (aOuts > 1)
  285. {
  286. portName += "output_";
  287. portName += CarlaString(j+1);
  288. }
  289. else
  290. portName += "output";
  291. portName.truncate(portNameSize);
  292. pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false);
  293. pData->audioOut.ports[j].rindex = j;
  294. }
  295. for (uint32_t j=0; j < params; ++j)
  296. {
  297. pData->param.data[j].type = PARAMETER_INPUT;
  298. pData->param.data[j].hints = 0x0;
  299. pData->param.data[j].index = static_cast<int32_t>(j);
  300. pData->param.data[j].rindex = static_cast<int32_t>(j);
  301. pData->param.data[j].midiCC = -1;
  302. pData->param.data[j].midiChannel = 0;
  303. float min, max, def, step, stepSmall, stepLarge;
  304. // TODO
  305. //const int numSteps(fInstance->getParameterNumSteps(static_cast<int>(j)));
  306. {
  307. min = 0.0f;
  308. max = 1.0f;
  309. step = 0.001f;
  310. stepSmall = 0.0001f;
  311. stepLarge = 0.1f;
  312. }
  313. pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  314. #ifndef BUILD_BRIDGE
  315. //pData->param.data[j].hints |= PARAMETER_USES_CUSTOM_TEXT;
  316. #endif
  317. if (fInstance->isParameterAutomatable(static_cast<int>(j)))
  318. pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
  319. // FIXME?
  320. def = fInstance->getParameterDefaultValue(static_cast<int>(j));
  321. if (def < min)
  322. def = min;
  323. else if (def > max)
  324. def = max;
  325. pData->param.ranges[j].min = min;
  326. pData->param.ranges[j].max = max;
  327. pData->param.ranges[j].def = def;
  328. pData->param.ranges[j].step = step;
  329. pData->param.ranges[j].stepSmall = stepSmall;
  330. pData->param.ranges[j].stepLarge = stepLarge;
  331. }
  332. if (needsCtrlIn)
  333. {
  334. portName.clear();
  335. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  336. {
  337. portName = pData->name;
  338. portName += ":";
  339. }
  340. portName += "events-in";
  341. portName.truncate(portNameSize);
  342. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true);
  343. }
  344. if (needsCtrlOut)
  345. {
  346. portName.clear();
  347. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  348. {
  349. portName = pData->name;
  350. portName += ":";
  351. }
  352. portName += "events-out";
  353. portName.truncate(portNameSize);
  354. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false);
  355. }
  356. // plugin hints
  357. pData->hints = 0x0;
  358. if (fDesc.isInstrument)
  359. pData->hints |= PLUGIN_IS_SYNTH;
  360. if (fInstance->hasEditor())
  361. {
  362. pData->hints |= PLUGIN_HAS_CUSTOM_UI;
  363. pData->hints |= PLUGIN_NEEDS_SINGLE_THREAD;
  364. }
  365. if (aOuts > 0 && (aIns == aOuts || aIns == 1))
  366. pData->hints |= PLUGIN_CAN_DRYWET;
  367. if (aOuts > 0)
  368. pData->hints |= PLUGIN_CAN_VOLUME;
  369. if (aOuts >= 2 && aOuts % 2 == 0)
  370. pData->hints |= PLUGIN_CAN_BALANCE;
  371. // extra plugin hints
  372. pData->extraHints = 0x0;
  373. if (mIns > 0)
  374. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  375. if (mOuts > 0)
  376. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
  377. if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0))
  378. pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
  379. bufferSizeChanged(pData->engine->getBufferSize());
  380. //reloadPrograms(true);
  381. if (pData->active)
  382. activate();
  383. carla_debug("VstPlugin::reload() - end");
  384. }
  385. // -------------------------------------------------------------------
  386. // Plugin processing
  387. void activate() noexcept override
  388. {
  389. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  390. try {
  391. fInstance->prepareToPlay(pData->engine->getSampleRate(), static_cast<int>(pData->engine->getBufferSize()));
  392. } catch(...) {}
  393. }
  394. void deactivate() noexcept override
  395. {
  396. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  397. try {
  398. fInstance->releaseResources();
  399. } catch(...) {}
  400. }
  401. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override
  402. {
  403. // --------------------------------------------------------------------------------------------------------
  404. // Check if active
  405. if (! pData->active)
  406. {
  407. // disable any output sound
  408. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  409. FloatVectorOperations::clear(outBuffer[i], static_cast<int>(frames));
  410. return;
  411. }
  412. // --------------------------------------------------------------------------------------------------------
  413. // Check if needs reset
  414. if (pData->needsReset)
  415. {
  416. fInstance->reset();
  417. pData->needsReset = false;
  418. }
  419. uint32_t l=0;
  420. for (; l < pData->audioIn.count; ++l)
  421. fAudioBuffer.clear(static_cast<int>(l), 0, static_cast<int>(frames));
  422. for (; l < pData->audioOut.count; ++l)
  423. fAudioBuffer.clear(static_cast<int>(l), 0, static_cast<int>(frames));
  424. processSingle(inBuffer, outBuffer, frames);
  425. }
  426. bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames)
  427. {
  428. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  429. if (pData->audioIn.count > 0)
  430. {
  431. CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
  432. }
  433. if (pData->audioOut.count > 0)
  434. {
  435. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  436. }
  437. // --------------------------------------------------------------------------------------------------------
  438. // Try lock, silence otherwise
  439. if (pData->engine->isOffline())
  440. {
  441. pData->singleMutex.lock();
  442. }
  443. else if (! pData->singleMutex.tryLock())
  444. {
  445. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  446. {
  447. for (uint32_t k=0; k < frames; ++k)
  448. outBuffer[i][k/*+timeOffset*/] = 0.0f;
  449. }
  450. return false;
  451. }
  452. // --------------------------------------------------------------------------------------------------------
  453. // Set audio in buffers
  454. uint32_t l;
  455. for (l=0; l < pData->audioIn.count; ++l)
  456. fAudioBuffer.copyFrom(static_cast<int>(l), 0, inBuffer[l], static_cast<int>(frames));
  457. //for (l=0; l < pData->audioOut.count; ++l)
  458. // fAudioBuffer.clear(static_cast<int>(l), 0, static_cast<int>(frames));
  459. // --------------------------------------------------------------------------------------------------------
  460. // Run plugin
  461. fInstance->processBlock(fAudioBuffer, fMidiBuffer);
  462. // --------------------------------------------------------------------------------------------------------
  463. // Set audio out buffers
  464. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  465. FloatVectorOperations::copy(outBuffer[i], fAudioBuffer.getSampleData(static_cast<int>(i)), static_cast<int>(frames));
  466. // --------------------------------------------------------------------------------------------------------
  467. pData->singleMutex.unlock();
  468. return true;
  469. }
  470. void bufferSizeChanged(const uint32_t newBufferSize) override
  471. {
  472. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  473. carla_debug("VstPlugin::bufferSizeChanged(%i)", newBufferSize);
  474. fAudioBuffer.setSize(static_cast<int>(std::max<uint32_t>(pData->audioIn.count, pData->audioOut.count)), static_cast<int>(newBufferSize));
  475. if (pData->active)
  476. {
  477. deactivate();
  478. activate();
  479. }
  480. }
  481. void sampleRateChanged(const double newSampleRate) override
  482. {
  483. CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
  484. carla_debug("VstPlugin::sampleRateChanged(%g)", newSampleRate);
  485. if (pData->active)
  486. {
  487. deactivate();
  488. activate();
  489. }
  490. }
  491. // -------------------------------------------------------------------
  492. // Plugin buffers
  493. // nothing
  494. // -------------------------------------------------------------------
  495. // Post-poned UI Stuff
  496. // nothing
  497. // -------------------------------------------------------------------
  498. protected:
  499. // TODO
  500. // -------------------------------------------------------------------
  501. public:
  502. bool init(const char* const filename, const char* const name, const char* const label)
  503. {
  504. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  505. // ---------------------------------------------------------------
  506. // first checks
  507. if (pData->client != nullptr)
  508. {
  509. pData->engine->setLastError("Plugin client is already registered");
  510. return false;
  511. }
  512. if (filename == nullptr || filename[0] == '\0')
  513. {
  514. pData->engine->setLastError("null filename");
  515. return false;
  516. }
  517. if (label == nullptr || label[0] == '\0')
  518. {
  519. pData->engine->setLastError("null label");
  520. return false;
  521. }
  522. #ifdef CARLA_OS_LINUX
  523. const MessageManagerLock mmLock;
  524. #endif
  525. // ---------------------------------------------------------------
  526. // fix path for wine usage
  527. String jfilename(filename);
  528. #ifdef CARLA_OS_WIN
  529. if (jfilename.startsWith("/"))
  530. {
  531. jfilename.replace("/", "\\");
  532. jfilename = "Z:" + jfilename;
  533. }
  534. #endif
  535. //fDesc.name = fDesc.descriptiveName = label;
  536. //fDesc.pluginFormatName = "VST";
  537. fDesc.uid = 0; // TODO - set uid for shell plugins
  538. fDesc.fileOrIdentifier = jfilename;
  539. fInstance = fFormat.createInstanceFromDescription(fDesc, 44100, 512);
  540. if (fInstance == nullptr)
  541. {
  542. pData->engine->setLastError("Plugin failed to initialize");
  543. return false;
  544. }
  545. fInstance->fillInPluginDescription(fDesc);
  546. // ---------------------------------------------------------------
  547. // get info
  548. if (name != nullptr && name[0] != '\0')
  549. pData->name = pData->engine->getUniquePluginName(name);
  550. else
  551. pData->name = pData->engine->getUniquePluginName(fInstance->getName().toRawUTF8());
  552. pData->filename = carla_strdup(filename);
  553. // ---------------------------------------------------------------
  554. // register client
  555. pData->client = pData->engine->addClient(this);
  556. if (pData->client == nullptr || ! pData->client->isOk())
  557. {
  558. pData->engine->setLastError("Failed to register plugin client");
  559. return false;
  560. }
  561. // ---------------------------------------------------------------
  562. // load plugin settings
  563. {
  564. // set default options
  565. pData->options = 0x0;
  566. //pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  567. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  568. //pData->options |= PLUGIN_OPTION_USE_CHUNKS;
  569. if (fInstance->acceptsMidi())
  570. {
  571. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  572. pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  573. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  574. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  575. }
  576. // set identifier string
  577. String juceId(fDesc.createIdentifierString());
  578. CarlaString identifier("Juce/");
  579. identifier += juceId.toRawUTF8();
  580. pData->identifier = identifier.dup();
  581. // load settings
  582. pData->options = pData->loadSettings(pData->options, getOptionsAvailable());
  583. }
  584. return true;
  585. }
  586. private:
  587. PluginDescription fDesc;
  588. VSTPluginFormat fFormat;
  589. AudioPluginInstance* fInstance;
  590. AudioSampleBuffer fAudioBuffer;
  591. MidiBuffer fMidiBuffer;
  592. ScopedPointer<JucePluginWindow> fWindow;
  593. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JucePlugin)
  594. };
  595. CARLA_BACKEND_END_NAMESPACE
  596. #endif // HAVE_JUCE
  597. // -------------------------------------------------------------------------------------------------------------------
  598. CARLA_BACKEND_START_NAMESPACE
  599. CarlaPlugin* CarlaPlugin::newJuce(const Initializer& init, const char* const format)
  600. {
  601. carla_debug("CarlaPlugin::newJuce({%p, \"%s\", \"%s\", \"%s\"}, %s)", init.engine, init.filename, init.name, init.label, format);
  602. #ifdef HAVE_JUCE
  603. JucePlugin* const plugin(new JucePlugin(init.engine, init.id));
  604. if (! plugin->init(init.filename, init.name, init.label))
  605. {
  606. delete plugin;
  607. return nullptr;
  608. }
  609. plugin->reload();
  610. if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack())
  611. {
  612. init.engine->setLastError("Carla's rack mode can only work with Stereo VST3 plugins, sorry!");
  613. delete plugin;
  614. return nullptr;
  615. }
  616. return plugin;
  617. #else
  618. init.engine->setLastError("Juce support not available");
  619. return nullptr;
  620. // unused
  621. (void)format;
  622. #endif
  623. }
  624. CARLA_BACKEND_END_NAMESPACE
  625. // -------------------------------------------------------------------------------------------------------------------