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.

BridgePlugin.cpp 71KB

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
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
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
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
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
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
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
10 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
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
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
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
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
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
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
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
10 years ago
10 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160
  1. /*
  2. * Carla Bridge Plugin
  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. #include "CarlaPluginInternal.hpp"
  18. #include "CarlaEngine.hpp"
  19. #ifndef BUILD_BRIDGE
  20. #include "CarlaBackendUtils.hpp"
  21. #include "CarlaBridgeUtils.hpp"
  22. #include "CarlaMathUtils.hpp"
  23. #include "CarlaShmUtils.hpp"
  24. #include "jackbridge/JackBridge.hpp"
  25. #include <cerrno>
  26. #include <cmath>
  27. #include <ctime>
  28. #include <QtCore/QString>
  29. #define CARLA_BRIDGE_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \
  30. /* check argument count */ \
  31. if (argc != argcToCompare) \
  32. { \
  33. carla_stderr("BridgePlugin::%s() - argument count mismatch: %i != %i", __FUNCTION__, argc, argcToCompare); \
  34. return 1; \
  35. } \
  36. if (argc > 0) \
  37. { \
  38. /* check for nullness */ \
  39. if (! (types && typesToCompare)) \
  40. { \
  41. carla_stderr("BridgePlugin::%s() - argument types are null", __FUNCTION__); \
  42. return 1; \
  43. } \
  44. /* check argument types */ \
  45. if (std::strcmp(types, typesToCompare) != 0) \
  46. { \
  47. carla_stderr("BridgePlugin::%s() - argument types mismatch: '%s' != '%s'", __FUNCTION__, types, typesToCompare); \
  48. return 1; \
  49. } \
  50. }
  51. CARLA_BACKEND_START_NAMESPACE
  52. // -------------------------------------------------------------------------------------------------------------------
  53. // call carla_shm_create with for a XXXXXX temp filename
  54. static shm_t shm_mkstemp(char* const fileBase)
  55. {
  56. CARLA_SAFE_ASSERT_RETURN(fileBase != nullptr, gNullCarlaShm);
  57. const size_t fileBaseLen(std::strlen(fileBase));
  58. CARLA_SAFE_ASSERT_RETURN(fileBaseLen > 6, gNullCarlaShm);
  59. CARLA_SAFE_ASSERT_RETURN(std::strcmp(fileBase + fileBaseLen - 6, "XXXXXX") == 0, gNullCarlaShm);
  60. static const char charSet[] = "abcdefghijklmnopqrstuvwxyz"
  61. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  62. "0123456789";
  63. static const int charSetLen = static_cast<int>(sizeof(charSet) - 1); // -1 to avoid trailing '\0'
  64. // try until getting a valid shm or an error occurs
  65. for (;;)
  66. {
  67. for (size_t c = fileBaseLen - 6; c < fileBaseLen; ++c)
  68. fileBase[c] = charSet[std::rand() % charSetLen];
  69. const shm_t shm = carla_shm_create(fileBase);
  70. if (carla_is_shm_valid(shm))
  71. return shm;
  72. if (errno != EEXIST)
  73. return gNullCarlaShm;
  74. }
  75. }
  76. // -------------------------------------------------------------------------------------------------------------------
  77. struct BridgeAudioPool {
  78. CarlaString filename;
  79. float* data;
  80. size_t size;
  81. shm_t shm;
  82. BridgeAudioPool()
  83. : data(nullptr),
  84. size(0)
  85. {
  86. carla_shm_init(shm);
  87. }
  88. ~BridgeAudioPool()
  89. {
  90. // should be cleared by now
  91. CARLA_ASSERT(data == nullptr);
  92. clear();
  93. }
  94. void clear()
  95. {
  96. filename.clear();
  97. if (! carla_is_shm_valid(shm))
  98. return;
  99. if (data != nullptr)
  100. {
  101. carla_shm_unmap(shm, data, size);
  102. data = nullptr;
  103. }
  104. size = 0;
  105. carla_shm_close(shm);
  106. }
  107. void resize(const uint32_t bufferSize, const uint32_t portCount)
  108. {
  109. if (data != nullptr)
  110. carla_shm_unmap(shm, data, size);
  111. size = portCount*bufferSize*sizeof(float);
  112. if (size == 0)
  113. size = sizeof(float);
  114. data = (float*)carla_shm_map(shm, size);
  115. }
  116. CARLA_DECLARE_NON_COPY_STRUCT(BridgeAudioPool)
  117. };
  118. struct BridgeControl : public RingBufferControl<StackBuffer> {
  119. CarlaString filename;
  120. CarlaMutex lock;
  121. BridgeShmControl* data;
  122. shm_t shm;
  123. BridgeControl()
  124. : RingBufferControl<StackBuffer>(nullptr),
  125. data(nullptr)
  126. {
  127. carla_shm_init(shm);
  128. }
  129. ~BridgeControl()
  130. {
  131. // should be cleared by now
  132. CARLA_ASSERT(data == nullptr);
  133. clear();
  134. }
  135. void clear()
  136. {
  137. filename.clear();
  138. if (! carla_is_shm_valid(shm))
  139. return;
  140. if (data != nullptr)
  141. {
  142. carla_shm_unmap(shm, data, sizeof(BridgeShmControl));
  143. data = nullptr;
  144. }
  145. carla_shm_close(shm);
  146. }
  147. bool mapData()
  148. {
  149. CARLA_ASSERT(data == nullptr);
  150. if (carla_shm_map<BridgeShmControl>(shm, data))
  151. {
  152. setRingBuffer(&data->buffer, true);
  153. return true;
  154. }
  155. return false;
  156. }
  157. void unmapData()
  158. {
  159. CARLA_ASSERT(data != nullptr);
  160. if (data == nullptr)
  161. return;
  162. carla_shm_unmap(shm, data, sizeof(BridgeShmControl));
  163. data = nullptr;
  164. setRingBuffer(nullptr, false);
  165. }
  166. bool waitForServer(const int secs)
  167. {
  168. CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);
  169. jackbridge_sem_post(&data->runServer);
  170. return jackbridge_sem_timedwait(&data->runClient, secs);
  171. }
  172. void writeOpcode(const PluginBridgeOpcode opcode) noexcept
  173. {
  174. writeInt(static_cast<int32_t>(opcode));
  175. }
  176. CARLA_DECLARE_NON_COPY_STRUCT(BridgeControl)
  177. };
  178. struct BridgeTime {
  179. CarlaString filename;
  180. BridgeTimeInfo* info;
  181. shm_t shm;
  182. BridgeTime()
  183. : info(nullptr)
  184. {
  185. carla_shm_init(shm);
  186. }
  187. ~BridgeTime()
  188. {
  189. // should be cleared by now
  190. CARLA_ASSERT(info == nullptr);
  191. clear();
  192. }
  193. void clear()
  194. {
  195. filename.clear();
  196. if (! carla_is_shm_valid(shm))
  197. return;
  198. if (info != nullptr)
  199. {
  200. carla_shm_unmap(shm, info, sizeof(BridgeTimeInfo));
  201. info = nullptr;
  202. }
  203. carla_shm_close(shm);
  204. }
  205. bool mapData()
  206. {
  207. CARLA_ASSERT(info == nullptr);
  208. return carla_shm_map<BridgeTimeInfo>(shm, info);
  209. }
  210. void unmapData()
  211. {
  212. CARLA_ASSERT(info != nullptr);
  213. if (info == nullptr)
  214. return;
  215. carla_shm_unmap(shm, info, sizeof(BridgeTimeInfo));
  216. info = nullptr;
  217. }
  218. CARLA_DECLARE_NON_COPY_STRUCT(BridgeTime)
  219. };
  220. // -------------------------------------------------------------------------------------------------------------------
  221. struct BridgeParamInfo {
  222. float value;
  223. QString name;
  224. QString unit;
  225. BridgeParamInfo()
  226. : value(0.0f) {}
  227. CARLA_DECLARE_NON_COPY_STRUCT(BridgeParamInfo)
  228. };
  229. // -------------------------------------------------------------------------------------------------------------------
  230. class BridgePlugin : public CarlaPlugin
  231. {
  232. public:
  233. BridgePlugin(CarlaEngine* const engine, const unsigned int id, const BinaryType btype, const PluginType ptype)
  234. : CarlaPlugin(engine, id),
  235. fBinaryType(btype),
  236. fPluginType(ptype),
  237. fInitiated(false),
  238. fInitError(false),
  239. fSaved(false),
  240. fNeedsSemDestroy(false),
  241. fTimedOut(false),
  242. fLastPongCounter(-1),
  243. fParams(nullptr)
  244. {
  245. carla_debug("BridgePlugin::BridgePlugin(%p, %i, %s, %s)", engine, id, BinaryType2Str(btype), PluginType2Str(ptype));
  246. pData->osc.thread.setMode(CarlaPluginThread::PLUGIN_THREAD_BRIDGE);
  247. pData->hints |= PLUGIN_IS_BRIDGE;
  248. }
  249. ~BridgePlugin() override
  250. {
  251. carla_debug("BridgePlugin::~BridgePlugin()");
  252. // close UI
  253. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  254. pData->transientTryCounter = 0;
  255. pData->singleMutex.lock();
  256. pData->masterMutex.lock();
  257. if (pData->client != nullptr && pData->client->isActive())
  258. pData->client->deactivate();
  259. if (pData->active)
  260. {
  261. deactivate();
  262. pData->active = false;
  263. }
  264. if (pData->osc.thread.isThreadRunning())
  265. {
  266. fShmControl.writeOpcode(kPluginBridgeOpcodeQuit);
  267. fShmControl.commitWrite();
  268. if (! fTimedOut)
  269. fShmControl.waitForServer(3);
  270. }
  271. if (pData->osc.data.target != nullptr)
  272. {
  273. osc_send_hide(pData->osc.data);
  274. osc_send_quit(pData->osc.data);
  275. }
  276. pData->osc.data.free();
  277. pData->osc.thread.stopThread(3000);
  278. if (fNeedsSemDestroy)
  279. {
  280. jackbridge_sem_destroy(&fShmControl.data->runServer);
  281. jackbridge_sem_destroy(&fShmControl.data->runClient);
  282. }
  283. fShmAudioPool.clear();
  284. fShmControl.clear();
  285. fShmTime.clear();
  286. clearBuffers();
  287. //info.chunk.clear();
  288. }
  289. // -------------------------------------------------------------------
  290. // Information (base)
  291. BinaryType getBinaryType() const noexcept
  292. {
  293. return fBinaryType;
  294. }
  295. PluginType getType() const noexcept override
  296. {
  297. return fPluginType;
  298. }
  299. PluginCategory getCategory() const noexcept override
  300. {
  301. return fInfo.category;
  302. }
  303. int64_t getUniqueId() const noexcept override
  304. {
  305. return fInfo.uniqueId;
  306. }
  307. // -------------------------------------------------------------------
  308. // Information (count)
  309. uint32_t getMidiInCount() const noexcept override
  310. {
  311. return fInfo.mIns;
  312. }
  313. uint32_t getMidiOutCount() const noexcept override
  314. {
  315. return fInfo.mOuts;
  316. }
  317. // -------------------------------------------------------------------
  318. // Information (current data)
  319. int32_t getChunkData(void** const dataPtr) const noexcept override
  320. {
  321. CARLA_ASSERT(pData->options & PLUGIN_OPTION_USE_CHUNKS);
  322. CARLA_ASSERT(dataPtr != nullptr);
  323. #if 0
  324. if (! info.chunk.isEmpty())
  325. {
  326. *dataPtr = info.chunk.data();
  327. return info.chunk.size();
  328. }
  329. #endif
  330. return 0;
  331. }
  332. // -------------------------------------------------------------------
  333. // Information (per-plugin data)
  334. unsigned int getOptionsAvailable() const noexcept override
  335. {
  336. unsigned int options = 0x0;
  337. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  338. options |= PLUGIN_OPTION_USE_CHUNKS;
  339. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  340. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  341. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  342. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  343. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  344. return options;
  345. }
  346. float getParameterValue(const uint32_t parameterId) const noexcept override
  347. {
  348. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  349. return fParams[parameterId].value;
  350. }
  351. void getLabel(char* const strBuf) const noexcept override
  352. {
  353. std::strncpy(strBuf, fInfo.label, STR_MAX);
  354. }
  355. void getMaker(char* const strBuf) const noexcept override
  356. {
  357. std::strncpy(strBuf, fInfo.maker, STR_MAX);
  358. }
  359. void getCopyright(char* const strBuf) const noexcept override
  360. {
  361. std::strncpy(strBuf, fInfo.copyright, STR_MAX);
  362. }
  363. void getRealName(char* const strBuf) const noexcept override
  364. {
  365. std::strncpy(strBuf, fInfo.name, STR_MAX);
  366. }
  367. void getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
  368. {
  369. CARLA_ASSERT(parameterId < pData->param.count);
  370. std::strncpy(strBuf, fParams[parameterId].name.toUtf8().constData(), STR_MAX);
  371. }
  372. void getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
  373. {
  374. CARLA_ASSERT(parameterId < pData->param.count);
  375. std::strncpy(strBuf, fParams[parameterId].unit.toUtf8().constData(), STR_MAX);
  376. }
  377. // -------------------------------------------------------------------
  378. // Set data (state)
  379. void prepareForSave() override
  380. {
  381. #if 0
  382. m_saved = false;
  383. osc_send_configure(&osc.data, CARLA_BRIDGE_MSG_SAVE_NOW, "");
  384. for (int i=0; i < 200; ++i)
  385. {
  386. if (m_saved)
  387. break;
  388. carla_msleep(50);
  389. }
  390. if (! m_saved)
  391. carla_stderr("BridgePlugin::prepareForSave() - Timeout while requesting save state");
  392. else
  393. carla_debug("BridgePlugin::prepareForSave() - success!");
  394. #endif
  395. }
  396. // -------------------------------------------------------------------
  397. // Set data (internal stuff)
  398. // nothing
  399. // -------------------------------------------------------------------
  400. // Set data (plugin-specific stuff)
  401. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  402. {
  403. CARLA_ASSERT(parameterId < pData->param.count);
  404. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  405. fParams[parameterId].value = fixedValue;
  406. {
  407. const CarlaMutexLocker _cml(fShmControl.lock);
  408. fShmControl.writeOpcode(sendGui ? kPluginBridgeOpcodeSetParameterNonRt : kPluginBridgeOpcodeSetParameterRt);
  409. fShmControl.writeInt(static_cast<int32_t>(parameterId));
  410. fShmControl.writeFloat(value);
  411. fShmControl.commitWrite();
  412. }
  413. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  414. }
  415. void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  416. {
  417. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);
  418. {
  419. const CarlaMutexLocker _cml(fShmControl.lock);
  420. fShmControl.writeOpcode(kPluginBridgeOpcodeSetProgram);
  421. fShmControl.writeInt(index);
  422. fShmControl.commitWrite();
  423. }
  424. CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback);
  425. }
  426. void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  427. {
  428. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),);
  429. {
  430. const CarlaMutexLocker _cml(fShmControl.lock);
  431. fShmControl.writeOpcode(kPluginBridgeOpcodeSetMidiProgram);
  432. fShmControl.writeInt(index);
  433. fShmControl.commitWrite();
  434. }
  435. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
  436. }
  437. #if 0
  438. void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override
  439. {
  440. CARLA_ASSERT(type);
  441. CARLA_ASSERT(key);
  442. CARLA_ASSERT(value);
  443. if (sendGui)
  444. {
  445. // TODO - if type is chunk|binary, store it in a file and send path instead
  446. QString cData;
  447. cData = type;
  448. cData += "·";
  449. cData += key;
  450. cData += "·";
  451. cData += value;
  452. osc_send_configure(&osc.data, CARLA_BRIDGE_MSG_SET_CUSTOM, cData.toUtf8().constData());
  453. }
  454. CarlaPlugin::setCustomData(type, key, value, sendGui);
  455. }
  456. void setChunkData(const char* const stringData) override
  457. {
  458. CARLA_ASSERT(m_hints & PLUGIN_USES_CHUNKS);
  459. CARLA_ASSERT(stringData);
  460. QString filePath;
  461. filePath = QDir::tempPath();
  462. filePath += "/.CarlaChunk_";
  463. filePath += m_name;
  464. filePath = QDir::toNativeSeparators(filePath);
  465. QFile file(filePath);
  466. if (file.open(QIODevice::WriteOnly | QIODevice::Text))
  467. {
  468. QTextStream out(&file);
  469. out << stringData;
  470. file.close();
  471. osc_send_configure(&osc.data, CARLA_BRIDGE_MSG_SET_CHUNK, filePath.toUtf8().constData());
  472. }
  473. }
  474. #endif
  475. // -------------------------------------------------------------------
  476. // Set ui stuff
  477. void showCustomUI(const bool yesNo) override
  478. {
  479. if (yesNo)
  480. {
  481. osc_send_show(pData->osc.data);
  482. pData->tryTransient();
  483. }
  484. else
  485. {
  486. pData->transientTryCounter = 0;
  487. osc_send_hide(pData->osc.data);
  488. }
  489. }
  490. void idle() override
  491. {
  492. if (! pData->osc.thread.isThreadRunning())
  493. carla_stderr2("TESTING: Bridge has closed!");
  494. CarlaPlugin::idle();
  495. }
  496. // -------------------------------------------------------------------
  497. // Plugin state
  498. void reload() override
  499. {
  500. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  501. carla_debug("BridgePlugin::reload() - start");
  502. const EngineProcessMode processMode(pData->engine->getProccessMode());
  503. // Safely disable plugin for reload
  504. const ScopedDisabler sd(this);
  505. bool needsCtrlIn, needsCtrlOut;
  506. needsCtrlIn = needsCtrlOut = false;
  507. if (fInfo.aIns > 0)
  508. {
  509. pData->audioIn.createNew(fInfo.aIns);
  510. }
  511. if (fInfo.aOuts > 0)
  512. {
  513. pData->audioOut.createNew(fInfo.aOuts);
  514. needsCtrlIn = true;
  515. }
  516. if (fInfo.mIns > 0)
  517. needsCtrlIn = true;
  518. if (fInfo.mOuts > 0)
  519. needsCtrlOut = true;
  520. const uint portNameSize(pData->engine->getMaxPortNameSize());
  521. CarlaString portName;
  522. // Audio Ins
  523. for (uint32_t j=0; j < fInfo.aIns; ++j)
  524. {
  525. portName.clear();
  526. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  527. {
  528. portName = pData->name;
  529. portName += ":";
  530. }
  531. if (fInfo.aIns > 1)
  532. {
  533. portName += "input_";
  534. portName += CarlaString(j+1);
  535. }
  536. else
  537. portName += "input";
  538. portName.truncate(portNameSize);
  539. pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true);
  540. pData->audioIn.ports[j].rindex = j;
  541. }
  542. // Audio Outs
  543. for (uint32_t j=0; j < fInfo.aOuts; ++j)
  544. {
  545. portName.clear();
  546. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  547. {
  548. portName = pData->name;
  549. portName += ":";
  550. }
  551. if (fInfo.aOuts > 1)
  552. {
  553. portName += "output_";
  554. portName += CarlaString(j+1);
  555. }
  556. else
  557. portName += "output";
  558. portName.truncate(portNameSize);
  559. pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false);
  560. pData->audioOut.ports[j].rindex = j;
  561. }
  562. if (needsCtrlIn)
  563. {
  564. portName.clear();
  565. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  566. {
  567. portName = pData->name;
  568. portName += ":";
  569. }
  570. portName += "event-in";
  571. portName.truncate(portNameSize);
  572. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true);
  573. }
  574. if (needsCtrlOut)
  575. {
  576. portName.clear();
  577. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  578. {
  579. portName = pData->name;
  580. portName += ":";
  581. }
  582. portName += "event-out";
  583. portName.truncate(portNameSize);
  584. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false);
  585. }
  586. // extra plugin hints
  587. pData->extraHints = 0x0;
  588. if (fInfo.mIns > 0)
  589. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  590. if (fInfo.mOuts > 0)
  591. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
  592. if (fInfo.aIns <= 2 && fInfo.aOuts <= 2 && (fInfo.aIns == fInfo.aOuts || fInfo.aIns == 0 || fInfo.aOuts == 0))
  593. pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
  594. bufferSizeChanged(pData->engine->getBufferSize());
  595. reloadPrograms(true);
  596. carla_debug("BridgePlugin::reload() - end");
  597. }
  598. // -------------------------------------------------------------------
  599. // Plugin processing
  600. void activate() noexcept override
  601. {
  602. {
  603. const CarlaMutexLocker _cml(fShmControl.lock);
  604. fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameterNonRt);
  605. fShmControl.writeInt(PARAMETER_ACTIVE);
  606. fShmControl.writeFloat(1.0f);
  607. fShmControl.commitWrite();
  608. }
  609. bool timedOut = true;
  610. try {
  611. timedOut = waitForServer();
  612. } catch(...) {}
  613. if (! timedOut)
  614. fTimedOut = false;
  615. }
  616. void deactivate() noexcept override
  617. {
  618. {
  619. const CarlaMutexLocker _cml(fShmControl.lock);
  620. fShmControl.writeOpcode(kPluginBridgeOpcodeSetParameterNonRt);
  621. fShmControl.writeInt(PARAMETER_ACTIVE);
  622. fShmControl.writeFloat(0.0f);
  623. fShmControl.commitWrite();
  624. }
  625. bool timedOut = true;
  626. try {
  627. timedOut = waitForServer();
  628. } catch(...) {}
  629. if (! timedOut)
  630. fTimedOut = false;
  631. }
  632. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override
  633. {
  634. // --------------------------------------------------------------------------------------------------------
  635. // Check if active
  636. if (fTimedOut || ! pData->active)
  637. {
  638. // disable any output sound
  639. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  640. FLOAT_CLEAR(outBuffer[i], frames);
  641. return;
  642. }
  643. // --------------------------------------------------------------------------------------------------------
  644. // Check if needs reset
  645. if (pData->needsReset)
  646. {
  647. // TODO
  648. pData->needsReset = false;
  649. }
  650. // --------------------------------------------------------------------------------------------------------
  651. // Event Input
  652. if (pData->event.portIn != nullptr)
  653. {
  654. // ----------------------------------------------------------------------------------------------------
  655. // MIDI Input (External)
  656. if (pData->extNotes.mutex.tryLock())
  657. {
  658. for (; ! pData->extNotes.data.isEmpty();)
  659. {
  660. const ExternalMidiNote& note(pData->extNotes.data.getFirst(true));
  661. CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  662. char data1, data2, data3;
  663. data1 = static_cast<char>((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
  664. data2 = static_cast<char>(note.note);
  665. data3 = static_cast<char>(note.velo);
  666. const CarlaMutexLocker _cml(fShmControl.lock);
  667. fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent);
  668. fShmControl.writeLong(0);
  669. fShmControl.writeInt(3);
  670. fShmControl.writeChar(data1);
  671. fShmControl.writeChar(data2);
  672. fShmControl.writeChar(data3);
  673. fShmControl.commitWrite();
  674. }
  675. pData->extNotes.mutex.unlock();
  676. } // End of MIDI Input (External)
  677. // ----------------------------------------------------------------------------------------------------
  678. // Event Input (System)
  679. bool allNotesOffSent = false;
  680. uint32_t numEvents = pData->event.portIn->getEventCount();
  681. uint32_t nextBankId;
  682. if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
  683. nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
  684. else
  685. nextBankId = 0;
  686. for (uint32_t i=0; i < numEvents; ++i)
  687. {
  688. const EngineEvent& event(pData->event.portIn->getEvent(i));
  689. // Control change
  690. switch (event.type)
  691. {
  692. case kEngineEventTypeNull:
  693. break;
  694. case kEngineEventTypeControl: {
  695. const EngineControlEvent& ctrlEvent = event.ctrl;
  696. switch (ctrlEvent.type)
  697. {
  698. case kEngineControlEventTypeNull:
  699. break;
  700. case kEngineControlEventTypeParameter:
  701. {
  702. // Control backend stuff
  703. if (event.channel == pData->ctrlChannel)
  704. {
  705. float value;
  706. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
  707. {
  708. value = ctrlEvent.value;
  709. setDryWet(value, false, false);
  710. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
  711. break;
  712. }
  713. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
  714. {
  715. value = ctrlEvent.value*127.0f/100.0f;
  716. setVolume(value, false, false);
  717. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
  718. break;
  719. }
  720. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
  721. {
  722. float left, right;
  723. value = ctrlEvent.value/0.5f - 1.0f;
  724. if (value < 0.0f)
  725. {
  726. left = -1.0f;
  727. right = (value*2.0f)+1.0f;
  728. }
  729. else if (value > 0.0f)
  730. {
  731. left = (value*2.0f)-1.0f;
  732. right = 1.0f;
  733. }
  734. else
  735. {
  736. left = -1.0f;
  737. right = 1.0f;
  738. }
  739. setBalanceLeft(left, false, false);
  740. setBalanceRight(right, false, false);
  741. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  742. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  743. break;
  744. }
  745. }
  746. // Control plugin parameters
  747. uint32_t k;
  748. for (k=0; k < pData->param.count; ++k)
  749. {
  750. if (pData->param.data[k].midiChannel != event.channel)
  751. continue;
  752. if (pData->param.data[k].midiCC != ctrlEvent.param)
  753. continue;
  754. if (pData->param.data[k].type != PARAMETER_INPUT)
  755. continue;
  756. if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  757. continue;
  758. float value;
  759. if (pData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
  760. {
  761. value = (ctrlEvent.value < 0.5f) ? pData->param.ranges[k].min : pData->param.ranges[k].max;
  762. }
  763. else
  764. {
  765. value = pData->param.ranges[k].getUnnormalizedValue(ctrlEvent.value);
  766. if (pData->param.data[k].hints & PARAMETER_IS_INTEGER)
  767. value = std::rint(value);
  768. }
  769. setParameterValue(k, value, false, false, false);
  770. pData->postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
  771. break;
  772. }
  773. // check if event is already handled
  774. if (k != pData->param.count)
  775. break;
  776. if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F)
  777. {
  778. const CarlaMutexLocker _cml(fShmControl.lock);
  779. fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent);
  780. fShmControl.writeLong(event.time);
  781. fShmControl.writeInt(3);
  782. fShmControl.writeChar(static_cast<char>(MIDI_STATUS_CONTROL_CHANGE + event.channel));
  783. fShmControl.writeChar(static_cast<char>(ctrlEvent.param));
  784. fShmControl.writeChar(char(ctrlEvent.value*127.0f));
  785. fShmControl.commitWrite();
  786. }
  787. break;
  788. } // case kEngineControlEventTypeParameter
  789. case kEngineControlEventTypeMidiBank:
  790. if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  791. nextBankId = ctrlEvent.param;
  792. break;
  793. case kEngineControlEventTypeMidiProgram:
  794. if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  795. {
  796. const uint32_t nextProgramId(ctrlEvent.param);
  797. if (pData->midiprog.count > 0)
  798. {
  799. for (uint32_t k=0; k < pData->midiprog.count; ++k)
  800. {
  801. if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId)
  802. {
  803. const int32_t index(static_cast<int32_t>(k));
  804. setMidiProgram(index, false, false, false);
  805. pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, index, 0, 0.0f);
  806. break;
  807. }
  808. }
  809. }
  810. else
  811. {
  812. }
  813. }
  814. break;
  815. case kEngineControlEventTypeAllSoundOff:
  816. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  817. {
  818. // TODO
  819. }
  820. break;
  821. case kEngineControlEventTypeAllNotesOff:
  822. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  823. {
  824. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  825. {
  826. allNotesOffSent = true;
  827. sendMidiAllNotesOffToCallback();
  828. }
  829. // TODO
  830. }
  831. break;
  832. } // switch (ctrlEvent.type)
  833. break;
  834. } // case kEngineEventTypeControl
  835. case kEngineEventTypeMidi:
  836. {
  837. const EngineMidiEvent& midiEvent(event.midi);
  838. if (midiEvent.size == 0 || midiEvent.size > 4)
  839. continue;
  840. uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiEvent.data));
  841. uint8_t channel = event.channel;
  842. if (MIDI_IS_STATUS_NOTE_ON(status) && midiEvent.data[2] == 0)
  843. status = MIDI_STATUS_NOTE_OFF;
  844. if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  845. continue;
  846. if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  847. continue;
  848. if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  849. continue;
  850. if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  851. continue;
  852. char data[4];
  853. data[0] = static_cast<char>(status + channel);
  854. for (uint8_t j=0; j < 4; ++j)
  855. data[j] = static_cast<char>(midiEvent.data[j]);
  856. {
  857. const CarlaMutexLocker _cml(fShmControl.lock);
  858. fShmControl.writeOpcode(kPluginBridgeOpcodeMidiEvent);
  859. fShmControl.writeLong(event.time);
  860. fShmControl.writeInt(midiEvent.size);
  861. for (uint8_t j=0; j < midiEvent.size; ++j)
  862. fShmControl.writeChar(data[j]);
  863. fShmControl.commitWrite();
  864. }
  865. if (status == MIDI_STATUS_NOTE_ON)
  866. pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, midiEvent.data[1], midiEvent.data[2]);
  867. else if (status == MIDI_STATUS_NOTE_OFF)
  868. pData->postponeRtEvent(kPluginPostRtEventNoteOff, channel, midiEvent.data[1], 0.0f);
  869. break;
  870. }
  871. }
  872. }
  873. pData->postRtEvents.trySplice();
  874. } // End of Event Input
  875. processSingle(inBuffer, outBuffer, frames);
  876. }
  877. bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames)
  878. {
  879. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  880. if (pData->audioIn.count > 0)
  881. {
  882. CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
  883. }
  884. if (pData->audioOut.count > 0)
  885. {
  886. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  887. }
  888. // --------------------------------------------------------------------------------------------------------
  889. // Try lock, silence otherwise
  890. if (pData->engine->isOffline())
  891. {
  892. pData->singleMutex.lock();
  893. }
  894. else if (! pData->singleMutex.tryLock())
  895. {
  896. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  897. FLOAT_CLEAR(outBuffer[i], frames);
  898. return false;
  899. }
  900. // --------------------------------------------------------------------------------------------------------
  901. // Reset audio buffers
  902. //std::memset(fShmAudioPool.data, 0, fShmAudioPool.size);
  903. for (uint32_t i=0; i < fInfo.aIns; ++i)
  904. FLOAT_COPY(fShmAudioPool.data + (i * frames), inBuffer[i], frames);
  905. // --------------------------------------------------------------------------------------------------------
  906. // TimeInfo
  907. const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
  908. BridgeTimeInfo* const bridgeInfo(fShmTime.info);
  909. bridgeInfo->playing = timeInfo.playing;
  910. bridgeInfo->frame = timeInfo.frame;
  911. bridgeInfo->usecs = timeInfo.usecs;
  912. bridgeInfo->valid = timeInfo.valid;
  913. if (timeInfo.valid & EngineTimeInfo::kValidBBT)
  914. {
  915. bridgeInfo->bar = timeInfo.bbt.bar;
  916. bridgeInfo->beat = timeInfo.bbt.beat;
  917. bridgeInfo->tick = timeInfo.bbt.tick;
  918. bridgeInfo->beatsPerBar = timeInfo.bbt.beatsPerBar;
  919. bridgeInfo->beatType = timeInfo.bbt.beatType;
  920. bridgeInfo->ticksPerBeat = timeInfo.bbt.ticksPerBeat;
  921. bridgeInfo->beatsPerMinute = timeInfo.bbt.beatsPerMinute;
  922. bridgeInfo->barStartTick = timeInfo.bbt.barStartTick;
  923. }
  924. // --------------------------------------------------------------------------------------------------------
  925. // Run plugin
  926. {
  927. const CarlaMutexLocker _cml(fShmControl.lock);
  928. fShmControl.writeOpcode(kPluginBridgeOpcodeProcess);
  929. fShmControl.commitWrite();
  930. }
  931. if (! waitForServer(2))
  932. {
  933. pData->singleMutex.unlock();
  934. return true;
  935. }
  936. for (uint32_t i=0; i < fInfo.aOuts; ++i)
  937. FLOAT_COPY(outBuffer[i], fShmAudioPool.data + ((i + fInfo.aIns) * frames), frames);
  938. // --------------------------------------------------------------------------------------------------------
  939. // Post-processing (dry/wet, volume and balance)
  940. {
  941. const bool doVolume = (pData->hints & PLUGIN_CAN_VOLUME) != 0 && pData->postProc.volume != 1.0f;
  942. const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && pData->postProc.dryWet != 1.0f;
  943. const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && (pData->postProc.balanceLeft != -1.0f || pData->postProc.balanceRight != 1.0f);
  944. bool isPair;
  945. float bufValue, oldBufLeft[doBalance ? frames : 1];
  946. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  947. {
  948. // Dry/Wet
  949. if (doDryWet)
  950. {
  951. for (uint32_t k=0; k < frames; ++k)
  952. {
  953. bufValue = inBuffer[(pData->audioIn.count == 1) ? 0 : i][k];
  954. outBuffer[i][k] = (outBuffer[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet));
  955. }
  956. }
  957. // Balance
  958. if (doBalance)
  959. {
  960. isPair = (i % 2 == 0);
  961. if (isPair)
  962. {
  963. CARLA_ASSERT(i+1 < pData->audioOut.count);
  964. FLOAT_COPY(oldBufLeft, outBuffer[i], frames);
  965. }
  966. float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f;
  967. float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
  968. for (uint32_t k=0; k < frames; ++k)
  969. {
  970. if (isPair)
  971. {
  972. // left
  973. outBuffer[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
  974. outBuffer[i][k] += outBuffer[i+1][k] * (1.0f - balRangeR);
  975. }
  976. else
  977. {
  978. // right
  979. outBuffer[i][k] = outBuffer[i][k] * balRangeR;
  980. outBuffer[i][k] += oldBufLeft[k] * balRangeL;
  981. }
  982. }
  983. }
  984. // Volume (and buffer copy)
  985. if (doVolume)
  986. {
  987. for (uint32_t k=0; k < frames; ++k)
  988. outBuffer[i][k] *= pData->postProc.volume;
  989. }
  990. }
  991. } // End of Post-processing
  992. // --------------------------------------------------------------------------------------------------------
  993. pData->singleMutex.unlock();
  994. return true;
  995. }
  996. void bufferSizeChanged(const uint32_t newBufferSize) override
  997. {
  998. const CarlaMutexLocker _cml(fShmControl.lock);
  999. resizeAudioPool(newBufferSize);
  1000. fShmControl.writeOpcode(kPluginBridgeOpcodeSetBufferSize);
  1001. fShmControl.writeInt(static_cast<int32_t>(newBufferSize));
  1002. fShmControl.commitWrite();
  1003. }
  1004. void sampleRateChanged(const double newSampleRate) override
  1005. {
  1006. const CarlaMutexLocker _cml(fShmControl.lock);
  1007. fShmControl.writeOpcode(kPluginBridgeOpcodeSetSampleRate);
  1008. fShmControl.writeFloat(static_cast<float>(newSampleRate));
  1009. fShmControl.commitWrite();
  1010. }
  1011. // -------------------------------------------------------------------
  1012. // Plugin buffers
  1013. void clearBuffers() override
  1014. {
  1015. if (fParams != nullptr)
  1016. {
  1017. delete[] fParams;
  1018. fParams = nullptr;
  1019. }
  1020. CarlaPlugin::clearBuffers();
  1021. }
  1022. // -------------------------------------------------------------------
  1023. // Post-poned UI Stuff
  1024. // nothing
  1025. // -------------------------------------------------------------------
  1026. int setOscPluginBridgeInfo(const PluginBridgeInfoType infoType, const int argc, const lo_arg* const* const argv, const char* const types)
  1027. {
  1028. #ifdef DEBUG
  1029. if (infoType != kPluginBridgePong) {
  1030. carla_debug("BridgePlugin::setOscPluginBridgeInfo(%s, %i, %p, \"%s\")", PluginBridgeInfoType2str(infoType), argc, argv, types);
  1031. }
  1032. #endif
  1033. switch (infoType)
  1034. {
  1035. case kPluginBridgePong:
  1036. if (fLastPongCounter > 0)
  1037. fLastPongCounter = 0;
  1038. break;
  1039. case kPluginBridgePluginInfo1: {
  1040. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "iih");
  1041. const int32_t category = argv[0]->i;
  1042. const int32_t hints = argv[1]->i;
  1043. const int64_t uniqueId = argv[2]->h;
  1044. CARLA_SAFE_ASSERT_BREAK(category >= 0);
  1045. CARLA_SAFE_ASSERT_BREAK(hints >= 0);
  1046. pData->hints = static_cast<uint>(hints);
  1047. pData->hints |= PLUGIN_IS_BRIDGE;
  1048. fInfo.category = static_cast<PluginCategory>(category);
  1049. fInfo.uniqueId = static_cast<long>(uniqueId);
  1050. break;
  1051. }
  1052. case kPluginBridgePluginInfo2: {
  1053. CARLA_BRIDGE_CHECK_OSC_TYPES(4, "ssss");
  1054. const char* const realName = (const char*)&argv[0]->s;
  1055. const char* const label = (const char*)&argv[1]->s;
  1056. const char* const maker = (const char*)&argv[2]->s;
  1057. const char* const copyright = (const char*)&argv[3]->s;
  1058. CARLA_SAFE_ASSERT_BREAK(realName != nullptr);
  1059. CARLA_SAFE_ASSERT_BREAK(label != nullptr);
  1060. CARLA_SAFE_ASSERT_BREAK(maker != nullptr);
  1061. CARLA_SAFE_ASSERT_BREAK(copyright != nullptr);
  1062. fInfo.name = realName;
  1063. fInfo.label = label;
  1064. fInfo.maker = maker;
  1065. fInfo.copyright = copyright;
  1066. if (pData->name == nullptr)
  1067. pData->name = pData->engine->getUniquePluginName(realName);
  1068. break;
  1069. }
  1070. case kPluginBridgeAudioCount: {
  1071. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "ii");
  1072. const int32_t ins = argv[0]->i;
  1073. const int32_t outs = argv[1]->i;
  1074. CARLA_SAFE_ASSERT_BREAK(ins >= 0);
  1075. CARLA_SAFE_ASSERT_BREAK(outs >= 0);
  1076. fInfo.aIns = static_cast<uint32_t>(ins);
  1077. fInfo.aOuts = static_cast<uint32_t>(outs);
  1078. break;
  1079. }
  1080. case kPluginBridgeMidiCount: {
  1081. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "ii");
  1082. const int32_t ins = argv[0]->i;
  1083. const int32_t outs = argv[1]->i;
  1084. CARLA_SAFE_ASSERT_BREAK(ins >= 0);
  1085. CARLA_SAFE_ASSERT_BREAK(outs >= 0);
  1086. fInfo.mIns = static_cast<uint32_t>(ins);
  1087. fInfo.mOuts = static_cast<uint32_t>(outs);
  1088. break;
  1089. }
  1090. case kPluginBridgeParameterCount: {
  1091. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "ii");
  1092. const int32_t ins = argv[0]->i;
  1093. const int32_t outs = argv[1]->i;
  1094. CARLA_SAFE_ASSERT_BREAK(ins >= 0);
  1095. CARLA_SAFE_ASSERT_BREAK(outs >= 0);
  1096. // delete old data
  1097. pData->param.clear();
  1098. if (fParams != nullptr)
  1099. {
  1100. delete[] fParams;
  1101. fParams = nullptr;
  1102. }
  1103. if (int32_t count = ins+outs)
  1104. {
  1105. const int32_t maxParams(static_cast<int32_t>(pData->engine->getOptions().maxParameters));
  1106. if (count > maxParams)
  1107. {
  1108. count = maxParams;
  1109. carla_safe_assert_int2("count <= pData->engine->getOptions().maxParameters", __FILE__, __LINE__, count, maxParams);
  1110. }
  1111. const uint32_t ucount(static_cast<uint32_t>(count));
  1112. pData->param.createNew(ucount, false, true);
  1113. fParams = new BridgeParamInfo[ucount];
  1114. }
  1115. break;
  1116. }
  1117. case kPluginBridgeProgramCount: {
  1118. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  1119. const int32_t count = argv[0]->i;
  1120. CARLA_SAFE_ASSERT_BREAK(count >= 0);
  1121. pData->prog.clear();
  1122. if (count > 0)
  1123. pData->prog.createNew(static_cast<uint32_t>(count));
  1124. break;
  1125. }
  1126. case kPluginBridgeMidiProgramCount: {
  1127. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  1128. const int32_t count = argv[0]->i;
  1129. CARLA_SAFE_ASSERT_BREAK(count >= 0);
  1130. pData->midiprog.clear();
  1131. if (count > 0)
  1132. pData->midiprog.createNew(static_cast<uint32_t>(count));
  1133. break;
  1134. }
  1135. case kPluginBridgeParameterData:
  1136. {
  1137. CARLA_BRIDGE_CHECK_OSC_TYPES(6, "iiiiss");
  1138. const int32_t index = argv[0]->i;
  1139. const int32_t rindex = argv[1]->i;
  1140. const int32_t type = argv[2]->i;
  1141. const int32_t hints = argv[3]->i;
  1142. const char* const name = (const char*)&argv[4]->s;
  1143. const char* const unit = (const char*)&argv[5]->s;
  1144. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  1145. CARLA_SAFE_ASSERT_BREAK(rindex >= 0);
  1146. CARLA_SAFE_ASSERT_BREAK(type >= 0);
  1147. CARLA_SAFE_ASSERT_BREAK(hints >= 0);
  1148. CARLA_SAFE_ASSERT_BREAK(name != nullptr);
  1149. CARLA_SAFE_ASSERT_BREAK(unit != nullptr);
  1150. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->param.count), index, pData->param.count);
  1151. if (index < static_cast<int32_t>(pData->param.count))
  1152. {
  1153. pData->param.data[index].type = static_cast<ParameterType>(type);
  1154. pData->param.data[index].index = index;
  1155. pData->param.data[index].rindex = rindex;
  1156. pData->param.data[index].hints = static_cast<uint>(hints);
  1157. fParams[index].name = name;
  1158. fParams[index].unit = unit;
  1159. }
  1160. break;
  1161. }
  1162. case kPluginBridgeParameterRanges1:
  1163. {
  1164. CARLA_BRIDGE_CHECK_OSC_TYPES(4, "ifff");
  1165. const int32_t index = argv[0]->i;
  1166. const float def = argv[1]->f;
  1167. const float min = argv[2]->f;
  1168. const float max = argv[3]->f;
  1169. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  1170. CARLA_SAFE_ASSERT_BREAK(min < max);
  1171. CARLA_SAFE_ASSERT_BREAK(def >= min);
  1172. CARLA_SAFE_ASSERT_BREAK(def <= max);
  1173. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->param.count), index, pData->param.count);
  1174. if (index < static_cast<int32_t>(pData->param.count))
  1175. {
  1176. pData->param.ranges[index].def = def;
  1177. pData->param.ranges[index].min = min;
  1178. pData->param.ranges[index].max = max;
  1179. }
  1180. break;
  1181. }
  1182. case kPluginBridgeParameterRanges2:
  1183. {
  1184. CARLA_BRIDGE_CHECK_OSC_TYPES(4, "ifff");
  1185. const int32_t index = argv[0]->i;
  1186. const float step = argv[1]->f;
  1187. const float stepSmall = argv[2]->f;
  1188. const float stepLarge = argv[3]->f;
  1189. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  1190. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->param.count), index, pData->param.count);
  1191. if (index < static_cast<int32_t>(pData->param.count))
  1192. {
  1193. pData->param.ranges[index].step = step;
  1194. pData->param.ranges[index].stepSmall = stepSmall;
  1195. pData->param.ranges[index].stepLarge = stepLarge;
  1196. }
  1197. break;
  1198. }
  1199. case kPluginBridgeParameterMidiCC: {
  1200. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "ii");
  1201. const int32_t index = argv[0]->i;
  1202. const int32_t cc = argv[1]->i;
  1203. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  1204. CARLA_SAFE_ASSERT_BREAK(cc >= -1 && cc < 0x5F);
  1205. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->param.count), index, pData->param.count);
  1206. if (index < static_cast<int32_t>(pData->param.count))
  1207. pData->param.data[index].midiCC = static_cast<int16_t>(cc);
  1208. break;
  1209. }
  1210. case kPluginBridgeParameterMidiChannel: {
  1211. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "ii");
  1212. const int32_t index = argv[0]->i;
  1213. const int32_t channel = argv[1]->i;
  1214. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  1215. CARLA_SAFE_ASSERT_BREAK(channel >= 0 && channel < MAX_MIDI_CHANNELS);
  1216. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->param.count), index, pData->param.count);
  1217. if (index < static_cast<int32_t>(pData->param.count))
  1218. pData->param.data[index].midiChannel = static_cast<uint8_t>(channel);
  1219. break;
  1220. }
  1221. case kPluginBridgeParameterValue:
  1222. {
  1223. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "if");
  1224. const int32_t index = argv[0]->i;
  1225. const float value = argv[1]->f;
  1226. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  1227. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->param.count), index, pData->param.count);
  1228. if (index < static_cast<int32_t>(pData->param.count))
  1229. {
  1230. const uint32_t uindex(static_cast<uint32_t>(index));
  1231. const float fixedValue(pData->param.getFixedValue(uindex, value));
  1232. fParams[uindex].value = fixedValue;
  1233. CarlaPlugin::setParameterValue(uindex, fixedValue, false, true, true);
  1234. }
  1235. break;
  1236. }
  1237. case kPluginBridgeDefaultValue:
  1238. {
  1239. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "if");
  1240. const int32_t index = argv[0]->i;
  1241. const float value = argv[1]->f;
  1242. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  1243. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->param.count), index, pData->param.count);
  1244. if (index < static_cast<int32_t>(pData->param.count))
  1245. pData->param.ranges[index].def = value;
  1246. break;
  1247. }
  1248. case kPluginBridgeCurrentProgram: {
  1249. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  1250. const int32_t index = argv[0]->i;
  1251. CARLA_SAFE_ASSERT_BREAK(index >= -1);
  1252. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->prog.count), index, pData->prog.count);
  1253. CarlaPlugin::setProgram(index, false, true, true);
  1254. break;
  1255. }
  1256. case kPluginBridgeCurrentMidiProgram: {
  1257. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "i");
  1258. const int32_t index = argv[0]->i;
  1259. CARLA_SAFE_ASSERT_BREAK(index >= -1);
  1260. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->midiprog.count), index, pData->midiprog.count);
  1261. CarlaPlugin::setMidiProgram(index, false, true, true);
  1262. break;
  1263. }
  1264. case kPluginBridgeProgramName: {
  1265. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "is");
  1266. const int32_t index = argv[0]->i;
  1267. const char* const name = (const char*)&argv[1]->s;
  1268. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  1269. CARLA_SAFE_ASSERT_BREAK(name != nullptr);
  1270. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->prog.count), index, pData->prog.count);
  1271. if (index < static_cast<int32_t>(pData->prog.count))
  1272. {
  1273. if (pData->prog.names[index] != nullptr)
  1274. delete[] pData->prog.names[index];
  1275. pData->prog.names[index] = carla_strdup(name);
  1276. }
  1277. break;
  1278. }
  1279. case kPluginBridgeMidiProgramData: {
  1280. CARLA_BRIDGE_CHECK_OSC_TYPES(4, "iiis");
  1281. const int32_t index = argv[0]->i;
  1282. const int32_t bank = argv[1]->i;
  1283. const int32_t program = argv[2]->i;
  1284. const char* const name = (const char*)&argv[3]->s;
  1285. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  1286. CARLA_SAFE_ASSERT_BREAK(bank >= 0);
  1287. CARLA_SAFE_ASSERT_BREAK(program >= 0);
  1288. CARLA_SAFE_ASSERT_BREAK(name != nullptr);
  1289. CARLA_SAFE_ASSERT_INT2(index < static_cast<int32_t>(pData->midiprog.count), index, pData->midiprog.count);
  1290. if (index < static_cast<int32_t>(pData->midiprog.count))
  1291. {
  1292. if (pData->midiprog.data[index].name != nullptr)
  1293. delete[] pData->midiprog.data[index].name;
  1294. pData->midiprog.data[index].bank = static_cast<uint32_t>(bank);
  1295. pData->midiprog.data[index].program = static_cast<uint32_t>(program);
  1296. pData->midiprog.data[index].name = carla_strdup(name);
  1297. }
  1298. break;
  1299. }
  1300. case kPluginBridgeConfigure: {
  1301. CARLA_BRIDGE_CHECK_OSC_TYPES(2, "ss");
  1302. const char* const key = (const char*)&argv[0]->s;
  1303. const char* const value = (const char*)&argv[1]->s;
  1304. CARLA_SAFE_ASSERT_BREAK(key != nullptr);
  1305. CARLA_SAFE_ASSERT_BREAK(value != nullptr);
  1306. if (std::strcmp(key, CARLA_BRIDGE_MSG_HIDE_GUI) == 0)
  1307. pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr);
  1308. else if (std::strcmp(key, CARLA_BRIDGE_MSG_SAVED) == 0)
  1309. fSaved = true;
  1310. break;
  1311. }
  1312. case kPluginBridgeSetCustomData: {
  1313. CARLA_BRIDGE_CHECK_OSC_TYPES(3, "sss");
  1314. const char* const type = (const char*)&argv[0]->s;
  1315. const char* const key = (const char*)&argv[1]->s;
  1316. const char* const value = (const char*)&argv[2]->s;
  1317. CARLA_SAFE_ASSERT_BREAK(type != nullptr);
  1318. CARLA_SAFE_ASSERT_BREAK(key != nullptr);
  1319. CARLA_SAFE_ASSERT_BREAK(value != nullptr);
  1320. CarlaPlugin::setCustomData(type, key, value, false);
  1321. break;
  1322. }
  1323. case kPluginBridgeSetChunkData: {
  1324. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "s");
  1325. #if 0
  1326. const char* const chunkFileChar = (const char*)&argv[0]->s;
  1327. CARLA_ASSERT(chunkFileChar);
  1328. QString chunkFileStr(chunkFileChar);
  1329. #ifndef CARLA_OS_WIN
  1330. // Using Wine, fix temp dir
  1331. if (m_binary == BINARY_WIN32 || m_binary == BINARY_WIN64)
  1332. {
  1333. // Get WINEPREFIX
  1334. QString wineDir;
  1335. if (const char* const WINEPREFIX = getenv("WINEPREFIX"))
  1336. wineDir = QString(WINEPREFIX);
  1337. else
  1338. wineDir = QDir::homePath() + "/.wine";
  1339. QStringList chunkFileStrSplit1 = chunkFileStr.split(":/");
  1340. QStringList chunkFileStrSplit2 = chunkFileStrSplit1.at(1).split("\\");
  1341. QString wineDrive = chunkFileStrSplit1.at(0).toLower();
  1342. QString wineTMP = chunkFileStrSplit2.at(0);
  1343. QString baseName = chunkFileStrSplit2.at(1);
  1344. chunkFileStr = wineDir;
  1345. chunkFileStr += "/drive_";
  1346. chunkFileStr += wineDrive;
  1347. chunkFileStr += "/";
  1348. chunkFileStr += wineTMP;
  1349. chunkFileStr += "/";
  1350. chunkFileStr += baseName;
  1351. chunkFileStr = QDir::toNativeSeparators(chunkFileStr);
  1352. }
  1353. #endif
  1354. QFile chunkFile(chunkFileStr);
  1355. if (chunkFile.open(QIODevice::ReadOnly))
  1356. {
  1357. info.chunk = chunkFile.readAll();
  1358. chunkFile.close();
  1359. chunkFile.remove();
  1360. }
  1361. #endif
  1362. break;
  1363. }
  1364. case kPluginBridgeUpdateNow:
  1365. fInitiated = true;
  1366. break;
  1367. case kPluginBridgeError: {
  1368. CARLA_BRIDGE_CHECK_OSC_TYPES(1, "s");
  1369. const char* const error = (const char*)&argv[0]->s;
  1370. CARLA_ASSERT(error != nullptr);
  1371. pData->engine->setLastError(error);
  1372. fInitError = true;
  1373. fInitiated = true;
  1374. break;
  1375. }
  1376. }
  1377. return 0;
  1378. }
  1379. // -------------------------------------------------------------------
  1380. const void* getExtraStuff() const noexcept override
  1381. {
  1382. return fBridgeBinary.isNotEmpty() ? fBridgeBinary.buffer() : nullptr;
  1383. }
  1384. bool init(const char* const filename, const char* const name, const char* const label, const char* const bridgeBinary)
  1385. {
  1386. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  1387. // ---------------------------------------------------------------
  1388. // first checks
  1389. if (pData->client != nullptr)
  1390. {
  1391. pData->engine->setLastError("Plugin client is already registered");
  1392. return false;
  1393. }
  1394. // ---------------------------------------------------------------
  1395. // set info
  1396. if (name != nullptr && name[0] != '\0')
  1397. pData->name = pData->engine->getUniquePluginName(name);
  1398. pData->filename = carla_strdup(filename);
  1399. if (bridgeBinary != nullptr)
  1400. fBridgeBinary = bridgeBinary;
  1401. std::srand(static_cast<uint>(std::time(nullptr)));
  1402. // ---------------------------------------------------------------
  1403. // SHM Audio Pool
  1404. {
  1405. char tmpFileBase[60];
  1406. std::sprintf(tmpFileBase, "/carla-bridge_shm_XXXXXX");
  1407. fShmAudioPool.shm = shm_mkstemp(tmpFileBase);
  1408. if (! carla_is_shm_valid(fShmAudioPool.shm))
  1409. {
  1410. carla_stdout("Failed to open or create shared memory file #1");
  1411. return false;
  1412. }
  1413. fShmAudioPool.filename = tmpFileBase;
  1414. }
  1415. // ---------------------------------------------------------------
  1416. // SHM Control
  1417. {
  1418. char tmpFileBase[60];
  1419. std::sprintf(tmpFileBase, "/carla-bridge_shc_XXXXXX");
  1420. fShmControl.shm = shm_mkstemp(tmpFileBase);
  1421. if (! carla_is_shm_valid(fShmControl.shm))
  1422. {
  1423. carla_stdout("Failed to open or create shared memory file #2");
  1424. // clear
  1425. carla_shm_close(fShmAudioPool.shm);
  1426. return false;
  1427. }
  1428. fShmControl.filename = tmpFileBase;
  1429. if (! fShmControl.mapData())
  1430. {
  1431. carla_stdout("Failed to map shared memory file #2");
  1432. // clear
  1433. carla_shm_close(fShmControl.shm);
  1434. carla_shm_close(fShmAudioPool.shm);
  1435. return false;
  1436. }
  1437. CARLA_ASSERT(fShmControl.data != nullptr);
  1438. if (! jackbridge_sem_init(&fShmControl.data->runServer))
  1439. {
  1440. carla_stdout("Failed to initialize shared memory semaphore #1");
  1441. // clear
  1442. fShmControl.unmapData();
  1443. carla_shm_close(fShmControl.shm);
  1444. carla_shm_close(fShmAudioPool.shm);
  1445. return false;
  1446. }
  1447. if (! jackbridge_sem_init(&fShmControl.data->runClient))
  1448. {
  1449. carla_stdout("Failed to initialize shared memory semaphore #2");
  1450. // clear
  1451. jackbridge_sem_destroy(&fShmControl.data->runServer);
  1452. fShmControl.unmapData();
  1453. carla_shm_close(fShmControl.shm);
  1454. carla_shm_close(fShmAudioPool.shm);
  1455. return false;
  1456. }
  1457. fNeedsSemDestroy = true;
  1458. }
  1459. // ---------------------------------------------------------------
  1460. // SHM TimeInfo
  1461. {
  1462. char tmpFileBase[60];
  1463. std::sprintf(tmpFileBase, "/carla-bridge_sht_XXXXXX");
  1464. fShmTime.shm = shm_mkstemp(tmpFileBase);
  1465. if (! carla_is_shm_valid(fShmTime.shm))
  1466. {
  1467. carla_stdout("Failed to open or create shared memory file #3");
  1468. return false;
  1469. }
  1470. fShmTime.filename = tmpFileBase;
  1471. if (! fShmTime.mapData())
  1472. {
  1473. carla_stdout("Failed to map shared memory file #3");
  1474. // clear
  1475. jackbridge_sem_destroy(&fShmControl.data->runServer);
  1476. fShmControl.unmapData();
  1477. carla_shm_close(fShmTime.shm);
  1478. carla_shm_close(fShmControl.shm);
  1479. carla_shm_close(fShmAudioPool.shm);
  1480. return false;
  1481. }
  1482. }
  1483. carla_stdout("Carla Server Info:");
  1484. carla_stdout(" sizeof(BridgeShmControl): " P_SIZE, sizeof(BridgeShmControl));
  1485. carla_stdout(" sizeof(BridgeTimeInfo): " P_SIZE, sizeof(BridgeTimeInfo));
  1486. // lock memory
  1487. //fShmControl.lockMemory();
  1488. // initial values
  1489. fShmControl.writeOpcode(kPluginBridgeOpcodeNull);
  1490. fShmControl.writeInt(static_cast<int32_t>(sizeof(BridgeShmControl)));
  1491. fShmControl.writeInt(static_cast<int32_t>(sizeof(BridgeTimeInfo)));
  1492. fShmControl.writeOpcode(kPluginBridgeOpcodeSetBufferSize);
  1493. fShmControl.writeInt(static_cast<int32_t>(pData->engine->getBufferSize()));
  1494. fShmControl.writeOpcode(kPluginBridgeOpcodeSetSampleRate);
  1495. fShmControl.writeFloat(float(pData->engine->getSampleRate()));
  1496. fShmControl.commitWrite();
  1497. // register plugin now so we can receive OSC (and wait for it)
  1498. pData->hints |= PLUGIN_IS_BRIDGE;
  1499. pData->engine->registerEnginePlugin(pData->id, this);
  1500. // init OSC
  1501. {
  1502. char shmIdStr[18+1] = { 0 };
  1503. std::strncpy(shmIdStr, &fShmAudioPool.filename[fShmAudioPool.filename.length()-6], 6);
  1504. std::strncat(shmIdStr, &fShmControl.filename[fShmControl.filename.length()-6], 6);
  1505. std::strncat(shmIdStr, &fShmTime.filename[fShmTime.filename.length()-6], 6);
  1506. pData->osc.thread.setOscData(bridgeBinary, label, getPluginTypeAsString(fPluginType), shmIdStr);
  1507. pData->osc.thread.startThread();
  1508. }
  1509. fInitiated = false;
  1510. fLastPongCounter = 0;
  1511. for (; fLastPongCounter < 200; ++fLastPongCounter)
  1512. {
  1513. if (fInitiated || ! pData->osc.thread.isThreadRunning())
  1514. break;
  1515. carla_msleep(30);
  1516. pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  1517. pData->engine->idle();
  1518. }
  1519. fLastPongCounter = -1;
  1520. if (fInitError || ! fInitiated)
  1521. {
  1522. pData->osc.thread.stopThread(6000);
  1523. if (! fInitError)
  1524. pData->engine->setLastError("Timeout while waiting for a response from plugin-bridge\n(or the plugin crashed on initialization?)");
  1525. return false;
  1526. }
  1527. // ---------------------------------------------------------------
  1528. // register client
  1529. if (pData->name == nullptr)
  1530. {
  1531. if (name != nullptr && name[0] != '\0')
  1532. pData->name = pData->engine->getUniquePluginName(name);
  1533. else if (label != nullptr && label[0] != '\0')
  1534. pData->name = pData->engine->getUniquePluginName(label);
  1535. else
  1536. pData->name = pData->engine->getUniquePluginName("unknown");
  1537. }
  1538. pData->client = pData->engine->addClient(this);
  1539. if (pData->client == nullptr || ! pData->client->isOk())
  1540. {
  1541. pData->engine->setLastError("Failed to register plugin client");
  1542. return false;
  1543. }
  1544. return true;
  1545. }
  1546. private:
  1547. const BinaryType fBinaryType;
  1548. const PluginType fPluginType;
  1549. bool fInitiated;
  1550. bool fInitError;
  1551. bool fSaved;
  1552. bool fNeedsSemDestroy;
  1553. bool fTimedOut;
  1554. volatile int32_t fLastPongCounter;
  1555. CarlaString fBridgeBinary;
  1556. BridgeAudioPool fShmAudioPool;
  1557. BridgeControl fShmControl;
  1558. BridgeTime fShmTime;
  1559. struct Info {
  1560. uint32_t aIns, aOuts;
  1561. uint32_t mIns, mOuts;
  1562. PluginCategory category;
  1563. long uniqueId;
  1564. CarlaString name;
  1565. CarlaString label;
  1566. CarlaString maker;
  1567. CarlaString copyright;
  1568. //QByteArray chunk;
  1569. Info()
  1570. : aIns(0),
  1571. aOuts(0),
  1572. mIns(0),
  1573. mOuts(0),
  1574. category(PLUGIN_CATEGORY_NONE),
  1575. uniqueId(0) {}
  1576. } fInfo;
  1577. BridgeParamInfo* fParams;
  1578. void resizeAudioPool(const uint32_t bufferSize)
  1579. {
  1580. fShmAudioPool.resize(bufferSize, fInfo.aIns+fInfo.aOuts);
  1581. fShmControl.writeOpcode(kPluginBridgeOpcodeSetAudioPool);
  1582. fShmControl.writeLong(static_cast<int64_t>(fShmAudioPool.size));
  1583. fShmControl.commitWrite();
  1584. waitForServer();
  1585. }
  1586. bool waitForServer(const int secs = 5)
  1587. {
  1588. CARLA_SAFE_ASSERT_RETURN(! fTimedOut, false);
  1589. if (! fShmControl.waitForServer(secs))
  1590. {
  1591. carla_stderr("waitForServer() timeout here");
  1592. fTimedOut = true;
  1593. return false;
  1594. }
  1595. return true;
  1596. }
  1597. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(BridgePlugin)
  1598. };
  1599. CARLA_BACKEND_END_NAMESPACE
  1600. #endif // ! BUILD_BRIDGE
  1601. // -------------------------------------------------------------------------------------------------------------------
  1602. CARLA_BACKEND_START_NAMESPACE
  1603. CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, PluginType ptype, const char* const bridgeBinary)
  1604. {
  1605. carla_debug("CarlaPlugin::newBridge({%p, \"%s\", \"%s\", \"%s\"}, %s, %s, \"%s\")", init.engine, init.filename, init.name, init.label, BinaryType2Str(btype), PluginType2Str(ptype), bridgeBinary);
  1606. #ifndef BUILD_BRIDGE
  1607. if (bridgeBinary == nullptr || bridgeBinary[0] == '\0')
  1608. {
  1609. init.engine->setLastError("Bridge not possible, bridge-binary not found");
  1610. return nullptr;
  1611. }
  1612. BridgePlugin* const plugin(new BridgePlugin(init.engine, init.id, btype, ptype));
  1613. if (! plugin->init(init.filename, init.name, init.label, bridgeBinary))
  1614. {
  1615. delete plugin;
  1616. return nullptr;
  1617. }
  1618. plugin->reload();
  1619. if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack())
  1620. {
  1621. init.engine->setLastError("Carla's rack mode can only work with Stereo Bridged plugins, sorry!");
  1622. delete plugin;
  1623. return nullptr;
  1624. }
  1625. return plugin;
  1626. #else
  1627. init.engine->setLastError("Plugin bridge support not available");
  1628. return nullptr;
  1629. // unused
  1630. (void)bridgeBinary;
  1631. #endif
  1632. }
  1633. CarlaPlugin* CarlaPlugin::newJACK(const Initializer& init)
  1634. {
  1635. carla_debug("CarlaPlugin::newJACK({%p, \"%s\", \"%s\", \"%s\", " P_INT64 "})", init.engine, init.filename, init.name, init.label, init.uniqueId);
  1636. #ifndef BUILD_BRIDGE
  1637. BridgePlugin* const plugin(new BridgePlugin(init.engine, init.id, BINARY_NATIVE, PLUGIN_JACK));
  1638. if (! plugin->init(init.filename, init.name, init.label, nullptr))
  1639. {
  1640. delete plugin;
  1641. return nullptr;
  1642. }
  1643. plugin->reload();
  1644. if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack())
  1645. {
  1646. init.engine->setLastError("Carla's rack mode can only work with Stereo bridged apps, sorry!");
  1647. delete plugin;
  1648. return nullptr;
  1649. }
  1650. return plugin;
  1651. #else
  1652. init.engine->setLastError("JACK app bridge support not available");
  1653. return nullptr;
  1654. #endif
  1655. }
  1656. #ifndef BUILD_BRIDGE
  1657. // -------------------------------------------------------------------------------------------------------------------
  1658. // Bridge Helper
  1659. #define bridgePlugin ((BridgePlugin*)plugin)
  1660. extern int CarlaPluginSetOscBridgeInfo(CarlaPlugin* const plugin, const PluginBridgeInfoType type,
  1661. const int argc, const lo_arg* const* const argv, const char* const types);
  1662. int CarlaPluginSetOscBridgeInfo(CarlaPlugin* const plugin, const PluginBridgeInfoType type,
  1663. const int argc, const lo_arg* const* const argv, const char* const types)
  1664. {
  1665. CARLA_ASSERT(plugin != nullptr && (plugin->getHints() & PLUGIN_IS_BRIDGE) != 0);
  1666. return bridgePlugin->setOscPluginBridgeInfo(type, argc, argv, types);
  1667. }
  1668. #undef bridgePlugin
  1669. #endif
  1670. CARLA_BACKEND_END_NAMESPACE
  1671. // -------------------------------------------------------------------------------------------------------------------