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.

CarlaPluginBridge.cpp 96KB

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
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
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
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
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
11 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 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
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
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 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
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
11 years ago
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
10 years ago
10 years ago
10 years ago
11 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
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
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
11 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
10 years ago
11 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
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
11 years ago
11 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
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
11 years ago
11 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
11 years ago
11 years ago
11 years ago
11 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764
  1. /*
  2. * Carla Plugin Bridge
  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. #include "CarlaPluginInternal.hpp"
  18. #include "CarlaBackendUtils.hpp"
  19. #include "CarlaBase64Utils.hpp"
  20. #include "CarlaBridgeUtils.hpp"
  21. #include "CarlaEngineUtils.hpp"
  22. #include "CarlaMathUtils.hpp"
  23. #include "CarlaPipeUtils.hpp"
  24. #include "CarlaShmUtils.hpp"
  25. #include "CarlaThread.hpp"
  26. #include "jackbridge/JackBridge.hpp"
  27. #include <ctime>
  28. #include "water/files/File.h"
  29. #include "water/misc/Time.h"
  30. #include "water/threads/ChildProcess.h"
  31. // ---------------------------------------------------------------------------------------------------------------------
  32. using water::ChildProcess;
  33. using water::File;
  34. using water::String;
  35. using water::StringArray;
  36. using water::Time;
  37. CARLA_BACKEND_START_NAMESPACE
  38. // ---------------------------------------------------------------------------------------------------------------------
  39. // Fallback data
  40. static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 };
  41. // ---------------------------------------------------------------------------------------------------------------------
  42. static String findWinePrefix(const String filename, const int recursionLimit = 10)
  43. {
  44. if (recursionLimit == 0 || filename.length() < 5 || ! filename.contains("/"))
  45. return "";
  46. const String path(filename.upToLastOccurrenceOf("/", false, false));
  47. if (File(path + "/dosdevices").isDirectory())
  48. return path;
  49. return findWinePrefix(path, recursionLimit-1);
  50. }
  51. // ---------------------------------------------------------------------------------------------------------------------
  52. struct BridgeParamInfo {
  53. float value;
  54. CarlaString name;
  55. CarlaString symbol;
  56. CarlaString unit;
  57. BridgeParamInfo() noexcept
  58. : value(0.0f),
  59. name(),
  60. symbol(),
  61. unit() {}
  62. CARLA_DECLARE_NON_COPY_STRUCT(BridgeParamInfo)
  63. };
  64. // ---------------------------------------------------------------------------------------------------------------------
  65. class CarlaPluginBridgeThread : public CarlaThread
  66. {
  67. public:
  68. CarlaPluginBridgeThread(CarlaEngine* const engine, CarlaPlugin* const plugin) noexcept
  69. : CarlaThread("CarlaPluginBridgeThread"),
  70. kEngine(engine),
  71. kPlugin(plugin),
  72. fBinary(),
  73. fLabel(),
  74. fShmIds(),
  75. #ifndef CARLA_OS_WIN
  76. fWinePrefix(),
  77. #endif
  78. fProcess() {}
  79. void setData(
  80. #ifndef CARLA_OS_WIN
  81. const char* const winePrefix,
  82. #endif
  83. const char* const binary,
  84. const char* const label,
  85. const char* const shmIds) noexcept
  86. {
  87. CARLA_SAFE_ASSERT_RETURN(binary != nullptr && binary[0] != '\0',);
  88. CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && shmIds[0] != '\0',);
  89. CARLA_SAFE_ASSERT(! isThreadRunning());
  90. #ifndef CARLA_OS_WIN
  91. fWinePrefix = winePrefix;
  92. #endif
  93. fBinary = binary;
  94. fShmIds = shmIds;
  95. if (label != nullptr)
  96. fLabel = label;
  97. if (fLabel.isEmpty())
  98. fLabel = "\"\"";
  99. }
  100. uintptr_t getProcessPID() const noexcept
  101. {
  102. CARLA_SAFE_ASSERT_RETURN(fProcess != nullptr, 0);
  103. return (uintptr_t)fProcess->getPID();
  104. }
  105. protected:
  106. void run()
  107. {
  108. if (fProcess == nullptr)
  109. {
  110. fProcess = new ChildProcess();
  111. }
  112. else if (fProcess->isRunning())
  113. {
  114. carla_stderr("CarlaPluginBridgeThread::run() - already running");
  115. }
  116. char strBuf[STR_MAX+1];
  117. strBuf[STR_MAX] = '\0';
  118. const EngineOptions& options(kEngine->getOptions());
  119. String name(kPlugin->getName());
  120. String filename(kPlugin->getFilename());
  121. if (name.isEmpty())
  122. name = "(none)";
  123. if (filename.isEmpty())
  124. filename = "\"\"";
  125. StringArray arguments;
  126. #ifndef CARLA_OS_WIN
  127. // start with "wine" if needed
  128. if (fBinary.endsWithIgnoreCase(".exe"))
  129. {
  130. String wineCMD;
  131. if (options.wine.executable != nullptr && options.wine.executable[0] != '\0')
  132. wineCMD = options.wine.executable;
  133. else
  134. wineCMD = "wine";
  135. if (fBinary.endsWithIgnoreCase("64.exe"))
  136. wineCMD += "64";
  137. arguments.add(wineCMD);
  138. }
  139. #endif
  140. // binary
  141. arguments.add(fBinary);
  142. // plugin type
  143. arguments.add(getPluginTypeAsString(kPlugin->getType()));
  144. // filename
  145. arguments.add(filename);
  146. // label
  147. arguments.add(fLabel);
  148. // uniqueId
  149. arguments.add(String(static_cast<water::int64>(kPlugin->getUniqueId())));
  150. bool started;
  151. {
  152. const ScopedEngineEnvironmentLocker _seel(kEngine);
  153. #ifdef CARLA_OS_LINUX
  154. const ScopedEnvVar sev1("LD_LIBRARY_PATH", nullptr);
  155. const ScopedEnvVar sev2("LD_PRELOAD", nullptr);
  156. #endif
  157. carla_setenv("ENGINE_OPTION_FORCE_STEREO", bool2str(options.forceStereo));
  158. carla_setenv("ENGINE_OPTION_PREFER_PLUGIN_BRIDGES", bool2str(options.preferPluginBridges));
  159. carla_setenv("ENGINE_OPTION_PREFER_UI_BRIDGES", bool2str(options.preferUiBridges));
  160. carla_setenv("ENGINE_OPTION_UIS_ALWAYS_ON_TOP", bool2str(options.uisAlwaysOnTop));
  161. std::snprintf(strBuf, STR_MAX, "%u", options.maxParameters);
  162. carla_setenv("ENGINE_OPTION_MAX_PARAMETERS", strBuf);
  163. std::snprintf(strBuf, STR_MAX, "%u", options.uiBridgesTimeout);
  164. carla_setenv("ENGINE_OPTION_UI_BRIDGES_TIMEOUT",strBuf);
  165. if (options.pathLADSPA != nullptr)
  166. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_LADSPA", options.pathLADSPA);
  167. else
  168. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_LADSPA", "");
  169. if (options.pathDSSI != nullptr)
  170. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_DSSI", options.pathDSSI);
  171. else
  172. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_DSSI", "");
  173. if (options.pathLV2 != nullptr)
  174. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_LV2", options.pathLV2);
  175. else
  176. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_LV2", "");
  177. if (options.pathVST2 != nullptr)
  178. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_VST2", options.pathVST2);
  179. else
  180. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_VST2", "");
  181. if (options.pathSF2 != nullptr)
  182. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_SF2", options.pathSF2);
  183. else
  184. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_SF2", "");
  185. if (options.pathSFZ != nullptr)
  186. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_SFZ", options.pathSFZ);
  187. else
  188. carla_setenv("ENGINE_OPTION_PLUGIN_PATH_SFZ", "");
  189. if (options.binaryDir != nullptr)
  190. carla_setenv("ENGINE_OPTION_PATH_BINARIES", options.binaryDir);
  191. else
  192. carla_setenv("ENGINE_OPTION_PATH_BINARIES", "");
  193. if (options.resourceDir != nullptr)
  194. carla_setenv("ENGINE_OPTION_PATH_RESOURCES", options.resourceDir);
  195. else
  196. carla_setenv("ENGINE_OPTION_PATH_RESOURCES", "");
  197. carla_setenv("ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR", bool2str(options.preventBadBehaviour));
  198. std::snprintf(strBuf, STR_MAX, P_UINTPTR, options.frontendWinId);
  199. carla_setenv("ENGINE_OPTION_FRONTEND_WIN_ID", strBuf);
  200. carla_setenv("ENGINE_BRIDGE_SHM_IDS", fShmIds.toRawUTF8());
  201. #ifndef CARLA_OS_WIN
  202. if (fWinePrefix.isNotEmpty())
  203. {
  204. carla_setenv("WINEDEBUG", "-all");
  205. carla_setenv("WINEPREFIX", fWinePrefix.toRawUTF8());
  206. if (options.wine.rtPrio)
  207. {
  208. carla_setenv("STAGING_SHARED_MEMORY", "1");
  209. carla_setenv("WINE_RT_POLICY", "FF");
  210. std::snprintf(strBuf, STR_MAX, "%i", options.wine.baseRtPrio);
  211. carla_setenv("STAGING_RT_PRIORITY_BASE", strBuf);
  212. carla_setenv("WINE_RT", strBuf);
  213. carla_setenv("WINE_RT_PRIO", strBuf);
  214. std::snprintf(strBuf, STR_MAX, "%i", options.wine.serverRtPrio);
  215. carla_setenv("STAGING_RT_PRIORITY_SERVER", strBuf);
  216. carla_setenv("WINE_SVR_RT", strBuf);
  217. }
  218. else
  219. {
  220. carla_unsetenv("STAGING_SHARED_MEMORY");
  221. carla_unsetenv("WINE_RT_POLICY");
  222. carla_unsetenv("STAGING_RT_PRIORITY_BASE");
  223. carla_unsetenv("STAGING_RT_PRIORITY_SERVER");
  224. carla_unsetenv("WINE_RT");
  225. carla_unsetenv("WINE_RT_PRIO");
  226. carla_unsetenv("WINE_SVR_RT");
  227. }
  228. carla_stdout("Using WINEPREFIX '%s'", fWinePrefix.toRawUTF8());
  229. }
  230. #endif
  231. carla_stdout("starting plugin bridge, command is:\n%s \"%s\" \"%s\" \"%s\" " P_INT64,
  232. fBinary.toRawUTF8(), getPluginTypeAsString(kPlugin->getType()), filename.toRawUTF8(), fLabel.toRawUTF8(), kPlugin->getUniqueId());
  233. started = fProcess->start(arguments);
  234. }
  235. if (! started)
  236. {
  237. carla_stdout("failed!");
  238. fProcess = nullptr;
  239. return;
  240. }
  241. for (; fProcess->isRunning() && ! shouldThreadExit();)
  242. carla_sleep(1);
  243. // we only get here if bridge crashed or thread asked to exit
  244. if (fProcess->isRunning() && shouldThreadExit())
  245. {
  246. fProcess->waitForProcessToFinish(2000);
  247. if (fProcess->isRunning())
  248. {
  249. carla_stdout("CarlaPluginBridgeThread::run() - bridge refused to close, force kill now");
  250. fProcess->kill();
  251. }
  252. else
  253. {
  254. carla_stdout("CarlaPluginBridgeThread::run() - bridge auto-closed successfully");
  255. }
  256. }
  257. else
  258. {
  259. // forced quit, may have crashed
  260. if (fProcess->getExitCode() != 0 /*|| fProcess->exitStatus() == QProcess::CrashExit*/)
  261. {
  262. carla_stderr("CarlaPluginBridgeThread::run() - bridge crashed");
  263. CarlaString errorString("Plugin '" + CarlaString(kPlugin->getName()) + "' has crashed!\n"
  264. "Saving now will lose its current settings.\n"
  265. "Please remove this plugin, and not rely on it from this point.");
  266. kEngine->callback(CarlaBackend::ENGINE_CALLBACK_ERROR, kPlugin->getId(), 0, 0, 0.0f, errorString);
  267. }
  268. }
  269. fProcess = nullptr;
  270. }
  271. private:
  272. CarlaEngine* const kEngine;
  273. CarlaPlugin* const kPlugin;
  274. String fBinary;
  275. String fLabel;
  276. String fShmIds;
  277. #ifndef CARLA_OS_WIN
  278. String fWinePrefix;
  279. #endif
  280. ScopedPointer<ChildProcess> fProcess;
  281. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginBridgeThread)
  282. };
  283. // ---------------------------------------------------------------------------------------------------------------------
  284. class CarlaPluginBridge : public CarlaPlugin
  285. {
  286. public:
  287. CarlaPluginBridge(CarlaEngine* const engine, const uint id, const BinaryType btype, const PluginType ptype)
  288. : CarlaPlugin(engine, id),
  289. fBinaryType(btype),
  290. fPluginType(ptype),
  291. fInitiated(false),
  292. fInitError(false),
  293. fSaved(true),
  294. fTimedOut(false),
  295. fTimedError(false),
  296. fProcWaitTime(0),
  297. fLastPongTime(-1),
  298. fBridgeBinary(),
  299. fBridgeThread(engine, this),
  300. fShmAudioPool(),
  301. fShmRtClientControl(),
  302. fShmNonRtClientControl(),
  303. fShmNonRtServerControl(),
  304. #ifndef CARLA_OS_WIN
  305. fWinePrefix(),
  306. #endif
  307. fReceivingParamText(),
  308. fInfo(),
  309. fUniqueId(0),
  310. fLatency(0),
  311. fParams(nullptr)
  312. {
  313. carla_debug("CarlaPluginBridge::CarlaPluginBridge(%p, %i, %s, %s)", engine, id, BinaryType2Str(btype), PluginType2Str(ptype));
  314. pData->hints |= PLUGIN_IS_BRIDGE;
  315. }
  316. ~CarlaPluginBridge() override
  317. {
  318. carla_debug("CarlaPluginBridge::~CarlaPluginBridge()");
  319. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  320. // close UI
  321. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  322. pData->transientTryCounter = 0;
  323. #endif
  324. pData->singleMutex.lock();
  325. pData->masterMutex.lock();
  326. if (pData->client != nullptr && pData->client->isActive())
  327. pData->client->deactivate();
  328. if (pData->active)
  329. {
  330. deactivate();
  331. pData->active = false;
  332. }
  333. if (fBridgeThread.isThreadRunning())
  334. {
  335. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientQuit);
  336. fShmNonRtClientControl.commitWrite();
  337. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientQuit);
  338. fShmRtClientControl.commitWrite();
  339. if (! fTimedOut)
  340. waitForClient("stopping", 3000);
  341. }
  342. fBridgeThread.stopThread(3000);
  343. fShmNonRtServerControl.clear();
  344. fShmNonRtClientControl.clear();
  345. fShmRtClientControl.clear();
  346. fShmAudioPool.clear();
  347. clearBuffers();
  348. fInfo.chunk.clear();
  349. }
  350. // -------------------------------------------------------------------
  351. // Information (base)
  352. BinaryType getBinaryType() const noexcept override
  353. {
  354. return fBinaryType;
  355. }
  356. PluginType getType() const noexcept override
  357. {
  358. return fPluginType;
  359. }
  360. PluginCategory getCategory() const noexcept override
  361. {
  362. return fInfo.category;
  363. }
  364. int64_t getUniqueId() const noexcept override
  365. {
  366. return fUniqueId;
  367. }
  368. uint32_t getLatencyInFrames() const noexcept override
  369. {
  370. return fLatency;
  371. }
  372. // -------------------------------------------------------------------
  373. // Information (count)
  374. uint32_t getMidiInCount() const noexcept override
  375. {
  376. return fInfo.mIns;
  377. }
  378. uint32_t getMidiOutCount() const noexcept override
  379. {
  380. return fInfo.mOuts;
  381. }
  382. // -------------------------------------------------------------------
  383. // Information (current data)
  384. std::size_t getChunkData(void** const dataPtr) noexcept override
  385. {
  386. CARLA_SAFE_ASSERT_RETURN(pData->options & PLUGIN_OPTION_USE_CHUNKS, 0);
  387. CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr, 0);
  388. waitForSaved();
  389. CARLA_SAFE_ASSERT_RETURN(fInfo.chunk.size() > 0, 0);
  390. #ifdef CARLA_PROPER_CPP11_SUPPORT
  391. *dataPtr = fInfo.chunk.data();
  392. #else
  393. *dataPtr = &fInfo.chunk.front();
  394. #endif
  395. return fInfo.chunk.size();
  396. }
  397. // -------------------------------------------------------------------
  398. // Information (per-plugin data)
  399. uint getOptionsAvailable() const noexcept override
  400. {
  401. return fInfo.optionsAvailable;
  402. }
  403. float getParameterValue(const uint32_t parameterId) const noexcept override
  404. {
  405. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  406. return fParams[parameterId].value;
  407. }
  408. void getLabel(char* const strBuf) const noexcept override
  409. {
  410. std::strncpy(strBuf, fInfo.label, STR_MAX);
  411. }
  412. void getMaker(char* const strBuf) const noexcept override
  413. {
  414. std::strncpy(strBuf, fInfo.maker, STR_MAX);
  415. }
  416. void getCopyright(char* const strBuf) const noexcept override
  417. {
  418. std::strncpy(strBuf, fInfo.copyright, STR_MAX);
  419. }
  420. void getRealName(char* const strBuf) const noexcept override
  421. {
  422. std::strncpy(strBuf, fInfo.name, STR_MAX);
  423. }
  424. void getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
  425. {
  426. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, nullStrBuf(strBuf));
  427. std::strncpy(strBuf, fParams[parameterId].name.buffer(), STR_MAX);
  428. }
  429. void getParameterText(const uint32_t parameterId, char* const strBuf) noexcept override
  430. {
  431. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, nullStrBuf(strBuf));
  432. CARLA_SAFE_ASSERT_RETURN(! fReceivingParamText.isCurrentlyWaitingData(), nullStrBuf(strBuf));
  433. const int32_t parameterIdi = static_cast<int32_t>(parameterId);
  434. fReceivingParamText.setTargetData(parameterIdi, strBuf);
  435. {
  436. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  437. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientGetParameterText);
  438. fShmNonRtClientControl.writeInt(parameterIdi);
  439. fShmNonRtClientControl.commitWrite();
  440. }
  441. if (! waitForParameterText())
  442. std::snprintf(strBuf, STR_MAX, "%f", fParams[parameterId].value);
  443. }
  444. void getParameterSymbol(const uint32_t parameterId, char* const strBuf) const noexcept override
  445. {
  446. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, nullStrBuf(strBuf));
  447. std::strncpy(strBuf, fParams[parameterId].symbol.buffer(), STR_MAX);
  448. }
  449. void getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
  450. {
  451. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, nullStrBuf(strBuf));
  452. std::strncpy(strBuf, fParams[parameterId].unit.buffer(), STR_MAX);
  453. }
  454. // -------------------------------------------------------------------
  455. // Set data (state)
  456. void prepareForSave() noexcept override
  457. {
  458. fSaved = false;
  459. {
  460. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  461. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientPrepareForSave);
  462. fShmNonRtClientControl.commitWrite();
  463. }
  464. }
  465. bool waitForParameterText()
  466. {
  467. bool success;
  468. if (fReceivingParamText.wasDataReceived(&success))
  469. return success;
  470. const uint32_t timeoutEnd(Time::getMillisecondCounter() + 500); // 500 ms
  471. for (; Time::getMillisecondCounter() < timeoutEnd && fBridgeThread.isThreadRunning();)
  472. {
  473. if (fReceivingParamText.wasDataReceived(&success))
  474. return success;
  475. carla_msleep(5);
  476. }
  477. carla_stderr("CarlaPluginBridge::waitForParameterText() - Timeout while requesting text");
  478. #if 0
  479. // we waited and blocked for 5 secs, give host idle time now
  480. pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  481. if (pData->engine->getType() != kEngineTypePlugin)
  482. pData->engine->idle();
  483. #endif
  484. return false;
  485. }
  486. void waitForSaved()
  487. {
  488. if (fSaved)
  489. return;
  490. // TODO: only wait 1 minute for NI plugins
  491. const uint32_t timeoutEnd(Time::getMillisecondCounter() + 60*1000); // 60 secs, 1 minute
  492. const bool needsEngineIdle(pData->engine->getType() != kEngineTypePlugin);
  493. for (; Time::getMillisecondCounter() < timeoutEnd && fBridgeThread.isThreadRunning();)
  494. {
  495. pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  496. if (needsEngineIdle)
  497. pData->engine->idle();
  498. if (fSaved)
  499. break;
  500. carla_msleep(20);
  501. }
  502. if (! fSaved)
  503. carla_stderr("CarlaPluginBridge::waitForSaved() - Timeout while requesting save state");
  504. }
  505. // -------------------------------------------------------------------
  506. // Set data (internal stuff)
  507. void setOption(const uint option, const bool yesNo, const bool sendCallback) override
  508. {
  509. {
  510. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  511. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetOption);
  512. fShmNonRtClientControl.writeUInt(option);
  513. fShmNonRtClientControl.writeBool(yesNo);
  514. fShmNonRtClientControl.commitWrite();
  515. }
  516. CarlaPlugin::setOption(option, yesNo, sendCallback);
  517. }
  518. void setCtrlChannel(const int8_t channel, const bool sendOsc, const bool sendCallback) noexcept override
  519. {
  520. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,);
  521. {
  522. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  523. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetCtrlChannel);
  524. fShmNonRtClientControl.writeShort(channel);
  525. fShmNonRtClientControl.commitWrite();
  526. }
  527. CarlaPlugin::setCtrlChannel(channel, sendOsc, sendCallback);
  528. }
  529. // -------------------------------------------------------------------
  530. // Set data (plugin-specific stuff)
  531. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  532. {
  533. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  534. CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,);
  535. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  536. fParams[parameterId].value = fixedValue;
  537. {
  538. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  539. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetParameterValue);
  540. fShmNonRtClientControl.writeUInt(parameterId);
  541. fShmNonRtClientControl.writeFloat(value);
  542. fShmNonRtClientControl.commitWrite();
  543. fShmNonRtClientControl.waitIfDataIsReachingLimit();
  544. }
  545. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  546. }
  547. void setParameterMidiChannel(const uint32_t parameterId, const uint8_t channel, const bool sendOsc, const bool sendCallback) noexcept override
  548. {
  549. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  550. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  551. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,);
  552. {
  553. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  554. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetParameterMidiChannel);
  555. fShmNonRtClientControl.writeUInt(parameterId);
  556. fShmNonRtClientControl.writeByte(channel);
  557. fShmNonRtClientControl.commitWrite();
  558. }
  559. CarlaPlugin::setParameterMidiChannel(parameterId, channel, sendOsc, sendCallback);
  560. }
  561. void setParameterMidiCC(const uint32_t parameterId, const int16_t cc, const bool sendOsc, const bool sendCallback) noexcept override
  562. {
  563. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  564. CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL,);
  565. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,);
  566. {
  567. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  568. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetParameterMidiCC);
  569. fShmNonRtClientControl.writeUInt(parameterId);
  570. fShmNonRtClientControl.writeShort(cc);
  571. fShmNonRtClientControl.commitWrite();
  572. }
  573. CarlaPlugin::setParameterMidiCC(parameterId, cc, sendOsc, sendCallback);
  574. }
  575. void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool doingInit) noexcept override
  576. {
  577. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);
  578. CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback || doingInit,);
  579. {
  580. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  581. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetProgram);
  582. fShmNonRtClientControl.writeInt(index);
  583. fShmNonRtClientControl.commitWrite();
  584. }
  585. CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback, doingInit);
  586. }
  587. void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool doingInit) noexcept override
  588. {
  589. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),);
  590. CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback || doingInit,);
  591. {
  592. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  593. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetMidiProgram);
  594. fShmNonRtClientControl.writeInt(index);
  595. fShmNonRtClientControl.commitWrite();
  596. }
  597. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, doingInit);
  598. }
  599. void setMidiProgramRT(const uint32_t uindex) noexcept override
  600. {
  601. CARLA_SAFE_ASSERT_RETURN(uindex < pData->midiprog.count,);
  602. {
  603. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  604. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetMidiProgram);
  605. fShmNonRtClientControl.writeInt(static_cast<int32_t>(uindex));
  606. fShmNonRtClientControl.commitWrite();
  607. }
  608. CarlaPlugin::setMidiProgramRT(uindex);
  609. }
  610. void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override
  611. {
  612. CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
  613. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  614. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  615. if (std::strcmp(type, CUSTOM_DATA_TYPE_PROPERTY) == 0)
  616. return CarlaPlugin::setCustomData(type, key, value, sendGui);
  617. if (std::strcmp(type, CUSTOM_DATA_TYPE_STRING) == 0 && std::strcmp(key, "__CarlaPingOnOff__") == 0)
  618. {
  619. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  620. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientPingOnOff);
  621. fShmNonRtClientControl.writeBool(std::strcmp(value, "true") == 0);
  622. fShmNonRtClientControl.commitWrite();
  623. return;
  624. }
  625. const uint32_t typeLen(static_cast<uint32_t>(std::strlen(type)));
  626. const uint32_t keyLen(static_cast<uint32_t>(std::strlen(key)));
  627. const uint32_t valueLen(static_cast<uint32_t>(std::strlen(value)));
  628. {
  629. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  630. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetCustomData);
  631. fShmNonRtClientControl.writeUInt(typeLen);
  632. fShmNonRtClientControl.writeCustomData(type, typeLen);
  633. fShmNonRtClientControl.writeUInt(keyLen);
  634. fShmNonRtClientControl.writeCustomData(key, keyLen);
  635. fShmNonRtClientControl.writeUInt(valueLen);
  636. if (valueLen > 0)
  637. fShmNonRtClientControl.writeCustomData(value, valueLen);
  638. fShmNonRtClientControl.commitWrite();
  639. }
  640. CarlaPlugin::setCustomData(type, key, value, sendGui);
  641. }
  642. void setChunkData(const void* const data, const std::size_t dataSize) override
  643. {
  644. CARLA_SAFE_ASSERT_RETURN(pData->options & PLUGIN_OPTION_USE_CHUNKS,);
  645. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  646. CARLA_SAFE_ASSERT_RETURN(dataSize > 0,);
  647. CarlaString dataBase64(CarlaString::asBase64(data, dataSize));
  648. CARLA_SAFE_ASSERT_RETURN(dataBase64.length() > 0,);
  649. String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName());
  650. filePath += CARLA_OS_SEP_STR ".CarlaChunk_";
  651. filePath += fShmAudioPool.getFilenameSuffix();
  652. if (File(filePath).replaceWithText(dataBase64.buffer()))
  653. {
  654. const uint32_t ulength(static_cast<uint32_t>(filePath.length()));
  655. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  656. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetChunkDataFile);
  657. fShmNonRtClientControl.writeUInt(ulength);
  658. fShmNonRtClientControl.writeCustomData(filePath.toRawUTF8(), ulength);
  659. fShmNonRtClientControl.commitWrite();
  660. }
  661. // save data internally as well
  662. fInfo.chunk.resize(dataSize);
  663. #ifdef CARLA_PROPER_CPP11_SUPPORT
  664. std::memcpy(fInfo.chunk.data(), data, dataSize);
  665. #else
  666. std::memcpy(&fInfo.chunk.front(), data, dataSize);
  667. #endif
  668. }
  669. // -------------------------------------------------------------------
  670. // Set ui stuff
  671. void showCustomUI(const bool yesNo) override
  672. {
  673. {
  674. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  675. fShmNonRtClientControl.writeOpcode(yesNo ? kPluginBridgeNonRtClientShowUI : kPluginBridgeNonRtClientHideUI);
  676. fShmNonRtClientControl.commitWrite();
  677. }
  678. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  679. if (yesNo)
  680. {
  681. pData->tryTransient();
  682. }
  683. else
  684. {
  685. pData->transientTryCounter = 0;
  686. }
  687. #endif
  688. }
  689. void idle() override
  690. {
  691. if (fBridgeThread.isThreadRunning())
  692. {
  693. if (fInitiated && fTimedOut && pData->active)
  694. setActive(false, true, true);
  695. {
  696. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  697. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientPing);
  698. fShmNonRtClientControl.commitWrite();
  699. }
  700. try {
  701. handleNonRtData();
  702. } CARLA_SAFE_EXCEPTION("handleNonRtData");
  703. }
  704. else if (fInitiated)
  705. {
  706. fTimedOut = true;
  707. fTimedError = true;
  708. fInitiated = false;
  709. handleProcessStopped();
  710. }
  711. CarlaPlugin::idle();
  712. }
  713. // -------------------------------------------------------------------
  714. // Plugin state
  715. void reload() override
  716. {
  717. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  718. carla_debug("CarlaPluginBridge::reload() - start");
  719. const EngineProcessMode processMode(pData->engine->getProccessMode());
  720. // Safely disable plugin for reload
  721. const ScopedDisabler sd(this);
  722. // cleanup of previous data
  723. pData->audioIn.clear();
  724. pData->audioOut.clear();
  725. pData->cvIn.clear();
  726. pData->cvOut.clear();
  727. pData->event.clear();
  728. bool needsCtrlIn, needsCtrlOut;
  729. needsCtrlIn = needsCtrlOut = false;
  730. if (fInfo.aIns > 0)
  731. {
  732. pData->audioIn.createNew(fInfo.aIns);
  733. }
  734. if (fInfo.aOuts > 0)
  735. {
  736. pData->audioOut.createNew(fInfo.aOuts);
  737. needsCtrlIn = true;
  738. }
  739. if (fInfo.cvIns > 0)
  740. {
  741. pData->cvIn.createNew(fInfo.cvIns);
  742. }
  743. if (fInfo.cvOuts > 0)
  744. {
  745. pData->cvOut.createNew(fInfo.cvOuts);
  746. }
  747. if (fInfo.mIns > 0)
  748. needsCtrlIn = true;
  749. if (fInfo.mOuts > 0)
  750. needsCtrlOut = true;
  751. const uint portNameSize(pData->engine->getMaxPortNameSize());
  752. CarlaString portName;
  753. // Audio Ins
  754. for (uint32_t j=0; j < fInfo.aIns; ++j)
  755. {
  756. portName.clear();
  757. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  758. {
  759. portName = pData->name;
  760. portName += ":";
  761. }
  762. if (fInfo.aInNames != nullptr && fInfo.aInNames[j] != nullptr)
  763. {
  764. portName += fInfo.aInNames[j];
  765. }
  766. else if (fInfo.aIns > 1)
  767. {
  768. portName += "input_";
  769. portName += CarlaString(j+1);
  770. }
  771. else
  772. portName += "input";
  773. portName.truncate(portNameSize);
  774. pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, j);
  775. pData->audioIn.ports[j].rindex = j;
  776. }
  777. // Audio Outs
  778. for (uint32_t j=0; j < fInfo.aOuts; ++j)
  779. {
  780. portName.clear();
  781. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  782. {
  783. portName = pData->name;
  784. portName += ":";
  785. }
  786. if (fInfo.aOutNames != nullptr && fInfo.aOutNames[j] != nullptr)
  787. {
  788. portName += fInfo.aOutNames[j];
  789. }
  790. else if (fInfo.aOuts > 1)
  791. {
  792. portName += "output_";
  793. portName += CarlaString(j+1);
  794. }
  795. else
  796. portName += "output";
  797. portName.truncate(portNameSize);
  798. pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, j);
  799. pData->audioOut.ports[j].rindex = j;
  800. }
  801. // TODO - MIDI
  802. // TODO - CV
  803. if (needsCtrlIn)
  804. {
  805. portName.clear();
  806. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  807. {
  808. portName = pData->name;
  809. portName += ":";
  810. }
  811. portName += "event-in";
  812. portName.truncate(portNameSize);
  813. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0);
  814. }
  815. if (needsCtrlOut)
  816. {
  817. portName.clear();
  818. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  819. {
  820. portName = pData->name;
  821. portName += ":";
  822. }
  823. portName += "event-out";
  824. portName.truncate(portNameSize);
  825. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, 0);
  826. }
  827. // extra plugin hints
  828. pData->extraHints = 0x0;
  829. if (fInfo.mIns > 0)
  830. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  831. if (fInfo.mOuts > 0)
  832. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
  833. bufferSizeChanged(pData->engine->getBufferSize());
  834. reloadPrograms(true);
  835. carla_debug("CarlaPluginBridge::reload() - end");
  836. }
  837. // -------------------------------------------------------------------
  838. // Plugin processing
  839. void activate() noexcept override
  840. {
  841. if (! fBridgeThread.isThreadRunning())
  842. {
  843. CARLA_SAFE_ASSERT_RETURN(restartBridgeThread(),);
  844. }
  845. {
  846. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  847. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientActivate);
  848. fShmNonRtClientControl.commitWrite();
  849. }
  850. fTimedOut = false;
  851. try {
  852. waitForClient("activate", 2000);
  853. } CARLA_SAFE_EXCEPTION("activate - waitForClient");
  854. }
  855. void deactivate() noexcept override
  856. {
  857. CARLA_SAFE_ASSERT_RETURN(! fTimedError,);
  858. {
  859. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  860. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientDeactivate);
  861. fShmNonRtClientControl.commitWrite();
  862. }
  863. fTimedOut = false;
  864. try {
  865. waitForClient("deactivate", 2000);
  866. } CARLA_SAFE_EXCEPTION("deactivate - waitForClient");
  867. }
  868. void process(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames) override
  869. {
  870. // --------------------------------------------------------------------------------------------------------
  871. // Check if active
  872. if (fTimedOut || fTimedError || ! pData->active)
  873. {
  874. // disable any output sound
  875. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  876. carla_zeroFloats(audioOut[i], frames);
  877. for (uint32_t i=0; i < pData->cvOut.count; ++i)
  878. carla_zeroFloats(cvOut[i], frames);
  879. return;
  880. }
  881. // --------------------------------------------------------------------------------------------------------
  882. // Check if needs reset
  883. if (pData->needsReset)
  884. {
  885. // TODO
  886. pData->needsReset = false;
  887. }
  888. // --------------------------------------------------------------------------------------------------------
  889. // Event Input
  890. if (pData->event.portIn != nullptr)
  891. {
  892. // ----------------------------------------------------------------------------------------------------
  893. // MIDI Input (External)
  894. if (pData->extNotes.mutex.tryLock())
  895. {
  896. for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin2(); it.valid(); it.next())
  897. {
  898. const ExternalMidiNote& note(it.getValue(kExternalMidiNoteFallback));
  899. CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  900. uint8_t data1, data2, data3;
  901. data1 = uint8_t((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
  902. data2 = note.note;
  903. data3 = note.velo;
  904. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientMidiEvent);
  905. fShmRtClientControl.writeUInt(0); // time
  906. fShmRtClientControl.writeByte(0); // port
  907. fShmRtClientControl.writeByte(3); // size
  908. fShmRtClientControl.writeByte(data1);
  909. fShmRtClientControl.writeByte(data2);
  910. fShmRtClientControl.writeByte(data3);
  911. fShmRtClientControl.commitWrite();
  912. }
  913. pData->extNotes.data.clear();
  914. pData->extNotes.mutex.unlock();
  915. } // End of MIDI Input (External)
  916. // ----------------------------------------------------------------------------------------------------
  917. // Event Input (System)
  918. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  919. bool allNotesOffSent = false;
  920. #endif
  921. for (uint32_t i=0, numEvents=pData->event.portIn->getEventCount(); i < numEvents; ++i)
  922. {
  923. const EngineEvent& event(pData->event.portIn->getEvent(i));
  924. // Control change
  925. switch (event.type)
  926. {
  927. case kEngineEventTypeNull:
  928. break;
  929. case kEngineEventTypeControl: {
  930. const EngineControlEvent& ctrlEvent = event.ctrl;
  931. switch (ctrlEvent.type)
  932. {
  933. case kEngineControlEventTypeNull:
  934. break;
  935. case kEngineControlEventTypeParameter:
  936. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  937. // Control backend stuff
  938. if (event.channel == pData->ctrlChannel)
  939. {
  940. float value;
  941. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
  942. {
  943. value = ctrlEvent.value;
  944. setDryWetRT(value);
  945. }
  946. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
  947. {
  948. value = ctrlEvent.value*127.0f/100.0f;
  949. setVolumeRT(value);
  950. }
  951. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
  952. {
  953. float left, right;
  954. value = ctrlEvent.value/0.5f - 1.0f;
  955. if (value < 0.0f)
  956. {
  957. left = -1.0f;
  958. right = (value*2.0f)+1.0f;
  959. }
  960. else if (value > 0.0f)
  961. {
  962. left = (value*2.0f)-1.0f;
  963. right = 1.0f;
  964. }
  965. else
  966. {
  967. left = -1.0f;
  968. right = 1.0f;
  969. }
  970. setBalanceLeftRT(left);
  971. setBalanceRightRT(right);
  972. }
  973. }
  974. #endif
  975. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventParameter);
  976. fShmRtClientControl.writeUInt(event.time);
  977. fShmRtClientControl.writeByte(event.channel);
  978. fShmRtClientControl.writeUShort(event.ctrl.param);
  979. fShmRtClientControl.writeFloat(event.ctrl.value);
  980. fShmRtClientControl.commitWrite();
  981. break;
  982. case kEngineControlEventTypeMidiBank:
  983. if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES)
  984. {
  985. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventMidiBank);
  986. fShmRtClientControl.writeUInt(event.time);
  987. fShmRtClientControl.writeByte(event.channel);
  988. fShmRtClientControl.writeUShort(event.ctrl.param);
  989. fShmRtClientControl.commitWrite();
  990. }
  991. break;
  992. case kEngineControlEventTypeMidiProgram:
  993. if (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES)
  994. {
  995. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventMidiProgram);
  996. fShmRtClientControl.writeUInt(event.time);
  997. fShmRtClientControl.writeByte(event.channel);
  998. fShmRtClientControl.writeUShort(event.ctrl.param);
  999. fShmRtClientControl.commitWrite();
  1000. }
  1001. break;
  1002. case kEngineControlEventTypeAllSoundOff:
  1003. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  1004. {
  1005. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventAllSoundOff);
  1006. fShmRtClientControl.writeUInt(event.time);
  1007. fShmRtClientControl.writeByte(event.channel);
  1008. fShmRtClientControl.commitWrite();
  1009. }
  1010. break;
  1011. case kEngineControlEventTypeAllNotesOff:
  1012. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  1013. {
  1014. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1015. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  1016. {
  1017. allNotesOffSent = true;
  1018. sendMidiAllNotesOffToCallback();
  1019. }
  1020. #endif
  1021. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientControlEventAllNotesOff);
  1022. fShmRtClientControl.writeUInt(event.time);
  1023. fShmRtClientControl.writeByte(event.channel);
  1024. fShmRtClientControl.commitWrite();
  1025. }
  1026. break;
  1027. } // switch (ctrlEvent.type)
  1028. break;
  1029. } // case kEngineEventTypeControl
  1030. case kEngineEventTypeMidi: {
  1031. const EngineMidiEvent& midiEvent(event.midi);
  1032. if (midiEvent.size == 0 || midiEvent.size >= MAX_MIDI_VALUE)
  1033. continue;
  1034. const uint8_t* const midiData(midiEvent.size > EngineMidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data);
  1035. uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiData));
  1036. if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  1037. continue;
  1038. if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  1039. continue;
  1040. if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  1041. continue;
  1042. if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  1043. continue;
  1044. // Fix bad note-off
  1045. if (status == MIDI_STATUS_NOTE_ON && midiData[2] == 0)
  1046. status = MIDI_STATUS_NOTE_OFF;
  1047. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientMidiEvent);
  1048. fShmRtClientControl.writeUInt(event.time);
  1049. fShmRtClientControl.writeByte(midiEvent.port);
  1050. fShmRtClientControl.writeByte(midiEvent.size);
  1051. fShmRtClientControl.writeByte(uint8_t(midiData[0] | (event.channel & MIDI_CHANNEL_BIT)));
  1052. for (uint8_t j=1; j < midiEvent.size; ++j)
  1053. fShmRtClientControl.writeByte(midiData[j]);
  1054. fShmRtClientControl.commitWrite();
  1055. if (status == MIDI_STATUS_NOTE_ON)
  1056. pData->postponeRtEvent(kPluginPostRtEventNoteOn, event.channel, midiData[1], midiData[2]);
  1057. else if (status == MIDI_STATUS_NOTE_OFF)
  1058. pData->postponeRtEvent(kPluginPostRtEventNoteOff, event.channel, midiData[1], 0.0f);
  1059. } break;
  1060. }
  1061. }
  1062. pData->postRtEvents.trySplice();
  1063. } // End of Event Input
  1064. if (! processSingle(audioIn, audioOut, cvIn, cvOut, frames))
  1065. return;
  1066. // --------------------------------------------------------------------------------------------------------
  1067. // Control and MIDI Output
  1068. if (pData->event.portOut != nullptr)
  1069. {
  1070. float value;
  1071. for (uint32_t k=0; k < pData->param.count; ++k)
  1072. {
  1073. if (pData->param.data[k].type != PARAMETER_OUTPUT)
  1074. continue;
  1075. if (pData->param.data[k].midiCC > 0)
  1076. {
  1077. value = pData->param.ranges[k].getNormalizedValue(fParams[k].value);
  1078. pData->event.portOut->writeControlEvent(0, pData->param.data[k].midiChannel, kEngineControlEventTypeParameter, static_cast<uint16_t>(pData->param.data[k].midiCC), value);
  1079. }
  1080. }
  1081. uint32_t time;
  1082. uint8_t port, size;
  1083. const uint8_t* midiData(fShmRtClientControl.data->midiOut);
  1084. for (std::size_t read=0; read<kBridgeRtClientDataMidiOutSize-kBridgeBaseMidiOutHeaderSize;)
  1085. {
  1086. // get time
  1087. time = *(const uint32_t*)midiData;
  1088. midiData += 4;
  1089. // get port and size
  1090. port = *midiData++;
  1091. size = *midiData++;
  1092. if (size == 0)
  1093. break;
  1094. // store midi data advancing as needed
  1095. uint8_t data[size];
  1096. for (uint8_t j=0; j<size; ++j)
  1097. data[j] = *midiData++;
  1098. pData->event.portOut->writeMidiEvent(time, size, data);
  1099. read += kBridgeBaseMidiOutHeaderSize + size;
  1100. }
  1101. // TODO
  1102. (void)port;
  1103. } // End of Control and MIDI Output
  1104. }
  1105. bool processSingle(const float** const audioIn, float** const audioOut,
  1106. const float** const cvIn, float** const cvOut, const uint32_t frames)
  1107. {
  1108. CARLA_SAFE_ASSERT_RETURN(! fTimedError, false);
  1109. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  1110. if (pData->audioIn.count > 0)
  1111. {
  1112. CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false);
  1113. }
  1114. if (pData->audioOut.count > 0)
  1115. {
  1116. CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false);
  1117. }
  1118. if (pData->cvIn.count > 0)
  1119. {
  1120. CARLA_SAFE_ASSERT_RETURN(cvIn != nullptr, false);
  1121. }
  1122. if (pData->cvOut.count > 0)
  1123. {
  1124. CARLA_SAFE_ASSERT_RETURN(cvOut != nullptr, false);
  1125. }
  1126. // --------------------------------------------------------------------------------------------------------
  1127. // Try lock, silence otherwise
  1128. #ifndef STOAT_TEST_BUILD
  1129. if (pData->engine->isOffline())
  1130. {
  1131. pData->singleMutex.lock();
  1132. }
  1133. else
  1134. #endif
  1135. if (! pData->singleMutex.tryLock())
  1136. {
  1137. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1138. carla_zeroFloats(audioOut[i], frames);
  1139. for (uint32_t i=0; i < pData->cvOut.count; ++i)
  1140. carla_zeroFloats(cvOut[i], frames);
  1141. return false;
  1142. }
  1143. // --------------------------------------------------------------------------------------------------------
  1144. // Reset audio buffers
  1145. for (uint32_t i=0; i < fInfo.aIns; ++i)
  1146. carla_copyFloats(fShmAudioPool.data + (i * frames), audioIn[i], frames);
  1147. // --------------------------------------------------------------------------------------------------------
  1148. // TimeInfo
  1149. const EngineTimeInfo timeInfo(pData->engine->getTimeInfo());
  1150. BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);
  1151. bridgeTimeInfo.playing = timeInfo.playing;
  1152. bridgeTimeInfo.frame = timeInfo.frame;
  1153. bridgeTimeInfo.usecs = timeInfo.usecs;
  1154. bridgeTimeInfo.validFlags = timeInfo.bbt.valid ? kPluginBridgeTimeInfoValidBBT : 0x0;
  1155. if (timeInfo.bbt.valid)
  1156. {
  1157. bridgeTimeInfo.bar = timeInfo.bbt.bar;
  1158. bridgeTimeInfo.beat = timeInfo.bbt.beat;
  1159. bridgeTimeInfo.tick = timeInfo.bbt.tick;
  1160. bridgeTimeInfo.beatsPerBar = timeInfo.bbt.beatsPerBar;
  1161. bridgeTimeInfo.beatType = timeInfo.bbt.beatType;
  1162. bridgeTimeInfo.ticksPerBeat = timeInfo.bbt.ticksPerBeat;
  1163. bridgeTimeInfo.beatsPerMinute = timeInfo.bbt.beatsPerMinute;
  1164. bridgeTimeInfo.barStartTick = timeInfo.bbt.barStartTick;
  1165. }
  1166. // --------------------------------------------------------------------------------------------------------
  1167. // Run plugin
  1168. {
  1169. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientProcess);
  1170. fShmRtClientControl.writeUInt(frames);
  1171. fShmRtClientControl.commitWrite();
  1172. }
  1173. waitForClient("process", fProcWaitTime);
  1174. if (fTimedOut)
  1175. {
  1176. pData->singleMutex.unlock();
  1177. return false;
  1178. }
  1179. for (uint32_t i=0; i < fInfo.aOuts; ++i)
  1180. carla_copyFloats(audioOut[i], fShmAudioPool.data + ((i + fInfo.aIns) * frames), frames);
  1181. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1182. // --------------------------------------------------------------------------------------------------------
  1183. // Post-processing (dry/wet, volume and balance)
  1184. {
  1185. const bool doVolume = (pData->hints & PLUGIN_CAN_VOLUME) != 0 && carla_isNotEqual(pData->postProc.volume, 1.0f);
  1186. const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && carla_isNotEqual(pData->postProc.dryWet, 1.0f);
  1187. const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && ! (carla_isEqual(pData->postProc.balanceLeft, -1.0f) && carla_isEqual(pData->postProc.balanceRight, 1.0f));
  1188. const bool isMono = (pData->audioIn.count == 1);
  1189. bool isPair;
  1190. float bufValue, oldBufLeft[doBalance ? frames : 1];
  1191. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1192. {
  1193. // Dry/Wet
  1194. if (doDryWet)
  1195. {
  1196. const uint32_t c = isMono ? 0 : i;
  1197. for (uint32_t k=0; k < frames; ++k)
  1198. {
  1199. # ifndef BUILD_BRIDGE
  1200. if (k < pData->latency.frames)
  1201. bufValue = pData->latency.buffers[c][k];
  1202. else if (pData->latency.frames < frames)
  1203. bufValue = audioIn[c][k-pData->latency.frames];
  1204. else
  1205. # endif
  1206. bufValue = audioIn[c][k];
  1207. audioOut[i][k] = (audioOut[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet));
  1208. }
  1209. }
  1210. // Balance
  1211. if (doBalance)
  1212. {
  1213. isPair = (i % 2 == 0);
  1214. if (isPair)
  1215. {
  1216. CARLA_ASSERT(i+1 < pData->audioOut.count);
  1217. carla_copyFloats(oldBufLeft, audioOut[i], frames);
  1218. }
  1219. float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f;
  1220. float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
  1221. for (uint32_t k=0; k < frames; ++k)
  1222. {
  1223. if (isPair)
  1224. {
  1225. // left
  1226. audioOut[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
  1227. audioOut[i][k] += audioOut[i+1][k] * (1.0f - balRangeR);
  1228. }
  1229. else
  1230. {
  1231. // right
  1232. audioOut[i][k] = audioOut[i][k] * balRangeR;
  1233. audioOut[i][k] += oldBufLeft[k] * balRangeL;
  1234. }
  1235. }
  1236. }
  1237. // Volume (and buffer copy)
  1238. if (doVolume)
  1239. {
  1240. for (uint32_t k=0; k < frames; ++k)
  1241. audioOut[i][k] *= pData->postProc.volume;
  1242. }
  1243. }
  1244. } // End of Post-processing
  1245. # ifndef BUILD_BRIDGE
  1246. // --------------------------------------------------------------------------------------------------------
  1247. // Save latency values for next callback
  1248. if (const uint32_t latframes = pData->latency.frames)
  1249. {
  1250. if (latframes <= frames)
  1251. {
  1252. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  1253. carla_copyFloats(pData->latency.buffers[i], audioIn[i]+(frames-latframes), latframes);
  1254. }
  1255. else
  1256. {
  1257. const uint32_t diff = pData->latency.frames-frames;
  1258. for (uint32_t i=0, k; i<pData->audioIn.count; ++i)
  1259. {
  1260. // push back buffer by 'frames'
  1261. for (k=0; k < diff; ++k)
  1262. pData->latency.buffers[i][k] = pData->latency.buffers[i][k+frames];
  1263. // put current input at the end
  1264. for (uint32_t j=0; k < latframes; ++j, ++k)
  1265. pData->latency.buffers[i][k] = audioIn[i][j];
  1266. }
  1267. }
  1268. }
  1269. # endif
  1270. #endif // BUILD_BRIDGE_ALTERNATIVE_ARCH
  1271. // --------------------------------------------------------------------------------------------------------
  1272. pData->singleMutex.unlock();
  1273. return true;
  1274. }
  1275. void bufferSizeChanged(const uint32_t newBufferSize) override
  1276. {
  1277. resizeAudioPool(newBufferSize);
  1278. {
  1279. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientSetBufferSize);
  1280. fShmRtClientControl.writeUInt(newBufferSize);
  1281. fShmRtClientControl.commitWrite();
  1282. }
  1283. //fProcWaitTime = newBufferSize*1000/pData->engine->getSampleRate();
  1284. fProcWaitTime = 1000;
  1285. waitForClient("buffersize", 1000);
  1286. }
  1287. void sampleRateChanged(const double newSampleRate) override
  1288. {
  1289. {
  1290. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientSetSampleRate);
  1291. fShmRtClientControl.writeDouble(newSampleRate);
  1292. fShmRtClientControl.commitWrite();
  1293. }
  1294. //fProcWaitTime = pData->engine->getBufferSize()*1000/newSampleRate;
  1295. fProcWaitTime = 1000;
  1296. waitForClient("samplerate", 1000);
  1297. }
  1298. void offlineModeChanged(const bool isOffline) override
  1299. {
  1300. {
  1301. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientSetOnline);
  1302. fShmRtClientControl.writeBool(isOffline);
  1303. fShmRtClientControl.commitWrite();
  1304. }
  1305. waitForClient("offline", 1000);
  1306. }
  1307. // -------------------------------------------------------------------
  1308. // Plugin buffers
  1309. void clearBuffers() noexcept override
  1310. {
  1311. if (fParams != nullptr)
  1312. {
  1313. delete[] fParams;
  1314. fParams = nullptr;
  1315. }
  1316. CarlaPlugin::clearBuffers();
  1317. }
  1318. // -------------------------------------------------------------------
  1319. // Post-poned UI Stuff
  1320. void uiParameterChange(const uint32_t index, const float value) noexcept override
  1321. {
  1322. CARLA_SAFE_ASSERT_RETURN(index < pData->param.count,);
  1323. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  1324. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientUiParameterChange);
  1325. fShmNonRtClientControl.writeUInt(index);
  1326. fShmNonRtClientControl.writeFloat(value);
  1327. fShmNonRtClientControl.commitWrite();
  1328. }
  1329. void uiProgramChange(const uint32_t index) noexcept override
  1330. {
  1331. CARLA_SAFE_ASSERT_RETURN(index < pData->prog.count,);
  1332. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  1333. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientUiProgramChange);
  1334. fShmNonRtClientControl.writeUInt(index);
  1335. fShmNonRtClientControl.commitWrite();
  1336. }
  1337. void uiMidiProgramChange(const uint32_t index) noexcept override
  1338. {
  1339. CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count,);
  1340. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  1341. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientUiMidiProgramChange);
  1342. fShmNonRtClientControl.writeUInt(index);
  1343. fShmNonRtClientControl.commitWrite();
  1344. }
  1345. void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) noexcept override
  1346. {
  1347. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  1348. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  1349. CARLA_SAFE_ASSERT_RETURN(velo > 0 && velo < MAX_MIDI_VALUE,);
  1350. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  1351. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientUiNoteOn);
  1352. fShmNonRtClientControl.writeByte(channel);
  1353. fShmNonRtClientControl.writeByte(note);
  1354. fShmNonRtClientControl.writeByte(velo);
  1355. fShmNonRtClientControl.commitWrite();
  1356. }
  1357. void uiNoteOff(const uint8_t channel, const uint8_t note) noexcept override
  1358. {
  1359. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  1360. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  1361. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  1362. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientUiNoteOff);
  1363. fShmNonRtClientControl.writeByte(channel);
  1364. fShmNonRtClientControl.writeByte(note);
  1365. fShmNonRtClientControl.commitWrite();
  1366. }
  1367. // -------------------------------------------------------------------
  1368. // Internal helper functions
  1369. void restoreLV2State() noexcept override
  1370. {
  1371. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  1372. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientRestoreLV2State);
  1373. fShmNonRtClientControl.commitWrite();
  1374. }
  1375. void waitForBridgeSaveSignal() noexcept override
  1376. {
  1377. waitForSaved();
  1378. }
  1379. // -------------------------------------------------------------------
  1380. void handleNonRtData()
  1381. {
  1382. for (; fShmNonRtServerControl.isDataAvailableForReading();)
  1383. {
  1384. const PluginBridgeNonRtServerOpcode opcode(fShmNonRtServerControl.readOpcode());
  1385. #ifdef DEBUG
  1386. if (opcode != kPluginBridgeNonRtServerPong && opcode != kPluginBridgeNonRtServerParameterValue2) {
  1387. carla_debug("CarlaPluginBridge::handleNonRtData() - got opcode: %s", PluginBridgeNonRtServerOpcode2str(opcode));
  1388. }
  1389. #endif
  1390. if (opcode != kPluginBridgeNonRtServerNull && fLastPongTime > 0)
  1391. fLastPongTime = Time::currentTimeMillis();
  1392. switch (opcode)
  1393. {
  1394. case kPluginBridgeNonRtServerNull:
  1395. case kPluginBridgeNonRtServerPong:
  1396. break;
  1397. case kPluginBridgeNonRtServerPluginInfo1: {
  1398. // uint/category, uint/hints, uint/optionsAvailable, uint/optionsEnabled, long/uniqueId
  1399. const uint32_t category = fShmNonRtServerControl.readUInt();
  1400. const uint32_t hints = fShmNonRtServerControl.readUInt();
  1401. const uint32_t optionAv = fShmNonRtServerControl.readUInt();
  1402. const uint32_t optionEn = fShmNonRtServerControl.readUInt();
  1403. const int64_t uniqueId = fShmNonRtServerControl.readLong();
  1404. if (fUniqueId != 0) {
  1405. CARLA_SAFE_ASSERT_INT2(fUniqueId == uniqueId, fUniqueId, uniqueId);
  1406. }
  1407. pData->hints = hints | PLUGIN_IS_BRIDGE;
  1408. pData->options = optionEn;
  1409. fInfo.category = static_cast<PluginCategory>(category);
  1410. fInfo.optionsAvailable = optionAv;
  1411. } break;
  1412. case kPluginBridgeNonRtServerPluginInfo2: {
  1413. // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright)
  1414. // realName
  1415. const uint32_t realNameSize(fShmNonRtServerControl.readUInt());
  1416. char realName[realNameSize+1];
  1417. carla_zeroChars(realName, realNameSize+1);
  1418. fShmNonRtServerControl.readCustomData(realName, realNameSize);
  1419. // label
  1420. const uint32_t labelSize(fShmNonRtServerControl.readUInt());
  1421. char label[labelSize+1];
  1422. carla_zeroChars(label, labelSize+1);
  1423. fShmNonRtServerControl.readCustomData(label, labelSize);
  1424. // maker
  1425. const uint32_t makerSize(fShmNonRtServerControl.readUInt());
  1426. char maker[makerSize+1];
  1427. carla_zeroChars(maker, makerSize+1);
  1428. fShmNonRtServerControl.readCustomData(maker, makerSize);
  1429. // copyright
  1430. const uint32_t copyrightSize(fShmNonRtServerControl.readUInt());
  1431. char copyright[copyrightSize+1];
  1432. carla_zeroChars(copyright, copyrightSize+1);
  1433. fShmNonRtServerControl.readCustomData(copyright, copyrightSize);
  1434. fInfo.name = realName;
  1435. fInfo.label = label;
  1436. fInfo.maker = maker;
  1437. fInfo.copyright = copyright;
  1438. if (pData->name == nullptr)
  1439. pData->name = pData->engine->getUniquePluginName(realName);
  1440. } break;
  1441. case kPluginBridgeNonRtServerAudioCount: {
  1442. // uint/ins, uint/outs
  1443. fInfo.clear();
  1444. fInfo.aIns = fShmNonRtServerControl.readUInt();
  1445. fInfo.aOuts = fShmNonRtServerControl.readUInt();
  1446. if (fInfo.aIns > 0)
  1447. {
  1448. fInfo.aInNames = new const char*[fInfo.aIns];
  1449. carla_zeroPointers(fInfo.aInNames, fInfo.aIns);
  1450. }
  1451. if (fInfo.aOuts > 0)
  1452. {
  1453. fInfo.aOutNames = new const char*[fInfo.aOuts];
  1454. carla_zeroPointers(fInfo.aOutNames, fInfo.aOuts);
  1455. }
  1456. } break;
  1457. case kPluginBridgeNonRtServerMidiCount: {
  1458. // uint/ins, uint/outs
  1459. fInfo.mIns = fShmNonRtServerControl.readUInt();
  1460. fInfo.mOuts = fShmNonRtServerControl.readUInt();
  1461. } break;
  1462. case kPluginBridgeNonRtServerCvCount: {
  1463. // uint/ins, uint/outs
  1464. fInfo.cvIns = fShmNonRtServerControl.readUInt();
  1465. fInfo.cvOuts = fShmNonRtServerControl.readUInt();
  1466. } break;
  1467. case kPluginBridgeNonRtServerParameterCount: {
  1468. // uint/count
  1469. const uint32_t count = fShmNonRtServerControl.readUInt();
  1470. // delete old data
  1471. pData->param.clear();
  1472. if (fParams != nullptr)
  1473. {
  1474. delete[] fParams;
  1475. fParams = nullptr;
  1476. }
  1477. if (count > 0)
  1478. {
  1479. pData->param.createNew(count, false);
  1480. fParams = new BridgeParamInfo[count];
  1481. // we might not receive all parameter data, so ensure range max is not 0
  1482. for (uint32_t i=0; i<count; ++i)
  1483. {
  1484. pData->param.ranges[i].def = 0.0f;
  1485. pData->param.ranges[i].min = 0.0f;
  1486. pData->param.ranges[i].max = 1.0f;
  1487. pData->param.ranges[i].step = 0.001f;
  1488. pData->param.ranges[i].stepSmall = 0.0001f;
  1489. pData->param.ranges[i].stepLarge = 0.1f;
  1490. }
  1491. }
  1492. } break;
  1493. case kPluginBridgeNonRtServerProgramCount: {
  1494. // uint/count
  1495. pData->prog.clear();
  1496. if (const uint32_t count = fShmNonRtServerControl.readUInt())
  1497. pData->prog.createNew(static_cast<uint32_t>(count));
  1498. } break;
  1499. case kPluginBridgeNonRtServerMidiProgramCount: {
  1500. // uint/count
  1501. pData->midiprog.clear();
  1502. if (const uint32_t count = fShmNonRtServerControl.readUInt())
  1503. pData->midiprog.createNew(static_cast<uint32_t>(count));
  1504. } break;
  1505. case kPluginBridgeNonRtServerPortName: {
  1506. // byte/type, uint/index, uint/size, str[] (name)
  1507. const uint8_t portType = fShmNonRtServerControl.readByte();
  1508. const uint32_t index = fShmNonRtServerControl.readUInt();
  1509. // name
  1510. const uint32_t nameSize(fShmNonRtServerControl.readUInt());
  1511. char* const name = new char[nameSize+1];
  1512. carla_zeroChars(name, nameSize+1);
  1513. fShmNonRtServerControl.readCustomData(name, nameSize);
  1514. CARLA_SAFE_ASSERT_BREAK(portType > kPluginBridgePortNull && portType < kPluginBridgePortTypeCount);
  1515. switch (portType)
  1516. {
  1517. case kPluginBridgePortAudioInput:
  1518. CARLA_SAFE_ASSERT_BREAK(index < fInfo.aIns);
  1519. fInfo.aInNames[index] = name;
  1520. break;
  1521. case kPluginBridgePortAudioOutput:
  1522. CARLA_SAFE_ASSERT_BREAK(index < fInfo.aOuts);
  1523. fInfo.aOutNames[index] = name;
  1524. break;
  1525. }
  1526. } break;
  1527. case kPluginBridgeNonRtServerParameterData1: {
  1528. // uint/index, int/rindex, uint/type, uint/hints, int/cc
  1529. const uint32_t index = fShmNonRtServerControl.readUInt();
  1530. const int32_t rindex = fShmNonRtServerControl.readInt();
  1531. const uint32_t type = fShmNonRtServerControl.readUInt();
  1532. const uint32_t hints = fShmNonRtServerControl.readUInt();
  1533. const int16_t midiCC = fShmNonRtServerControl.readShort();
  1534. CARLA_SAFE_ASSERT_BREAK(midiCC >= -1 && midiCC < MAX_MIDI_CONTROL);
  1535. CARLA_SAFE_ASSERT_INT2(index < pData->param.count, index, pData->param.count);
  1536. if (index < pData->param.count)
  1537. {
  1538. pData->param.data[index].type = static_cast<ParameterType>(type);
  1539. pData->param.data[index].index = static_cast<int32_t>(index);
  1540. pData->param.data[index].rindex = rindex;
  1541. pData->param.data[index].hints = hints;
  1542. pData->param.data[index].midiCC = midiCC;
  1543. }
  1544. } break;
  1545. case kPluginBridgeNonRtServerParameterData2: {
  1546. // uint/index, uint/size, str[] (name), uint/size, str[] (unit)
  1547. const uint32_t index = fShmNonRtServerControl.readUInt();
  1548. // name
  1549. const uint32_t nameSize(fShmNonRtServerControl.readUInt());
  1550. char name[nameSize+1];
  1551. carla_zeroChars(name, nameSize+1);
  1552. fShmNonRtServerControl.readCustomData(name, nameSize);
  1553. // symbol
  1554. const uint32_t symbolSize(fShmNonRtServerControl.readUInt());
  1555. char symbol[symbolSize+1];
  1556. carla_zeroChars(symbol, symbolSize+1);
  1557. fShmNonRtServerControl.readCustomData(symbol, symbolSize);
  1558. // unit
  1559. const uint32_t unitSize(fShmNonRtServerControl.readUInt());
  1560. char unit[unitSize+1];
  1561. carla_zeroChars(unit, unitSize+1);
  1562. fShmNonRtServerControl.readCustomData(unit, unitSize);
  1563. CARLA_SAFE_ASSERT_INT2(index < pData->param.count, index, pData->param.count);
  1564. if (index < pData->param.count)
  1565. {
  1566. fParams[index].name = name;
  1567. fParams[index].symbol = symbol;
  1568. fParams[index].unit = unit;
  1569. }
  1570. } break;
  1571. case kPluginBridgeNonRtServerParameterRanges: {
  1572. // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge
  1573. const uint32_t index = fShmNonRtServerControl.readUInt();
  1574. const float def = fShmNonRtServerControl.readFloat();
  1575. const float min = fShmNonRtServerControl.readFloat();
  1576. const float max = fShmNonRtServerControl.readFloat();
  1577. const float step = fShmNonRtServerControl.readFloat();
  1578. const float stepSmall = fShmNonRtServerControl.readFloat();
  1579. const float stepLarge = fShmNonRtServerControl.readFloat();
  1580. CARLA_SAFE_ASSERT_BREAK(min < max);
  1581. CARLA_SAFE_ASSERT_BREAK(def >= min);
  1582. CARLA_SAFE_ASSERT_BREAK(def <= max);
  1583. CARLA_SAFE_ASSERT_INT2(index < pData->param.count, index, pData->param.count);
  1584. if (index < pData->param.count)
  1585. {
  1586. pData->param.ranges[index].def = def;
  1587. pData->param.ranges[index].min = min;
  1588. pData->param.ranges[index].max = max;
  1589. pData->param.ranges[index].step = step;
  1590. pData->param.ranges[index].stepSmall = stepSmall;
  1591. pData->param.ranges[index].stepLarge = stepLarge;
  1592. }
  1593. } break;
  1594. case kPluginBridgeNonRtServerParameterValue: {
  1595. // uint/index, float/value
  1596. const uint32_t index = fShmNonRtServerControl.readUInt();
  1597. const float value = fShmNonRtServerControl.readFloat();
  1598. if (index < pData->param.count)
  1599. {
  1600. const float fixedValue(pData->param.getFixedValue(index, value));
  1601. fParams[index].value = fixedValue;
  1602. CarlaPlugin::setParameterValue(index, fixedValue, false, true, true);
  1603. }
  1604. } break;
  1605. case kPluginBridgeNonRtServerParameterValue2: {
  1606. // uint/index, float/value
  1607. const uint32_t index = fShmNonRtServerControl.readUInt();
  1608. const float value = fShmNonRtServerControl.readFloat();
  1609. if (index < pData->param.count)
  1610. {
  1611. const float fixedValue(pData->param.getFixedValue(index, value));
  1612. fParams[index].value = fixedValue;
  1613. }
  1614. } break;
  1615. case kPluginBridgeNonRtServerDefaultValue: {
  1616. // uint/index, float/value
  1617. const uint32_t index = fShmNonRtServerControl.readUInt();
  1618. const float value = fShmNonRtServerControl.readFloat();
  1619. if (index < pData->param.count)
  1620. pData->param.ranges[index].def = value;
  1621. } break;
  1622. case kPluginBridgeNonRtServerCurrentProgram: {
  1623. // int/index
  1624. const int32_t index = fShmNonRtServerControl.readInt();
  1625. CARLA_SAFE_ASSERT_BREAK(index >= -1);
  1626. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->prog.count), index, pData->prog.count);
  1627. CarlaPlugin::setProgram(index, false, true, true);
  1628. } break;
  1629. case kPluginBridgeNonRtServerCurrentMidiProgram: {
  1630. // int/index
  1631. const int32_t index = fShmNonRtServerControl.readInt();
  1632. CARLA_SAFE_ASSERT_BREAK(index >= -1);
  1633. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->midiprog.count), index, pData->midiprog.count);
  1634. CarlaPlugin::setMidiProgram(index, false, true, true);
  1635. } break;
  1636. case kPluginBridgeNonRtServerProgramName: {
  1637. // uint/index, uint/size, str[] (name)
  1638. const uint32_t index = fShmNonRtServerControl.readUInt();
  1639. // name
  1640. const uint32_t nameSize(fShmNonRtServerControl.readUInt());
  1641. char name[nameSize+1];
  1642. carla_zeroChars(name, nameSize+1);
  1643. fShmNonRtServerControl.readCustomData(name, nameSize);
  1644. CARLA_SAFE_ASSERT_INT2(index < pData->prog.count, index, pData->prog.count);
  1645. if (index < pData->prog.count)
  1646. {
  1647. if (pData->prog.names[index] != nullptr)
  1648. delete[] pData->prog.names[index];
  1649. pData->prog.names[index] = carla_strdup(name);
  1650. }
  1651. } break;
  1652. case kPluginBridgeNonRtServerMidiProgramData: {
  1653. // uint/index, uint/bank, uint/program, uint/size, str[] (name)
  1654. const uint32_t index = fShmNonRtServerControl.readUInt();
  1655. const uint32_t bank = fShmNonRtServerControl.readUInt();
  1656. const uint32_t program = fShmNonRtServerControl.readUInt();
  1657. // name
  1658. const uint32_t nameSize(fShmNonRtServerControl.readUInt());
  1659. char name[nameSize+1];
  1660. carla_zeroChars(name, nameSize+1);
  1661. fShmNonRtServerControl.readCustomData(name, nameSize);
  1662. CARLA_SAFE_ASSERT_INT2(index < pData->midiprog.count, index, pData->midiprog.count);
  1663. if (index < pData->midiprog.count)
  1664. {
  1665. if (pData->midiprog.data[index].name != nullptr)
  1666. delete[] pData->midiprog.data[index].name;
  1667. pData->midiprog.data[index].bank = bank;
  1668. pData->midiprog.data[index].program = program;
  1669. pData->midiprog.data[index].name = carla_strdup(name);
  1670. }
  1671. } break;
  1672. case kPluginBridgeNonRtServerSetCustomData: {
  1673. // uint/size, str[], uint/size, str[], uint/size, str[]
  1674. // type
  1675. const uint32_t typeSize(fShmNonRtServerControl.readUInt());
  1676. char type[typeSize+1];
  1677. carla_zeroChars(type, typeSize+1);
  1678. fShmNonRtServerControl.readCustomData(type, typeSize);
  1679. // key
  1680. const uint32_t keySize(fShmNonRtServerControl.readUInt());
  1681. char key[keySize+1];
  1682. carla_zeroChars(key, keySize+1);
  1683. fShmNonRtServerControl.readCustomData(key, keySize);
  1684. // value
  1685. const uint32_t valueSize(fShmNonRtServerControl.readUInt());
  1686. char value[valueSize+1];
  1687. carla_zeroChars(value, valueSize+1);
  1688. if (valueSize > 0)
  1689. fShmNonRtServerControl.readCustomData(value, valueSize);
  1690. CarlaPlugin::setCustomData(type, key, value, false);
  1691. } break;
  1692. case kPluginBridgeNonRtServerSetChunkDataFile: {
  1693. // uint/size, str[] (filename)
  1694. // chunkFilePath
  1695. const uint32_t chunkFilePathSize(fShmNonRtServerControl.readUInt());
  1696. char chunkFilePath[chunkFilePathSize+1];
  1697. carla_zeroChars(chunkFilePath, chunkFilePathSize+1);
  1698. fShmNonRtServerControl.readCustomData(chunkFilePath, chunkFilePathSize);
  1699. String realChunkFilePath(chunkFilePath);
  1700. #ifndef CARLA_OS_WIN
  1701. // Using Wine, fix temp dir
  1702. if (fBinaryType == BINARY_WIN32 || fBinaryType == BINARY_WIN64)
  1703. {
  1704. const StringArray driveLetterSplit(StringArray::fromTokens(realChunkFilePath, ":/", ""));
  1705. carla_stdout("chunk save path BEFORE => %s", realChunkFilePath.toRawUTF8());
  1706. realChunkFilePath = fWinePrefix;
  1707. realChunkFilePath += "/drive_";
  1708. realChunkFilePath += driveLetterSplit[0].toLowerCase();
  1709. realChunkFilePath += driveLetterSplit[1];
  1710. realChunkFilePath = realChunkFilePath.replace("\\", "/");
  1711. carla_stdout("chunk save path AFTER => %s", realChunkFilePath.toRawUTF8());
  1712. }
  1713. #endif
  1714. File chunkFile(realChunkFilePath);
  1715. CARLA_SAFE_ASSERT_BREAK(chunkFile.existsAsFile());
  1716. fInfo.chunk = carla_getChunkFromBase64String(chunkFile.loadFileAsString().toRawUTF8());
  1717. chunkFile.deleteFile();
  1718. } break;
  1719. case kPluginBridgeNonRtServerSetLatency:
  1720. if (true)
  1721. {
  1722. // FIXME - latency adjust code on this file is broken
  1723. fShmNonRtServerControl.readUInt();
  1724. break;
  1725. }
  1726. // uint
  1727. fLatency = fShmNonRtServerControl.readUInt();
  1728. #ifndef BUILD_BRIDGE
  1729. if (! fInitiated)
  1730. pData->latency.recreateBuffers(std::max(fInfo.aIns, fInfo.aOuts), fLatency);
  1731. #endif
  1732. break;
  1733. case kPluginBridgeNonRtServerSetParameterText: {
  1734. const int32_t index = fShmNonRtServerControl.readInt();
  1735. const uint32_t textSize(fShmNonRtServerControl.readUInt());
  1736. char text[textSize+1];
  1737. carla_zeroChars(text, textSize+1);
  1738. fShmNonRtServerControl.readCustomData(text, textSize);
  1739. fReceivingParamText.setReceivedData(index, text, textSize);
  1740. } break;
  1741. case kPluginBridgeNonRtServerReady:
  1742. fInitiated = true;
  1743. break;
  1744. case kPluginBridgeNonRtServerSaved:
  1745. fSaved = true;
  1746. break;
  1747. case kPluginBridgeNonRtServerUiClosed:
  1748. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1749. pData->transientTryCounter = 0;
  1750. #endif
  1751. pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr);
  1752. break;
  1753. case kPluginBridgeNonRtServerError: {
  1754. // error
  1755. const uint32_t errorSize(fShmNonRtServerControl.readUInt());
  1756. char error[errorSize+1];
  1757. carla_zeroChars(error, errorSize+1);
  1758. fShmNonRtServerControl.readCustomData(error, errorSize);
  1759. if (fInitiated)
  1760. {
  1761. pData->engine->callback(ENGINE_CALLBACK_ERROR, pData->id, 0, 0, 0.0f, error);
  1762. // just in case
  1763. pData->engine->setLastError(error);
  1764. fInitError = true;
  1765. }
  1766. else
  1767. {
  1768. pData->engine->setLastError(error);
  1769. fInitError = true;
  1770. fInitiated = true;
  1771. }
  1772. } break;
  1773. }
  1774. }
  1775. }
  1776. // -------------------------------------------------------------------
  1777. uintptr_t getUiBridgeProcessId() const noexcept override
  1778. {
  1779. return fBridgeThread.getProcessPID();
  1780. }
  1781. const void* getExtraStuff() const noexcept override
  1782. {
  1783. return fBridgeBinary.isNotEmpty() ? fBridgeBinary.buffer() : nullptr;
  1784. }
  1785. // -------------------------------------------------------------------
  1786. bool init(const char* const filename, const char* const name, const char* const label, const int64_t uniqueId, const char* const bridgeBinary)
  1787. {
  1788. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  1789. // ---------------------------------------------------------------
  1790. // first checks
  1791. if (pData->client != nullptr)
  1792. {
  1793. pData->engine->setLastError("Plugin client is already registered");
  1794. return false;
  1795. }
  1796. if (bridgeBinary == nullptr || bridgeBinary[0] == '\0')
  1797. {
  1798. pData->engine->setLastError("null bridge binary");
  1799. return false;
  1800. }
  1801. // ---------------------------------------------------------------
  1802. // set info
  1803. if (name != nullptr && name[0] != '\0')
  1804. pData->name = pData->engine->getUniquePluginName(name);
  1805. if (filename != nullptr && filename[0] != '\0')
  1806. pData->filename = carla_strdup(filename);
  1807. else
  1808. pData->filename = carla_strdup("");
  1809. fUniqueId = uniqueId;
  1810. fBridgeBinary = bridgeBinary;
  1811. std::srand(static_cast<uint>(std::time(nullptr)));
  1812. // ---------------------------------------------------------------
  1813. // init sem/shm
  1814. if (! fShmAudioPool.initializeServer())
  1815. {
  1816. carla_stderr("Failed to initialize shared memory audio pool");
  1817. return false;
  1818. }
  1819. if (! fShmRtClientControl.initializeServer())
  1820. {
  1821. carla_stderr("Failed to initialize RT client control");
  1822. fShmAudioPool.clear();
  1823. return false;
  1824. }
  1825. if (! fShmNonRtClientControl.initializeServer())
  1826. {
  1827. carla_stderr("Failed to initialize Non-RT client control");
  1828. fShmRtClientControl.clear();
  1829. fShmAudioPool.clear();
  1830. return false;
  1831. }
  1832. if (! fShmNonRtServerControl.initializeServer())
  1833. {
  1834. carla_stderr("Failed to initialize Non-RT server control");
  1835. fShmNonRtClientControl.clear();
  1836. fShmRtClientControl.clear();
  1837. fShmAudioPool.clear();
  1838. return false;
  1839. }
  1840. #ifndef CARLA_OS_WIN
  1841. // ---------------------------------------------------------------
  1842. // set wine prefix
  1843. if (fBridgeBinary.contains(".exe", true))
  1844. {
  1845. const EngineOptions& options(pData->engine->getOptions());
  1846. if (options.wine.autoPrefix)
  1847. fWinePrefix = findWinePrefix(pData->filename);
  1848. if (fWinePrefix.isEmpty())
  1849. {
  1850. const char* const envWinePrefix(std::getenv("WINEPREFIX"));
  1851. if (envWinePrefix != nullptr && envWinePrefix[0] != '\0')
  1852. fWinePrefix = envWinePrefix;
  1853. else if (options.wine.fallbackPrefix != nullptr && options.wine.fallbackPrefix[0] != '\0')
  1854. fWinePrefix = options.wine.fallbackPrefix;
  1855. else
  1856. fWinePrefix = File::getSpecialLocation(File::userHomeDirectory).getFullPathName() + "/.wine";
  1857. }
  1858. }
  1859. #endif
  1860. // ---------------------------------------------------------------
  1861. // init bridge thread
  1862. {
  1863. char shmIdsStr[6*4+1];
  1864. carla_zeroChars(shmIdsStr, 6*4+1);
  1865. std::strncpy(shmIdsStr+6*0, &fShmAudioPool.filename[fShmAudioPool.filename.length()-6], 6);
  1866. std::strncpy(shmIdsStr+6*1, &fShmRtClientControl.filename[fShmRtClientControl.filename.length()-6], 6);
  1867. std::strncpy(shmIdsStr+6*2, &fShmNonRtClientControl.filename[fShmNonRtClientControl.filename.length()-6], 6);
  1868. std::strncpy(shmIdsStr+6*3, &fShmNonRtServerControl.filename[fShmNonRtServerControl.filename.length()-6], 6);
  1869. fBridgeThread.setData(
  1870. #ifndef CARLA_OS_WIN
  1871. fWinePrefix.toRawUTF8(),
  1872. #endif
  1873. bridgeBinary, label, shmIdsStr);
  1874. }
  1875. if (! restartBridgeThread())
  1876. return false;
  1877. // ---------------------------------------------------------------
  1878. // register client
  1879. if (pData->name == nullptr)
  1880. {
  1881. if (label != nullptr && label[0] != '\0')
  1882. pData->name = pData->engine->getUniquePluginName(label);
  1883. else
  1884. pData->name = pData->engine->getUniquePluginName("unknown");
  1885. }
  1886. pData->client = pData->engine->addClient(this);
  1887. if (pData->client == nullptr || ! pData->client->isOk())
  1888. {
  1889. pData->engine->setLastError("Failed to register plugin client");
  1890. return false;
  1891. }
  1892. return true;
  1893. }
  1894. private:
  1895. const BinaryType fBinaryType;
  1896. const PluginType fPluginType;
  1897. bool fInitiated;
  1898. bool fInitError;
  1899. bool fSaved;
  1900. bool fTimedOut;
  1901. bool fTimedError;
  1902. uint fProcWaitTime;
  1903. int64_t fLastPongTime;
  1904. CarlaString fBridgeBinary;
  1905. CarlaPluginBridgeThread fBridgeThread;
  1906. BridgeAudioPool fShmAudioPool;
  1907. BridgeRtClientControl fShmRtClientControl;
  1908. BridgeNonRtClientControl fShmNonRtClientControl;
  1909. BridgeNonRtServerControl fShmNonRtServerControl;
  1910. #ifndef CARLA_OS_WIN
  1911. String fWinePrefix;
  1912. #endif
  1913. class ReceivingParamText {
  1914. public:
  1915. ReceivingParamText() noexcept
  1916. : dataRecv(false),
  1917. dataOk(false),
  1918. index(-1),
  1919. strBuf(nullptr),
  1920. mutex() {}
  1921. bool isCurrentlyWaitingData() const noexcept
  1922. {
  1923. return index >= 0;
  1924. }
  1925. bool wasDataReceived(bool* const success) const noexcept
  1926. {
  1927. *success = dataOk;
  1928. return dataRecv;
  1929. }
  1930. void setTargetData(const int32_t i, char* const b) noexcept
  1931. {
  1932. const CarlaMutexLocker cml(mutex);
  1933. dataOk = false;
  1934. dataRecv = false;
  1935. index = i;
  1936. strBuf = b;
  1937. }
  1938. void setReceivedData(const int32_t i, const char* const b, const uint blen) noexcept
  1939. {
  1940. ScopedValueSetter<bool> svs(dataRecv, false, true);
  1941. const CarlaMutexLocker cml(mutex);
  1942. // make backup and reset data
  1943. const int32_t indexCopy = index;
  1944. char* const strBufCopy = strBuf;
  1945. index = -1;
  1946. strBuf = nullptr;
  1947. CARLA_SAFE_ASSERT_RETURN(indexCopy == i,);
  1948. CARLA_SAFE_ASSERT_RETURN(strBufCopy != nullptr,);
  1949. std::strncpy(strBufCopy, b, std::min(blen, STR_MAX-1U));
  1950. dataOk = true;
  1951. }
  1952. private:
  1953. bool dataRecv;
  1954. bool dataOk;
  1955. int32_t index;
  1956. char* strBuf;
  1957. CarlaMutex mutex;
  1958. CARLA_DECLARE_NON_COPY_CLASS(ReceivingParamText)
  1959. } fReceivingParamText;
  1960. struct Info {
  1961. uint32_t aIns, aOuts;
  1962. uint32_t cvIns, cvOuts;
  1963. uint32_t mIns, mOuts;
  1964. PluginCategory category;
  1965. uint optionsAvailable;
  1966. CarlaString name;
  1967. CarlaString label;
  1968. CarlaString maker;
  1969. CarlaString copyright;
  1970. const char** aInNames;
  1971. const char** aOutNames;
  1972. std::vector<uint8_t> chunk;
  1973. Info()
  1974. : aIns(0),
  1975. aOuts(0),
  1976. cvIns(0),
  1977. cvOuts(0),
  1978. mIns(0),
  1979. mOuts(0),
  1980. category(PLUGIN_CATEGORY_NONE),
  1981. optionsAvailable(0),
  1982. name(),
  1983. label(),
  1984. maker(),
  1985. copyright(),
  1986. aInNames(nullptr),
  1987. aOutNames(nullptr),
  1988. chunk() {}
  1989. ~Info()
  1990. {
  1991. clear();
  1992. }
  1993. void clear()
  1994. {
  1995. if (aInNames != nullptr)
  1996. {
  1997. CARLA_SAFE_ASSERT_INT(aIns > 0, aIns);
  1998. for (uint32_t i=0; i<aIns; ++i)
  1999. delete[] aInNames[i];
  2000. delete[] aInNames;
  2001. aInNames = nullptr;
  2002. }
  2003. if (aOutNames != nullptr)
  2004. {
  2005. CARLA_SAFE_ASSERT_INT(aOuts > 0, aOuts);
  2006. for (uint32_t i=0; i<aOuts; ++i)
  2007. delete[] aOutNames[i];
  2008. delete[] aOutNames;
  2009. aOutNames = nullptr;
  2010. }
  2011. aIns = aOuts = 0;
  2012. }
  2013. CARLA_DECLARE_NON_COPY_STRUCT(Info)
  2014. } fInfo;
  2015. int64_t fUniqueId;
  2016. uint32_t fLatency;
  2017. BridgeParamInfo* fParams;
  2018. void handleProcessStopped() noexcept
  2019. {
  2020. const bool wasActive = pData->active;
  2021. pData->active = false;
  2022. if (wasActive)
  2023. {
  2024. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  2025. if (pData->engine->isOscControlRegistered())
  2026. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_ACTIVE, 0.0f);
  2027. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, PARAMETER_ACTIVE, 0, 0.0f, nullptr);
  2028. #endif
  2029. }
  2030. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  2031. pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr);
  2032. }
  2033. void resizeAudioPool(const uint32_t bufferSize)
  2034. {
  2035. fShmAudioPool.resize(bufferSize, fInfo.aIns+fInfo.aOuts, fInfo.cvIns+fInfo.cvOuts);
  2036. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientSetAudioPool);
  2037. fShmRtClientControl.writeULong(static_cast<uint64_t>(fShmAudioPool.dataSize));
  2038. fShmRtClientControl.commitWrite();
  2039. waitForClient("resize-pool", 5000);
  2040. }
  2041. void waitForClient(const char* const action, const uint msecs)
  2042. {
  2043. CARLA_SAFE_ASSERT_RETURN(! fTimedOut,);
  2044. CARLA_SAFE_ASSERT_RETURN(! fTimedError,);
  2045. if (fShmRtClientControl.waitForClient(msecs))
  2046. return;
  2047. fTimedOut = true;
  2048. carla_stderr2("waitForClient(%s) timed out", action);
  2049. }
  2050. bool restartBridgeThread()
  2051. {
  2052. fInitiated = false;
  2053. fInitError = false;
  2054. fTimedError = false;
  2055. // reset memory
  2056. fShmRtClientControl.data->procFlags = 0;
  2057. carla_zeroStruct(fShmRtClientControl.data->timeInfo);
  2058. carla_zeroBytes(fShmRtClientControl.data->midiOut, kBridgeRtClientDataMidiOutSize);
  2059. fShmRtClientControl.clearData();
  2060. fShmNonRtClientControl.clearData();
  2061. fShmNonRtServerControl.clearData();
  2062. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientVersion);
  2063. fShmNonRtClientControl.writeUInt(CARLA_PLUGIN_BRIDGE_API_VERSION);
  2064. fShmNonRtClientControl.writeUInt(static_cast<uint32_t>(sizeof(BridgeRtClientData)));
  2065. fShmNonRtClientControl.writeUInt(static_cast<uint32_t>(sizeof(BridgeNonRtClientData)));
  2066. fShmNonRtClientControl.writeUInt(static_cast<uint32_t>(sizeof(BridgeNonRtServerData)));
  2067. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientInitialSetup);
  2068. fShmNonRtClientControl.writeUInt(pData->engine->getBufferSize());
  2069. fShmNonRtClientControl.writeDouble(pData->engine->getSampleRate());
  2070. fShmNonRtClientControl.commitWrite();
  2071. if (fShmAudioPool.dataSize != 0)
  2072. {
  2073. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientSetAudioPool);
  2074. fShmRtClientControl.writeULong(static_cast<uint64_t>(fShmAudioPool.dataSize));
  2075. fShmRtClientControl.commitWrite();
  2076. }
  2077. else
  2078. {
  2079. // testing dummy message
  2080. fShmRtClientControl.writeOpcode(kPluginBridgeRtClientNull);
  2081. fShmRtClientControl.commitWrite();
  2082. }
  2083. fBridgeThread.startThread();
  2084. fLastPongTime = Time::currentTimeMillis();
  2085. CARLA_SAFE_ASSERT(fLastPongTime > 0);
  2086. static bool sFirstInit = true;
  2087. int64_t timeoutEnd = 5000;
  2088. if (sFirstInit)
  2089. timeoutEnd *= 2;
  2090. #ifndef CARLA_OS_WIN
  2091. if (fBinaryType == BINARY_WIN32 || fBinaryType == BINARY_WIN64)
  2092. timeoutEnd *= 2;
  2093. #endif
  2094. sFirstInit = false;
  2095. const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin;
  2096. for (; Time::currentTimeMillis() < fLastPongTime + timeoutEnd && fBridgeThread.isThreadRunning();)
  2097. {
  2098. pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  2099. if (needsEngineIdle)
  2100. pData->engine->idle();
  2101. idle();
  2102. if (fInitiated)
  2103. break;
  2104. if (pData->engine->isAboutToClose())
  2105. break;
  2106. carla_msleep(20);
  2107. }
  2108. fLastPongTime = -1;
  2109. if (fInitError || ! fInitiated)
  2110. {
  2111. fBridgeThread.stopThread(6000);
  2112. if (! fInitError)
  2113. pData->engine->setLastError("Timeout while waiting for a response from plugin-bridge\n"
  2114. "(or the plugin crashed on initialization?)");
  2115. return false;
  2116. }
  2117. if (const size_t dataSize = fInfo.chunk.size())
  2118. {
  2119. #ifdef CARLA_PROPER_CPP11_SUPPORT
  2120. void* data = fInfo.chunk.data();
  2121. #else
  2122. void* data = &fInfo.chunk.front();
  2123. #endif
  2124. CarlaString dataBase64(CarlaString::asBase64(data, dataSize));
  2125. CARLA_SAFE_ASSERT_RETURN(dataBase64.length() > 0, true);
  2126. String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName());
  2127. filePath += CARLA_OS_SEP_STR ".CarlaChunk_";
  2128. filePath += fShmAudioPool.getFilenameSuffix();
  2129. if (File(filePath).replaceWithText(dataBase64.buffer()))
  2130. {
  2131. const uint32_t ulength(static_cast<uint32_t>(filePath.length()));
  2132. const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
  2133. fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetChunkDataFile);
  2134. fShmNonRtClientControl.writeUInt(ulength);
  2135. fShmNonRtClientControl.writeCustomData(filePath.toRawUTF8(), ulength);
  2136. fShmNonRtClientControl.commitWrite();
  2137. }
  2138. }
  2139. return true;
  2140. }
  2141. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginBridge)
  2142. };
  2143. CARLA_BACKEND_END_NAMESPACE
  2144. // ---------------------------------------------------------------------------------------------------------------------
  2145. CARLA_BACKEND_START_NAMESPACE
  2146. CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, PluginType ptype, const char* bridgeBinary)
  2147. {
  2148. carla_debug("CarlaPlugin::newBridge({%p, \"%s\", \"%s\", \"%s\"}, %s, %s, \"%s\")", init.engine, init.filename, init.name, init.label, BinaryType2Str(btype), PluginType2Str(ptype), bridgeBinary);
  2149. if (bridgeBinary == nullptr || bridgeBinary[0] == '\0')
  2150. {
  2151. init.engine->setLastError("Bridge not possible, bridge-binary not found");
  2152. return nullptr;
  2153. }
  2154. #ifndef CARLA_OS_WIN
  2155. // FIXME: somewhere, somehow, we end up with double slashes, wine doesn't like that.
  2156. if (std::strncmp(bridgeBinary, "//", 2) == 0)
  2157. ++bridgeBinary;
  2158. #endif
  2159. CarlaPluginBridge* const plugin(new CarlaPluginBridge(init.engine, init.id, btype, ptype));
  2160. if (! plugin->init(init.filename, init.name, init.label, init.uniqueId, bridgeBinary))
  2161. {
  2162. delete plugin;
  2163. return nullptr;
  2164. }
  2165. return plugin;
  2166. }
  2167. CARLA_BACKEND_END_NAMESPACE
  2168. // ---------------------------------------------------------------------------------------------------------------------
  2169. #ifndef BUILD_BRIDGE
  2170. # include "CarlaBridgeUtils.cpp"
  2171. #endif
  2172. // ---------------------------------------------------------------------------------------------------------------------