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.

CarlaEngineJack.cpp 65KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004
  1. /*
  2. * Carla JACK Engine
  3. * Copyright (C) 2012-2013 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 "CarlaEngineInternal.hpp"
  18. #include "CarlaBackendUtils.hpp"
  19. #include "CarlaMIDI.h"
  20. #include "List.hpp"
  21. #include "jackbridge/JackBridge.hpp"
  22. #include <cmath>
  23. #include <QtCore/QStringList>
  24. #define URI_CANVAS_ICON "http://kxstudio.sf.net/ns/canvas/icon"
  25. CARLA_BACKEND_START_NAMESPACE
  26. #if 0
  27. } // Fix editor indentation
  28. #endif
  29. class CarlaEngineJack;
  30. // -----------------------------------------------------------------------
  31. // Fallback data
  32. static const EngineEvent kFallbackJackEngineEvent = { kEngineEventTypeNull, 0, 0, { kEngineControlEventTypeNull, 0, 0.0f } };
  33. // -----------------------------------------------------------------------
  34. // Carla Engine JACK-Audio port
  35. class CarlaEngineJackAudioPort : public CarlaEngineAudioPort
  36. {
  37. public:
  38. CarlaEngineJackAudioPort(const CarlaEngine& engine, const bool isInput, jack_client_t* const client, jack_port_t* const port)
  39. : CarlaEngineAudioPort(engine, isInput),
  40. fClient(client),
  41. fPort(port)
  42. {
  43. carla_debug("CarlaEngineJackAudioPort::CarlaEngineJackAudioPort(%s, %p, %p)", bool2str(isInput), client, port);
  44. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  45. {
  46. CARLA_ASSERT(client != nullptr && port != nullptr);
  47. }
  48. else
  49. {
  50. CARLA_ASSERT(client == nullptr && port == nullptr);
  51. }
  52. }
  53. ~CarlaEngineJackAudioPort() override
  54. {
  55. carla_debug("CarlaEngineJackAudioPort::~CarlaEngineJackAudioPort()");
  56. if (fClient != nullptr && fPort != nullptr)
  57. {
  58. jackbridge_port_unregister(fClient, fPort);
  59. fClient = nullptr;
  60. fPort = nullptr;
  61. }
  62. }
  63. void initBuffer() override
  64. {
  65. if (fPort == nullptr)
  66. return CarlaEngineAudioPort::initBuffer();
  67. const uint32_t bufferSize(fEngine.getBufferSize());
  68. fBuffer = (float*)jackbridge_port_get_buffer(fPort, bufferSize);
  69. if (! fIsInput)
  70. FLOAT_CLEAR(fBuffer, bufferSize);
  71. }
  72. private:
  73. jack_client_t* fClient;
  74. jack_port_t* fPort;
  75. friend class CarlaEngineJack;
  76. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackAudioPort)
  77. };
  78. // -----------------------------------------------------------------------
  79. // Carla Engine JACK-CV port
  80. class CarlaEngineJackCVPort : public CarlaEngineCVPort
  81. {
  82. public:
  83. CarlaEngineJackCVPort(const CarlaEngine& engine, const bool isInput, jack_client_t* const client, jack_port_t* const port)
  84. : CarlaEngineCVPort(engine, isInput),
  85. fClient(client),
  86. fPort(port)
  87. {
  88. carla_debug("CarlaEngineJackCVPort::CarlaEngineJackCVPort(%s, %p, %p)", bool2str(isInput), client, port);
  89. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  90. {
  91. CARLA_ASSERT(client != nullptr && port != nullptr);
  92. }
  93. else
  94. {
  95. CARLA_ASSERT(client == nullptr && port == nullptr);
  96. }
  97. }
  98. ~CarlaEngineJackCVPort() override
  99. {
  100. carla_debug("CarlaEngineJackCVPort::~CarlaEngineJackCVPort()");
  101. if (fClient != nullptr && fPort != nullptr)
  102. {
  103. jackbridge_port_unregister(fClient, fPort);
  104. fClient = nullptr;
  105. fPort = nullptr;
  106. }
  107. }
  108. void initBuffer() override
  109. {
  110. if (fPort == nullptr)
  111. return CarlaEngineCVPort::initBuffer();
  112. const uint32_t bufferSize(fEngine.getBufferSize());
  113. fBuffer = (float*)jackbridge_port_get_buffer(fPort, bufferSize);
  114. if (! fIsInput)
  115. FLOAT_CLEAR(fBuffer, bufferSize);
  116. }
  117. private:
  118. jack_client_t* fClient;
  119. jack_port_t* fPort;
  120. friend class CarlaEngineJack;
  121. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackCVPort)
  122. };
  123. // -----------------------------------------------------------------------
  124. // Carla Engine JACK-Event port
  125. class CarlaEngineJackEventPort : public CarlaEngineEventPort
  126. {
  127. public:
  128. CarlaEngineJackEventPort(const CarlaEngine& engine, const bool isInput, jack_client_t* const client, jack_port_t* const port)
  129. : CarlaEngineEventPort(engine, isInput),
  130. fClient(client),
  131. fPort(port),
  132. fJackBuffer(nullptr)
  133. {
  134. carla_debug("CarlaEngineJackEventPort::CarlaEngineJackEventPort(%s, %p, %p)", bool2str(isInput), client, port);
  135. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  136. {
  137. CARLA_ASSERT(client != nullptr && port != nullptr);
  138. }
  139. else
  140. {
  141. CARLA_ASSERT(client == nullptr && port == nullptr);
  142. }
  143. }
  144. ~CarlaEngineJackEventPort() override
  145. {
  146. carla_debug("CarlaEngineJackEventPort::~CarlaEngineJackEventPort()");
  147. if (fClient != nullptr && fPort != nullptr)
  148. {
  149. jackbridge_port_unregister(fClient, fPort);
  150. fClient = nullptr;
  151. fPort = nullptr;
  152. }
  153. }
  154. void initBuffer() override
  155. {
  156. if (fPort == nullptr)
  157. return CarlaEngineEventPort::initBuffer();
  158. fJackBuffer = jackbridge_port_get_buffer(fPort, fEngine.getBufferSize());
  159. if (! fIsInput)
  160. jackbridge_midi_clear_buffer(fJackBuffer);
  161. }
  162. uint32_t getEventCount() const override
  163. {
  164. if (fPort == nullptr)
  165. return CarlaEngineEventPort::getEventCount();
  166. CARLA_SAFE_ASSERT_RETURN(fIsInput, 0);
  167. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, 0);
  168. return jackbridge_midi_get_event_count(fJackBuffer);
  169. }
  170. const EngineEvent& getEvent(const uint32_t index) override
  171. {
  172. if (fPort == nullptr)
  173. return CarlaEngineEventPort::getEvent(index);
  174. CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackJackEngineEvent);
  175. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, kFallbackJackEngineEvent);
  176. return getEventUnchecked(index);
  177. }
  178. const EngineEvent& getEventUnchecked(const uint32_t index) override
  179. {
  180. jack_midi_event_t jackEvent;
  181. if (! jackbridge_midi_event_get(&jackEvent, fJackBuffer, index))
  182. return kFallbackJackEngineEvent;
  183. CARLA_SAFE_ASSERT_RETURN(jackEvent.size <= 0xFF /* uint8_t max */, kFallbackJackEngineEvent);
  184. fRetEvent.time = jackEvent.time;
  185. fRetEvent.fillFromMidiData(static_cast<uint8_t>(jackEvent.size), jackEvent.buffer);
  186. return fRetEvent;
  187. }
  188. bool writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) override
  189. {
  190. if (fPort == nullptr)
  191. return CarlaEngineEventPort::writeControlEvent(time, channel, type, param, value);
  192. CARLA_SAFE_ASSERT_RETURN(! fIsInput, false);
  193. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, false);
  194. CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false);
  195. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  196. CARLA_SAFE_ASSERT_RETURN(param < 0x5F, false);
  197. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f);
  198. if (type == kEngineControlEventTypeParameter)
  199. {
  200. CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param));
  201. }
  202. uint8_t size = 0;
  203. uint8_t data[3] = { 0, 0, 0 };
  204. EngineControlEvent ctrlEvent = { type, param, carla_fixValue<float>(0.0f, 1.0f, value) };
  205. ctrlEvent.dumpToMidiData(channel, size, data);
  206. if (size == 0)
  207. return false;
  208. return jackbridge_midi_event_write(fJackBuffer, time, data, size);
  209. }
  210. bool writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data) override
  211. {
  212. if (fPort == nullptr)
  213. return CarlaEngineEventPort::writeMidiEvent(time, channel, port, size, data);
  214. CARLA_SAFE_ASSERT_RETURN(! fIsInput, false);
  215. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, false);
  216. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  217. CARLA_SAFE_ASSERT_RETURN(size > 0, false);
  218. CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);
  219. jack_midi_data_t jdata[size];
  220. jdata[0] = static_cast<jack_midi_data_t>(MIDI_GET_STATUS_FROM_DATA(data) + channel);
  221. for (uint8_t i=1; i < size; ++i)
  222. jdata[i] = data[i];
  223. return jackbridge_midi_event_write(fJackBuffer, time, jdata, size);
  224. }
  225. private:
  226. jack_client_t* fClient;
  227. jack_port_t* fPort;
  228. void* fJackBuffer;
  229. EngineEvent fRetEvent;
  230. friend class CarlaEngineJack;
  231. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackEventPort)
  232. };
  233. // -----------------------------------------------------------------------
  234. // Jack Engine client
  235. class CarlaEngineJackClient : public CarlaEngineClient
  236. {
  237. public:
  238. CarlaEngineJackClient(const CarlaEngine& engine, jack_client_t* const client)
  239. : CarlaEngineClient(engine),
  240. fClient(client),
  241. fUseClient(engine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || engine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  242. {
  243. carla_debug("CarlaEngineJackClient::CarlaEngineJackClient(%p)", client);
  244. if (fUseClient)
  245. {
  246. CARLA_ASSERT(fClient != nullptr);
  247. }
  248. else
  249. {
  250. CARLA_ASSERT(fClient == nullptr);
  251. }
  252. }
  253. ~CarlaEngineJackClient() override
  254. {
  255. carla_debug("CarlaEngineClient::~CarlaEngineClient()");
  256. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS && fClient != nullptr)
  257. jackbridge_client_close(fClient);
  258. }
  259. void activate() override
  260. {
  261. carla_debug("CarlaEngineJackClient::activate()");
  262. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  263. {
  264. CARLA_SAFE_ASSERT_RETURN(fClient != nullptr && ! fActive,);
  265. jackbridge_activate(fClient);
  266. }
  267. CarlaEngineClient::activate();
  268. }
  269. void deactivate() override
  270. {
  271. carla_debug("CarlaEngineJackClient::deactivate()");
  272. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  273. {
  274. CARLA_SAFE_ASSERT_RETURN(fClient != nullptr && fActive,);
  275. jackbridge_deactivate(fClient);
  276. }
  277. CarlaEngineClient::deactivate();
  278. }
  279. bool isOk() const noexcept override
  280. {
  281. if (fUseClient)
  282. return (fClient != nullptr);
  283. return CarlaEngineClient::isOk();
  284. }
  285. #if 0
  286. void setLatency(const uint32_t samples) noexcept override
  287. {
  288. CarlaEngineClient::setLatency(samples);
  289. if (fUseClient && fClient != nullptr)
  290. {
  291. // try etc
  292. jackbridge_recompute_total_latencies(fClient);
  293. }
  294. }
  295. #endif
  296. CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput) override
  297. {
  298. carla_debug("CarlaEngineJackClient::addPort(%s, \"%s\", %s)", EnginePortType2Str(portType), name, bool2str(isInput));
  299. jack_port_t* port = nullptr;
  300. // Create JACK port first, if needed
  301. if (fUseClient && fClient != nullptr)
  302. {
  303. switch (portType)
  304. {
  305. case kEnginePortTypeNull:
  306. break;
  307. case kEnginePortTypeAudio:
  308. port = jackbridge_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
  309. break;
  310. case kEnginePortTypeCV:
  311. port = jackbridge_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsControlVoltage | (isInput ? JackPortIsInput : JackPortIsOutput), 0);
  312. break;
  313. case kEnginePortTypeEvent:
  314. port = jackbridge_port_register(fClient, name, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
  315. break;
  316. }
  317. }
  318. // Create Engine port
  319. switch (portType)
  320. {
  321. case kEnginePortTypeNull:
  322. break;
  323. case kEnginePortTypeAudio:
  324. return new CarlaEngineJackAudioPort(fEngine, isInput, fClient, port);
  325. case kEnginePortTypeCV:
  326. return new CarlaEngineJackCVPort(fEngine, isInput, fClient, port);
  327. case kEnginePortTypeEvent:
  328. return new CarlaEngineJackEventPort(fEngine, isInput, fClient, port);
  329. }
  330. carla_stderr("CarlaEngineJackClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput));
  331. return nullptr;
  332. }
  333. private:
  334. jack_client_t* fClient;
  335. const bool fUseClient;
  336. friend class CarlaEngineJack;
  337. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackClient)
  338. };
  339. // -----------------------------------------------------------------------
  340. // Jack Engine
  341. class CarlaEngineJack : public CarlaEngine
  342. {
  343. public:
  344. CarlaEngineJack()
  345. : CarlaEngine(),
  346. fClient(nullptr),
  347. fTransportState(JackTransportStopped),
  348. fFreewheel(false),
  349. #ifdef BUILD_BRIDGE
  350. fIsRunning(false)
  351. #else
  352. fLastGroupId(0),
  353. fLastPortId(0),
  354. fLastConnectionId(0)
  355. #endif
  356. {
  357. carla_debug("CarlaEngineJack::CarlaEngineJack()");
  358. #ifdef BUILD_BRIDGE
  359. pData->options.processMode = ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS;
  360. #else
  361. carla_fill<jack_port_t*>(fRackPorts, kRackPortCount, nullptr);
  362. #endif
  363. // FIXME: Always enable JACK transport for now
  364. pData->options.transportMode = ENGINE_TRANSPORT_MODE_JACK;
  365. carla_zeroStruct<jack_position_t>(fTransportPos);
  366. }
  367. ~CarlaEngineJack() override
  368. {
  369. carla_debug("CarlaEngineJack::~CarlaEngineJack()");
  370. CARLA_ASSERT(fClient == nullptr);
  371. #ifndef BUILD_BRIDGE
  372. fUsedGroupNames.clear();
  373. fUsedPortNames.clear();
  374. fUsedConnections.clear();
  375. //fGroupIconsChanged.clear();
  376. #endif
  377. }
  378. // -------------------------------------------------------------------
  379. // Maximum values
  380. unsigned int getMaxClientNameSize() const noexcept override
  381. {
  382. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT || pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  383. {
  384. unsigned int ret = 0;
  385. try {
  386. ret = static_cast<unsigned int>(jackbridge_client_name_size());
  387. }
  388. catch (...) {}
  389. return ret;
  390. }
  391. return CarlaEngine::getMaxClientNameSize();
  392. }
  393. unsigned int getMaxPortNameSize() const noexcept override
  394. {
  395. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT || pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  396. {
  397. unsigned int ret = 0;
  398. try {
  399. ret = static_cast<unsigned int>(jackbridge_port_name_size());
  400. }
  401. catch (...) {}
  402. return ret;
  403. }
  404. return CarlaEngine::getMaxPortNameSize();
  405. }
  406. // -------------------------------------------------------------------
  407. // Virtual, per-engine type calls
  408. bool init(const char* const clientName) override
  409. {
  410. carla_debug("CarlaEngineJack::init(\"%s\")", clientName);
  411. fFreewheel = false;
  412. fTransportState = JackTransportStopped;
  413. carla_zeroStruct<jack_position_t>(fTransportPos);
  414. #ifdef BUILD_BRIDGE
  415. if (pData->bufferSize == 0 || pData->sampleRate == 0.0)
  416. {
  417. // open temp client to get initial buffer-size and sample-rate values
  418. if (jack_client_t* tmpClient = jackbridge_client_open(clientName, JackNullOption, nullptr))
  419. {
  420. pData->bufferSize = jackbridge_get_buffer_size(tmpClient);
  421. pData->sampleRate = jackbridge_get_sample_rate(tmpClient);
  422. jackbridge_client_close(tmpClient);
  423. }
  424. }
  425. fIsRunning = true;
  426. return CarlaEngine::init(clientName);
  427. #else
  428. fLastGroupId = 0;
  429. fLastPortId = 0;
  430. fLastConnectionId = 0;
  431. fUsedGroupNames.clear();
  432. fUsedPortNames.clear();
  433. fUsedConnections.clear();
  434. //fGroupIconsChanged.clear();
  435. fClient = jackbridge_client_open(clientName, JackNullOption, nullptr);
  436. if (fClient != nullptr)
  437. {
  438. pData->bufferSize = jackbridge_get_buffer_size(fClient);
  439. pData->sampleRate = jackbridge_get_sample_rate(fClient);
  440. //jackbridge_custom_publish_data(fClient, URI_CANVAS_ICON, "carla", 6);
  441. //jackbridge_custom_set_data_appearance_callback(fClient, carla_jack_custom_appearance_callback, this);
  442. jackbridge_set_buffer_size_callback(fClient, carla_jack_bufsize_callback, this);
  443. jackbridge_set_sample_rate_callback(fClient, carla_jack_srate_callback, this);
  444. jackbridge_set_freewheel_callback(fClient, carla_jack_freewheel_callback, this);
  445. jackbridge_set_latency_callback(fClient, carla_jack_latency_callback, this);
  446. jackbridge_set_process_callback(fClient, carla_jack_process_callback, this);
  447. jackbridge_on_shutdown(fClient, carla_jack_shutdown_callback, this);
  448. const char* const jackClientName(jackbridge_get_client_name(fClient));
  449. initJackPatchbay(jackClientName);
  450. jackbridge_set_client_registration_callback(fClient, carla_jack_client_registration_callback, this);
  451. jackbridge_set_port_registration_callback(fClient, carla_jack_port_registration_callback, this);
  452. jackbridge_set_port_connect_callback(fClient, carla_jack_port_connect_callback, this);
  453. jackbridge_set_port_rename_callback(fClient, carla_jack_port_rename_callback, this);
  454. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  455. {
  456. fRackPorts[kRackPortAudioIn1] = jackbridge_port_register(fClient, "audio-in1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  457. fRackPorts[kRackPortAudioIn2] = jackbridge_port_register(fClient, "audio-in2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  458. fRackPorts[kRackPortAudioOut1] = jackbridge_port_register(fClient, "audio-out1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  459. fRackPorts[kRackPortAudioOut2] = jackbridge_port_register(fClient, "audio-out2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  460. fRackPorts[kRackPortEventIn] = jackbridge_port_register(fClient, "events-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
  461. fRackPorts[kRackPortEventOut] = jackbridge_port_register(fClient, "events-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
  462. }
  463. if (jackbridge_activate(fClient))
  464. {
  465. CarlaEngine::init(jackClientName);
  466. return true;
  467. }
  468. else
  469. {
  470. setLastError("Failed to activate the JACK client");
  471. jackbridge_client_close(fClient);
  472. fClient = nullptr;
  473. }
  474. }
  475. else
  476. setLastError("Failed to create new JACK client");
  477. return false;
  478. #endif
  479. }
  480. bool close() override
  481. {
  482. carla_debug("CarlaEngineJack::close()");
  483. CarlaEngine::close();
  484. #ifdef BUILD_BRIDGE
  485. fClient = nullptr;
  486. fIsRunning = false;
  487. return true;
  488. #else
  489. if (jackbridge_deactivate(fClient))
  490. {
  491. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  492. {
  493. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioIn1]);
  494. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioIn2]);
  495. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioOut1]);
  496. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioOut2]);
  497. jackbridge_port_unregister(fClient, fRackPorts[kRackPortEventIn]);
  498. jackbridge_port_unregister(fClient, fRackPorts[kRackPortEventOut]);
  499. carla_fill<jack_port_t*>(fRackPorts, kRackPortCount, nullptr);
  500. }
  501. if (jackbridge_client_close(fClient))
  502. {
  503. fClient = nullptr;
  504. return true;
  505. }
  506. else
  507. setLastError("Failed to close the JACK client");
  508. }
  509. else
  510. setLastError("Failed to deactivate the JACK client");
  511. fClient = nullptr;
  512. fUsedGroupNames.clear();
  513. fUsedPortNames.clear();
  514. fUsedConnections.clear();
  515. //fGroupIconsChanged.clear();
  516. return false;
  517. #endif
  518. }
  519. #if 0 //ndef BUILD_BRIDGE
  520. void idle() override
  521. {
  522. CarlaEngine::idle();
  523. if (fGroupIconsChanged.count() == 0)
  524. return;
  525. static bool checkIcons = false;
  526. if (! checkIcons)
  527. {
  528. checkIcons = true; // check them next time
  529. return;
  530. }
  531. checkIcons = false;
  532. void* data;
  533. size_t dataSize;
  534. List<int> groupIconsCopy;
  535. fGroupIconsChanged.spliceAppend(groupIconsCopy, true);
  536. for (List<int>::Itenerator it = groupIconsCopy.begin(); it.valid(); it.next())
  537. {
  538. const int& groupId(*it);
  539. const char* const groupName(getGroupName(groupId));
  540. data = nullptr;
  541. dataSize = 0;
  542. if (jackbridge_custom_get_data(fClient, groupName, URI_CANVAS_ICON, &data, &dataSize) && data != nullptr && dataSize != 0)
  543. {
  544. const char* const icon((const char*)data);
  545. CARLA_ASSERT(std::strlen(icon)+1 == dataSize);
  546. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ICON_CHANGED, 0, groupId, 0, 0.0f, icon);
  547. jackbridge_free(data);
  548. }
  549. }
  550. groupIconsCopy.clear();
  551. }
  552. #endif
  553. bool isRunning() const noexcept override
  554. {
  555. #ifdef BUILD_BRIDGE
  556. return (fClient != nullptr || fIsRunning);
  557. #else
  558. return (fClient != nullptr);
  559. #endif
  560. }
  561. bool isOffline() const noexcept override
  562. {
  563. return fFreewheel;
  564. }
  565. EngineType getType() const noexcept override
  566. {
  567. return kEngineTypeJack;
  568. }
  569. const char* getCurrentDriverName() const noexcept override
  570. {
  571. return "JACK";
  572. }
  573. CarlaEngineClient* addClient(CarlaPlugin* const plugin) override
  574. {
  575. //const char* const iconName(plugin->getIconName());
  576. jack_client_t* client = nullptr;
  577. #ifdef BUILD_BRIDGE
  578. client = fClient = jackbridge_client_open(plugin->getName(), JackNullOption, nullptr);
  579. CARLA_SAFE_ASSERT_RETURN(client != nullptr, nullptr);
  580. pData->bufferSize = jackbridge_get_buffer_size(client);
  581. pData->sampleRate = jackbridge_get_sample_rate(client);
  582. //jackbridge_custom_publish_data(client, URI_CANVAS_ICON, iconName, std::strlen(iconName)+1);
  583. jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this);
  584. jackbridge_set_sample_rate_callback(client, carla_jack_srate_callback, this);
  585. jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this);
  586. jackbridge_set_latency_callback(client, carla_jack_latency_callback, this);
  587. jackbridge_set_process_callback(client, carla_jack_process_callback, this);
  588. jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this);
  589. #else
  590. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  591. {
  592. client = fClient;
  593. }
  594. else if (pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  595. {
  596. client = jackbridge_client_open(plugin->getName(), JackNullOption, nullptr);
  597. CARLA_SAFE_ASSERT_RETURN(client != nullptr, nullptr);
  598. //jackbridge_custom_publish_data(client, URI_CANVAS_ICON, iconName, std::strlen(iconName)+1);
  599. jackbridge_set_latency_callback(client, carla_jack_latency_callback_plugin, plugin);
  600. jackbridge_set_process_callback(client, carla_jack_process_callback_plugin, plugin);
  601. }
  602. #endif
  603. return new CarlaEngineJackClient(*this, client);
  604. }
  605. #ifndef BUILD_BRIDGE
  606. const char* renamePlugin(const unsigned int id, const char* const newName) override
  607. {
  608. CARLA_ASSERT(pData->curPluginCount > 0);
  609. CARLA_ASSERT(id < pData->curPluginCount);
  610. CARLA_ASSERT(pData->plugins != nullptr);
  611. CARLA_ASSERT(newName != nullptr);
  612. if (pData->plugins == nullptr)
  613. {
  614. setLastError("Critical error: no plugins are currently loaded!");
  615. return nullptr;
  616. }
  617. CarlaPlugin* const plugin(pData->plugins[id].plugin);
  618. if (plugin == nullptr)
  619. {
  620. carla_stderr("CarlaEngine::clonePlugin(%i) - could not find plugin", id);
  621. return nullptr;
  622. }
  623. CARLA_ASSERT(plugin->getId() == id);
  624. bool needsReinit = (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT);
  625. const char* name = getUniquePluginName(newName);
  626. // TODO - use rename port if single-client
  627. // JACK client rename
  628. if (pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  629. {
  630. CarlaEngineJackClient* const client((CarlaEngineJackClient*)plugin->getEngineClient());
  631. #if 0
  632. if (bridge.client_rename_ptr != nullptr)
  633. {
  634. name = bridge.client_rename_ptr(client->fClient, name);
  635. }
  636. else
  637. #endif
  638. {
  639. // we should not be able to do this, jack really needs to allow client rename
  640. needsReinit = true;
  641. if (jack_client_t* jclient = jackbridge_client_open(name, JackNullOption, nullptr))
  642. {
  643. //const char* const iconName(plugin->getIconName());
  644. //jackbridge_custom_publish_data(jclient, URI_CANVAS_ICON, iconName, std::strlen(iconName)+1);
  645. // close old client
  646. plugin->setEnabled(false);
  647. if (client->isActive())
  648. client->deactivate();
  649. plugin->clearBuffers();
  650. jackbridge_client_close(client->fClient);
  651. // set new client data
  652. name = jackbridge_get_client_name(jclient);
  653. jackbridge_set_process_callback(jclient, carla_jack_process_callback_plugin, plugin);
  654. jackbridge_set_latency_callback(jclient, carla_jack_latency_callback_plugin, plugin);
  655. client->fClient = jclient;
  656. }
  657. }
  658. }
  659. if (name == nullptr)
  660. return nullptr;
  661. // Rename
  662. plugin->setName(name);
  663. if (needsReinit)
  664. {
  665. // reload plugin to recreate its ports
  666. const SaveState& saveState(plugin->getSaveState());
  667. plugin->reload();
  668. plugin->loadSaveState(saveState);
  669. }
  670. return name;
  671. }
  672. // -------------------------------------------------------------------
  673. // Patchbay
  674. bool patchbayConnect(int portA, int portB) override
  675. {
  676. CARLA_ASSERT(fClient != nullptr);
  677. if (fClient == nullptr)
  678. {
  679. setLastError("Invalid JACK client");
  680. return false;
  681. }
  682. char portNameA[STR_MAX+1];
  683. char portNameB[STR_MAX+1];
  684. getFullPortName(portA, portNameA);
  685. getFullPortName(portB, portNameB);
  686. if (! jackbridge_connect(fClient, portNameA, portNameB))
  687. {
  688. setLastError("JACK operation failed");
  689. return false;
  690. }
  691. return true;
  692. }
  693. bool patchbayDisconnect(int connectionId) override
  694. {
  695. CARLA_ASSERT(fClient != nullptr);
  696. if (fClient == nullptr)
  697. {
  698. setLastError("Invalid JACK client");
  699. return false;
  700. }
  701. for (List<ConnectionToId>::Itenerator it = fUsedConnections.begin(); it.valid(); it.next())
  702. {
  703. const ConnectionToId& connectionToId(it.getConstValue());
  704. if (connectionToId.id == connectionId)
  705. {
  706. char portNameOut[STR_MAX+1];
  707. char portNameIn[STR_MAX+1];
  708. getFullPortName(connectionToId.portOut, portNameOut);
  709. getFullPortName(connectionToId.portIn, portNameIn);
  710. if (! jackbridge_disconnect(fClient, portNameOut, portNameIn))
  711. {
  712. setLastError("JACK operation failed");
  713. return false;
  714. }
  715. return true;
  716. }
  717. }
  718. setLastError("Failed to find the requested connection");
  719. return false;
  720. }
  721. bool patchbayRefresh() override
  722. {
  723. CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false);
  724. fLastGroupId = 0;
  725. fLastPortId = 0;
  726. fLastConnectionId = 0;
  727. fUsedGroupNames.clear();
  728. fUsedPortNames.clear();
  729. fUsedConnections.clear();
  730. //fGroupIconsChanged.clear();
  731. initJackPatchbay(jackbridge_get_client_name(fClient));
  732. return true;
  733. }
  734. // -------------------------------------------------------------------
  735. // Transport
  736. void transportPlay() override
  737. {
  738. if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  739. CarlaEngine::transportPlay();
  740. else if (fClient != nullptr)
  741. jackbridge_transport_start(fClient);
  742. }
  743. void transportPause() override
  744. {
  745. if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  746. CarlaEngine::transportPause();
  747. else if (fClient != nullptr)
  748. jackbridge_transport_stop(fClient);
  749. }
  750. void transportRelocate(const uint64_t frame) override
  751. {
  752. if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  753. CarlaEngine::transportRelocate(frame);
  754. else if (fClient != nullptr)
  755. jackbridge_transport_locate(fClient, static_cast<jack_nframes_t>(frame));
  756. }
  757. #endif
  758. // -------------------------------------------------------------------
  759. protected:
  760. void handleJackBufferSizeCallback(const uint32_t newBufferSize)
  761. {
  762. if (pData->bufferSize == newBufferSize)
  763. return;
  764. pData->bufferSize = newBufferSize;
  765. bufferSizeChanged(newBufferSize);
  766. }
  767. void handleJackSampleRateCallback(const double newSampleRate)
  768. {
  769. if (pData->sampleRate == newSampleRate)
  770. return;
  771. pData->sampleRate = newSampleRate;
  772. sampleRateChanged(newSampleRate);
  773. }
  774. void handleJackFreewheelCallback(const bool isFreewheel)
  775. {
  776. if (fFreewheel == isFreewheel)
  777. return;
  778. fFreewheel = isFreewheel;
  779. offlineModeChanged(isFreewheel);
  780. }
  781. void saveTransportInfo()
  782. {
  783. if (pData->options.transportMode != ENGINE_TRANSPORT_MODE_JACK)
  784. return;
  785. fTransportPos.unique_1 = fTransportPos.unique_2 + 1; // invalidate
  786. fTransportState = jackbridge_transport_query(fClient, &fTransportPos);
  787. pData->timeInfo.playing = (fTransportState == JackTransportRolling);
  788. if (fTransportPos.unique_1 == fTransportPos.unique_2)
  789. {
  790. pData->timeInfo.frame = fTransportPos.frame;
  791. pData->timeInfo.usecs = fTransportPos.usecs;
  792. if (fTransportPos.valid & JackPositionBBT)
  793. {
  794. pData->timeInfo.valid = EngineTimeInfo::kValidBBT;
  795. pData->timeInfo.bbt.bar = fTransportPos.bar;
  796. pData->timeInfo.bbt.beat = fTransportPos.beat;
  797. pData->timeInfo.bbt.tick = fTransportPos.tick;
  798. pData->timeInfo.bbt.barStartTick = fTransportPos.bar_start_tick;
  799. pData->timeInfo.bbt.beatsPerBar = fTransportPos.beats_per_bar;
  800. pData->timeInfo.bbt.beatType = fTransportPos.beat_type;
  801. pData->timeInfo.bbt.ticksPerBeat = fTransportPos.ticks_per_beat;
  802. pData->timeInfo.bbt.beatsPerMinute = fTransportPos.beats_per_minute;
  803. }
  804. else
  805. pData->timeInfo.valid = 0x0;
  806. }
  807. else
  808. {
  809. pData->timeInfo.frame = 0;
  810. pData->timeInfo.valid = 0x0;
  811. }
  812. }
  813. void handleJackProcessCallback(const uint32_t nframes)
  814. {
  815. saveTransportInfo();
  816. if (pData->curPluginCount == 0)
  817. {
  818. #ifndef BUILD_BRIDGE
  819. // pass-through
  820. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  821. {
  822. float* const audioIn1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn1], nframes);
  823. float* const audioIn2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn2], nframes);
  824. float* const audioOut1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut1], nframes);
  825. float* const audioOut2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut2], nframes);
  826. void* const eventOut = jackbridge_port_get_buffer(fRackPorts[kRackPortEventOut], nframes);
  827. FLOAT_COPY(audioOut1, audioIn1, nframes);
  828. FLOAT_COPY(audioOut2, audioIn2, nframes);
  829. jackbridge_midi_clear_buffer(eventOut);
  830. }
  831. #endif
  832. return runPendingRtEvents();
  833. }
  834. #ifdef BUILD_BRIDGE
  835. CarlaPlugin* const plugin(pData->plugins[0].plugin);
  836. if (plugin != nullptr && plugin->isEnabled() && plugin->tryLock(fFreewheel))
  837. {
  838. plugin->initBuffers();
  839. processPlugin(plugin, nframes);
  840. plugin->unlock();
  841. }
  842. return runPendingRtEvents();
  843. #else
  844. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  845. {
  846. for (unsigned int i=0; i < pData->curPluginCount; ++i)
  847. {
  848. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  849. if (plugin != nullptr && plugin->isEnabled() && plugin->tryLock(fFreewheel))
  850. {
  851. plugin->initBuffers();
  852. processPlugin(plugin, nframes);
  853. plugin->unlock();
  854. }
  855. }
  856. return runPendingRtEvents();
  857. }
  858. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  859. {
  860. // get buffers from jack
  861. float* const audioIn1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn1], nframes);
  862. float* const audioIn2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn2], nframes);
  863. float* const audioOut1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut1], nframes);
  864. float* const audioOut2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut2], nframes);
  865. void* const eventIn = jackbridge_port_get_buffer(fRackPorts[kRackPortEventIn], nframes);
  866. void* const eventOut = jackbridge_port_get_buffer(fRackPorts[kRackPortEventOut], nframes);
  867. // assert buffers
  868. CARLA_ASSERT(audioIn1 != nullptr);
  869. CARLA_ASSERT(audioIn2 != nullptr);
  870. CARLA_ASSERT(audioOut1 != nullptr);
  871. CARLA_ASSERT(audioOut2 != nullptr);
  872. CARLA_ASSERT(eventIn != nullptr);
  873. CARLA_ASSERT(eventOut != nullptr);
  874. // create audio buffers
  875. float* inBuf[2] = { audioIn1, audioIn2 };
  876. float* outBuf[2] = { audioOut1, audioOut2 };
  877. // initialize input events
  878. carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kEngineMaxInternalEventCount);
  879. {
  880. uint32_t engineEventIndex = 0;
  881. jack_midi_event_t jackEvent;
  882. const uint32_t jackEventCount(jackbridge_midi_get_event_count(eventIn));
  883. for (uint32_t jackEventIndex=0; jackEventIndex < jackEventCount; ++jackEventIndex)
  884. {
  885. if (! jackbridge_midi_event_get(&jackEvent, eventIn, jackEventIndex))
  886. continue;
  887. CARLA_SAFE_ASSERT_CONTINUE(jackEvent.size <= 0xFF /* uint8_t max */);
  888. EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]);
  889. engineEvent.time = jackEvent.time;
  890. engineEvent.fillFromMidiData(static_cast<uint8_t>(jackEvent.size), jackEvent.buffer);
  891. if (engineEventIndex >= kEngineMaxInternalEventCount)
  892. break;
  893. }
  894. }
  895. // process rack
  896. pData->processRack(inBuf, outBuf, nframes, fFreewheel);
  897. // output control
  898. {
  899. jackbridge_midi_clear_buffer(eventOut);
  900. for (unsigned short i=0; i < kEngineMaxInternalEventCount; ++i)
  901. {
  902. const EngineEvent& engineEvent(pData->bufEvents.out[i]);
  903. uint8_t size = 0;
  904. uint8_t data[3] = { 0, 0, 0 };
  905. const uint8_t* dataPtr = data;
  906. switch (engineEvent.type)
  907. {
  908. case kEngineEventTypeNull:
  909. break;
  910. case kEngineEventTypeControl:
  911. {
  912. const EngineControlEvent& ctrlEvent(engineEvent.ctrl);
  913. ctrlEvent.dumpToMidiData(engineEvent.channel, size, data);
  914. break;
  915. }
  916. case kEngineEventTypeMidi:
  917. {
  918. const EngineMidiEvent& midiEvent(engineEvent.midi);
  919. size = midiEvent.size;
  920. if (size > EngineMidiEvent::kDataSize && midiEvent.dataExt != nullptr)
  921. dataPtr = midiEvent.dataExt;
  922. else
  923. dataPtr = midiEvent.dataExt;
  924. break;
  925. }
  926. }
  927. if (size > 0)
  928. jackbridge_midi_event_write(eventOut, engineEvent.time, dataPtr, size);
  929. }
  930. }
  931. return runPendingRtEvents();
  932. }
  933. #endif // ! BUILD_BRIDGE
  934. runPendingRtEvents();
  935. }
  936. void handleJackLatencyCallback(const jack_latency_callback_mode_t mode)
  937. {
  938. if (pData->options.processMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  939. return;
  940. for (unsigned int i=0; i < pData->curPluginCount; ++i)
  941. {
  942. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  943. if (plugin != nullptr && plugin->isEnabled())
  944. latencyPlugin(plugin, mode);
  945. }
  946. }
  947. #ifndef BUILD_BRIDGE
  948. # if 0
  949. void handleCustomAppearanceCallback(const char* client_name, const char* key, jack_custom_change_t change)
  950. {
  951. if ((change == JackCustomAdded || change == JackCustomReplaced) && std::strcmp(key, URI_CANVAS_ICON) == 0)
  952. {
  953. const int groupId (getGroupId(client_name));
  954. if (groupId == -1)
  955. return;
  956. fGroupIconsChanged.append(groupId);
  957. }
  958. }
  959. # endif
  960. void handleJackClientRegistrationCallback(const char* const name, const bool reg)
  961. {
  962. // do nothing on client registration, wait for first port
  963. if (reg) return;
  964. const int id(getGroupId(name)); // also checks name nullness
  965. if (id == -1)
  966. return;
  967. GroupNameToId groupNameId(id, name);
  968. fUsedGroupNames.removeAll(groupNameId);
  969. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_REMOVED, id, 0, 0, 0.0f, nullptr);
  970. }
  971. void handleJackPortRegistrationCallback(const jack_port_id_t port, const bool reg)
  972. {
  973. jack_port_t* const jackPort(jackbridge_port_by_id(fClient, port));
  974. const char* const portName(jackbridge_port_short_name(jackPort));
  975. const char* const fullPortName(jackbridge_port_name(jackPort));
  976. CARLA_ASSERT(jackPort != nullptr);
  977. CARLA_ASSERT(portName != nullptr);
  978. CARLA_ASSERT(fullPortName != nullptr);
  979. if (jackPort == nullptr)
  980. return;
  981. if (portName == nullptr)
  982. return;
  983. if (fullPortName == nullptr)
  984. return;
  985. CarlaString groupName(fullPortName);
  986. groupName.truncate(groupName.rfind(portName)-1);
  987. int groupId = getGroupId(groupName);
  988. if (reg)
  989. {
  990. const int jackPortFlags(jackbridge_port_flags(jackPort));
  991. if (groupId == -1)
  992. {
  993. groupId = fLastGroupId++;
  994. GroupNameToId groupNameToId(groupId, groupName);
  995. fUsedGroupNames.append(groupNameToId);
  996. if (jackPortFlags & JackPortIsPhysical)
  997. {
  998. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, groupId, PATCHBAY_ICON_HARDWARE, 0, 0.0f, groupName);
  999. // hardware
  1000. }
  1001. else
  1002. {
  1003. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, groupId, 0, 0, 0.0f, groupName);
  1004. //fGroupIconsChanged.append(groupId);
  1005. // "application"
  1006. }
  1007. }
  1008. bool portIsInput = (jackPortFlags & JackPortIsInput);
  1009. bool portIsAudio = (std::strcmp(jackbridge_port_type(jackPort), JACK_DEFAULT_AUDIO_TYPE) == 0);
  1010. bool portIsCV = (jackPortFlags & JackPortIsControlVoltage);
  1011. unsigned int canvasPortFlags = 0x0;
  1012. canvasPortFlags |= portIsInput ? PATCHBAY_PORT_IS_INPUT : 0x0;
  1013. canvasPortFlags |= portIsAudio ? PATCHBAY_PORT_TYPE_AUDIO : PATCHBAY_PORT_TYPE_MIDI;
  1014. if (portIsAudio && portIsCV)
  1015. canvasPortFlags |= PATCHBAY_PORT_TYPE_CV;
  1016. PortNameToId portNameToId(groupId, fLastPortId++, portName, fullPortName);
  1017. fUsedPortNames.append(portNameToId);
  1018. callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, groupId, portNameToId.portId, canvasPortFlags, 0.0f, portName);
  1019. }
  1020. else
  1021. {
  1022. const int portId(getPortId(fullPortName));
  1023. CARLA_ASSERT(groupId != -1);
  1024. CARLA_ASSERT(portId != -1);
  1025. if (groupId == -1 || portId == -1)
  1026. return;
  1027. PortNameToId portNameId(groupId, portId, portName, fullPortName);
  1028. fUsedPortNames.removeOne(portNameId);
  1029. callback(ENGINE_CALLBACK_PATCHBAY_PORT_REMOVED, groupId, portId, 0, 0.0f, nullptr);
  1030. }
  1031. }
  1032. void handleJackPortConnectCallback(const jack_port_id_t a, const jack_port_id_t b, const bool connect)
  1033. {
  1034. jack_port_t* const jackPortA(jackbridge_port_by_id(fClient, a));
  1035. jack_port_t* const jackPortB(jackbridge_port_by_id(fClient, b));
  1036. const char* const fullPortNameA(jackbridge_port_name(jackPortA));
  1037. const char* const fullPortNameB(jackbridge_port_name(jackPortB));
  1038. CARLA_ASSERT(jackPortA != nullptr);
  1039. CARLA_ASSERT(jackPortB != nullptr);
  1040. CARLA_ASSERT(fullPortNameA != nullptr);
  1041. CARLA_ASSERT(fullPortNameB != nullptr);
  1042. if (jackPortA == nullptr)
  1043. return;
  1044. if (jackPortB == nullptr)
  1045. return;
  1046. if (fullPortNameA == nullptr)
  1047. return;
  1048. if (fullPortNameB == nullptr)
  1049. return;
  1050. const int portIdA(getPortId(fullPortNameA));
  1051. const int portIdB(getPortId(fullPortNameB));
  1052. if (portIdA == -1 || portIdB == -1)
  1053. return;
  1054. if (connect)
  1055. {
  1056. ConnectionToId connectionToId(fLastConnectionId++, portIdA, portIdB);
  1057. fUsedConnections.append(connectionToId);
  1058. callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, connectionToId.portOut, connectionToId.portIn, 0.0f, nullptr);
  1059. }
  1060. else
  1061. {
  1062. for (List<ConnectionToId>::Itenerator it = fUsedConnections.begin(); it.valid(); it.next())
  1063. {
  1064. const ConnectionToId& connectionToId(it.getConstValue());
  1065. if (connectionToId.portOut == portIdA && connectionToId.portIn == portIdB)
  1066. {
  1067. callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connectionToId.id, connectionToId.portOut, connectionToId.portIn, 0.0f, nullptr);
  1068. fUsedConnections.remove(it);
  1069. break;
  1070. }
  1071. }
  1072. }
  1073. }
  1074. void handleJackClientRenameCallback(const char* const oldName, const char* const newName)
  1075. {
  1076. for (List<GroupNameToId>::Itenerator it = fUsedGroupNames.begin(); it.valid(); it.next())
  1077. {
  1078. GroupNameToId& groupNameToId(it.getValue());
  1079. if (std::strcmp(groupNameToId.name, oldName) == 0)
  1080. {
  1081. groupNameToId.rename(newName);
  1082. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_RENAMED, groupNameToId.id, 0, 0, 0.0f, newName);
  1083. break;
  1084. }
  1085. }
  1086. }
  1087. void handleJackPortRenameCallback(const jack_port_id_t port, const char* const oldName, const char* const newName)
  1088. {
  1089. jack_port_t* const jackPort(jackbridge_port_by_id(fClient, port));
  1090. const char* const portName(jackbridge_port_short_name(jackPort));
  1091. CARLA_ASSERT(jackPort != nullptr);
  1092. CARLA_ASSERT(portName != nullptr);
  1093. if (jackPort == nullptr)
  1094. return;
  1095. if (portName == nullptr)
  1096. return;
  1097. CarlaString groupName(newName);
  1098. groupName.truncate(groupName.rfind(portName)-1);
  1099. const int groupId(getGroupId(groupName));
  1100. CARLA_ASSERT(groupId != -1);
  1101. if (groupId == -1)
  1102. return;
  1103. for (List<PortNameToId>::Itenerator it = fUsedPortNames.begin(); it.valid(); it.next())
  1104. {
  1105. PortNameToId& portNameId(it.getValue());
  1106. if (std::strcmp(portNameId.fullName, oldName) == 0)
  1107. {
  1108. CARLA_ASSERT(portNameId.groupId == groupId);
  1109. portNameId.rename(portName, newName);
  1110. callback(ENGINE_CALLBACK_PATCHBAY_PORT_RENAMED, groupId, portNameId.portId, 0, 0.0f, newName);
  1111. break;
  1112. }
  1113. }
  1114. }
  1115. #endif
  1116. void handleJackShutdownCallback()
  1117. {
  1118. for (unsigned int i=0; i < pData->curPluginCount; ++i)
  1119. {
  1120. //CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1121. //if (plugin)
  1122. // plugin->x_client = nullptr;
  1123. }
  1124. fClient = nullptr;
  1125. callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr);
  1126. }
  1127. // -------------------------------------------------------------------
  1128. private:
  1129. jack_client_t* fClient;
  1130. jack_position_t fTransportPos;
  1131. jack_transport_state_t fTransportState;
  1132. bool fFreewheel;
  1133. // -------------------------------------------------------------------
  1134. #ifdef BUILD_BRIDGE
  1135. bool fIsRunning;
  1136. #else
  1137. enum RackPorts {
  1138. kRackPortAudioIn1 = 0,
  1139. kRackPortAudioIn2 = 1,
  1140. kRackPortAudioOut1 = 2,
  1141. kRackPortAudioOut2 = 3,
  1142. kRackPortEventIn = 4,
  1143. kRackPortEventOut = 5,
  1144. kRackPortCount = 6
  1145. };
  1146. jack_port_t* fRackPorts[kRackPortCount];
  1147. struct GroupNameToId {
  1148. int id;
  1149. char name[STR_MAX+1];
  1150. GroupNameToId()
  1151. {
  1152. id = -1;
  1153. name[0] = '\0';
  1154. }
  1155. GroupNameToId(const int id, const char name[])
  1156. {
  1157. this->id = id;
  1158. std::strncpy(this->name, name, STR_MAX);
  1159. this->name[STR_MAX] = '\0';
  1160. }
  1161. void rename(const char name[])
  1162. {
  1163. std::strncpy(this->name, name, STR_MAX);
  1164. this->name[STR_MAX] = '\0';
  1165. }
  1166. bool operator==(const GroupNameToId& groupNameId)
  1167. {
  1168. if (groupNameId.id != id)
  1169. return false;
  1170. if (std::strcmp(groupNameId.name, name) != 0)
  1171. return false;
  1172. return true;
  1173. }
  1174. };
  1175. struct PortNameToId {
  1176. int groupId;
  1177. int portId;
  1178. char name[STR_MAX+1];
  1179. char fullName[STR_MAX+1]; // unique
  1180. PortNameToId()
  1181. {
  1182. groupId = -1;
  1183. portId = -1;
  1184. name[0] = '\0';
  1185. fullName[0] = '\0';
  1186. }
  1187. PortNameToId(const int groupId, const int portId, const char name[], const char fullName[])
  1188. {
  1189. this->groupId = groupId;
  1190. this->portId = portId;
  1191. std::strncpy(this->name, name, STR_MAX);
  1192. this->name[STR_MAX] = '\0';
  1193. std::strncpy(this->fullName, fullName, STR_MAX);
  1194. this->fullName[STR_MAX] = '\0';
  1195. }
  1196. void rename(const char name[], const char fullName[])
  1197. {
  1198. std::strncpy(this->name, name, STR_MAX);
  1199. this->name[STR_MAX] = '\0';
  1200. std::strncpy(this->fullName, fullName, STR_MAX);
  1201. this->fullName[STR_MAX] = '\0';
  1202. }
  1203. bool operator==(const PortNameToId& portNameId)
  1204. {
  1205. if (portNameId.groupId != groupId)
  1206. return false;
  1207. if (portNameId.portId != portId)
  1208. return false;
  1209. if (std::strcmp(portNameId.name, name) != 0)
  1210. return false;
  1211. if (std::strcmp(portNameId.fullName, fullName) != 0)
  1212. return false;
  1213. return true;
  1214. }
  1215. };
  1216. struct ConnectionToId {
  1217. int id;
  1218. int portOut;
  1219. int portIn;
  1220. ConnectionToId()
  1221. {
  1222. id = -1;
  1223. portOut = -1;
  1224. portIn = -1;
  1225. }
  1226. ConnectionToId(const int id, const int portOut, const int portIn)
  1227. {
  1228. this->id = id;
  1229. this->portOut = portOut;
  1230. this->portIn = portIn;
  1231. }
  1232. bool operator==(const ConnectionToId& connectionId)
  1233. {
  1234. if (connectionId.id != id)
  1235. return false;
  1236. if (connectionId.portOut != portOut)
  1237. return false;
  1238. if (connectionId.portIn != portIn)
  1239. return false;
  1240. return true;
  1241. }
  1242. };
  1243. int fLastGroupId;
  1244. int fLastPortId;
  1245. int fLastConnectionId;
  1246. List<GroupNameToId> fUsedGroupNames;
  1247. List<PortNameToId> fUsedPortNames;
  1248. List<ConnectionToId> fUsedConnections;
  1249. //List<int> fGroupIconsChanged;
  1250. int getGroupId(const char* const name)
  1251. {
  1252. CARLA_SAFE_ASSERT_RETURN(name != nullptr, -1);
  1253. for (List<GroupNameToId>::Itenerator it = fUsedGroupNames.begin(); it.valid(); it.next())
  1254. {
  1255. const GroupNameToId& groupNameId(it.getConstValue());
  1256. if (std::strcmp(groupNameId.name, name) == 0)
  1257. return groupNameId.id;
  1258. }
  1259. return -1;
  1260. }
  1261. const char* getGroupName(const int groupId)
  1262. {
  1263. static const char fallback[1] = { '\0' };
  1264. CARLA_SAFE_ASSERT_RETURN(groupId >= 0, fallback);
  1265. for (List<GroupNameToId>::Itenerator it = fUsedGroupNames.begin(); it.valid(); it.next())
  1266. {
  1267. const GroupNameToId& groupNameId(it.getConstValue());
  1268. if (groupNameId.id == groupId)
  1269. return groupNameId.name;
  1270. }
  1271. return fallback;
  1272. }
  1273. int getPortId(const char* const fullName)
  1274. {
  1275. CARLA_SAFE_ASSERT_RETURN(fullName != nullptr, -1);
  1276. for (List<PortNameToId>::Itenerator it = fUsedPortNames.begin(); it.valid(); it.next())
  1277. {
  1278. const PortNameToId& portNameId(it.getConstValue());
  1279. if (std::strcmp(portNameId.fullName, fullName) == 0)
  1280. return portNameId.portId;
  1281. }
  1282. return -1;
  1283. }
  1284. void getFullPortName(const int portId, char nameBuf[STR_MAX+1])
  1285. {
  1286. for (List<PortNameToId>::Itenerator it = fUsedPortNames.begin(); it.valid(); it.next())
  1287. {
  1288. const PortNameToId& portNameId(it.getConstValue());
  1289. if (portNameId.portId == portId)
  1290. {
  1291. std::strncpy(nameBuf, portNameId.fullName, STR_MAX);
  1292. nameBuf[STR_MAX] = '\0';
  1293. return;
  1294. }
  1295. }
  1296. nameBuf[0] = '\0';
  1297. }
  1298. void initJackPatchbay(const char* const ourName)
  1299. {
  1300. CARLA_SAFE_ASSERT_RETURN(fLastGroupId == 0,);
  1301. CARLA_SAFE_ASSERT_RETURN(fLastPortId == 0,);
  1302. CARLA_SAFE_ASSERT_RETURN(fLastConnectionId == 0,);
  1303. CARLA_SAFE_ASSERT_RETURN(ourName != nullptr,);
  1304. // query initial jack ports
  1305. QStringList parsedGroups;
  1306. // our client
  1307. {
  1308. parsedGroups.append(QString(ourName));
  1309. GroupNameToId groupNameToId(fLastGroupId++, ourName);
  1310. fUsedGroupNames.append(groupNameToId);
  1311. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, groupNameToId.id, PATCHBAY_ICON_CARLA, 0, 0.0f, ourName);
  1312. }
  1313. if (const char** ports = jackbridge_get_ports(fClient, nullptr, nullptr, 0))
  1314. {
  1315. for (int i=0; ports[i] != nullptr; ++i)
  1316. {
  1317. jack_port_t* const jackPort(jackbridge_port_by_name(fClient, ports[i]));
  1318. const char* const portName(jackbridge_port_short_name(jackPort));
  1319. const char* const fullPortName(ports[i]);
  1320. CARLA_SAFE_ASSERT_CONTINUE(jackPort != nullptr);
  1321. CARLA_SAFE_ASSERT_CONTINUE(portName != nullptr);
  1322. const int jackPortFlags(jackbridge_port_flags(jackPort));
  1323. int groupId = -1;
  1324. bool found;
  1325. CarlaString groupName(fullPortName);
  1326. groupName.truncate(groupName.rfind(portName, &found)-1);
  1327. CARLA_ASSERT(found);
  1328. QString qGroupName((const char*)groupName);
  1329. if (parsedGroups.contains(qGroupName))
  1330. {
  1331. groupId = getGroupId(groupName);
  1332. CARLA_ASSERT(groupId != -1);
  1333. }
  1334. else
  1335. {
  1336. groupId = fLastGroupId++;
  1337. parsedGroups.append(qGroupName);
  1338. GroupNameToId groupNameToId(groupId, groupName);
  1339. fUsedGroupNames.append(groupNameToId);
  1340. PatchbayIcon groupIcon = PATCHBAY_ICON_APPLICATION;
  1341. #if 0
  1342. void* data = nullptr;
  1343. size_t dataSize = 0;
  1344. #endif
  1345. if (jackPortFlags & JackPortIsPhysical)
  1346. {
  1347. groupIcon = PATCHBAY_ICON_HARDWARE;
  1348. }
  1349. #if 0
  1350. else if (jackbridge_custom_get_data(fClient, groupName, URI_CANVAS_ICON, &data, &dataSize) && data != nullptr && dataSize != 0)
  1351. {
  1352. const char* const icon((const char*)data);
  1353. CARLA_ASSERT(std::strlen(icon)+1 == dataSize);
  1354. if (std::strcmp(icon, "app") == 0 || std::strcmp(icon, "application") == 0)
  1355. groupIcon = PATCHBAY_ICON_APPLICATION;
  1356. else if (std::strcmp(icon, "hardware") == 0)
  1357. groupIcon = PATCHBAY_ICON_HARDWARE;
  1358. else if (std::strcmp(icon, "carla") == 0)
  1359. groupIcon = PATCHBAY_ICON_CARLA;
  1360. else if (std::strcmp(icon, "distrho") == 0)
  1361. groupIcon = PATCHBAY_ICON_DISTRHO;
  1362. else if (std::strcmp(icon, "file") == 0)
  1363. groupIcon = PATCHBAY_ICON_FILE;
  1364. else if (std::strcmp(icon, "plugin") == 0)
  1365. groupIcon = PATCHBAY_ICON_PLUGIN;
  1366. }
  1367. #endif
  1368. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, groupId, groupIcon, 0, 0.0f, groupName);
  1369. }
  1370. bool portIsInput = (jackPortFlags & JackPortIsInput);
  1371. bool portIsAudio = (std::strcmp(jackbridge_port_type(jackPort), JACK_DEFAULT_AUDIO_TYPE) == 0);
  1372. bool portIsCV = (portIsAudio && (jackPortFlags & JackPortIsControlVoltage) != 0);
  1373. unsigned int canvasPortFlags = 0x0;
  1374. canvasPortFlags |= portIsInput ? PATCHBAY_PORT_IS_INPUT : 0x0;
  1375. canvasPortFlags |= portIsAudio ? PATCHBAY_PORT_TYPE_AUDIO : PATCHBAY_PORT_TYPE_MIDI;
  1376. if (portIsCV)
  1377. canvasPortFlags |= PATCHBAY_PORT_TYPE_CV;
  1378. PortNameToId portNameToId(groupId, fLastPortId++, portName, fullPortName);
  1379. fUsedPortNames.append(portNameToId);
  1380. callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, groupId, portNameToId.portId, canvasPortFlags, 0.0f, portName);
  1381. }
  1382. // query connections, after all ports are in place
  1383. for (int i=0; ports[i] != nullptr; ++i)
  1384. {
  1385. jack_port_t* const jackPort(jackbridge_port_by_name(fClient, ports[i]));
  1386. const char* const fullPortName(ports[i]);
  1387. const int thisPortId(getPortId(fullPortName));
  1388. CARLA_SAFE_ASSERT_CONTINUE(jackPort != nullptr);
  1389. CARLA_SAFE_ASSERT_CONTINUE(thisPortId != -1);
  1390. if (const char** connections = jackbridge_port_get_all_connections(fClient, jackPort))
  1391. {
  1392. for (int j=0; connections[j] != nullptr; ++j)
  1393. {
  1394. const int targetPortId(getPortId(connections[j]));
  1395. ConnectionToId connectionToId(fLastConnectionId++, thisPortId, targetPortId);
  1396. fUsedConnections.append(connectionToId);
  1397. callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, connectionToId.portOut, connectionToId.portIn, 0.0f, nullptr);
  1398. }
  1399. jackbridge_free(connections);
  1400. }
  1401. }
  1402. jackbridge_free(ports);
  1403. }
  1404. }
  1405. #endif
  1406. // -------------------------------------
  1407. void processPlugin(CarlaPlugin* const plugin, const uint32_t nframes)
  1408. {
  1409. const uint32_t inCount(plugin->getAudioInCount());
  1410. const uint32_t outCount(plugin->getAudioOutCount());
  1411. float* inBuffer[inCount];
  1412. float* outBuffer[outCount];
  1413. float inPeaks[2] = { 0.0f };
  1414. float outPeaks[2] = { 0.0f };
  1415. for (uint32_t i=0; i < inCount; ++i)
  1416. {
  1417. CarlaEngineAudioPort* const port(plugin->getAudioInPort(i));
  1418. inBuffer[i] = port->getBuffer();
  1419. }
  1420. for (uint32_t i=0; i < outCount; ++i)
  1421. {
  1422. CarlaEngineAudioPort* const port(plugin->getAudioOutPort(i));
  1423. outBuffer[i] = port->getBuffer();
  1424. }
  1425. for (uint32_t i=0; i < inCount && i < 2; ++i)
  1426. {
  1427. for (uint32_t j=0; j < nframes; ++j)
  1428. {
  1429. const float absV(std::abs(inBuffer[i][j]));
  1430. if (absV > inPeaks[i])
  1431. inPeaks[i] = absV;
  1432. }
  1433. }
  1434. plugin->process(inBuffer, outBuffer, nframes);
  1435. for (uint32_t i=0; i < outCount && i < 2; ++i)
  1436. {
  1437. for (uint32_t j=0; j < nframes; ++j)
  1438. {
  1439. const float absV(std::abs(outBuffer[i][j]));
  1440. if (absV > outPeaks[i])
  1441. outPeaks[i] = absV;
  1442. }
  1443. }
  1444. setPluginPeaks(plugin->getId(), inPeaks, outPeaks);
  1445. }
  1446. void latencyPlugin(CarlaPlugin* const plugin, jack_latency_callback_mode_t mode)
  1447. {
  1448. //const uint32_t inCount(plugin->audioInCount());
  1449. //const uint32_t outCount(plugin->audioOutCount());
  1450. const uint32_t latency(plugin->getLatencyInFrames());
  1451. if (latency == 0)
  1452. return;
  1453. //jack_latency_range_t range;
  1454. // TODO
  1455. if (mode == JackCaptureLatency)
  1456. {
  1457. #if 0
  1458. for (uint32_t i=0; i < inCount; ++i)
  1459. {
  1460. uint32_t aOutI = (i >= outCount) ? outCount : i;
  1461. jack_port_t* const portIn = ((CarlaEngineJackAudioPort*)CarlaPluginGetAudioInPort(plugin, i))->kPort;
  1462. jack_port_t* const portOut = ((CarlaEngineJackAudioPort*)CarlaPluginGetAudioOutPort(plugin, aOutI))->kPort;
  1463. jackbridge_port_get_latency_range(portIn, mode, &range);
  1464. range.min += latency;
  1465. range.max += latency;
  1466. jackbridge_port_set_latency_range(portOut, mode, &range);
  1467. }
  1468. #endif
  1469. }
  1470. else
  1471. {
  1472. #if 0
  1473. for (uint32_t i=0; i < outCount; ++i)
  1474. {
  1475. uint32_t aInI = (i >= inCount) ? inCount : i;
  1476. jack_port_t* const portIn = ((CarlaEngineJackAudioPort*)CarlaPluginGetAudioInPort(plugin, aInI))->kPort;
  1477. jack_port_t* const portOut = ((CarlaEngineJackAudioPort*)CarlaPluginGetAudioOutPort(plugin, i))->kPort;
  1478. jackbridge_port_get_latency_range(portOut, mode, &range);
  1479. range.min += latency;
  1480. range.max += latency;
  1481. jackbridge_port_set_latency_range(portIn, mode, &range);
  1482. }
  1483. #endif
  1484. }
  1485. }
  1486. // -------------------------------------
  1487. #define handlePtr ((CarlaEngineJack*)arg)
  1488. static int carla_jack_bufsize_callback(jack_nframes_t newBufferSize, void* arg)
  1489. {
  1490. handlePtr->handleJackBufferSizeCallback(newBufferSize);
  1491. return 0;
  1492. }
  1493. static int carla_jack_srate_callback(jack_nframes_t newSampleRate, void* arg)
  1494. {
  1495. handlePtr->handleJackSampleRateCallback(newSampleRate);
  1496. return 0;
  1497. }
  1498. static void carla_jack_freewheel_callback(int starting, void* arg)
  1499. {
  1500. handlePtr->handleJackFreewheelCallback(bool(starting));
  1501. }
  1502. static int carla_jack_process_callback(jack_nframes_t nframes, void* arg)
  1503. {
  1504. handlePtr->handleJackProcessCallback(nframes);
  1505. return 0;
  1506. }
  1507. static void carla_jack_latency_callback(jack_latency_callback_mode_t mode, void* arg)
  1508. {
  1509. handlePtr->handleJackLatencyCallback(mode);
  1510. }
  1511. #ifndef BUILD_BRIDGE
  1512. # if 0
  1513. static void carla_jack_custom_appearance_callback(const char* client_name, const char* key, jack_custom_change_t change, void* arg)
  1514. {
  1515. handlePtr->handleCustomAppearanceCallback(client_name, key, change);
  1516. }
  1517. # endif
  1518. static void carla_jack_client_registration_callback(const char* name, int reg, void* arg)
  1519. {
  1520. handlePtr->handleJackClientRegistrationCallback(name, (reg != 0));
  1521. }
  1522. static void carla_jack_port_registration_callback(jack_port_id_t port, int reg, void* arg)
  1523. {
  1524. handlePtr->handleJackPortRegistrationCallback(port, (reg != 0));
  1525. }
  1526. static void carla_jack_port_connect_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg)
  1527. {
  1528. handlePtr->handleJackPortConnectCallback(a, b, (connect != 0));
  1529. }
  1530. static int carla_jack_client_rename_callback(const char* oldName, const char* newName, void* arg)
  1531. {
  1532. handlePtr->handleJackClientRenameCallback(oldName, newName);
  1533. return 0;
  1534. }
  1535. static int carla_jack_port_rename_callback(jack_port_id_t port, const char* oldName, const char* newName, void* arg)
  1536. {
  1537. handlePtr->handleJackPortRenameCallback(port, oldName, newName);
  1538. return 0;
  1539. }
  1540. #endif
  1541. static void carla_jack_shutdown_callback(void* arg)
  1542. {
  1543. handlePtr->handleJackShutdownCallback();
  1544. }
  1545. #undef handlePtr
  1546. // -------------------------------------------------------------------
  1547. #ifndef BUILD_BRIDGE
  1548. static int carla_jack_process_callback_plugin(jack_nframes_t nframes, void* arg)
  1549. {
  1550. CarlaPlugin* const plugin((CarlaPlugin*)arg);
  1551. if (plugin != nullptr && plugin->isEnabled())
  1552. {
  1553. CarlaEngineJack* const engine((CarlaEngineJack*)plugin->getEngine());
  1554. CARLA_SAFE_ASSERT_RETURN(engine != nullptr,0);
  1555. if (plugin->tryLock(engine->fFreewheel))
  1556. {
  1557. plugin->initBuffers();
  1558. engine->saveTransportInfo();
  1559. engine->processPlugin(plugin, nframes);
  1560. plugin->unlock();
  1561. }
  1562. }
  1563. return 0;
  1564. }
  1565. static void carla_jack_latency_callback_plugin(jack_latency_callback_mode_t mode, void* arg)
  1566. {
  1567. CarlaPlugin* const plugin((CarlaPlugin*)arg);
  1568. if (plugin != nullptr && plugin->isEnabled())
  1569. {
  1570. CarlaEngineJack* const engine((CarlaEngineJack*)plugin->getEngine());
  1571. CARLA_SAFE_ASSERT_RETURN(engine != nullptr,);
  1572. engine->latencyPlugin(plugin, mode);
  1573. }
  1574. }
  1575. #endif
  1576. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJack)
  1577. };
  1578. // -----------------------------------------------------------------------
  1579. CarlaEngine* CarlaEngine::newJack()
  1580. {
  1581. carla_debug("CarlaEngine::newJack()");
  1582. return new CarlaEngineJack();
  1583. }
  1584. // -----------------------------------------------------------------------
  1585. CARLA_BACKEND_END_NAMESPACE