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.

CarlaEngine.cpp 83KB

11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
11 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
11 years ago
10 years ago
10 years ago
11 years ago
10 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
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
7 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 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
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 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
11 years ago
10 years ago
10 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
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
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 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
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
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408
  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2018 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. /* TODO:
  18. * - complete processRack(): carefully add to input, sorted events
  19. * - implement processPatchbay()
  20. * - implement oscSend_control_switch_plugins()
  21. * - something about the peaks?
  22. */
  23. #include "CarlaEngineInternal.hpp"
  24. #include "CarlaPlugin.hpp"
  25. #include "CarlaBackendUtils.hpp"
  26. #include "CarlaBinaryUtils.hpp"
  27. #include "CarlaEngineUtils.hpp"
  28. #include "CarlaMathUtils.hpp"
  29. #include "CarlaPipeUtils.hpp"
  30. #include "CarlaStateUtils.hpp"
  31. #include "CarlaMIDI.h"
  32. #include "jackbridge/JackBridge.hpp"
  33. #include "water/files/File.h"
  34. #include "water/streams/MemoryOutputStream.h"
  35. #include "water/xml/XmlDocument.h"
  36. #include "water/xml/XmlElement.h"
  37. using water::Array;
  38. using water::CharPointer_UTF8;
  39. using water::File;
  40. using water::MemoryOutputStream;
  41. using water::String;
  42. using water::StringArray;
  43. using water::XmlDocument;
  44. using water::XmlElement;
  45. CARLA_BACKEND_START_NAMESPACE
  46. // -----------------------------------------------------------------------
  47. // Carla Engine
  48. CarlaEngine::CarlaEngine()
  49. : pData(new ProtectedData(this))
  50. {
  51. carla_debug("CarlaEngine::CarlaEngine()");
  52. }
  53. CarlaEngine::~CarlaEngine()
  54. {
  55. carla_debug("CarlaEngine::~CarlaEngine()");
  56. delete pData;
  57. }
  58. // -----------------------------------------------------------------------
  59. // Static calls
  60. uint CarlaEngine::getDriverCount()
  61. {
  62. carla_debug("CarlaEngine::getDriverCount()");
  63. uint count = 0;
  64. if (jackbridge_is_ok())
  65. count += 1;
  66. #ifndef BUILD_BRIDGE
  67. count += getRtAudioApiCount();
  68. #endif
  69. return count;
  70. }
  71. const char* CarlaEngine::getDriverName(const uint index2)
  72. {
  73. carla_debug("CarlaEngine::getDriverName(%i)", index2);
  74. uint index(index2);
  75. if (jackbridge_is_ok() && index-- == 0)
  76. return "JACK";
  77. #ifndef BUILD_BRIDGE
  78. if (const uint count = getRtAudioApiCount())
  79. {
  80. if (index < count)
  81. return getRtAudioApiName(index);
  82. }
  83. #endif
  84. carla_stderr("CarlaEngine::getDriverName(%i) - invalid index", index2);
  85. return nullptr;
  86. }
  87. const char* const* CarlaEngine::getDriverDeviceNames(const uint index2)
  88. {
  89. carla_debug("CarlaEngine::getDriverDeviceNames(%i)", index2);
  90. uint index(index2);
  91. if (jackbridge_is_ok() && index-- == 0)
  92. {
  93. static const char* ret[3] = { "Auto-Connect OFF", "Auto-Connect ON", nullptr };
  94. return ret;
  95. }
  96. #ifndef BUILD_BRIDGE
  97. if (const uint count = getRtAudioApiCount())
  98. {
  99. if (index < count)
  100. return getRtAudioApiDeviceNames(index);
  101. }
  102. #endif
  103. carla_stderr("CarlaEngine::getDriverDeviceNames(%i) - invalid index", index2);
  104. return nullptr;
  105. }
  106. const EngineDriverDeviceInfo* CarlaEngine::getDriverDeviceInfo(const uint index2, const char* const deviceName)
  107. {
  108. carla_debug("CarlaEngine::getDriverDeviceInfo(%i, \"%s\")", index2, deviceName);
  109. uint index(index2);
  110. if (jackbridge_is_ok() && index-- == 0)
  111. {
  112. static uint32_t bufSizes[11] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 0 };
  113. static EngineDriverDeviceInfo devInfo;
  114. devInfo.hints = ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE;
  115. devInfo.bufferSizes = bufSizes;
  116. devInfo.sampleRates = nullptr;
  117. return &devInfo;
  118. }
  119. #ifndef BUILD_BRIDGE
  120. if (const uint count = getRtAudioApiCount())
  121. {
  122. if (index < count)
  123. return getRtAudioDeviceInfo(index, deviceName);
  124. }
  125. #endif
  126. carla_stderr("CarlaEngine::getDriverDeviceNames(%i, \"%s\") - invalid index", index2, deviceName);
  127. return nullptr;
  128. }
  129. CarlaEngine* CarlaEngine::newDriverByName(const char* const driverName)
  130. {
  131. CARLA_SAFE_ASSERT_RETURN(driverName != nullptr && driverName[0] != '\0', nullptr);
  132. carla_debug("CarlaEngine::newDriverByName(\"%s\")", driverName);
  133. if (std::strcmp(driverName, "JACK") == 0)
  134. return newJack();
  135. #ifndef BUILD_BRIDGE
  136. // -------------------------------------------------------------------
  137. // common
  138. if (std::strcmp(driverName, "Dummy") == 0)
  139. return newRtAudio(AUDIO_API_NULL);
  140. if (std::strncmp(driverName, "JACK ", 5) == 0)
  141. return newRtAudio(AUDIO_API_JACK);
  142. if (std::strcmp(driverName, "OSS") == 0)
  143. return newRtAudio(AUDIO_API_OSS);
  144. // -------------------------------------------------------------------
  145. // linux
  146. if (std::strcmp(driverName, "ALSA") == 0)
  147. return newRtAudio(AUDIO_API_ALSA);
  148. if (std::strcmp(driverName, "PulseAudio") == 0)
  149. return newRtAudio(AUDIO_API_PULSEAUDIO);
  150. // -------------------------------------------------------------------
  151. // macos
  152. if (std::strcmp(driverName, "CoreAudio") == 0)
  153. return newRtAudio(AUDIO_API_COREAUDIO);
  154. // -------------------------------------------------------------------
  155. // windows
  156. if (std::strcmp(driverName, "ASIO") == 0)
  157. return newRtAudio(AUDIO_API_ASIO);
  158. if (std::strcmp(driverName, "DirectSound") == 0)
  159. return newRtAudio(AUDIO_API_DIRECTSOUND);
  160. if (std::strcmp(driverName, "WASAPI") == 0)
  161. return newRtAudio(AUDIO_API_WASAPI);
  162. #endif
  163. carla_stderr("CarlaEngine::newDriverByName(\"%s\") - invalid driver name", driverName);
  164. return nullptr;
  165. }
  166. // -----------------------------------------------------------------------
  167. // Constant values
  168. uint CarlaEngine::getMaxClientNameSize() const noexcept
  169. {
  170. return STR_MAX/2;
  171. }
  172. uint CarlaEngine::getMaxPortNameSize() const noexcept
  173. {
  174. return STR_MAX;
  175. }
  176. uint CarlaEngine::getCurrentPluginCount() const noexcept
  177. {
  178. return pData->curPluginCount;
  179. }
  180. uint CarlaEngine::getMaxPluginNumber() const noexcept
  181. {
  182. return pData->maxPluginNumber;
  183. }
  184. // -----------------------------------------------------------------------
  185. // Virtual, per-engine type calls
  186. bool CarlaEngine::close()
  187. {
  188. carla_debug("CarlaEngine::close()");
  189. if (pData->curPluginCount != 0)
  190. {
  191. pData->aboutToClose = true;
  192. removeAllPlugins();
  193. }
  194. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  195. if (pData->osc.isControlRegistered())
  196. oscSend_control_exit();
  197. #endif
  198. pData->close();
  199. callback(ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0.0f, nullptr);
  200. return true;
  201. }
  202. bool CarlaEngine::usesConstantBufferSize() const noexcept
  203. {
  204. return true;
  205. }
  206. void CarlaEngine::idle() noexcept
  207. {
  208. CARLA_SAFE_ASSERT_RETURN(pData->nextAction.opcode == kEnginePostActionNull,);
  209. CARLA_SAFE_ASSERT_RETURN(pData->nextPluginId == pData->maxPluginNumber,);
  210. CARLA_SAFE_ASSERT_RETURN(getType() != kEngineTypePlugin,);
  211. for (uint i=0; i < pData->curPluginCount; ++i)
  212. {
  213. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  214. if (plugin != nullptr && plugin->isEnabled())
  215. {
  216. const uint hints(plugin->getHints());
  217. if ((hints & PLUGIN_HAS_CUSTOM_UI) != 0 && (hints & PLUGIN_NEEDS_UI_MAIN_THREAD) != 0)
  218. {
  219. try {
  220. plugin->uiIdle();
  221. } CARLA_SAFE_EXCEPTION_CONTINUE("Plugin uiIdle");
  222. }
  223. }
  224. }
  225. #ifdef HAVE_LIBLO
  226. pData->osc.idle();
  227. #endif
  228. }
  229. CarlaEngineClient* CarlaEngine::addClient(CarlaPlugin* const)
  230. {
  231. return new CarlaEngineClient(*this);
  232. }
  233. // -----------------------------------------------------------------------
  234. // Plugin management
  235. bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype,
  236. const char* const filename, const char* const name, const char* const label, const int64_t uniqueId,
  237. const void* const extra, const uint options)
  238. {
  239. CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
  240. #ifndef BUILD_BRIDGE
  241. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
  242. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId <= pData->maxPluginNumber, "Invalid engine internal data");
  243. #endif
  244. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
  245. CARLA_SAFE_ASSERT_RETURN_ERR(btype != BINARY_NONE, "Invalid plugin binary mode");
  246. CARLA_SAFE_ASSERT_RETURN_ERR(ptype != PLUGIN_NONE, "Invalid plugin type");
  247. CARLA_SAFE_ASSERT_RETURN_ERR((filename != nullptr && filename[0] != '\0') || (label != nullptr && label[0] != '\0'), "Invalid plugin filename and label");
  248. carla_debug("CarlaEngine::addPlugin(%i:%s, %i:%s, \"%s\", \"%s\", \"%s\", " P_INT64 ", %p, %u)", btype, BinaryType2Str(btype), ptype, PluginType2Str(ptype), filename, name, label, uniqueId, extra, options);
  249. uint id;
  250. #ifndef BUILD_BRIDGE
  251. CarlaPlugin* oldPlugin = nullptr;
  252. if (pData->nextPluginId < pData->curPluginCount)
  253. {
  254. id = pData->nextPluginId;
  255. pData->nextPluginId = pData->maxPluginNumber;
  256. oldPlugin = pData->plugins[id].plugin;
  257. CARLA_SAFE_ASSERT_RETURN_ERR(oldPlugin != nullptr, "Invalid replace plugin Id");
  258. }
  259. else
  260. #endif
  261. {
  262. id = pData->curPluginCount;
  263. if (id == pData->maxPluginNumber)
  264. {
  265. setLastError("Maximum number of plugins reached");
  266. return false;
  267. }
  268. #ifndef BUILD_BRIDGE
  269. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins[id].plugin == nullptr, "Invalid engine internal data");
  270. #endif
  271. }
  272. CarlaPlugin::Initializer initializer = {
  273. this,
  274. id,
  275. filename,
  276. name,
  277. label,
  278. uniqueId,
  279. options
  280. };
  281. CarlaPlugin* plugin = nullptr;
  282. CarlaString bridgeBinary(pData->options.binaryDir);
  283. if (bridgeBinary.isNotEmpty())
  284. {
  285. #ifndef CARLA_OS_WIN
  286. if (btype == BINARY_NATIVE)
  287. {
  288. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-native";
  289. }
  290. else
  291. #endif
  292. {
  293. switch (btype)
  294. {
  295. case BINARY_POSIX32:
  296. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-posix32";
  297. break;
  298. case BINARY_POSIX64:
  299. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-posix64";
  300. break;
  301. case BINARY_WIN32:
  302. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-win32.exe";
  303. break;
  304. case BINARY_WIN64:
  305. bridgeBinary += CARLA_OS_SEP_STR "carla-bridge-win64.exe";
  306. break;
  307. default:
  308. bridgeBinary.clear();
  309. break;
  310. }
  311. }
  312. if (! File(bridgeBinary.buffer()).existsAsFile())
  313. bridgeBinary.clear();
  314. }
  315. // Prefer bridges for some specific plugins
  316. bool preferBridges = pData->options.preferPluginBridges;
  317. #ifndef BUILD_BRIDGE
  318. if (! preferBridges)
  319. {
  320. if (ptype == PLUGIN_LV2 && label != nullptr)
  321. {
  322. if (std::strncmp(label, "http://calf.sourceforge.net/plugins/", 36) == 0 ||
  323. std::strcmp(label, "http://factorial.hu/plugins/lv2/ir") == 0 ||
  324. std::strstr(label, "v1.sourceforge.net/lv2") != nullptr)
  325. {
  326. preferBridges = true;
  327. }
  328. }
  329. # if 0
  330. else if (ptype == PLUGIN_VST2)
  331. {
  332. /*
  333. char uniqueIdChars[5] = {
  334. static_cast<char>((uniqueId & 0xFF000000) >> 24),
  335. static_cast<char>((uniqueId & 0x00FF0000) >> 16),
  336. static_cast<char>((uniqueId & 0x0000FF00) >> 8),
  337. static_cast<char>((uniqueId & 0x000000FF) >> 1),
  338. 0
  339. };
  340. */
  341. /**/ if (uniqueId == 1633895765 && std::strstr(filename, "/ACE.") != nullptr)
  342. preferBridges = true;
  343. else if (uniqueId == 1433421876 && std::strstr(filename, "/Bazille.") != nullptr)
  344. preferBridges = true;
  345. else if (uniqueId == 1147754081 && std::strstr(filename, "/Diva.") != nullptr)
  346. preferBridges = true;
  347. else if (uniqueId == 1095583057 && std::strstr(filename, "/Filterscape.") != nullptr)
  348. preferBridges = true;
  349. else if (uniqueId == 1179866689 && std::strstr(filename, "/Filterscape.") != nullptr)
  350. preferBridges = true;
  351. else if (uniqueId == 1179865398 && std::strstr(filename, "/Filterscape.") != nullptr)
  352. preferBridges = true;
  353. else if (uniqueId == 1749636677 && std::strstr(filename, "/Hive.") != nullptr)
  354. preferBridges = true;
  355. else if (uniqueId == 1296452914 && std::strstr(filename, "/MFM2.") != nullptr)
  356. preferBridges = true;
  357. else if (uniqueId == 1349477487 && std::strstr(filename, "/Podolski.") != nullptr)
  358. preferBridges = true;
  359. else if (uniqueId == 1886548821 && std::strstr(filename, "/Presswerk.") != nullptr)
  360. preferBridges = true;
  361. else if (uniqueId == 1969770582 && std::strstr(filename, "/Protoverb.") != nullptr)
  362. preferBridges = true;
  363. else if (uniqueId == 1969771348 && std::strstr(filename, "/Satin.") != nullptr)
  364. preferBridges = true;
  365. else if (uniqueId == 1667388281 && std::strstr(filename, "/TripleCheese.") != nullptr)
  366. preferBridges = true;
  367. else if (uniqueId == 1952017974 && std::strstr(filename, "/TyrellN6.") != nullptr)
  368. preferBridges = true;
  369. else if (uniqueId == 1432568113 && std::strstr(filename, "/Uhbik.") != nullptr)
  370. preferBridges = true;
  371. else if (uniqueId == 1432568881 && std::strstr(filename, "/Uhbik.") != nullptr)
  372. preferBridges = true;
  373. else if (uniqueId == 1432572209 && std::strstr(filename, "/Uhbik.") != nullptr)
  374. preferBridges = true;
  375. else if (uniqueId == 1432569393 && std::strstr(filename, "/Uhbik.") != nullptr)
  376. preferBridges = true;
  377. else if (uniqueId == 1432569649 && std::strstr(filename, "/Uhbik.") != nullptr)
  378. preferBridges = true;
  379. else if (uniqueId == 1432571953 && std::strstr(filename, "/Uhbik.") != nullptr)
  380. preferBridges = true;
  381. else if (uniqueId == 1382232375 && std::strstr(filename, "/Uhbik.") != nullptr)
  382. preferBridges = true;
  383. else if (uniqueId == 1432572721 && std::strstr(filename, "/Uhbik.") != nullptr)
  384. preferBridges = true;
  385. else if (uniqueId == 1432572977 && std::strstr(filename, "/Uhbik.") != nullptr)
  386. preferBridges = true;
  387. else if (uniqueId == 1397572658 && std::strstr(filename, "/Zebra2.") != nullptr)
  388. preferBridges = true;
  389. else if (uniqueId == 1397572659 && std::strstr(filename, "/Zebra2.") != nullptr)
  390. preferBridges = true;
  391. else if (uniqueId == 1919243824 && std::strstr(filename, "/Zebra2.") != nullptr)
  392. preferBridges = true;
  393. else if (uniqueId == 1397578034 && std::strstr(filename, "/Zebra2.") != nullptr)
  394. preferBridges = true;
  395. else if (uniqueId == 1397573722 && std::strstr(filename, "/ZebraHZ.") != nullptr)
  396. preferBridges = true;
  397. }
  398. # endif
  399. // FIXME: linuxsampler inside carla-rack/patchbay plugin has some issues (only last kit makes noise)
  400. else if (getType() == kEngineTypePlugin && (ptype == PLUGIN_GIG || ptype == PLUGIN_SFZ))
  401. {
  402. // if we're not loading a project consider all is ok
  403. if (! pData->loadingProject)
  404. pData->firstLinuxSamplerInstance = true;
  405. // loading a project, revert first status if set
  406. else if (pData->firstLinuxSamplerInstance)
  407. pData->firstLinuxSamplerInstance = false;
  408. // now check if bridge is needed
  409. if (! pData->firstLinuxSamplerInstance)
  410. preferBridges = true;
  411. }
  412. }
  413. #endif // ! BUILD_BRIDGE
  414. if (ptype != PLUGIN_INTERNAL && (btype != BINARY_NATIVE || (preferBridges && bridgeBinary.isNotEmpty())))
  415. {
  416. if (bridgeBinary.isNotEmpty())
  417. {
  418. plugin = CarlaPlugin::newBridge(initializer, btype, ptype, bridgeBinary);
  419. }
  420. else
  421. {
  422. setLastError("This Carla build cannot handle this binary");
  423. return false;
  424. }
  425. }
  426. else
  427. {
  428. bool use16Outs;
  429. setLastError("Invalid or unsupported plugin type");
  430. switch (ptype)
  431. {
  432. case PLUGIN_NONE:
  433. break;
  434. case PLUGIN_INTERNAL:
  435. /*if (std::strcmp(label, "FluidSynth") == 0)
  436. {
  437. use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true") == 0);
  438. plugin = CarlaPlugin::newFluidSynth(initializer, use16Outs);
  439. }
  440. else if (std::strcmp(label, "LinuxSampler (GIG)") == 0)
  441. {
  442. use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true") == 0);
  443. plugin = CarlaPlugin::newLinuxSampler(initializer, "GIG", use16Outs);
  444. }
  445. else if (std::strcmp(label, "LinuxSampler (SF2)") == 0)
  446. {
  447. use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true") == 0);
  448. plugin = CarlaPlugin::newLinuxSampler(initializer, "SF2", use16Outs);
  449. }
  450. else if (std::strcmp(label, "LinuxSampler (SFZ)") == 0)
  451. {
  452. use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true") == 0);
  453. plugin = CarlaPlugin::newLinuxSampler(initializer, "SFZ", use16Outs);
  454. }*/
  455. plugin = CarlaPlugin::newNative(initializer);
  456. break;
  457. case PLUGIN_LADSPA:
  458. plugin = CarlaPlugin::newLADSPA(initializer, (const LADSPA_RDF_Descriptor*)extra);
  459. break;
  460. case PLUGIN_DSSI:
  461. plugin = CarlaPlugin::newDSSI(initializer);
  462. break;
  463. case PLUGIN_LV2:
  464. plugin = CarlaPlugin::newLV2(initializer);
  465. break;
  466. case PLUGIN_VST2:
  467. plugin = CarlaPlugin::newVST2(initializer);
  468. break;
  469. case PLUGIN_GIG:
  470. use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true") == 0);
  471. plugin = CarlaPlugin::newFileGIG(initializer, use16Outs);
  472. break;
  473. case PLUGIN_SF2:
  474. use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true") == 0);
  475. plugin = CarlaPlugin::newFileSF2(initializer, use16Outs);
  476. break;
  477. case PLUGIN_SFZ:
  478. plugin = CarlaPlugin::newFileSFZ(initializer);
  479. break;
  480. case PLUGIN_JACK:
  481. plugin = CarlaPlugin::newJackApp(initializer);
  482. break;
  483. }
  484. }
  485. if (plugin == nullptr)
  486. return false;
  487. plugin->reload();
  488. #ifndef BUILD_BRIDGE
  489. bool canRun = true;
  490. /**/ if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  491. {
  492. /**/ if (! plugin->canRunInRack())
  493. {
  494. setLastError("Carla's rack mode can only work with Mono or Stereo plugins, sorry!");
  495. canRun = false;
  496. }
  497. else if (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0)
  498. {
  499. setLastError("Carla's rack mode cannot work with plugins that have CV ports, sorry!");
  500. canRun = false;
  501. }
  502. }
  503. else if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  504. {
  505. /**/ if (plugin->getMidiInCount() > 1 || plugin->getMidiOutCount() > 1)
  506. {
  507. setLastError("Carla's patchbay mode cannot work with plugins that have multiple MIDI ports, sorry!");
  508. canRun = false;
  509. }
  510. else if (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0)
  511. {
  512. setLastError("CV ports in patchbay mode is still TODO");
  513. canRun = false;
  514. }
  515. }
  516. if (! canRun)
  517. {
  518. delete plugin;
  519. return false;
  520. }
  521. # ifdef HAVE_LIBLO
  522. plugin->registerToOscClient();
  523. # endif
  524. #endif
  525. EnginePluginData& pluginData(pData->plugins[id]);
  526. pluginData.plugin = plugin;
  527. pluginData.insPeak[0] = 0.0f;
  528. pluginData.insPeak[1] = 0.0f;
  529. pluginData.outsPeak[0] = 0.0f;
  530. pluginData.outsPeak[1] = 0.0f;
  531. #ifndef BUILD_BRIDGE
  532. if (oldPlugin != nullptr)
  533. {
  534. CARLA_SAFE_ASSERT(! pData->loadingProject);
  535. const ScopedThreadStopper sts(this);
  536. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  537. pData->graph.replacePlugin(oldPlugin, plugin);
  538. const bool wasActive = oldPlugin->getInternalParameterValue(PARAMETER_ACTIVE) >= 0.5f;
  539. const float oldDryWet = oldPlugin->getInternalParameterValue(PARAMETER_DRYWET);
  540. const float oldVolume = oldPlugin->getInternalParameterValue(PARAMETER_VOLUME);
  541. delete oldPlugin;
  542. if (plugin->getHints() & PLUGIN_CAN_DRYWET)
  543. plugin->setDryWet(oldDryWet, true, true);
  544. if (plugin->getHints() & PLUGIN_CAN_VOLUME)
  545. plugin->setVolume(oldVolume, true, true);
  546. plugin->setActive(wasActive, true, true);
  547. plugin->setEnabled(true);
  548. callback(ENGINE_CALLBACK_RELOAD_ALL, id, 0, 0, 0.0f, nullptr);
  549. }
  550. else if (! pData->loadingProject)
  551. #endif
  552. {
  553. plugin->setActive(true, true, false);
  554. plugin->setEnabled(true);
  555. ++pData->curPluginCount;
  556. callback(ENGINE_CALLBACK_PLUGIN_ADDED, id, 0, 0, 0.0f, plugin->getName());
  557. #ifndef BUILD_BRIDGE
  558. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  559. pData->graph.addPlugin(plugin);
  560. #endif
  561. }
  562. return true;
  563. }
  564. bool CarlaEngine::addPlugin(const PluginType ptype, const char* const filename, const char* const name, const char* const label, const int64_t uniqueId, const void* const extra)
  565. {
  566. return addPlugin(BINARY_NATIVE, ptype, filename, name, label, uniqueId, extra, 0x0);
  567. }
  568. bool CarlaEngine::removePlugin(const uint id)
  569. {
  570. CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
  571. #ifndef BUILD_BRIDGE
  572. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
  573. CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data");
  574. #endif
  575. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
  576. CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id");
  577. carla_debug("CarlaEngine::removePlugin(%i)", id);
  578. CarlaPlugin* const plugin(pData->plugins[id].plugin);
  579. CARLA_SAFE_ASSERT_RETURN_ERR(plugin != nullptr, "Could not find plugin to remove");
  580. CARLA_SAFE_ASSERT_RETURN_ERR(plugin->getId() == id, "Invalid engine internal data");
  581. const ScopedThreadStopper sts(this);
  582. #ifndef BUILD_BRIDGE
  583. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  584. pData->graph.removePlugin(plugin);
  585. const ScopedActionLock sal(this, kEnginePostActionRemovePlugin, id, 0);
  586. /*
  587. for (uint i=id; i < pData->curPluginCount; ++i)
  588. {
  589. CarlaPlugin* const plugin2(pData->plugins[i].plugin);
  590. CARLA_SAFE_ASSERT_BREAK(plugin2 != nullptr);
  591. plugin2->updateOscURL();
  592. }
  593. */
  594. # ifdef HAVE_LIBLO
  595. if (isOscControlRegistered())
  596. oscSend_control_remove_plugin(id);
  597. # endif
  598. #else
  599. pData->curPluginCount = 0;
  600. carla_zeroStructs(pData->plugins, 1);
  601. #endif
  602. delete plugin;
  603. callback(ENGINE_CALLBACK_PLUGIN_REMOVED, id, 0, 0, 0.0f, nullptr);
  604. return true;
  605. }
  606. bool CarlaEngine::removeAllPlugins()
  607. {
  608. CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
  609. #ifndef BUILD_BRIDGE
  610. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
  611. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId == pData->maxPluginNumber, "Invalid engine internal data");
  612. #endif
  613. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
  614. carla_debug("CarlaEngine::removeAllPlugins()");
  615. if (pData->curPluginCount == 0)
  616. return true;
  617. const ScopedThreadStopper sts(this);
  618. const uint curPluginCount(pData->curPluginCount);
  619. #ifndef BUILD_BRIDGE
  620. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  621. pData->graph.removeAllPlugins();
  622. # ifdef HAVE_LIBLO
  623. if (isOscControlRegistered())
  624. {
  625. for (uint i=0; i < curPluginCount; ++i)
  626. oscSend_control_remove_plugin(curPluginCount-i-1);
  627. }
  628. # endif
  629. #endif
  630. const ScopedActionLock sal(this, kEnginePostActionZeroCount, 0, 0);
  631. callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  632. for (uint i=0; i < curPluginCount; ++i)
  633. {
  634. EnginePluginData& pluginData(pData->plugins[i]);
  635. if (pluginData.plugin != nullptr)
  636. {
  637. delete pluginData.plugin;
  638. pluginData.plugin = nullptr;
  639. }
  640. pluginData.insPeak[0] = 0.0f;
  641. pluginData.insPeak[1] = 0.0f;
  642. pluginData.outsPeak[0] = 0.0f;
  643. pluginData.outsPeak[1] = 0.0f;
  644. callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  645. }
  646. return true;
  647. }
  648. #ifndef BUILD_BRIDGE
  649. const char* CarlaEngine::renamePlugin(const uint id, const char* const newName)
  650. {
  651. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
  652. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data");
  653. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data");
  654. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
  655. CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id");
  656. CARLA_SAFE_ASSERT_RETURN_ERRN(newName != nullptr && newName[0] != '\0', "Invalid plugin name");
  657. carla_debug("CarlaEngine::renamePlugin(%i, \"%s\")", id, newName);
  658. CarlaPlugin* const plugin(pData->plugins[id].plugin);
  659. CARLA_SAFE_ASSERT_RETURN_ERRN(plugin != nullptr, "Could not find plugin to rename");
  660. CARLA_SAFE_ASSERT_RETURN_ERRN(plugin->getId() == id, "Invalid engine internal data");
  661. const char* const uniqueName(getUniquePluginName(newName));
  662. CARLA_SAFE_ASSERT_RETURN_ERRN(uniqueName != nullptr, "Unable to get new unique plugin name");
  663. plugin->setName(uniqueName);
  664. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  665. pData->graph.renamePlugin(plugin, uniqueName);
  666. delete[] uniqueName;
  667. return plugin->getName();
  668. }
  669. bool CarlaEngine::clonePlugin(const uint id)
  670. {
  671. CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
  672. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
  673. CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data");
  674. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
  675. CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id");
  676. carla_debug("CarlaEngine::clonePlugin(%i)", id);
  677. CarlaPlugin* const plugin(pData->plugins[id].plugin);
  678. CARLA_SAFE_ASSERT_RETURN_ERR(plugin != nullptr, "Could not find plugin to clone");
  679. CARLA_SAFE_ASSERT_RETURN_ERR(plugin->getId() == id, "Invalid engine internal data");
  680. char label[STR_MAX+1];
  681. carla_zeroChars(label, STR_MAX+1);
  682. plugin->getLabel(label);
  683. const uint pluginCountBefore(pData->curPluginCount);
  684. if (! addPlugin(plugin->getBinaryType(), plugin->getType(),
  685. plugin->getFilename(), plugin->getName(), label, plugin->getUniqueId(),
  686. plugin->getExtraStuff(), plugin->getOptionsEnabled()))
  687. return false;
  688. CARLA_SAFE_ASSERT_RETURN_ERR(pluginCountBefore+1 == pData->curPluginCount, "No new plugin found");
  689. if (CarlaPlugin* const newPlugin = pData->plugins[pluginCountBefore].plugin)
  690. newPlugin->loadStateSave(plugin->getStateSave());
  691. return true;
  692. }
  693. bool CarlaEngine::replacePlugin(const uint id) noexcept
  694. {
  695. CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
  696. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
  697. CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data");
  698. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
  699. carla_debug("CarlaEngine::replacePlugin(%i)", id);
  700. // might use this to reset
  701. if (id == pData->maxPluginNumber)
  702. {
  703. pData->nextPluginId = pData->maxPluginNumber;
  704. return true;
  705. }
  706. CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id");
  707. CarlaPlugin* const plugin(pData->plugins[id].plugin);
  708. CARLA_SAFE_ASSERT_RETURN_ERR(plugin != nullptr, "Could not find plugin to replace");
  709. CARLA_SAFE_ASSERT_RETURN_ERR(plugin->getId() == id, "Invalid engine internal data");
  710. pData->nextPluginId = id;
  711. return true;
  712. }
  713. bool CarlaEngine::switchPlugins(const uint idA, const uint idB) noexcept
  714. {
  715. CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
  716. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data");
  717. CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount >= 2, "Invalid engine internal data");
  718. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
  719. CARLA_SAFE_ASSERT_RETURN_ERR(idA != idB, "Invalid operation, cannot switch plugin with itself");
  720. CARLA_SAFE_ASSERT_RETURN_ERR(idA < pData->curPluginCount, "Invalid plugin Id");
  721. CARLA_SAFE_ASSERT_RETURN_ERR(idB < pData->curPluginCount, "Invalid plugin Id");
  722. carla_debug("CarlaEngine::switchPlugins(%i)", idA, idB);
  723. CarlaPlugin* const pluginA(pData->plugins[idA].plugin);
  724. CarlaPlugin* const pluginB(pData->plugins[idB].plugin);
  725. CARLA_SAFE_ASSERT_RETURN_ERR(pluginA != nullptr, "Could not find plugin to switch");
  726. CARLA_SAFE_ASSERT_RETURN_ERR(pluginA != nullptr, "Could not find plugin to switch");
  727. CARLA_SAFE_ASSERT_RETURN_ERR(pluginA->getId() == idA, "Invalid engine internal data");
  728. CARLA_SAFE_ASSERT_RETURN_ERR(pluginB->getId() == idB, "Invalid engine internal data");
  729. const ScopedThreadStopper sts(this);
  730. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  731. pData->graph.replacePlugin(pluginA, pluginB);
  732. const ScopedActionLock sal(this, kEnginePostActionSwitchPlugins, idA, idB);
  733. // TODO
  734. /*
  735. pluginA->updateOscURL();
  736. pluginB->updateOscURL();
  737. if (isOscControlRegistered())
  738. oscSend_control_switch_plugins(idA, idB);
  739. */
  740. return true;
  741. }
  742. #endif
  743. CarlaPlugin* CarlaEngine::getPlugin(const uint id) const noexcept
  744. {
  745. #ifndef BUILD_BRIDGE
  746. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data");
  747. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data");
  748. #endif
  749. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data");
  750. CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id");
  751. return pData->plugins[id].plugin;
  752. }
  753. CarlaPlugin* CarlaEngine::getPluginUnchecked(const uint id) const noexcept
  754. {
  755. return pData->plugins[id].plugin;
  756. }
  757. const char* CarlaEngine::getUniquePluginName(const char* const name) const
  758. {
  759. CARLA_SAFE_ASSERT_RETURN(pData->nextAction.opcode == kEnginePostActionNull, nullptr);
  760. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr);
  761. carla_debug("CarlaEngine::getUniquePluginName(\"%s\")", name);
  762. CarlaString sname;
  763. sname = name;
  764. if (sname.isEmpty())
  765. {
  766. sname = "(No name)";
  767. return sname.dup();
  768. }
  769. const std::size_t maxNameSize(carla_minConstrained<uint>(getMaxClientNameSize(), 0xff, 6U) - 6); // 6 = strlen(" (10)") + 1
  770. if (maxNameSize == 0 || ! isRunning())
  771. return sname.dup();
  772. sname.truncate(maxNameSize);
  773. sname.replace(':', '.'); // ':' is used in JACK1 to split client/port names
  774. for (uint i=0; i < pData->curPluginCount; ++i)
  775. {
  776. CARLA_SAFE_ASSERT_BREAK(pData->plugins[i].plugin != nullptr);
  777. // Check if unique name doesn't exist
  778. if (const char* const pluginName = pData->plugins[i].plugin->getName())
  779. {
  780. if (sname != pluginName)
  781. continue;
  782. }
  783. // Check if string has already been modified
  784. {
  785. const std::size_t len(sname.length());
  786. // 1 digit, ex: " (2)"
  787. if (sname[len-4] == ' ' && sname[len-3] == '(' && sname.isDigit(len-2) && sname[len-1] == ')')
  788. {
  789. const int number = sname[len-2] - '0';
  790. if (number == 9)
  791. {
  792. // next number is 10, 2 digits
  793. sname.truncate(len-4);
  794. sname += " (10)";
  795. //sname.replace(" (9)", " (10)");
  796. }
  797. else
  798. sname[len-2] = char('0' + number + 1);
  799. continue;
  800. }
  801. // 2 digits, ex: " (11)"
  802. if (sname[len-5] == ' ' && sname[len-4] == '(' && sname.isDigit(len-3) && sname.isDigit(len-2) && sname[len-1] == ')')
  803. {
  804. char n2 = sname[len-2];
  805. char n3 = sname[len-3];
  806. if (n2 == '9')
  807. {
  808. n2 = '0';
  809. n3 = static_cast<char>(n3 + 1);
  810. }
  811. else
  812. n2 = static_cast<char>(n2 + 1);
  813. sname[len-2] = n2;
  814. sname[len-3] = n3;
  815. continue;
  816. }
  817. }
  818. // Modify string if not
  819. sname += " (2)";
  820. }
  821. return sname.dup();
  822. }
  823. // -----------------------------------------------------------------------
  824. // Project management
  825. bool CarlaEngine::loadFile(const char* const filename)
  826. {
  827. CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
  828. CARLA_SAFE_ASSERT_RETURN_ERR(filename != nullptr && filename[0] != '\0', "Invalid filename");
  829. carla_debug("CarlaEngine::loadFile(\"%s\")", filename);
  830. const String jfilename = String(CharPointer_UTF8(filename));
  831. File file(jfilename);
  832. CARLA_SAFE_ASSERT_RETURN_ERR(file.exists(), "Requested file does not exist or is not a readable");
  833. CarlaString baseName(file.getFileNameWithoutExtension().toRawUTF8());
  834. CarlaString extension(file.getFileExtension().replace(".","").toLowerCase().toRawUTF8());
  835. const uint curPluginId(pData->nextPluginId < pData->curPluginCount ? pData->nextPluginId : pData->curPluginCount);
  836. // -------------------------------------------------------------------
  837. // NOTE: please keep in sync with carla_get_supported_file_extensions!!
  838. if (extension == "carxp" || extension == "carxs")
  839. return loadProject(filename);
  840. // -------------------------------------------------------------------
  841. if (extension == "gig")
  842. return addPlugin(PLUGIN_GIG, filename, baseName, baseName, 0, nullptr);
  843. if (extension == "sf2")
  844. return addPlugin(PLUGIN_SF2, filename, baseName, baseName, 0, nullptr);
  845. if (extension == "sfz")
  846. return addPlugin(PLUGIN_SFZ, filename, baseName, baseName, 0, nullptr);
  847. // -------------------------------------------------------------------
  848. if (
  849. #ifdef HAVE_SNDFILE
  850. extension == "aif" ||
  851. extension == "aiff" ||
  852. extension == "bwf" ||
  853. extension == "flac" ||
  854. extension == "oga" ||
  855. extension == "ogg" ||
  856. extension == "w64" ||
  857. extension == "wav" ||
  858. #endif
  859. #ifdef HAVE_FFMPEG
  860. extension == "3g2" ||
  861. extension == "3gp" ||
  862. extension == "aac" ||
  863. extension == "ac3" ||
  864. extension == "amr" ||
  865. extension == "ape" ||
  866. extension == "mp2" ||
  867. extension == "mp3" ||
  868. extension == "mpc" ||
  869. extension == "wma" ||
  870. #endif
  871. false
  872. )
  873. {
  874. if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "audiofile", 0, nullptr))
  875. {
  876. if (CarlaPlugin* const plugin = getPlugin(curPluginId))
  877. plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, "file", filename, true);
  878. return true;
  879. }
  880. return false;
  881. }
  882. // -------------------------------------------------------------------
  883. if (extension == "mid" || extension == "midi")
  884. {
  885. if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "midifile", 0, nullptr))
  886. {
  887. if (CarlaPlugin* const plugin = getPlugin(curPluginId))
  888. plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, "file", filename, true);
  889. return true;
  890. }
  891. return false;
  892. }
  893. // -------------------------------------------------------------------
  894. // ZynAddSubFX
  895. if (extension == "xmz" || extension == "xiz")
  896. {
  897. #ifdef HAVE_ZYN_DEPS
  898. CarlaString nicerName("Zyn - ");
  899. const std::size_t sep(baseName.find('-')+1);
  900. if (sep < baseName.length())
  901. nicerName += baseName.buffer()+sep;
  902. else
  903. nicerName += baseName;
  904. //nicerName
  905. if (addPlugin(PLUGIN_INTERNAL, nullptr, nicerName, "zynaddsubfx", 0, nullptr))
  906. {
  907. callback(ENGINE_CALLBACK_UI_STATE_CHANGED, curPluginId, 0, 0, 0.0f, nullptr);
  908. if (CarlaPlugin* const plugin = getPlugin(curPluginId))
  909. plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, (extension == "xmz") ? "CarlaAlternateFile1" : "CarlaAlternateFile2", filename, true);
  910. return true;
  911. }
  912. return false;
  913. #else
  914. setLastError("This Carla build does not have ZynAddSubFX support");
  915. return false;
  916. #endif
  917. }
  918. // -------------------------------------------------------------------
  919. // Direct plugin binaries
  920. #ifdef CARLA_OS_MAC
  921. if (extension == "vst")
  922. return addPlugin(PLUGIN_VST2, filename, nullptr, nullptr, 0, nullptr);
  923. #else
  924. if (extension == "dll" || extension == "so")
  925. return addPlugin(getBinaryTypeFromFile(filename), PLUGIN_VST2, filename, nullptr, nullptr, 0, nullptr, 0x0);
  926. #endif
  927. // -------------------------------------------------------------------
  928. setLastError("Unknown file extension");
  929. return false;
  930. }
  931. bool CarlaEngine::loadProject(const char* const filename)
  932. {
  933. CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish");
  934. CARLA_SAFE_ASSERT_RETURN_ERR(filename != nullptr && filename[0] != '\0', "Invalid filename");
  935. carla_debug("CarlaEngine::loadProject(\"%s\")", filename);
  936. const String jfilename = String(CharPointer_UTF8(filename));
  937. File file(jfilename);
  938. CARLA_SAFE_ASSERT_RETURN_ERR(file.existsAsFile(), "Requested file does not exist or is not a readable file");
  939. XmlDocument xml(file);
  940. return loadProjectInternal(xml);
  941. }
  942. bool CarlaEngine::saveProject(const char* const filename)
  943. {
  944. CARLA_SAFE_ASSERT_RETURN_ERR(filename != nullptr && filename[0] != '\0', "Invalid filename");
  945. carla_debug("CarlaEngine::saveProject(\"%s\")", filename);
  946. MemoryOutputStream out;
  947. saveProjectInternal(out);
  948. const String jfilename = String(CharPointer_UTF8(filename));
  949. File file(jfilename);
  950. if (file.replaceWithData(out.getData(), out.getDataSize()))
  951. return true;
  952. setLastError("Failed to write file");
  953. return false;
  954. }
  955. // -----------------------------------------------------------------------
  956. // Information (base)
  957. uint CarlaEngine::getHints() const noexcept
  958. {
  959. return pData->hints;
  960. }
  961. uint32_t CarlaEngine::getBufferSize() const noexcept
  962. {
  963. return pData->bufferSize;
  964. }
  965. double CarlaEngine::getSampleRate() const noexcept
  966. {
  967. return pData->sampleRate;
  968. }
  969. const char* CarlaEngine::getName() const noexcept
  970. {
  971. return pData->name;
  972. }
  973. EngineProcessMode CarlaEngine::getProccessMode() const noexcept
  974. {
  975. return pData->options.processMode;
  976. }
  977. const EngineOptions& CarlaEngine::getOptions() const noexcept
  978. {
  979. return pData->options;
  980. }
  981. const EngineTimeInfo& CarlaEngine::getTimeInfo() const noexcept
  982. {
  983. return pData->timeInfo;
  984. }
  985. // -----------------------------------------------------------------------
  986. // Information (peaks)
  987. float CarlaEngine::getInputPeak(const uint pluginId, const bool isLeft) const noexcept
  988. {
  989. if (pluginId == MAIN_CARLA_PLUGIN_ID)
  990. {
  991. // get peak from first plugin, if available
  992. if (pData->curPluginCount > 0)
  993. return pData->plugins[0].insPeak[isLeft ? 0 : 1];
  994. return 0.0f;
  995. }
  996. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount, 0.0f);
  997. return pData->plugins[pluginId].insPeak[isLeft ? 0 : 1];
  998. }
  999. float CarlaEngine::getOutputPeak(const uint pluginId, const bool isLeft) const noexcept
  1000. {
  1001. if (pluginId == MAIN_CARLA_PLUGIN_ID)
  1002. {
  1003. // get peak from last plugin, if available
  1004. if (pData->curPluginCount > 0)
  1005. return pData->plugins[pData->curPluginCount-1].outsPeak[isLeft ? 0 : 1];
  1006. return 0.0f;
  1007. }
  1008. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount, 0.0f);
  1009. return pData->plugins[pluginId].outsPeak[isLeft ? 0 : 1];
  1010. }
  1011. // -----------------------------------------------------------------------
  1012. // Callback
  1013. void CarlaEngine::callback(const EngineCallbackOpcode action, const uint pluginId, const int value1, const int value2, const float value3, const char* const valueStr) noexcept
  1014. {
  1015. #ifdef DEBUG
  1016. if (action != ENGINE_CALLBACK_IDLE)
  1017. carla_debug("CarlaEngine::callback(%i:%s, %i, %i, %i, %f, \"%s\")", action, EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valueStr);
  1018. #endif
  1019. #ifdef BUILD_BRIDGE
  1020. if (pData->isIdling)
  1021. #else
  1022. if (pData->isIdling && action != ENGINE_CALLBACK_PATCHBAY_CLIENT_DATA_CHANGED)
  1023. #endif
  1024. {
  1025. carla_stdout("callback while idling (%i:%s, %i, %i, %i, %f, \"%s\")", action, EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valueStr);
  1026. }
  1027. if (pData->callback != nullptr)
  1028. {
  1029. if (action == ENGINE_CALLBACK_IDLE)
  1030. ++pData->isIdling;
  1031. try {
  1032. pData->callback(pData->callbackPtr, action, pluginId, value1, value2, value3, valueStr);
  1033. #if defined(CARLA_OS_LINUX) && defined(__arm__)
  1034. } catch (__cxxabiv1::__forced_unwind&) {
  1035. carla_stderr2("Caught forced unwind exception in callback");
  1036. throw;
  1037. #endif
  1038. } catch (...) {
  1039. carla_safe_exception("callback", __FILE__, __LINE__);
  1040. }
  1041. if (action == ENGINE_CALLBACK_IDLE)
  1042. --pData->isIdling;
  1043. }
  1044. }
  1045. void CarlaEngine::setCallback(const EngineCallbackFunc func, void* const ptr) noexcept
  1046. {
  1047. carla_debug("CarlaEngine::setCallback(%p, %p)", func, ptr);
  1048. pData->callback = func;
  1049. pData->callbackPtr = ptr;
  1050. }
  1051. // -----------------------------------------------------------------------
  1052. // File Callback
  1053. const char* CarlaEngine::runFileCallback(const FileCallbackOpcode action, const bool isDir, const char* const title, const char* const filter) noexcept
  1054. {
  1055. CARLA_SAFE_ASSERT_RETURN(title != nullptr && title[0] != '\0', nullptr);
  1056. CARLA_SAFE_ASSERT_RETURN(filter != nullptr, nullptr);
  1057. carla_debug("CarlaEngine::runFileCallback(%i:%s, %s, \"%s\", \"%s\")", action, FileCallbackOpcode2Str(action), bool2str(isDir), title, filter);
  1058. const char* ret = nullptr;
  1059. if (pData->fileCallback != nullptr)
  1060. {
  1061. try {
  1062. ret = pData->fileCallback(pData->fileCallbackPtr, action, isDir, title, filter);
  1063. } CARLA_SAFE_EXCEPTION("runFileCallback");
  1064. }
  1065. return ret;
  1066. }
  1067. void CarlaEngine::setFileCallback(const FileCallbackFunc func, void* const ptr) noexcept
  1068. {
  1069. carla_debug("CarlaEngine::setFileCallback(%p, %p)", func, ptr);
  1070. pData->fileCallback = func;
  1071. pData->fileCallbackPtr = ptr;
  1072. }
  1073. // -----------------------------------------------------------------------
  1074. // Transport
  1075. void CarlaEngine::transportPlay() noexcept
  1076. {
  1077. pData->timeInfo.playing = true;
  1078. pData->time.setNeedsReset();
  1079. }
  1080. void CarlaEngine::transportPause() noexcept
  1081. {
  1082. if (pData->timeInfo.playing)
  1083. pData->time.pause();
  1084. else
  1085. pData->time.setNeedsReset();
  1086. }
  1087. void CarlaEngine::transportBPM(const double bpm) noexcept
  1088. {
  1089. try {
  1090. pData->time.setBPM(bpm);
  1091. } CARLA_SAFE_EXCEPTION("CarlaEngine::transportBPM");
  1092. }
  1093. void CarlaEngine::transportRelocate(const uint64_t frame) noexcept
  1094. {
  1095. pData->time.relocate(frame);
  1096. }
  1097. // -----------------------------------------------------------------------
  1098. // Error handling
  1099. const char* CarlaEngine::getLastError() const noexcept
  1100. {
  1101. return pData->lastError;
  1102. }
  1103. void CarlaEngine::setLastError(const char* const error) const noexcept
  1104. {
  1105. pData->lastError = error;
  1106. }
  1107. // -----------------------------------------------------------------------
  1108. // Misc
  1109. bool CarlaEngine::isAboutToClose() const noexcept
  1110. {
  1111. return pData->aboutToClose;
  1112. }
  1113. bool CarlaEngine::setAboutToClose() noexcept
  1114. {
  1115. carla_debug("CarlaEngine::setAboutToClose()");
  1116. pData->aboutToClose = true;
  1117. return (pData->isIdling == 0);
  1118. }
  1119. // -----------------------------------------------------------------------
  1120. // Global options
  1121. void CarlaEngine::setOption(const EngineOption option, const int value, const char* const valueStr) noexcept
  1122. {
  1123. carla_debug("CarlaEngine::setOption(%i:%s, %i, \"%s\")", option, EngineOption2Str(option), value, valueStr);
  1124. if (isRunning() && (option == ENGINE_OPTION_PROCESS_MODE || option == ENGINE_OPTION_AUDIO_NUM_PERIODS || option == ENGINE_OPTION_AUDIO_DEVICE))
  1125. return carla_stderr("CarlaEngine::setOption(%i:%s, %i, \"%s\") - Cannot set this option while engine is running!", option, EngineOption2Str(option), value, valueStr);
  1126. // do not un-force stereo for rack mode
  1127. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && option == ENGINE_OPTION_FORCE_STEREO && value != 0)
  1128. return;
  1129. switch (option)
  1130. {
  1131. case ENGINE_OPTION_DEBUG:
  1132. break;
  1133. case ENGINE_OPTION_PROCESS_MODE:
  1134. CARLA_SAFE_ASSERT_RETURN(value >= ENGINE_PROCESS_MODE_SINGLE_CLIENT && value <= ENGINE_PROCESS_MODE_BRIDGE,);
  1135. pData->options.processMode = static_cast<EngineProcessMode>(value);
  1136. break;
  1137. case ENGINE_OPTION_TRANSPORT_MODE:
  1138. CARLA_SAFE_ASSERT_RETURN(value >= ENGINE_TRANSPORT_MODE_DISABLED && value <= ENGINE_TRANSPORT_MODE_BRIDGE,);
  1139. CARLA_SAFE_ASSERT_RETURN(getType() == kEngineTypeJack || value != ENGINE_TRANSPORT_MODE_JACK,);
  1140. pData->options.transportMode = static_cast<EngineTransportMode>(value);
  1141. delete[] pData->options.transportExtra;
  1142. if (value >= ENGINE_TRANSPORT_MODE_DISABLED && valueStr != nullptr)
  1143. pData->options.transportExtra = carla_strdup_safe(valueStr);
  1144. else
  1145. pData->options.transportExtra = nullptr;
  1146. pData->time.setNeedsReset();
  1147. #if defined(HAVE_HYLIA) && !defined(BUILD_BRIDGE)
  1148. // enable link now if needed
  1149. {
  1150. const bool linkEnabled = pData->options.transportExtra != nullptr && std::strstr(pData->options.transportExtra, ":link:") != nullptr;
  1151. pData->time.enableLink(linkEnabled);
  1152. }
  1153. #endif
  1154. break;
  1155. case ENGINE_OPTION_FORCE_STEREO:
  1156. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  1157. pData->options.forceStereo = (value != 0);
  1158. break;
  1159. case ENGINE_OPTION_PREFER_PLUGIN_BRIDGES:
  1160. #ifdef BUILD_BRIDGE
  1161. CARLA_SAFE_ASSERT_RETURN(value == 0,);
  1162. #else
  1163. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  1164. #endif
  1165. pData->options.preferPluginBridges = (value != 0);
  1166. break;
  1167. case ENGINE_OPTION_PREFER_UI_BRIDGES:
  1168. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  1169. pData->options.preferUiBridges = (value != 0);
  1170. break;
  1171. case ENGINE_OPTION_UIS_ALWAYS_ON_TOP:
  1172. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  1173. pData->options.uisAlwaysOnTop = (value != 0);
  1174. break;
  1175. case ENGINE_OPTION_MAX_PARAMETERS:
  1176. CARLA_SAFE_ASSERT_RETURN(value >= 0,);
  1177. pData->options.maxParameters = static_cast<uint>(value);
  1178. break;
  1179. case ENGINE_OPTION_UI_BRIDGES_TIMEOUT:
  1180. CARLA_SAFE_ASSERT_RETURN(value >= 0,);
  1181. pData->options.uiBridgesTimeout = static_cast<uint>(value);
  1182. break;
  1183. case ENGINE_OPTION_AUDIO_NUM_PERIODS:
  1184. CARLA_SAFE_ASSERT_RETURN(value >= 2 && value <= 3,);
  1185. pData->options.audioNumPeriods = static_cast<uint>(value);
  1186. break;
  1187. case ENGINE_OPTION_AUDIO_BUFFER_SIZE:
  1188. CARLA_SAFE_ASSERT_RETURN(value >= 8,);
  1189. pData->options.audioBufferSize = static_cast<uint>(value);
  1190. break;
  1191. case ENGINE_OPTION_AUDIO_SAMPLE_RATE:
  1192. CARLA_SAFE_ASSERT_RETURN(value >= 22050,);
  1193. pData->options.audioSampleRate = static_cast<uint>(value);
  1194. break;
  1195. case ENGINE_OPTION_AUDIO_DEVICE:
  1196. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr,);
  1197. if (pData->options.audioDevice != nullptr)
  1198. delete[] pData->options.audioDevice;
  1199. pData->options.audioDevice = carla_strdup_safe(valueStr);
  1200. break;
  1201. case ENGINE_OPTION_PLUGIN_PATH:
  1202. CARLA_SAFE_ASSERT_RETURN(value > PLUGIN_NONE,);
  1203. CARLA_SAFE_ASSERT_RETURN(value <= PLUGIN_SFZ,);
  1204. switch (value)
  1205. {
  1206. case PLUGIN_LADSPA:
  1207. if (pData->options.pathLADSPA != nullptr)
  1208. delete[] pData->options.pathLADSPA;
  1209. if (valueStr != nullptr)
  1210. pData->options.pathLADSPA = carla_strdup_safe(valueStr);
  1211. else
  1212. pData->options.pathLADSPA = nullptr;
  1213. break;
  1214. case PLUGIN_DSSI:
  1215. if (pData->options.pathDSSI != nullptr)
  1216. delete[] pData->options.pathDSSI;
  1217. if (valueStr != nullptr)
  1218. pData->options.pathDSSI = carla_strdup_safe(valueStr);
  1219. else
  1220. pData->options.pathDSSI = nullptr;
  1221. break;
  1222. case PLUGIN_LV2:
  1223. if (pData->options.pathLV2 != nullptr)
  1224. delete[] pData->options.pathLV2;
  1225. if (valueStr != nullptr)
  1226. pData->options.pathLV2 = carla_strdup_safe(valueStr);
  1227. else
  1228. pData->options.pathLV2 = nullptr;
  1229. break;
  1230. case PLUGIN_VST2:
  1231. if (pData->options.pathVST2 != nullptr)
  1232. delete[] pData->options.pathVST2;
  1233. if (valueStr != nullptr)
  1234. pData->options.pathVST2 = carla_strdup_safe(valueStr);
  1235. else
  1236. pData->options.pathVST2 = nullptr;
  1237. break;
  1238. case PLUGIN_GIG:
  1239. if (pData->options.pathGIG != nullptr)
  1240. delete[] pData->options.pathGIG;
  1241. if (valueStr != nullptr)
  1242. pData->options.pathGIG = carla_strdup_safe(valueStr);
  1243. else
  1244. pData->options.pathGIG = nullptr;
  1245. break;
  1246. case PLUGIN_SF2:
  1247. if (pData->options.pathSF2 != nullptr)
  1248. delete[] pData->options.pathSF2;
  1249. if (valueStr != nullptr)
  1250. pData->options.pathSF2 = carla_strdup_safe(valueStr);
  1251. else
  1252. pData->options.pathSF2 = nullptr;
  1253. break;
  1254. case PLUGIN_SFZ:
  1255. if (pData->options.pathSFZ != nullptr)
  1256. delete[] pData->options.pathSFZ;
  1257. if (valueStr != nullptr)
  1258. pData->options.pathSFZ = carla_strdup_safe(valueStr);
  1259. else
  1260. pData->options.pathSFZ = nullptr;
  1261. break;
  1262. default:
  1263. return carla_stderr("CarlaEngine::setOption(%i:%s, %i, \"%s\") - Invalid plugin type", option, EngineOption2Str(option), value, valueStr);
  1264. break;
  1265. }
  1266. break;
  1267. case ENGINE_OPTION_PATH_BINARIES:
  1268. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  1269. if (pData->options.binaryDir != nullptr)
  1270. delete[] pData->options.binaryDir;
  1271. pData->options.binaryDir = carla_strdup_safe(valueStr);
  1272. break;
  1273. case ENGINE_OPTION_PATH_RESOURCES:
  1274. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  1275. if (pData->options.resourceDir != nullptr)
  1276. delete[] pData->options.resourceDir;
  1277. pData->options.resourceDir = carla_strdup_safe(valueStr);
  1278. break;
  1279. case ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR: {
  1280. CARLA_SAFE_ASSERT_RETURN(pData->options.binaryDir != nullptr && pData->options.binaryDir[0] != '\0',);
  1281. #ifdef CARLA_OS_LINUX
  1282. const ScopedEngineEnvironmentLocker _seel(this);
  1283. if (value != 0)
  1284. {
  1285. CarlaString interposerPath(CarlaString(pData->options.binaryDir) + "/libcarla_interposer-safe.so");
  1286. ::setenv("LD_PRELOAD", interposerPath.buffer(), 1);
  1287. }
  1288. else
  1289. {
  1290. ::unsetenv("LD_PRELOAD");
  1291. }
  1292. #endif
  1293. } break;
  1294. case ENGINE_OPTION_FRONTEND_WIN_ID: {
  1295. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  1296. const long long winId(std::strtoll(valueStr, nullptr, 16));
  1297. CARLA_SAFE_ASSERT_RETURN(winId >= 0,);
  1298. pData->options.frontendWinId = static_cast<uintptr_t>(winId);
  1299. } break;
  1300. #ifndef CARLA_OS_WIN
  1301. case ENGINE_OPTION_WINE_EXECUTABLE:
  1302. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  1303. if (pData->options.wine.executable != nullptr)
  1304. delete[] pData->options.wine.executable;
  1305. pData->options.wine.executable = carla_strdup_safe(valueStr);
  1306. break;
  1307. case ENGINE_OPTION_WINE_AUTO_PREFIX:
  1308. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  1309. pData->options.wine.autoPrefix = (value != 0);
  1310. break;
  1311. case ENGINE_OPTION_WINE_FALLBACK_PREFIX:
  1312. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  1313. if (pData->options.wine.fallbackPrefix != nullptr)
  1314. delete[] pData->options.wine.fallbackPrefix;
  1315. pData->options.wine.fallbackPrefix = carla_strdup_safe(valueStr);
  1316. break;
  1317. case ENGINE_OPTION_WINE_RT_PRIO_ENABLED:
  1318. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  1319. pData->options.wine.rtPrio = (value != 0);
  1320. break;
  1321. case ENGINE_OPTION_WINE_BASE_RT_PRIO:
  1322. CARLA_SAFE_ASSERT_RETURN(value >= 1 && value <= 89,);
  1323. pData->options.wine.baseRtPrio = value;
  1324. break;
  1325. case ENGINE_OPTION_WINE_SERVER_RT_PRIO:
  1326. CARLA_SAFE_ASSERT_RETURN(value >= 1 && value <= 99,);
  1327. pData->options.wine.serverRtPrio = value;
  1328. break;
  1329. #endif
  1330. case ENGINE_OPTION_DEBUG_CONSOLE_OUTPUT:
  1331. break;
  1332. }
  1333. }
  1334. #ifdef HAVE_LIBLO
  1335. // -----------------------------------------------------------------------
  1336. // OSC Stuff
  1337. # ifndef BUILD_BRIDGE
  1338. bool CarlaEngine::isOscControlRegistered() const noexcept
  1339. {
  1340. return pData->osc.isControlRegistered();
  1341. }
  1342. # endif
  1343. void CarlaEngine::idleOsc() const noexcept
  1344. {
  1345. pData->osc.idle();
  1346. }
  1347. const char* CarlaEngine::getOscServerPathTCP() const noexcept
  1348. {
  1349. return pData->osc.getServerPathTCP();
  1350. }
  1351. const char* CarlaEngine::getOscServerPathUDP() const noexcept
  1352. {
  1353. return pData->osc.getServerPathUDP();
  1354. }
  1355. #endif
  1356. // -----------------------------------------------------------------------
  1357. // Helper functions
  1358. EngineEvent* CarlaEngine::getInternalEventBuffer(const bool isInput) const noexcept
  1359. {
  1360. return isInput ? pData->events.in : pData->events.out;
  1361. }
  1362. // -----------------------------------------------------------------------
  1363. // Internal stuff
  1364. void CarlaEngine::bufferSizeChanged(const uint32_t newBufferSize)
  1365. {
  1366. carla_debug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize);
  1367. #ifndef BUILD_BRIDGE
  1368. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK ||
  1369. pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  1370. {
  1371. pData->graph.setBufferSize(newBufferSize);
  1372. }
  1373. #endif
  1374. pData->time.updateAudioValues(newBufferSize, pData->sampleRate);
  1375. for (uint i=0; i < pData->curPluginCount; ++i)
  1376. {
  1377. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1378. if (plugin != nullptr && plugin->isEnabled())
  1379. plugin->bufferSizeChanged(newBufferSize);
  1380. }
  1381. callback(ENGINE_CALLBACK_BUFFER_SIZE_CHANGED, 0, static_cast<int>(newBufferSize), 0, 0.0f, nullptr);
  1382. }
  1383. void CarlaEngine::sampleRateChanged(const double newSampleRate)
  1384. {
  1385. carla_debug("CarlaEngine::sampleRateChanged(%g)", newSampleRate);
  1386. #ifndef BUILD_BRIDGE
  1387. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK ||
  1388. pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  1389. {
  1390. pData->graph.setSampleRate(newSampleRate);
  1391. }
  1392. #endif
  1393. pData->time.updateAudioValues(pData->bufferSize, newSampleRate);
  1394. for (uint i=0; i < pData->curPluginCount; ++i)
  1395. {
  1396. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1397. if (plugin != nullptr && plugin->isEnabled())
  1398. plugin->sampleRateChanged(newSampleRate);
  1399. }
  1400. callback(ENGINE_CALLBACK_SAMPLE_RATE_CHANGED, 0, 0, 0, static_cast<float>(newSampleRate), nullptr);
  1401. }
  1402. void CarlaEngine::offlineModeChanged(const bool isOfflineNow)
  1403. {
  1404. carla_debug("CarlaEngine::offlineModeChanged(%s)", bool2str(isOfflineNow));
  1405. #ifndef BUILD_BRIDGE
  1406. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK ||
  1407. pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  1408. {
  1409. pData->graph.setOffline(isOfflineNow);
  1410. }
  1411. #endif
  1412. for (uint i=0; i < pData->curPluginCount; ++i)
  1413. {
  1414. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1415. if (plugin != nullptr && plugin->isEnabled())
  1416. plugin->offlineModeChanged(isOfflineNow);
  1417. }
  1418. }
  1419. void CarlaEngine::setPluginPeaks(const uint pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept
  1420. {
  1421. EnginePluginData& pluginData(pData->plugins[pluginId]);
  1422. pluginData.insPeak[0] = inPeaks[0];
  1423. pluginData.insPeak[1] = inPeaks[1];
  1424. pluginData.outsPeak[0] = outPeaks[0];
  1425. pluginData.outsPeak[1] = outPeaks[1];
  1426. }
  1427. void CarlaEngine::saveProjectInternal(water::MemoryOutputStream& outStream) const
  1428. {
  1429. // send initial prepareForSave first, giving time for bridges to act
  1430. for (uint i=0; i < pData->curPluginCount; ++i)
  1431. {
  1432. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1433. if (plugin != nullptr && plugin->isEnabled())
  1434. {
  1435. #ifndef BUILD_BRIDGE
  1436. // deactivate bridge client-side ping check, since some plugins block during save
  1437. if (plugin->getHints() & PLUGIN_IS_BRIDGE)
  1438. plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, "__CarlaPingOnOff__", "false", false);
  1439. #endif
  1440. plugin->prepareForSave();
  1441. }
  1442. }
  1443. outStream << "<?xml version='1.0' encoding='UTF-8'?>\n";
  1444. outStream << "<!DOCTYPE CARLA-PROJECT>\n";
  1445. outStream << "<CARLA-PROJECT VERSION='2.0'>\n";
  1446. const bool isPlugin(getType() == kEngineTypePlugin);
  1447. const EngineOptions& options(pData->options);
  1448. MemoryOutputStream outSettings(1024);
  1449. // save appropriate engine settings
  1450. outSettings << " <EngineSettings>\n";
  1451. //processMode
  1452. //transportMode
  1453. outSettings << " <ForceStereo>" << bool2str(options.forceStereo) << "</ForceStereo>\n";
  1454. outSettings << " <PreferPluginBridges>" << bool2str(options.preferPluginBridges) << "</PreferPluginBridges>\n";
  1455. outSettings << " <PreferUiBridges>" << bool2str(options.preferUiBridges) << "</PreferUiBridges>\n";
  1456. outSettings << " <UIsAlwaysOnTop>" << bool2str(options.uisAlwaysOnTop) << "</UIsAlwaysOnTop>\n";
  1457. outSettings << " <MaxParameters>" << String(options.maxParameters) << "</MaxParameters>\n";
  1458. outSettings << " <UIBridgesTimeout>" << String(options.uiBridgesTimeout) << "</UIBridgesTimeout>\n";
  1459. if (isPlugin)
  1460. {
  1461. outSettings << " <LADSPA_PATH>" << xmlSafeString(options.pathLADSPA, true) << "</LADSPA_PATH>\n";
  1462. outSettings << " <DSSI_PATH>" << xmlSafeString(options.pathDSSI, true) << "</DSSI_PATH>\n";
  1463. outSettings << " <LV2_PATH>" << xmlSafeString(options.pathLV2, true) << "</LV2_PATH>\n";
  1464. outSettings << " <VST2_PATH>" << xmlSafeString(options.pathVST2, true) << "</VST2_PATH>\n";
  1465. outSettings << " <GIG_PATH>" << xmlSafeString(options.pathGIG, true) << "</GIG_PATH>\n";
  1466. outSettings << " <SF2_PATH>" << xmlSafeString(options.pathSF2, true) << "</SF2_PATH>\n";
  1467. outSettings << " <SFZ_PATH>" << xmlSafeString(options.pathSFZ, true) << "</SFZ_PATH>\n";
  1468. }
  1469. outSettings << " </EngineSettings>\n";
  1470. outStream << outSettings;
  1471. char strBuf[STR_MAX+1];
  1472. for (uint i=0; i < pData->curPluginCount; ++i)
  1473. {
  1474. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1475. if (plugin != nullptr && plugin->isEnabled())
  1476. {
  1477. MemoryOutputStream outPlugin(4096), streamPlugin;
  1478. plugin->getStateSave(false).dumpToMemoryStream(streamPlugin);
  1479. outPlugin << "\n";
  1480. strBuf[0] = '\0';
  1481. plugin->getRealName(strBuf);
  1482. if (strBuf[0] != '\0')
  1483. outPlugin << " <!-- " << xmlSafeString(strBuf, true) << " -->\n";
  1484. outPlugin << " <Plugin>\n";
  1485. outPlugin << streamPlugin;
  1486. outPlugin << " </Plugin>\n";
  1487. outStream << outPlugin;
  1488. }
  1489. }
  1490. #ifndef BUILD_BRIDGE
  1491. // tell bridges we're done saving
  1492. for (uint i=0; i < pData->curPluginCount; ++i)
  1493. {
  1494. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1495. if (plugin != nullptr && plugin->isEnabled() && (plugin->getHints() & PLUGIN_IS_BRIDGE) != 0)
  1496. plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, "__CarlaPingOnOff__", "true", false);
  1497. }
  1498. // save internal connections
  1499. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  1500. {
  1501. if (const char* const* const patchbayConns = getPatchbayConnections(false))
  1502. {
  1503. MemoryOutputStream outPatchbay(2048);
  1504. outPatchbay << "\n <Patchbay>\n";
  1505. for (int i=0; patchbayConns[i] != nullptr && patchbayConns[i+1] != nullptr; ++i, ++i )
  1506. {
  1507. const char* const connSource(patchbayConns[i]);
  1508. const char* const connTarget(patchbayConns[i+1]);
  1509. CARLA_SAFE_ASSERT_CONTINUE(connSource != nullptr && connSource[0] != '\0');
  1510. CARLA_SAFE_ASSERT_CONTINUE(connTarget != nullptr && connTarget[0] != '\0');
  1511. outPatchbay << " <Connection>\n";
  1512. outPatchbay << " <Source>" << xmlSafeString(connSource, true) << "</Source>\n";
  1513. outPatchbay << " <Target>" << xmlSafeString(connTarget, true) << "</Target>\n";
  1514. outPatchbay << " </Connection>\n";
  1515. }
  1516. outPatchbay << " </Patchbay>\n";
  1517. outStream << outPatchbay;
  1518. }
  1519. }
  1520. // if we're running inside some session-manager (and using JACK), let them handle the connections
  1521. bool saveExternalConnections;
  1522. /**/ if (isPlugin)
  1523. saveExternalConnections = false;
  1524. else if (std::strcmp(getCurrentDriverName(), "JACK") != 0)
  1525. saveExternalConnections = true;
  1526. else if (std::getenv("CARLA_DONT_MANAGE_CONNECTIONS") != nullptr)
  1527. saveExternalConnections = false;
  1528. else if (std::getenv("LADISH_APP_NAME") != nullptr)
  1529. saveExternalConnections = false;
  1530. else if (std::getenv("NSM_URL") != nullptr)
  1531. saveExternalConnections = false;
  1532. else
  1533. saveExternalConnections = true;
  1534. if (saveExternalConnections)
  1535. {
  1536. if (const char* const* const patchbayConns = getPatchbayConnections(true))
  1537. {
  1538. MemoryOutputStream outPatchbay(2048);
  1539. outPatchbay << "\n <ExternalPatchbay>\n";
  1540. for (int i=0; patchbayConns[i] != nullptr && patchbayConns[i+1] != nullptr; ++i, ++i )
  1541. {
  1542. const char* const connSource(patchbayConns[i]);
  1543. const char* const connTarget(patchbayConns[i+1]);
  1544. CARLA_SAFE_ASSERT_CONTINUE(connSource != nullptr && connSource[0] != '\0');
  1545. CARLA_SAFE_ASSERT_CONTINUE(connTarget != nullptr && connTarget[0] != '\0');
  1546. outPatchbay << " <Connection>\n";
  1547. outPatchbay << " <Source>" << xmlSafeString(connSource, true) << "</Source>\n";
  1548. outPatchbay << " <Target>" << xmlSafeString(connTarget, true) << "</Target>\n";
  1549. outPatchbay << " </Connection>\n";
  1550. }
  1551. outPatchbay << " </ExternalPatchbay>\n";
  1552. outStream << outPatchbay;
  1553. }
  1554. }
  1555. #endif
  1556. outStream << "</CARLA-PROJECT>\n";
  1557. }
  1558. static String findBinaryInCustomPath(const char* const searchPath, const char* const binary)
  1559. {
  1560. const StringArray searchPaths(StringArray::fromTokens(searchPath, CARLA_OS_SPLIT_STR, ""));
  1561. // try direct filename first
  1562. String jbinary(binary);
  1563. // adjust for current platform
  1564. #ifdef CARLA_OS_WIN
  1565. if (jbinary[0] == '/')
  1566. jbinary = "C:" + jbinary.replaceCharacter('/', '\\');
  1567. #else
  1568. if (jbinary[1] == ':' && (jbinary[2] == '\\' || jbinary[2] == '/'))
  1569. jbinary = jbinary.substring(2).replaceCharacter('\\', '/');
  1570. #endif
  1571. String filename = File(jbinary).getFileName();
  1572. int searchFlags = File::findFiles|File::ignoreHiddenFiles;
  1573. #ifdef CARLA_OS_MAC
  1574. if (filename.endsWithIgnoreCase(".vst"))
  1575. searchFlags |= File::findDirectories;
  1576. #endif
  1577. Array<File> results;
  1578. for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it)
  1579. {
  1580. const File path(*it);
  1581. results.clear();
  1582. path.findChildFiles(results, searchFlags, true, filename);
  1583. if (results.size() > 0)
  1584. return results.getFirst().getFullPathName();
  1585. }
  1586. // try changing extension
  1587. #if defined(CARLA_OS_MAC)
  1588. if (filename.endsWithIgnoreCase(".dll") || filename.endsWithIgnoreCase(".so"))
  1589. filename = File(jbinary).getFileNameWithoutExtension() + ".dylib";
  1590. #elif defined(CARLA_OS_WIN)
  1591. if (filename.endsWithIgnoreCase(".dylib") || filename.endsWithIgnoreCase(".so"))
  1592. filename = File(jbinary).getFileNameWithoutExtension() + ".dll";
  1593. #else
  1594. if (filename.endsWithIgnoreCase(".dll") || filename.endsWithIgnoreCase(".dylib"))
  1595. filename = File(jbinary).getFileNameWithoutExtension() + ".so";
  1596. #endif
  1597. else
  1598. return String();
  1599. for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it)
  1600. {
  1601. const File path(*it);
  1602. results.clear();
  1603. path.findChildFiles(results, searchFlags, true, filename);
  1604. if (results.size() > 0)
  1605. return results.getFirst().getFullPathName();
  1606. }
  1607. return String();
  1608. }
  1609. bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)
  1610. {
  1611. ScopedPointer<XmlElement> xmlElement(xmlDoc.getDocumentElement(true));
  1612. CARLA_SAFE_ASSERT_RETURN_ERR(xmlElement != nullptr, "Failed to parse project file");
  1613. const String& xmlType(xmlElement->getTagName());
  1614. const bool isPreset(xmlType.equalsIgnoreCase("carla-preset"));
  1615. if (! (xmlType.equalsIgnoreCase("carla-project") || isPreset))
  1616. {
  1617. callback(ENGINE_CALLBACK_PROJECT_LOAD_FINISHED, 0, 0, 0, 0.0f, nullptr);
  1618. setLastError("Not a valid Carla project or preset file");
  1619. return false;
  1620. }
  1621. #ifndef BUILD_BRIDGE
  1622. const ScopedValueSetter<bool> _svs(pData->loadingProject, true, false);
  1623. #endif
  1624. // completely load file
  1625. xmlElement = xmlDoc.getDocumentElement(false);
  1626. CARLA_SAFE_ASSERT_RETURN_ERR(xmlElement != nullptr, "Failed to completely parse project file");
  1627. if (pData->aboutToClose)
  1628. return true;
  1629. const bool isPlugin(getType() == kEngineTypePlugin);
  1630. // engine settings
  1631. for (XmlElement* elem = xmlElement->getFirstChildElement(); elem != nullptr; elem = elem->getNextElement())
  1632. {
  1633. const String& tagName(elem->getTagName());
  1634. if (! tagName.equalsIgnoreCase("enginesettings"))
  1635. continue;
  1636. for (XmlElement* settElem = elem->getFirstChildElement(); settElem != nullptr; settElem = settElem->getNextElement())
  1637. {
  1638. const String& tag(settElem->getTagName());
  1639. const String text(settElem->getAllSubText().trim());
  1640. /** some settings might be incorrect or require extra work,
  1641. so we call setOption rather than modifying them direly */
  1642. int option = -1;
  1643. int value = 0;
  1644. const char* valueStr = nullptr;
  1645. /**/ if (tag.equalsIgnoreCase("forcestereo"))
  1646. {
  1647. option = ENGINE_OPTION_FORCE_STEREO;
  1648. value = text.equalsIgnoreCase("true") ? 1 : 0;
  1649. }
  1650. else if (tag.equalsIgnoreCase("preferpluginbridges"))
  1651. {
  1652. option = ENGINE_OPTION_PREFER_PLUGIN_BRIDGES;
  1653. value = text.equalsIgnoreCase("true") ? 1 : 0;
  1654. }
  1655. else if (tag.equalsIgnoreCase("preferuibridges"))
  1656. {
  1657. option = ENGINE_OPTION_PREFER_UI_BRIDGES;
  1658. value = text.equalsIgnoreCase("true") ? 1 : 0;
  1659. }
  1660. else if (tag.equalsIgnoreCase("uisalwaysontop"))
  1661. {
  1662. option = ENGINE_OPTION_UIS_ALWAYS_ON_TOP;
  1663. value = text.equalsIgnoreCase("true") ? 1 : 0;
  1664. }
  1665. else if (tag.equalsIgnoreCase("maxparameters"))
  1666. {
  1667. option = ENGINE_OPTION_MAX_PARAMETERS;
  1668. value = text.getIntValue();
  1669. }
  1670. else if (tag.equalsIgnoreCase("uibridgestimeout"))
  1671. {
  1672. option = ENGINE_OPTION_UI_BRIDGES_TIMEOUT;
  1673. value = text.getIntValue();
  1674. }
  1675. else if (isPlugin)
  1676. {
  1677. /**/ if (tag.equalsIgnoreCase("LADSPA_PATH"))
  1678. {
  1679. option = ENGINE_OPTION_PLUGIN_PATH;
  1680. value = PLUGIN_LADSPA;
  1681. valueStr = text.toRawUTF8();
  1682. }
  1683. else if (tag.equalsIgnoreCase("DSSI_PATH"))
  1684. {
  1685. option = ENGINE_OPTION_PLUGIN_PATH;
  1686. value = PLUGIN_DSSI;
  1687. valueStr = text.toRawUTF8();
  1688. }
  1689. else if (tag.equalsIgnoreCase("LV2_PATH"))
  1690. {
  1691. option = ENGINE_OPTION_PLUGIN_PATH;
  1692. value = PLUGIN_LV2;
  1693. valueStr = text.toRawUTF8();
  1694. }
  1695. else if (tag.equalsIgnoreCase("VST2_PATH"))
  1696. {
  1697. option = ENGINE_OPTION_PLUGIN_PATH;
  1698. value = PLUGIN_VST2;
  1699. valueStr = text.toRawUTF8();
  1700. }
  1701. else if (tag.equalsIgnoreCase("GIG_PATH"))
  1702. {
  1703. option = ENGINE_OPTION_PLUGIN_PATH;
  1704. value = PLUGIN_GIG;
  1705. valueStr = text.toRawUTF8();
  1706. }
  1707. else if (tag.equalsIgnoreCase("SF2_PATH"))
  1708. {
  1709. option = ENGINE_OPTION_PLUGIN_PATH;
  1710. value = PLUGIN_SF2;
  1711. valueStr = text.toRawUTF8();
  1712. }
  1713. else if (tag.equalsIgnoreCase("SFZ_PATH"))
  1714. {
  1715. option = ENGINE_OPTION_PLUGIN_PATH;
  1716. value = PLUGIN_SFZ;
  1717. valueStr = text.toRawUTF8();
  1718. }
  1719. }
  1720. CARLA_SAFE_ASSERT_CONTINUE(option != -1);
  1721. setOption(static_cast<EngineOption>(option), value, valueStr);
  1722. }
  1723. break;
  1724. }
  1725. if (pData->aboutToClose)
  1726. return true;
  1727. // handle plugins first
  1728. for (XmlElement* elem = xmlElement->getFirstChildElement(); elem != nullptr; elem = elem->getNextElement())
  1729. {
  1730. const String& tagName(elem->getTagName());
  1731. if (isPreset || tagName.equalsIgnoreCase("plugin"))
  1732. {
  1733. CarlaStateSave stateSave;
  1734. stateSave.fillFromXmlElement(isPreset ? xmlElement.get() : elem);
  1735. callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  1736. if (pData->aboutToClose)
  1737. return true;
  1738. CARLA_SAFE_ASSERT_CONTINUE(stateSave.type != nullptr);
  1739. const void* extraStuff = nullptr;
  1740. static const char kTrue[] = "true";
  1741. const PluginType ptype(getPluginTypeFromString(stateSave.type));
  1742. switch (ptype)
  1743. {
  1744. case PLUGIN_GIG:
  1745. case PLUGIN_SF2:
  1746. if (CarlaString(stateSave.label).endsWith(" (16 outs)"))
  1747. extraStuff = kTrue;
  1748. // fall through
  1749. case PLUGIN_LADSPA:
  1750. case PLUGIN_DSSI:
  1751. case PLUGIN_VST2:
  1752. case PLUGIN_SFZ:
  1753. if (stateSave.binary != nullptr && stateSave.binary[0] != '\0' &&
  1754. ! (File::isAbsolutePath(stateSave.binary) && File(stateSave.binary).exists()))
  1755. {
  1756. const char* searchPath;
  1757. switch (ptype)
  1758. {
  1759. case PLUGIN_LADSPA: searchPath = pData->options.pathLADSPA; break;
  1760. case PLUGIN_DSSI: searchPath = pData->options.pathDSSI; break;
  1761. case PLUGIN_VST2: searchPath = pData->options.pathVST2; break;
  1762. case PLUGIN_GIG: searchPath = pData->options.pathGIG; break;
  1763. case PLUGIN_SF2: searchPath = pData->options.pathSF2; break;
  1764. case PLUGIN_SFZ: searchPath = pData->options.pathSFZ; break;
  1765. default: searchPath = nullptr; break;
  1766. }
  1767. if (searchPath != nullptr && searchPath[0] != '\0')
  1768. {
  1769. carla_stderr("Plugin binary '%s' doesn't exist on this filesystem, let's look for it...",
  1770. stateSave.binary);
  1771. String result = findBinaryInCustomPath(searchPath, stateSave.binary);
  1772. if (result.isEmpty())
  1773. {
  1774. switch (ptype)
  1775. {
  1776. case PLUGIN_LADSPA: searchPath = std::getenv("LADSPA_PATH"); break;
  1777. case PLUGIN_DSSI: searchPath = std::getenv("DSSI_PATH"); break;
  1778. case PLUGIN_VST2: searchPath = std::getenv("VST_PATH"); break;
  1779. case PLUGIN_GIG: searchPath = std::getenv("GIG_PATH"); break;
  1780. case PLUGIN_SF2: searchPath = std::getenv("SF2_PATH"); break;
  1781. case PLUGIN_SFZ: searchPath = std::getenv("SFZ_PATH"); break;
  1782. default: searchPath = nullptr; break;
  1783. }
  1784. if (searchPath != nullptr && searchPath[0] != '\0')
  1785. result = findBinaryInCustomPath(searchPath, stateSave.binary);
  1786. }
  1787. if (result.isNotEmpty())
  1788. {
  1789. delete[] stateSave.binary;
  1790. stateSave.binary = carla_strdup(result.toRawUTF8());
  1791. carla_stderr("Found it! :)");
  1792. }
  1793. else
  1794. {
  1795. carla_stderr("Damn, we failed... :(");
  1796. }
  1797. }
  1798. }
  1799. break;
  1800. default:
  1801. break;
  1802. }
  1803. if (addPlugin(getBinaryTypeFromFile(stateSave.binary), ptype, stateSave.binary,
  1804. stateSave.name, stateSave.label, stateSave.uniqueId, extraStuff, stateSave.options))
  1805. {
  1806. #ifndef BUILD_BRIDGE
  1807. const uint pluginId = pData->curPluginCount;
  1808. #else
  1809. const uint pluginId = 0;
  1810. #endif
  1811. if (CarlaPlugin* const plugin = pData->plugins[pluginId].plugin)
  1812. {
  1813. callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  1814. if (pData->aboutToClose)
  1815. return true;
  1816. // deactivate bridge client-side ping check, since some plugins block during load
  1817. if ((plugin->getHints() & PLUGIN_IS_BRIDGE) != 0 && ! isPreset)
  1818. plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, "__CarlaPingOnOff__", "false", false);
  1819. plugin->loadStateSave(stateSave);
  1820. /* NOTE: The following code is the same as the end of addPlugin().
  1821. * When project is loading we do not enable the plugin right away,
  1822. * as we want to load state first.
  1823. */
  1824. #ifdef BUILD_BRIDGE
  1825. plugin->setActive(true, true, false);
  1826. #else
  1827. ++pData->curPluginCount;
  1828. #endif
  1829. plugin->setEnabled(true);
  1830. callback(ENGINE_CALLBACK_PLUGIN_ADDED, pluginId, 0, 0, 0.0f, plugin->getName());
  1831. #ifndef BUILD_BRIDGE
  1832. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  1833. pData->graph.addPlugin(plugin);
  1834. #endif
  1835. }
  1836. else
  1837. {
  1838. carla_stderr2("Failed to get new plugin, state will not be restored correctly\n");
  1839. }
  1840. }
  1841. else
  1842. {
  1843. carla_stderr2("Failed to load a plugin, error was:\n%s", getLastError());
  1844. }
  1845. }
  1846. if (isPreset)
  1847. return true;
  1848. }
  1849. #ifndef BUILD_BRIDGE
  1850. // tell bridges we're done loading
  1851. for (uint i=0; i < pData->curPluginCount; ++i)
  1852. {
  1853. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1854. if (plugin != nullptr && plugin->isEnabled() && (plugin->getHints() & PLUGIN_IS_BRIDGE) != 0)
  1855. plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, "__CarlaPingOnOff__", "true", false);
  1856. }
  1857. callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  1858. if (pData->aboutToClose)
  1859. return true;
  1860. // handle connections (internal)
  1861. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  1862. {
  1863. const bool isUsingExternal(pData->graph.isUsingExternal());
  1864. for (XmlElement* elem = xmlElement->getFirstChildElement(); elem != nullptr; elem = elem->getNextElement())
  1865. {
  1866. const String& tagName(elem->getTagName());
  1867. // only load internal patchbay connections
  1868. if (! tagName.equalsIgnoreCase("patchbay"))
  1869. continue;
  1870. CarlaString sourcePort, targetPort;
  1871. for (XmlElement* patchElem = elem->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement())
  1872. {
  1873. const String& patchTag(patchElem->getTagName());
  1874. sourcePort.clear();
  1875. targetPort.clear();
  1876. if (! patchTag.equalsIgnoreCase("connection"))
  1877. continue;
  1878. for (XmlElement* connElem = patchElem->getFirstChildElement(); connElem != nullptr; connElem = connElem->getNextElement())
  1879. {
  1880. const String& tag(connElem->getTagName());
  1881. const String text(connElem->getAllSubText().trim());
  1882. /**/ if (tag.equalsIgnoreCase("source"))
  1883. sourcePort = xmlSafeString(text, false).toRawUTF8();
  1884. else if (tag.equalsIgnoreCase("target"))
  1885. targetPort = xmlSafeString(text, false).toRawUTF8();
  1886. }
  1887. if (sourcePort.isNotEmpty() && targetPort.isNotEmpty())
  1888. restorePatchbayConnection(false, sourcePort, targetPort, !isUsingExternal);
  1889. }
  1890. break;
  1891. }
  1892. callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  1893. if (pData->aboutToClose)
  1894. return true;
  1895. }
  1896. // if we're running inside some session-manager (and using JACK), let them handle the external connections
  1897. bool loadExternalConnections;
  1898. /**/ if (isPlugin)
  1899. loadExternalConnections = false;
  1900. else if (std::strcmp(getCurrentDriverName(), "JACK") != 0)
  1901. loadExternalConnections = true;
  1902. else if (std::getenv("CARLA_DONT_MANAGE_CONNECTIONS") != nullptr)
  1903. loadExternalConnections = false;
  1904. else if (std::getenv("LADISH_APP_NAME") != nullptr)
  1905. loadExternalConnections = false;
  1906. else if (std::getenv("NSM_URL") != nullptr)
  1907. loadExternalConnections = false;
  1908. else
  1909. loadExternalConnections = true;
  1910. // handle connections
  1911. if (loadExternalConnections)
  1912. {
  1913. const bool isUsingExternal(pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY ||
  1914. pData->graph.isUsingExternal());
  1915. for (XmlElement* elem = xmlElement->getFirstChildElement(); elem != nullptr; elem = elem->getNextElement())
  1916. {
  1917. const String& tagName(elem->getTagName());
  1918. // check if we want to load patchbay-mode connections into an external (multi-client) graph
  1919. if (tagName.equalsIgnoreCase("patchbay"))
  1920. {
  1921. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  1922. continue;
  1923. }
  1924. // or load external patchbay connections
  1925. else if (! tagName.equalsIgnoreCase("externalpatchbay"))
  1926. {
  1927. continue;
  1928. }
  1929. CarlaString sourcePort, targetPort;
  1930. for (XmlElement* patchElem = elem->getFirstChildElement(); patchElem != nullptr; patchElem = patchElem->getNextElement())
  1931. {
  1932. const String& patchTag(patchElem->getTagName());
  1933. sourcePort.clear();
  1934. targetPort.clear();
  1935. if (! patchTag.equalsIgnoreCase("connection"))
  1936. continue;
  1937. for (XmlElement* connElem = patchElem->getFirstChildElement(); connElem != nullptr; connElem = connElem->getNextElement())
  1938. {
  1939. const String& tag(connElem->getTagName());
  1940. const String text(connElem->getAllSubText().trim());
  1941. /**/ if (tag.equalsIgnoreCase("source"))
  1942. sourcePort = xmlSafeString(text, false).toRawUTF8();
  1943. else if (tag.equalsIgnoreCase("target"))
  1944. targetPort = xmlSafeString(text, false).toRawUTF8();
  1945. }
  1946. if (sourcePort.isNotEmpty() && targetPort.isNotEmpty())
  1947. restorePatchbayConnection(true, sourcePort, targetPort, isUsingExternal);
  1948. }
  1949. break;
  1950. }
  1951. }
  1952. #endif
  1953. callback(ENGINE_CALLBACK_PROJECT_LOAD_FINISHED, 0, 0, 0, 0.0f, nullptr);
  1954. return true;
  1955. }
  1956. // -----------------------------------------------------------------------
  1957. CARLA_BACKEND_END_NAMESPACE