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

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