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 40KB

11 years ago
11 years ago
11 years ago
10 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
10 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
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 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
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199
  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. #if defined(CARLA_OS_MAC)
  21. /*
  22. * Missing functions in OSX.
  23. */
  24. namespace std {
  25. inline float
  26. fmin(float __x, float __y)
  27. { return __builtin_fminf(__x, __y); }
  28. inline float
  29. fmax(float __x, float __y)
  30. { return __builtin_fmaxf(__x, __y); }
  31. inline float
  32. rint(float __x)
  33. { return __builtin_rintf(__x); }
  34. }
  35. #endif
  36. #include "CarlaBackendUtils.hpp"
  37. #include "JucePluginWindow.hpp"
  38. #include "juce_audio_processors.h"
  39. using namespace juce;
  40. CARLA_BACKEND_START_NAMESPACE
  41. class JucePlugin : public CarlaPlugin,
  42. public AudioPlayHead,
  43. public AudioProcessorListener
  44. {
  45. public:
  46. JucePlugin(CarlaEngine* const engine, const uint id)
  47. : CarlaPlugin(engine, id),
  48. fInstance(nullptr),
  49. fAudioBuffer(1, 0)
  50. {
  51. carla_debug("JucePlugin::JucePlugin(%p, %i)", engine, id);
  52. fMidiBuffer.ensureSize(2048);
  53. fMidiBuffer.clear();
  54. fPosInfo.resetToDefault();
  55. }
  56. ~JucePlugin() override
  57. {
  58. carla_debug("JucePlugin::~JucePlugin()");
  59. // close UI
  60. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  61. showCustomUI(false);
  62. pData->singleMutex.lock();
  63. pData->masterMutex.lock();
  64. if (pData->client != nullptr && pData->client->isActive())
  65. pData->client->deactivate();
  66. if (pData->active)
  67. {
  68. deactivate();
  69. pData->active = false;
  70. }
  71. if (fInstance != nullptr)
  72. {
  73. delete fInstance;
  74. fInstance = nullptr;
  75. }
  76. clearBuffers();
  77. }
  78. // -------------------------------------------------------------------
  79. // Information (base)
  80. PluginType getType() const noexcept override
  81. {
  82. PluginType type = PLUGIN_NONE;
  83. try {
  84. type = getPluginTypeFromString(fDesc.pluginFormatName.toRawUTF8());
  85. } catch(...) {}
  86. return type;
  87. }
  88. PluginCategory getCategory() const noexcept override
  89. {
  90. PluginCategory category = PLUGIN_CATEGORY_NONE;
  91. try {
  92. category = getPluginCategoryFromName(fDesc.category.toRawUTF8());
  93. } catch(...) {}
  94. return category;
  95. }
  96. int64_t getUniqueId() const noexcept override
  97. {
  98. return fDesc.uid;
  99. }
  100. // -------------------------------------------------------------------
  101. // Information (count)
  102. // nothing
  103. // -------------------------------------------------------------------
  104. // Information (current data)
  105. // nothing
  106. // -------------------------------------------------------------------
  107. // Information (per-plugin data)
  108. uint getOptionsAvailable() const noexcept override
  109. {
  110. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, 0x0);
  111. uint options = 0x0;
  112. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  113. //options |= PLUGIN_OPTION_USE_CHUNKS;
  114. if (fInstance->acceptsMidi())
  115. {
  116. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  117. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  118. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  119. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  120. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  121. }
  122. return options;
  123. }
  124. float getParameterValue(const uint32_t parameterId) const noexcept override
  125. {
  126. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  127. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr, 0.0f);
  128. return fInstance->getParameter(static_cast<int>(parameterId));
  129. }
  130. void getLabel(char* const strBuf) const noexcept override
  131. {
  132. std::strncpy(strBuf, fDesc.name.toRawUTF8(), STR_MAX);
  133. }
  134. void getMaker(char* const strBuf) const noexcept override
  135. {
  136. std::strncpy(strBuf, fDesc.manufacturerName.toRawUTF8(), STR_MAX);
  137. }
  138. void getCopyright(char* const strBuf) const noexcept override
  139. {
  140. getMaker(strBuf);
  141. }
  142. void getRealName(char* const strBuf) const noexcept override
  143. {
  144. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  145. std::strncpy(strBuf, fInstance->getName().toRawUTF8(), STR_MAX);
  146. }
  147. void getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
  148. {
  149. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  150. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  151. std::strncpy(strBuf, fInstance->getParameterName(static_cast<int>(parameterId), STR_MAX).toRawUTF8(), STR_MAX);
  152. }
  153. void getParameterText(const uint32_t parameterId, char* const strBuf) const noexcept override
  154. {
  155. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  156. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  157. std::strncpy(strBuf, fInstance->getParameterText(static_cast<int>(parameterId), STR_MAX).toRawUTF8(), STR_MAX);
  158. }
  159. void getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
  160. {
  161. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  162. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  163. std::strncpy(strBuf, fInstance->getParameterLabel(static_cast<int>(parameterId)).toRawUTF8(), STR_MAX);
  164. }
  165. // -------------------------------------------------------------------
  166. // Set data (state)
  167. // nothing
  168. // -------------------------------------------------------------------
  169. // Set data (internal stuff)
  170. void setName(const char* const newName) override
  171. {
  172. CarlaPlugin::setName(newName);
  173. if (fWindow != nullptr)
  174. {
  175. String uiName(pData->name);
  176. uiName += " (GUI)";
  177. fWindow->setName(uiName);
  178. }
  179. }
  180. // -------------------------------------------------------------------
  181. // Set data (plugin-specific stuff)
  182. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  183. {
  184. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  185. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  186. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  187. fInstance->setParameter(static_cast<int>(parameterId), value);
  188. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  189. }
  190. // -------------------------------------------------------------------
  191. // Set ui stuff
  192. void showCustomUI(const bool yesNo) override
  193. {
  194. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  195. #ifdef CARLA_OS_LINUX
  196. const MessageManagerLock mmLock;
  197. #endif
  198. if (yesNo)
  199. {
  200. if (fWindow == nullptr)
  201. {
  202. String uiName(pData->name);
  203. uiName += " (GUI)";
  204. fWindow = new JucePluginWindow();
  205. fWindow->setName(uiName);
  206. }
  207. if (AudioProcessorEditor* const editor = fInstance->createEditorIfNeeded())
  208. fWindow->show(editor);
  209. }
  210. else
  211. {
  212. if (fWindow != nullptr)
  213. fWindow->hide();
  214. if (AudioProcessorEditor* const editor = fInstance->getActiveEditor())
  215. delete editor;
  216. fWindow = nullptr;
  217. }
  218. }
  219. void idle() override
  220. {
  221. if (fWindow != nullptr)
  222. {
  223. if (fWindow->wasClosedByUser())
  224. {
  225. showCustomUI(false);
  226. pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr);
  227. }
  228. }
  229. CarlaPlugin::idle();
  230. }
  231. // -------------------------------------------------------------------
  232. // Plugin state
  233. void reload() override
  234. {
  235. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  236. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  237. carla_debug("VstPlugin::reload() - start");
  238. const EngineProcessMode processMode(pData->engine->getProccessMode());
  239. // Safely disable plugin for reload
  240. const ScopedDisabler sd(this);
  241. if (pData->active)
  242. deactivate();
  243. clearBuffers();
  244. fInstance->refreshParameterList();
  245. uint32_t aIns, aOuts, mIns, mOuts, params;
  246. aIns = aOuts = mIns = mOuts = params = 0;
  247. bool needsCtrlIn, needsCtrlOut;
  248. needsCtrlIn = needsCtrlOut = false;
  249. aIns = (fInstance->getNumInputChannels() > 0) ? static_cast<uint32_t>(fInstance->getNumInputChannels()) : 0;
  250. aOuts = (fInstance->getNumOutputChannels() > 0) ? static_cast<uint32_t>(fInstance->getNumOutputChannels()) : 0;
  251. params = (fInstance->getNumParameters() > 0) ? static_cast<uint32_t>(fInstance->getNumParameters()) : 0;
  252. if (fInstance->acceptsMidi())
  253. {
  254. mIns = 1;
  255. needsCtrlIn = true;
  256. }
  257. if (fInstance->producesMidi())
  258. {
  259. mOuts = 1;
  260. needsCtrlOut = true;
  261. }
  262. if (aIns > 0)
  263. {
  264. pData->audioIn.createNew(aIns);
  265. }
  266. if (aOuts > 0)
  267. {
  268. pData->audioOut.createNew(aOuts);
  269. needsCtrlIn = true;
  270. }
  271. if (params > 0)
  272. {
  273. pData->param.createNew(params, false);
  274. needsCtrlIn = true;
  275. }
  276. const uint portNameSize(pData->engine->getMaxPortNameSize());
  277. CarlaString portName;
  278. // Audio Ins
  279. for (uint32_t j=0; j < aIns; ++j)
  280. {
  281. portName.clear();
  282. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  283. {
  284. portName = pData->name;
  285. portName += ":";
  286. }
  287. if (aIns > 1)
  288. {
  289. portName += "input_";
  290. portName += CarlaString(j+1);
  291. }
  292. else
  293. portName += "input";
  294. portName.truncate(portNameSize);
  295. pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true);
  296. pData->audioIn.ports[j].rindex = j;
  297. }
  298. // Audio Outs
  299. for (uint32_t j=0; j < aOuts; ++j)
  300. {
  301. portName.clear();
  302. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  303. {
  304. portName = pData->name;
  305. portName += ":";
  306. }
  307. if (aOuts > 1)
  308. {
  309. portName += "output_";
  310. portName += CarlaString(j+1);
  311. }
  312. else
  313. portName += "output";
  314. portName.truncate(portNameSize);
  315. pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false);
  316. pData->audioOut.ports[j].rindex = j;
  317. }
  318. for (uint32_t j=0; j < params; ++j)
  319. {
  320. pData->param.data[j].type = PARAMETER_INPUT;
  321. pData->param.data[j].index = static_cast<int32_t>(j);
  322. pData->param.data[j].rindex = static_cast<int32_t>(j);
  323. float min, max, def, step, stepSmall, stepLarge;
  324. // TODO
  325. //const int numSteps(fInstance->getParameterNumSteps(static_cast<int>(j)));
  326. {
  327. min = 0.0f;
  328. max = 1.0f;
  329. step = 0.001f;
  330. stepSmall = 0.0001f;
  331. stepLarge = 0.1f;
  332. }
  333. pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  334. #ifndef BUILD_BRIDGE
  335. pData->param.data[j].hints |= PARAMETER_USES_CUSTOM_TEXT;
  336. #endif
  337. if (fInstance->isParameterAutomatable(static_cast<int>(j)))
  338. pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
  339. // FIXME?
  340. def = fInstance->getParameterDefaultValue(static_cast<int>(j));
  341. if (def < min)
  342. def = min;
  343. else if (def > max)
  344. def = max;
  345. pData->param.ranges[j].min = min;
  346. pData->param.ranges[j].max = max;
  347. pData->param.ranges[j].def = def;
  348. pData->param.ranges[j].step = step;
  349. pData->param.ranges[j].stepSmall = stepSmall;
  350. pData->param.ranges[j].stepLarge = stepLarge;
  351. }
  352. if (needsCtrlIn)
  353. {
  354. portName.clear();
  355. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  356. {
  357. portName = pData->name;
  358. portName += ":";
  359. }
  360. portName += "events-in";
  361. portName.truncate(portNameSize);
  362. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true);
  363. }
  364. if (needsCtrlOut)
  365. {
  366. portName.clear();
  367. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  368. {
  369. portName = pData->name;
  370. portName += ":";
  371. }
  372. portName += "events-out";
  373. portName.truncate(portNameSize);
  374. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false);
  375. }
  376. // plugin hints
  377. pData->hints = 0x0;
  378. if (fDesc.isInstrument)
  379. pData->hints |= PLUGIN_IS_SYNTH;
  380. if (fInstance->hasEditor())
  381. {
  382. pData->hints |= PLUGIN_HAS_CUSTOM_UI;
  383. pData->hints |= PLUGIN_NEEDS_SINGLE_THREAD;
  384. }
  385. if (aOuts > 0 && (aIns == aOuts || aIns == 1))
  386. pData->hints |= PLUGIN_CAN_DRYWET;
  387. if (aOuts > 0)
  388. pData->hints |= PLUGIN_CAN_VOLUME;
  389. if (aOuts >= 2 && aOuts % 2 == 0)
  390. pData->hints |= PLUGIN_CAN_BALANCE;
  391. // extra plugin hints
  392. pData->extraHints = 0x0;
  393. if (mIns > 0)
  394. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  395. if (mOuts > 0)
  396. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
  397. if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0))
  398. pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
  399. fInstance->setPlayConfigDetails(static_cast<int>(aIns), static_cast<int>(aOuts), pData->engine->getSampleRate(), static_cast<int>(pData->engine->getBufferSize()));
  400. bufferSizeChanged(pData->engine->getBufferSize());
  401. //reloadPrograms(true);
  402. if (pData->active)
  403. activate();
  404. carla_debug("VstPlugin::reload() - end");
  405. }
  406. // -------------------------------------------------------------------
  407. // Plugin processing
  408. void activate() noexcept override
  409. {
  410. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  411. try {
  412. fInstance->prepareToPlay(pData->engine->getSampleRate(), static_cast<int>(pData->engine->getBufferSize()));
  413. } catch(...) {}
  414. }
  415. void deactivate() noexcept override
  416. {
  417. CARLA_SAFE_ASSERT_RETURN(fInstance != nullptr,);
  418. try {
  419. fInstance->releaseResources();
  420. } catch(...) {}
  421. }
  422. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override
  423. {
  424. // --------------------------------------------------------------------------------------------------------
  425. // Check if active
  426. if (! pData->active)
  427. {
  428. // disable any output sound
  429. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  430. FloatVectorOperations::clear(outBuffer[i], static_cast<int>(frames));
  431. return;
  432. }
  433. // --------------------------------------------------------------------------------------------------------
  434. // Check if needs reset
  435. if (pData->needsReset)
  436. {
  437. fInstance->reset();
  438. pData->needsReset = false;
  439. }
  440. // --------------------------------------------------------------------------------------------------------
  441. // TimeInfo
  442. // TODO
  443. // --------------------------------------------------------------------------------------------------------
  444. // Event Input
  445. fMidiBuffer.clear();
  446. if (pData->event.portIn != nullptr)
  447. {
  448. // ----------------------------------------------------------------------------------------------------
  449. // MIDI Input (External)
  450. if (pData->extNotes.mutex.tryLock())
  451. {
  452. for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin(); it.valid(); it.next())
  453. {
  454. const ExternalMidiNote& note(it.getValue());
  455. CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  456. uint8_t midiEvent[3];
  457. midiEvent[0] = static_cast<uint8_t>((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
  458. midiEvent[1] = note.note;
  459. midiEvent[2] = note.velo;
  460. fMidiBuffer.addEvent(midiEvent, 3, 0);
  461. }
  462. pData->extNotes.data.clear();
  463. pData->extNotes.mutex.unlock();
  464. } // End of MIDI Input (External)
  465. // ----------------------------------------------------------------------------------------------------
  466. // Event Input (System)
  467. bool allNotesOffSent = false;
  468. uint32_t numEvents = pData->event.portIn->getEventCount();
  469. uint32_t nextBankId;
  470. if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
  471. nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
  472. else
  473. nextBankId = 0;
  474. for (uint32_t i=0; i < numEvents; ++i)
  475. {
  476. const EngineEvent& event(pData->event.portIn->getEvent(i));
  477. if (event.time >= frames)
  478. continue;
  479. switch (event.type)
  480. {
  481. case kEngineEventTypeNull:
  482. break;
  483. case kEngineEventTypeControl: {
  484. const EngineControlEvent& ctrlEvent(event.ctrl);
  485. switch (ctrlEvent.type)
  486. {
  487. case kEngineControlEventTypeNull:
  488. break;
  489. case kEngineControlEventTypeParameter: {
  490. #ifndef BUILD_BRIDGE
  491. // Control backend stuff
  492. if (event.channel == pData->ctrlChannel)
  493. {
  494. float value;
  495. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
  496. {
  497. value = ctrlEvent.value;
  498. setDryWet(value, false, false);
  499. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
  500. break;
  501. }
  502. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
  503. {
  504. value = ctrlEvent.value*127.0f/100.0f;
  505. setVolume(value, false, false);
  506. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
  507. break;
  508. }
  509. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
  510. {
  511. float left, right;
  512. value = ctrlEvent.value/0.5f - 1.0f;
  513. if (value < 0.0f)
  514. {
  515. left = -1.0f;
  516. right = (value*2.0f)+1.0f;
  517. }
  518. else if (value > 0.0f)
  519. {
  520. left = (value*2.0f)-1.0f;
  521. right = 1.0f;
  522. }
  523. else
  524. {
  525. left = -1.0f;
  526. right = 1.0f;
  527. }
  528. setBalanceLeft(left, false, false);
  529. setBalanceRight(right, false, false);
  530. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  531. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  532. break;
  533. }
  534. }
  535. #endif
  536. // Control plugin parameters
  537. uint32_t k;
  538. for (k=0; k < pData->param.count; ++k)
  539. {
  540. if (pData->param.data[k].midiChannel != event.channel)
  541. continue;
  542. if (pData->param.data[k].midiCC != ctrlEvent.param)
  543. continue;
  544. if (pData->param.data[k].type != PARAMETER_INPUT)
  545. continue;
  546. if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  547. continue;
  548. float value;
  549. if (pData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
  550. {
  551. value = (ctrlEvent.value < 0.5f) ? pData->param.ranges[k].min : pData->param.ranges[k].max;
  552. }
  553. else
  554. {
  555. value = pData->param.ranges[k].getUnnormalizedValue(ctrlEvent.value);
  556. if (pData->param.data[k].hints & PARAMETER_IS_INTEGER)
  557. value = std::rint(value);
  558. }
  559. setParameterValue(k, value, false, false, false);
  560. pData->postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
  561. break;
  562. }
  563. // check if event is already handled
  564. if (k != pData->param.count)
  565. break;
  566. if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F)
  567. {
  568. uint8_t midiData[3];
  569. midiData[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + i);
  570. midiData[1] = static_cast<uint8_t>(ctrlEvent.param);
  571. midiData[2] = uint8_t(ctrlEvent.value*127.0f);
  572. fMidiBuffer.addEvent(midiData, 3, static_cast<int>(event.time));
  573. }
  574. break;
  575. } // case kEngineControlEventTypeParameter
  576. case kEngineControlEventTypeMidiBank:
  577. if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  578. nextBankId = ctrlEvent.param;
  579. break;
  580. case kEngineControlEventTypeMidiProgram:
  581. if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  582. {
  583. const uint32_t nextProgramId = ctrlEvent.param;
  584. for (uint32_t k=0; k < pData->midiprog.count; ++k)
  585. {
  586. if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId)
  587. {
  588. const int32_t index(static_cast<int32_t>(k));
  589. setMidiProgram(index, false, false, false);
  590. pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, index, 0, 0.0f);
  591. break;
  592. }
  593. }
  594. }
  595. break;
  596. case kEngineControlEventTypeAllSoundOff:
  597. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  598. {
  599. uint8_t midiData[3];
  600. midiData[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + i);
  601. midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  602. midiData[2] = 0;
  603. fMidiBuffer.addEvent(midiData, 3, static_cast<int>(event.time));
  604. }
  605. break;
  606. case kEngineControlEventTypeAllNotesOff:
  607. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  608. {
  609. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  610. {
  611. allNotesOffSent = true;
  612. sendMidiAllNotesOffToCallback();
  613. }
  614. uint8_t midiData[3];
  615. midiData[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + i);
  616. midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  617. midiData[2] = 0;
  618. fMidiBuffer.addEvent(midiData, 3, static_cast<int>(event.time));
  619. }
  620. break;
  621. } // switch (ctrlEvent.type)
  622. break;
  623. } // case kEngineEventTypeControl
  624. case kEngineEventTypeMidi:
  625. {
  626. const EngineMidiEvent& midiEvent(event.midi);
  627. uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiEvent.data));
  628. uint8_t channel = event.channel;
  629. // Fix bad note-off
  630. if (MIDI_IS_STATUS_NOTE_ON(status) && midiEvent.data[2] == 0)
  631. status = MIDI_STATUS_NOTE_OFF;
  632. if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  633. continue;
  634. if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  635. continue;
  636. if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  637. continue;
  638. if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  639. continue;
  640. fMidiBuffer.addEvent(midiEvent.data, midiEvent.size, static_cast<int>(event.time));
  641. if (status == MIDI_STATUS_NOTE_ON)
  642. pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, midiEvent.data[1], midiEvent.data[2]);
  643. else if (status == MIDI_STATUS_NOTE_OFF)
  644. pData->postponeRtEvent(kPluginPostRtEventNoteOff, channel, midiEvent.data[1], 0.0f);
  645. break;
  646. } // case kEngineEventTypeMidi
  647. } // switch (event.type)
  648. }
  649. pData->postRtEvents.trySplice();
  650. } // End of Event Input
  651. // --------------------------------------------------------------------------------------------------------
  652. // Set TimeInfo
  653. const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
  654. fPosInfo.isPlaying = timeInfo.playing;
  655. if (timeInfo.valid & EngineTimeInfo::kValidBBT)
  656. {
  657. const double ppqBar = double(timeInfo.bbt.bar - 1) * timeInfo.bbt.beatsPerBar;
  658. const double ppqBeat = double(timeInfo.bbt.beat - 1);
  659. const double ppqTick = double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat;
  660. fPosInfo.bpm = timeInfo.bbt.beatsPerMinute;
  661. fPosInfo.timeSigNumerator = static_cast<int>(timeInfo.bbt.beatsPerBar);
  662. fPosInfo.timeSigDenominator = static_cast<int>(timeInfo.bbt.beatType);
  663. fPosInfo.timeInSamples = static_cast<int64_t>(timeInfo.frame);
  664. fPosInfo.timeInSeconds = static_cast<double>(fPosInfo.timeInSamples)/pData->engine->getSampleRate();
  665. fPosInfo.ppqPosition = ppqBar + ppqBeat + ppqTick;
  666. fPosInfo.ppqPositionOfLastBarStart = ppqBar;
  667. }
  668. // --------------------------------------------------------------------------------------------------------
  669. // Process
  670. processSingle(inBuffer, outBuffer, frames);
  671. // --------------------------------------------------------------------------------------------------------
  672. // MIDI Output
  673. if (pData->event.portOut != nullptr)
  674. {
  675. // TODO
  676. }
  677. }
  678. bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames)
  679. {
  680. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  681. if (pData->audioIn.count > 0)
  682. {
  683. CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
  684. }
  685. if (pData->audioOut.count > 0)
  686. {
  687. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  688. }
  689. // --------------------------------------------------------------------------------------------------------
  690. // Try lock, silence otherwise
  691. if (pData->engine->isOffline())
  692. {
  693. pData->singleMutex.lock();
  694. }
  695. else if (! pData->singleMutex.tryLock())
  696. {
  697. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  698. FloatVectorOperations::clear(outBuffer[i], static_cast<int>(frames));
  699. return false;
  700. }
  701. // --------------------------------------------------------------------------------------------------------
  702. // Set audio in buffers
  703. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  704. fAudioBuffer.copyFrom(static_cast<int>(i), 0, inBuffer[i], static_cast<int>(frames));
  705. // --------------------------------------------------------------------------------------------------------
  706. // Run plugin
  707. fInstance->processBlock(fAudioBuffer, fMidiBuffer);
  708. // --------------------------------------------------------------------------------------------------------
  709. // Set audio out buffers
  710. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  711. FloatVectorOperations::copy(outBuffer[i], fAudioBuffer.getReadPointer(static_cast<int>(i)), static_cast<int>(frames));
  712. // --------------------------------------------------------------------------------------------------------
  713. // Midi out
  714. if (! fMidiBuffer.isEmpty())
  715. {
  716. if (pData->event.portOut != nullptr)
  717. {
  718. const uint8* midiEventData;
  719. int midiEventSize, midiEventPosition;
  720. for (MidiBuffer::Iterator i(fMidiBuffer); i.getNextEvent(midiEventData, midiEventSize, midiEventPosition);)
  721. {
  722. CARLA_SAFE_ASSERT_BREAK(midiEventPosition >= 0 && midiEventPosition < static_cast<int>(frames));
  723. CARLA_SAFE_ASSERT_BREAK(midiEventSize > 0);
  724. if (! pData->event.portOut->writeMidiEvent(static_cast<uint32_t>(midiEventPosition), static_cast<uint8_t>(midiEventSize), midiEventData))
  725. break;
  726. }
  727. }
  728. fMidiBuffer.clear();
  729. }
  730. // --------------------------------------------------------------------------------------------------------
  731. pData->singleMutex.unlock();
  732. return true;
  733. }
  734. void bufferSizeChanged(const uint32_t newBufferSize) override
  735. {
  736. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  737. carla_debug("VstPlugin::bufferSizeChanged(%i)", newBufferSize);
  738. fAudioBuffer.setSize(static_cast<int>(std::max<uint32_t>(pData->audioIn.count, pData->audioOut.count)), static_cast<int>(newBufferSize));
  739. if (pData->active)
  740. {
  741. deactivate();
  742. activate();
  743. }
  744. }
  745. void sampleRateChanged(const double newSampleRate) override
  746. {
  747. CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
  748. carla_debug("VstPlugin::sampleRateChanged(%g)", newSampleRate);
  749. if (pData->active)
  750. {
  751. deactivate();
  752. activate();
  753. }
  754. }
  755. // -------------------------------------------------------------------
  756. // Plugin buffers
  757. // nothing
  758. // -------------------------------------------------------------------
  759. // Post-poned UI Stuff
  760. // nothing
  761. // -------------------------------------------------------------------
  762. protected:
  763. void audioProcessorParameterChanged(AudioProcessor*, int index, float value) override
  764. {
  765. CARLA_SAFE_ASSERT_RETURN(index >= 0,);
  766. const uint32_t uindex(static_cast<uint32_t>(index));
  767. const float fixedValue(pData->param.getFixedValue(uindex, value));
  768. CarlaPlugin::setParameterValue(static_cast<uint32_t>(index), fixedValue, false, true, true);
  769. }
  770. void audioProcessorChanged(AudioProcessor*) override
  771. {
  772. pData->engine->callback(ENGINE_CALLBACK_UPDATE, pData->id, 0, 0, 0.0f, nullptr);
  773. }
  774. void audioProcessorParameterChangeGestureBegin(AudioProcessor*, int) {}
  775. void audioProcessorParameterChangeGestureEnd(AudioProcessor*, int) {}
  776. bool getCurrentPosition(CurrentPositionInfo& result) override
  777. {
  778. carla_copyStruct<CurrentPositionInfo>(result, fPosInfo);
  779. return true;
  780. }
  781. // -------------------------------------------------------------------
  782. public:
  783. bool init(const char* const filename, const char* const name, /*const char* const label, */const int64_t uniqueId, const char* const format)
  784. {
  785. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  786. // ---------------------------------------------------------------
  787. // first checks
  788. if (pData->client != nullptr)
  789. {
  790. pData->engine->setLastError("Plugin client is already registered");
  791. return false;
  792. }
  793. if (filename == nullptr || filename[0] == '\0')
  794. {
  795. pData->engine->setLastError("null filename");
  796. return false;
  797. }
  798. #if 0
  799. if (label == nullptr || label[0] == '\0')
  800. {
  801. pData->engine->setLastError("null label");
  802. return false;
  803. }
  804. #endif
  805. if (format == nullptr || format[0] == '\0')
  806. {
  807. pData->engine->setLastError("null format");
  808. return false;
  809. }
  810. #ifdef CARLA_OS_LINUX
  811. const MessageManagerLock mmLock;
  812. #endif
  813. // ---------------------------------------------------------------
  814. // fix path for wine usage
  815. String jfilename(filename);
  816. #ifdef CARLA_OS_WIN
  817. if (jfilename.startsWith("/"))
  818. {
  819. jfilename.replace("/", "\\");
  820. jfilename = "Z:" + jfilename;
  821. }
  822. #endif
  823. //fDesc.name = fDesc.descriptiveName = label;
  824. fDesc.uid = static_cast<int>(uniqueId);
  825. fDesc.fileOrIdentifier = jfilename;
  826. fDesc.pluginFormatName = format;
  827. fFormatManager.addDefaultFormats();
  828. String error;
  829. fInstance = fFormatManager.createPluginInstance(fDesc, 44100, 512, error);
  830. if (fInstance == nullptr)
  831. {
  832. pData->engine->setLastError(error.toRawUTF8());
  833. return false;
  834. }
  835. fInstance->fillInPluginDescription(fDesc);
  836. fInstance->setPlayHead(this);
  837. fInstance->addListener(this);
  838. // ---------------------------------------------------------------
  839. // get info
  840. if (name != nullptr && name[0] != '\0')
  841. pData->name = pData->engine->getUniquePluginName(name);
  842. else
  843. pData->name = pData->engine->getUniquePluginName(fInstance->getName().toRawUTF8());
  844. pData->filename = carla_strdup(filename);
  845. // ---------------------------------------------------------------
  846. // register client
  847. pData->client = pData->engine->addClient(this);
  848. if (pData->client == nullptr || ! pData->client->isOk())
  849. {
  850. pData->engine->setLastError("Failed to register plugin client");
  851. return false;
  852. }
  853. // ---------------------------------------------------------------
  854. // load plugin settings
  855. {
  856. // set default options
  857. pData->options = 0x0;
  858. pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  859. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  860. //pData->options |= PLUGIN_OPTION_USE_CHUNKS;
  861. if (fInstance->acceptsMidi())
  862. {
  863. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  864. pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  865. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  866. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  867. }
  868. #ifndef BUILD_BRIDGE
  869. // set identifier string
  870. String juceId(fDesc.createIdentifierString());
  871. CarlaString identifier("Juce/");
  872. identifier += juceId.toRawUTF8();
  873. pData->identifier = identifier.dup();
  874. // load settings
  875. pData->options = pData->loadSettings(pData->options, getOptionsAvailable());
  876. // ignore settings, we need this anyway
  877. pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  878. #endif
  879. }
  880. return true;
  881. }
  882. private:
  883. PluginDescription fDesc;
  884. AudioPluginInstance* fInstance;
  885. AudioPluginFormatManager fFormatManager;
  886. AudioSampleBuffer fAudioBuffer;
  887. MidiBuffer fMidiBuffer;
  888. CurrentPositionInfo fPosInfo;
  889. const char* fUniqueId;
  890. ScopedPointer<JucePluginWindow> fWindow;
  891. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JucePlugin)
  892. };
  893. CARLA_BACKEND_END_NAMESPACE
  894. #endif // HAVE_JUCE
  895. // -------------------------------------------------------------------------------------------------------------------
  896. CARLA_BACKEND_START_NAMESPACE
  897. CarlaPlugin* CarlaPlugin::newJuce(const Initializer& init, const char* const format)
  898. {
  899. carla_debug("CarlaPlugin::newJuce({%p, \"%s\", \"%s\", \"%s\", " P_INT64 "}, %s)", init.engine, init.filename, init.name, init.label, init.uniqueId, format);
  900. #ifdef HAVE_JUCE
  901. JucePlugin* const plugin(new JucePlugin(init.engine, init.id));
  902. if (! plugin->init(init.filename, init.name, /*init.label,*/ init.uniqueId, format))
  903. {
  904. delete plugin;
  905. return nullptr;
  906. }
  907. plugin->reload();
  908. if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack())
  909. {
  910. init.engine->setLastError("Carla's rack mode can only work with Stereo VST3 plugins, sorry!");
  911. delete plugin;
  912. return nullptr;
  913. }
  914. return plugin;
  915. #else
  916. init.engine->setLastError("Juce support not available");
  917. return nullptr;
  918. // unused
  919. (void)format;
  920. #endif
  921. }
  922. CARLA_BACKEND_END_NAMESPACE
  923. // -------------------------------------------------------------------------------------------------------------------