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.

1100 lines
32KB

  1. /*
  2. * Carla ReWire Plugin
  3. * Copyright (C) 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. #ifdef WANT_REWIRE
  20. #include "CarlaLibUtils.hpp"
  21. #include "CarlaMathUtils.hpp"
  22. // -----------------------------------------------------
  23. CARLA_BACKEND_START_NAMESPACE
  24. #if 0
  25. }
  26. #endif
  27. // -----------------------------------------------------------------------
  28. // ReWire assumes sizeof(long) == 4
  29. typedef int32_t rlong;
  30. typedef uint32_t rulong;
  31. static_assert(sizeof(rlong) == 4, "Incorrect rlong size");
  32. static_assert(sizeof(rulong) == 4, "Incorrect rulong size");
  33. // rewire is not for linux, so for easy testing+development, we can skip this
  34. #ifndef CARLA_OS_LINUX
  35. static_assert(sizeof(long) == 4, "Incorrect long size");
  36. static_assert(sizeof(ulong) == 4, "Incorrect ulong size");
  37. static_assert(sizeof(long) == sizeof(rlong), "long size mismatch");
  38. static_assert(sizeof(ulong) == sizeof(rulong), "ulon size mismatch");
  39. #endif
  40. struct RwOpenInfo {
  41. rulong size1; // 16
  42. rulong size2; // 12
  43. rlong sampleRate;
  44. rlong bufferSize;
  45. };
  46. struct RwDevInfo {
  47. rulong size; // 8288
  48. char name[32];
  49. rlong channelCount; // max limited to 255
  50. char channelNames[256][32];
  51. rulong defaultChannels[8];
  52. rulong stereoPairs[4];
  53. rulong eventBufferSize;
  54. rlong version;
  55. };
  56. struct RwAudioInfo {
  57. rulong size; // 12
  58. rlong sampleRate;
  59. rlong bufferSize;
  60. };
  61. struct RwBusInfo {
  62. rulong size; // 40
  63. rulong channel;
  64. char name[32];
  65. };
  66. struct RwEventInfo {
  67. rulong size; // 132 FIXME?
  68. rulong bus[32];
  69. };
  70. struct RwEvent { // 24
  71. ushort type;
  72. uchar d1, d2;
  73. rulong s1, s2, s3, s4, s5;
  74. };
  75. struct RwEventBuffer {
  76. rulong size1; // 20
  77. rulong size2; // 24 (of RwEvent)
  78. rulong count;
  79. rulong maxCount;
  80. #ifndef CARLA_OS_LINUX // pointers on 64bit linux are size 8, skip this
  81. RwEvent* buf;
  82. #else
  83. rulong buf;
  84. #endif
  85. };
  86. struct RwAudioInInfo {
  87. rulong size; // 1116
  88. RwEventBuffer evBuf;
  89. rulong channels[8];
  90. #ifndef CARLA_OS_LINUX // pointers on 64bit linux are size 8, skip this
  91. float* audioBuf[256];
  92. #else
  93. rulong audioBuf[256];
  94. #endif
  95. rlong tickStart;
  96. rulong frames;
  97. rulong playMode;
  98. rulong tempo; // bpm
  99. rulong signNumerator;
  100. rulong signDenominator;
  101. rlong loopStartPos;
  102. rlong loopEndPos;
  103. rulong loopOn;
  104. };
  105. struct RwAudioOutInfo {
  106. rulong size; // 56
  107. RwEventBuffer evBuf;
  108. rulong channels[8];
  109. };
  110. static_assert(sizeof(RwOpenInfo) == 16, "Incorrect ReWire struct size");
  111. static_assert(sizeof(RwDevInfo) == 8288, "Incorrect ReWire struct size");
  112. static_assert(sizeof(RwAudioInfo) == 12, "Incorrect ReWire struct size");
  113. static_assert(sizeof(RwBusInfo) == 40, "Incorrect ReWire struct size");
  114. static_assert(sizeof(RwEventInfo) == 132, "Incorrect ReWire struct size");
  115. static_assert(sizeof(RwEvent) == 24, "Incorrect ReWire struct size");
  116. static_assert(sizeof(RwEventBuffer) == 20, "Incorrect ReWire struct size");
  117. static_assert(sizeof(RwAudioInInfo) == 1116, "Incorrect ReWire struct size");
  118. static_assert(sizeof(RwAudioOutInfo) == 56, "Incorrect ReWire struct size");
  119. // -----------------------------------------------------------------------
  120. typedef void (*Fn_RWDEFCloseDevice)();
  121. typedef void (*Fn_RWDEFDriveAudio)(RwAudioInInfo* in, RwAudioOutInfo* out);
  122. typedef void (*Fn_RWDEFGetDeviceInfo)(RwDevInfo* info);
  123. typedef void (*Fn_RWDEFGetDeviceNameAndVersion)(long* version, char* name);
  124. typedef void (*Fn_RWDEFGetEventBusInfo)(ushort index, RwBusInfo* info);
  125. typedef void (*Fn_RWDEFGetEventChannelInfo)(void* v1, void* v2);
  126. typedef void (*Fn_RWDEFGetEventControllerInfo)(void* v1, ushort index, void* v2);
  127. typedef void (*Fn_RWDEFGetEventInfo)(RwEventInfo* info);
  128. typedef void (*Fn_RWDEFGetEventNoteInfo)(void* v1, ushort index, void* v2);
  129. typedef void (*Fn_RWDEFIdle)();
  130. typedef char (*Fn_RWDEFIsCloseOK)();
  131. typedef char (*Fn_RWDEFIsPanelAppLaunched)();
  132. typedef int (*Fn_RWDEFLaunchPanelApp)();
  133. typedef int (*Fn_RWDEFOpenDevice)(RwOpenInfo* info);
  134. typedef int (*Fn_RWDEFQuitPanelApp)();
  135. typedef void (*Fn_RWDEFSetAudioInfo)(RwAudioInfo* info);
  136. // -----------------------------------------------------------------------------
  137. struct RewireBridge {
  138. void* lib;
  139. Fn_RWDEFCloseDevice RWDEFCloseDevice;
  140. Fn_RWDEFDriveAudio RWDEFDriveAudio;
  141. Fn_RWDEFGetDeviceInfo RWDEFGetDeviceInfo;
  142. Fn_RWDEFGetDeviceNameAndVersion RWDEFGetDeviceNameAndVersion;
  143. Fn_RWDEFGetEventBusInfo RWDEFGetEventBusInfo;
  144. Fn_RWDEFGetEventChannelInfo RWDEFGetEventChannelInfo;
  145. Fn_RWDEFGetEventControllerInfo RWDEFGetEventControllerInfo;
  146. Fn_RWDEFGetEventInfo RWDEFGetEventInfo;
  147. Fn_RWDEFGetEventNoteInfo RWDEFGetEventNoteInfo;
  148. Fn_RWDEFIdle RWDEFIdle;
  149. Fn_RWDEFIsCloseOK RWDEFIsCloseOK;
  150. Fn_RWDEFIsPanelAppLaunched RWDEFIsPanelAppLaunched;
  151. Fn_RWDEFLaunchPanelApp RWDEFLaunchPanelApp;
  152. Fn_RWDEFOpenDevice RWDEFOpenDevice;
  153. Fn_RWDEFQuitPanelApp RWDEFQuitPanelApp;
  154. Fn_RWDEFSetAudioInfo RWDEFSetAudioInfo;
  155. RewireBridge()
  156. : lib(nullptr),
  157. RWDEFCloseDevice(nullptr),
  158. RWDEFDriveAudio(nullptr),
  159. RWDEFGetDeviceInfo(nullptr),
  160. RWDEFGetDeviceNameAndVersion(nullptr),
  161. RWDEFGetEventBusInfo(nullptr),
  162. RWDEFGetEventChannelInfo(nullptr),
  163. RWDEFGetEventControllerInfo(nullptr),
  164. RWDEFGetEventInfo(nullptr),
  165. RWDEFGetEventNoteInfo(nullptr),
  166. RWDEFIdle(nullptr),
  167. RWDEFIsCloseOK(nullptr),
  168. RWDEFIsPanelAppLaunched(nullptr),
  169. RWDEFLaunchPanelApp(nullptr),
  170. RWDEFOpenDevice(nullptr),
  171. RWDEFQuitPanelApp(nullptr),
  172. RWDEFSetAudioInfo(nullptr) {}
  173. ~RewireBridge()
  174. {
  175. cleanup();
  176. }
  177. int init(const char* const filename)
  178. {
  179. CARLA_SAFE_ASSERT_RETURN(lib == nullptr, -2);
  180. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', -2);
  181. lib = lib_open(filename);
  182. if (lib == nullptr)
  183. return -1;
  184. #define JOIN(a, b) a ## b
  185. #define LIB_SYMBOL(NAME) NAME = (Fn_##NAME)lib_symbol(lib, #NAME);
  186. //if (NAME == nullptr) cleanup(); return -2;
  187. LIB_SYMBOL(RWDEFCloseDevice)
  188. LIB_SYMBOL(RWDEFDriveAudio)
  189. LIB_SYMBOL(RWDEFGetDeviceInfo)
  190. LIB_SYMBOL(RWDEFGetDeviceNameAndVersion)
  191. LIB_SYMBOL(RWDEFGetEventBusInfo)
  192. LIB_SYMBOL(RWDEFGetEventChannelInfo)
  193. LIB_SYMBOL(RWDEFGetEventControllerInfo)
  194. LIB_SYMBOL(RWDEFGetEventInfo)
  195. LIB_SYMBOL(RWDEFGetEventNoteInfo)
  196. LIB_SYMBOL(RWDEFIdle)
  197. LIB_SYMBOL(RWDEFIsCloseOK)
  198. LIB_SYMBOL(RWDEFIsPanelAppLaunched)
  199. LIB_SYMBOL(RWDEFLaunchPanelApp)
  200. LIB_SYMBOL(RWDEFOpenDevice)
  201. LIB_SYMBOL(RWDEFQuitPanelApp)
  202. LIB_SYMBOL(RWDEFSetAudioInfo)
  203. #undef JOIN
  204. #undef LIB_SYMBOL
  205. return 0;
  206. }
  207. void cleanup()
  208. {
  209. if (lib != nullptr)
  210. {
  211. lib_close(lib);
  212. lib = nullptr;
  213. }
  214. RWDEFCloseDevice = nullptr;
  215. RWDEFDriveAudio = nullptr;
  216. RWDEFGetDeviceInfo = nullptr;
  217. RWDEFGetDeviceNameAndVersion = nullptr;
  218. RWDEFGetEventBusInfo = nullptr;
  219. RWDEFGetEventChannelInfo = nullptr;
  220. RWDEFGetEventControllerInfo = nullptr;
  221. RWDEFGetEventInfo = nullptr;
  222. RWDEFGetEventNoteInfo = nullptr;
  223. RWDEFIdle = nullptr;
  224. RWDEFIsCloseOK = nullptr;
  225. RWDEFIsPanelAppLaunched = nullptr;
  226. RWDEFLaunchPanelApp = nullptr;
  227. RWDEFOpenDevice = nullptr;
  228. RWDEFQuitPanelApp = nullptr;
  229. RWDEFSetAudioInfo = nullptr;
  230. }
  231. };
  232. // -----------------------------------------------------
  233. class ReWirePlugin : public CarlaPlugin
  234. {
  235. public:
  236. ReWirePlugin(CarlaEngine* const engine, const unsigned int id)
  237. : CarlaPlugin(engine, id),
  238. fIsOpen(false),
  239. fIsPanelLaunched(false),
  240. fLabel(nullptr)
  241. {
  242. carla_debug("ReWirePlugin::ReWirePlugin(%p, %i)", engine, id);
  243. carla_zeroStruct<RwAudioInInfo>(fRwAudioIn);
  244. fRwAudioIn.size = sizeof(RwAudioInInfo);
  245. carla_zeroStruct<RwAudioOutInfo>(fRwAudioOut);
  246. fRwAudioOut.size = sizeof(RwAudioOutInfo);
  247. }
  248. ~ReWirePlugin() override
  249. {
  250. carla_debug("ReWirePlugin::~ReWirePlugin()");
  251. // close panel
  252. if (fIsPanelLaunched)
  253. {
  254. fRw.RWDEFQuitPanelApp();
  255. fIsPanelLaunched = false;
  256. }
  257. pData->singleMutex.lock();
  258. pData->masterMutex.lock();
  259. if (pData->client != nullptr && pData->client->isActive())
  260. pData->client->deactivate();
  261. if (pData->active)
  262. {
  263. deactivate();
  264. pData->active = false;
  265. }
  266. if (fIsOpen)
  267. {
  268. for (; fRw.RWDEFIsCloseOK() == 0;)
  269. carla_msleep(2);
  270. fRw.RWDEFCloseDevice();
  271. fIsOpen = false;
  272. }
  273. if (fLabel != nullptr)
  274. {
  275. delete[] fLabel;
  276. fLabel = nullptr;
  277. }
  278. clearBuffers();
  279. }
  280. // -------------------------------------------------------------------
  281. // Information (base)
  282. PluginType getType() const noexcept override
  283. {
  284. return PLUGIN_REWIRE;
  285. }
  286. PluginCategory getCategory() const noexcept override
  287. {
  288. return PLUGIN_CATEGORY_SYNTH;
  289. }
  290. // -------------------------------------------------------------------
  291. // Information (count)
  292. // nothing
  293. // -------------------------------------------------------------------
  294. // Information (current data)
  295. int32_t getChunkData(void** const dataPtr) const noexcept override
  296. {
  297. CARLA_SAFE_ASSERT_RETURN(pData->options & PLUGIN_OPTION_USE_CHUNKS, 0);
  298. CARLA_SAFE_ASSERT_RETURN(fRw.lib != nullptr, 0);
  299. CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr, 0);
  300. // TODO
  301. return 0;
  302. }
  303. // -------------------------------------------------------------------
  304. // Information (per-plugin data)
  305. unsigned int getOptionsAvailable() const noexcept override
  306. {
  307. unsigned int options = 0x0;
  308. if (getMidiInCount() > 0)
  309. {
  310. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  311. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  312. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  313. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  314. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  315. }
  316. return options;
  317. }
  318. float getParameterValue(const uint32_t parameterId) const noexcept override
  319. {
  320. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  321. // TODO
  322. return 0.0f;
  323. }
  324. void getLabel(char* const strBuf) const noexcept override
  325. {
  326. CARLA_SAFE_ASSERT_RETURN(fLabel != nullptr,)
  327. std::strcpy(strBuf, fLabel);
  328. }
  329. void getRealName(char* const strBuf) const noexcept override
  330. {
  331. CARLA_SAFE_ASSERT_RETURN(fLabel != nullptr,)
  332. std::strcpy(strBuf, fLabel);
  333. }
  334. void getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
  335. {
  336. CARLA_SAFE_ASSERT_RETURN(fRw.lib != nullptr,);
  337. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  338. // TODO
  339. CarlaPlugin::getParameterName(parameterId, strBuf);
  340. }
  341. void getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
  342. {
  343. CARLA_SAFE_ASSERT_RETURN(fRw.lib != nullptr,);
  344. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  345. // TODO
  346. CarlaPlugin::getParameterUnit(parameterId, strBuf);
  347. }
  348. // -------------------------------------------------------------------
  349. // Set data (state)
  350. // nothing
  351. // -------------------------------------------------------------------
  352. // Set data (internal stuff)
  353. // nothing
  354. // -------------------------------------------------------------------
  355. // Set data (plugin-specific stuff)
  356. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  357. {
  358. CARLA_SAFE_ASSERT_RETURN(fRw.lib != nullptr,);
  359. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  360. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  361. // TODO
  362. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  363. }
  364. void setChunkData(const char* const stringData) override
  365. {
  366. CARLA_SAFE_ASSERT_RETURN(pData->options & PLUGIN_OPTION_USE_CHUNKS,);
  367. CARLA_SAFE_ASSERT_RETURN(fRw.lib != nullptr,);
  368. CARLA_SAFE_ASSERT_RETURN(stringData != nullptr,);
  369. // TODO
  370. }
  371. // -------------------------------------------------------------------
  372. // Set ui stuff
  373. void showCustomUI(const bool yesNo) override
  374. {
  375. if (yesNo)
  376. {
  377. if (! fRw.RWDEFIsPanelAppLaunched())
  378. fRw.RWDEFLaunchPanelApp();
  379. fIsPanelLaunched = true;
  380. }
  381. else
  382. {
  383. if (fRw.RWDEFIsPanelAppLaunched())
  384. fRw.RWDEFQuitPanelApp();
  385. fIsPanelLaunched = false;
  386. }
  387. }
  388. void idle() override
  389. {
  390. CARLA_SAFE_ASSERT_RETURN(fRw.lib != nullptr,);
  391. fRw.RWDEFIdle();
  392. // check if panel has been closed
  393. if (fIsPanelLaunched && ! fRw.RWDEFIsPanelAppLaunched())
  394. {
  395. // FIXME
  396. //fIsPanelLaunched = true;
  397. //pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr);
  398. // static int counter = 0;
  399. //
  400. // if (counter % 1000)
  401. // {
  402. // carla_stdout("Panel is closed?");
  403. // }
  404. //
  405. // ++counter;
  406. }
  407. CarlaPlugin::idle();
  408. }
  409. // -------------------------------------------------------------------
  410. // Plugin state
  411. void reload() override
  412. {
  413. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  414. CARLA_SAFE_ASSERT_RETURN(fRw.lib != nullptr,);
  415. carla_debug("ReWirePlugin::reload() - start");
  416. const EngineProcessMode processMode(pData->engine->getProccessMode());
  417. // Safely disable plugin for reload
  418. const ScopedDisabler sd(this);
  419. if (pData->active)
  420. deactivate();
  421. clearBuffers();
  422. uint32_t aIns, aOuts, mIns, mOuts, params;
  423. aIns = aOuts = 0;
  424. bool needsCtrlIn, needsCtrlOut;
  425. needsCtrlIn = needsCtrlOut = false;
  426. RwDevInfo devInfo;
  427. carla_zeroStruct<RwDevInfo>(devInfo);
  428. devInfo.size = sizeof(RwDevInfo);
  429. fRw.RWDEFGetDeviceInfo(&devInfo);
  430. if (devInfo.channelCount > 0)
  431. aIns = aOuts = static_cast<uint32_t>(devInfo.channelCount);
  432. mIns = mOuts = 0; // TODO, should always be 1
  433. params = 0; // TODO?
  434. if (aIns > 0)
  435. {
  436. pData->audioIn.createNew(aIns);
  437. }
  438. if (aOuts > 0)
  439. {
  440. pData->audioOut.createNew(aOuts);
  441. needsCtrlIn = true;
  442. }
  443. if (params > 0)
  444. {
  445. pData->param.createNew(params, false);
  446. needsCtrlIn = true;
  447. }
  448. const uint portNameSize(pData->engine->getMaxPortNameSize());
  449. CarlaString portName;
  450. // Audio Ins
  451. for (uint32_t j=0; j < aIns; ++j)
  452. {
  453. portName.clear();
  454. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  455. {
  456. portName = pData->name;
  457. portName += ":";
  458. }
  459. portName += "i";
  460. portName += devInfo.channelNames[j];
  461. portName.truncate(portNameSize);
  462. pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true);
  463. pData->audioIn.ports[j].rindex = j;
  464. }
  465. // Audio Outs
  466. for (uint32_t j=0; j < aOuts; ++j)
  467. {
  468. portName.clear();
  469. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  470. {
  471. portName = pData->name;
  472. portName += ":";
  473. }
  474. portName += "o";
  475. portName += devInfo.channelNames[j];
  476. portName.truncate(portNameSize);
  477. pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false);
  478. pData->audioOut.ports[j].rindex = j;
  479. }
  480. if (needsCtrlIn)
  481. {
  482. portName.clear();
  483. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  484. {
  485. portName = pData->name;
  486. portName += ":";
  487. }
  488. portName += "events-in";
  489. portName.truncate(portNameSize);
  490. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true);
  491. }
  492. if (needsCtrlOut)
  493. {
  494. portName.clear();
  495. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  496. {
  497. portName = pData->name;
  498. portName += ":";
  499. }
  500. portName += "events-out";
  501. portName.truncate(portNameSize);
  502. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false);
  503. }
  504. // plugin hints
  505. pData->hints = 0x0;
  506. pData->hints |= PLUGIN_IS_SYNTH;
  507. pData->hints |= PLUGIN_HAS_CUSTOM_UI;
  508. if (aOuts > 0 && (aIns == aOuts || aIns == 1))
  509. pData->hints |= PLUGIN_CAN_DRYWET;
  510. if (aOuts > 0)
  511. pData->hints |= PLUGIN_CAN_VOLUME;
  512. if (aOuts >= 2 && aOuts % 2 == 0)
  513. pData->hints |= PLUGIN_CAN_BALANCE;
  514. // extra plugin hints
  515. pData->extraHints = 0x0;
  516. if (mIns > 0)
  517. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  518. if (mOuts > 0)
  519. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
  520. if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0))
  521. pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
  522. bufferSizeChanged(pData->engine->getBufferSize());
  523. if (pData->active)
  524. activate();
  525. carla_debug("ReWirePlugin::reload() - end");
  526. }
  527. // -------------------------------------------------------------------
  528. // Plugin processing
  529. void activate() noexcept override
  530. {
  531. CARLA_SAFE_ASSERT_RETURN(fRw.lib != nullptr,);
  532. // TODO
  533. }
  534. void deactivate() noexcept override
  535. {
  536. CARLA_SAFE_ASSERT_RETURN(fRw.lib != nullptr,);
  537. // TODO
  538. }
  539. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override
  540. {
  541. // --------------------------------------------------------------------------------------------------------
  542. // Check if active
  543. if (! pData->active)
  544. {
  545. // disable any output sound
  546. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  547. FLOAT_CLEAR(outBuffer[i], frames);
  548. return;
  549. }
  550. // --------------------------------------------------------------------------------------------------------
  551. // Check if needs reset
  552. if (pData->needsReset)
  553. {
  554. if (pData->latency > 0)
  555. {
  556. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  557. FLOAT_CLEAR(pData->latencyBuffers[i], pData->latency);
  558. }
  559. pData->needsReset = false;
  560. }
  561. // --------------------------------------------------------------------------------------------------------
  562. // Set TimeInfo
  563. const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
  564. //fRwAudioIn.playMode; // ???
  565. //fRwAudioIn.frames = timeInfo.frame; // not sure if buf or tranport frames
  566. if (timeInfo.valid & EngineTimeInfo::kValidBBT)
  567. {
  568. double ppqBar = double(timeInfo.bbt.bar - 1) * timeInfo.bbt.beatsPerBar;
  569. double ppqBeat = double(timeInfo.bbt.beat - 1);
  570. double ppqTick = double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat;
  571. // PPQ Pos, ???
  572. fRwAudioIn.tickStart = static_cast<rlong>(ppqBar + ppqBeat + ppqTick);
  573. // Tempo
  574. fRwAudioIn.tempo = static_cast<rulong>(timeInfo.bbt.beatsPerMinute);
  575. // Bars
  576. //fTimeInfo.barStartPos = ppqBar;
  577. // Time Signature
  578. fRwAudioIn.signNumerator = static_cast<rulong>(timeInfo.bbt.beatsPerBar);
  579. fRwAudioIn.signDenominator = static_cast<rulong>(timeInfo.bbt.beatType);
  580. }
  581. else
  582. {
  583. fRwAudioIn.tickStart = 0;
  584. fRwAudioIn.tempo = 120;
  585. fRwAudioIn.signNumerator = 4;
  586. fRwAudioIn.signDenominator = 4;
  587. }
  588. // --------------------------------------------------------------------------------------------------------
  589. // Plugin processing (no events)
  590. {
  591. processSingle(inBuffer, outBuffer, frames, 0);
  592. } // End of Plugin processing (no events)
  593. }
  594. bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
  595. {
  596. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  597. if (pData->audioIn.count > 0)
  598. {
  599. CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
  600. }
  601. if (pData->audioOut.count > 0)
  602. {
  603. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  604. }
  605. // --------------------------------------------------------------------------------------------------------
  606. // Try lock, silence otherwise
  607. if (pData->engine->isOffline())
  608. {
  609. pData->singleMutex.lock();
  610. }
  611. else if (! pData->singleMutex.tryLock())
  612. {
  613. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  614. {
  615. for (uint32_t k=0; k < frames; ++k)
  616. outBuffer[i][k+timeOffset] = 0.0f;
  617. }
  618. return false;
  619. }
  620. // --------------------------------------------------------------------------------------------------------
  621. // Set audio buffers
  622. //rulong channels[8];
  623. fRwAudioIn.frames = frames;
  624. #ifndef CARLA_OS_LINUX
  625. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  626. {
  627. fRwAudioIn.audioBuf[i] = outBuffer[i]+timeOffset;
  628. FLOAT_COPY(fRwAudioIn.audioBuf[i], inBuffer[i]+timeOffset, frames);
  629. }
  630. #endif
  631. // --------------------------------------------------------------------------------------------------------
  632. // Run plugin
  633. fRw.RWDEFDriveAudio(&fRwAudioIn, &fRwAudioOut);
  634. #ifndef BUILD_BRIDGE
  635. // --------------------------------------------------------------------------------------------------------
  636. // Post-processing (dry/wet, volume and balance)
  637. {
  638. const bool doVolume = (pData->hints & PLUGIN_CAN_VOLUME) != 0 && pData->postProc.volume != 1.0f;
  639. const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && pData->postProc.dryWet != 1.0f;
  640. const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && (pData->postProc.balanceLeft != -1.0f || pData->postProc.balanceRight != 1.0f);
  641. bool isPair;
  642. float bufValue, oldBufLeft[doBalance ? frames : 1];
  643. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  644. {
  645. // Dry/Wet
  646. if (doDryWet)
  647. {
  648. for (uint32_t k=0; k < frames; ++k)
  649. {
  650. bufValue = inBuffer[(pData->audioIn.count == 1) ? 0 : i][k+timeOffset];
  651. outBuffer[i][k+timeOffset] = (outBuffer[i][k+timeOffset] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet));
  652. }
  653. }
  654. // Balance
  655. if (doBalance)
  656. {
  657. isPair = (i % 2 == 0);
  658. if (isPair)
  659. {
  660. CARLA_ASSERT(i+1 < pData->audioOut.count);
  661. FLOAT_COPY(oldBufLeft, outBuffer[i]+timeOffset, frames);
  662. }
  663. float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f;
  664. float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
  665. for (uint32_t k=0; k < frames; ++k)
  666. {
  667. if (isPair)
  668. {
  669. // left
  670. outBuffer[i][k+timeOffset] = oldBufLeft[k] * (1.0f - balRangeL);
  671. outBuffer[i][k+timeOffset] += outBuffer[i+1][k+timeOffset] * (1.0f - balRangeR);
  672. }
  673. else
  674. {
  675. // right
  676. outBuffer[i][k+timeOffset] = outBuffer[i][k+timeOffset] * balRangeR;
  677. outBuffer[i][k+timeOffset] += oldBufLeft[k] * balRangeL;
  678. }
  679. }
  680. }
  681. // Volume
  682. if (doVolume)
  683. {
  684. for (uint32_t k=0; k < frames; ++k)
  685. outBuffer[i][k+timeOffset] *= pData->postProc.volume;
  686. }
  687. }
  688. } // End of Post-processing
  689. #endif
  690. // --------------------------------------------------------------------------------------------------------
  691. pData->singleMutex.unlock();
  692. return true;
  693. }
  694. void bufferSizeChanged(const uint32_t newBufferSize) override
  695. {
  696. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  697. carla_debug("ReWirePlugin::bufferSizeChanged(%i)", newBufferSize);
  698. if (pData->active)
  699. deactivate();
  700. RwAudioInfo audioInfo;
  701. audioInfo.size = sizeof(RwAudioInfo);
  702. audioInfo.bufferSize = static_cast<rlong>(newBufferSize);
  703. audioInfo.sampleRate = static_cast<rlong>(pData->engine->getSampleRate());
  704. fRw.RWDEFSetAudioInfo(&audioInfo);
  705. if (pData->active)
  706. activate();
  707. }
  708. void sampleRateChanged(const double newSampleRate) override
  709. {
  710. CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
  711. carla_debug("ReWirePlugin::sampleRateChanged(%g)", newSampleRate);
  712. if (pData->active)
  713. deactivate();
  714. RwAudioInfo audioInfo;
  715. audioInfo.size = sizeof(RwAudioInfo);
  716. audioInfo.bufferSize = static_cast<rlong>(pData->engine->getBufferSize());
  717. audioInfo.sampleRate = static_cast<rlong>(newSampleRate);
  718. fRw.RWDEFSetAudioInfo(&audioInfo);
  719. if (pData->active)
  720. activate();
  721. }
  722. // -------------------------------------------------------------------
  723. // Plugin buffers
  724. // nothing
  725. // -------------------------------------------------------------------
  726. // Post-poned UI Stuff
  727. // nothing
  728. // -------------------------------------------------------------------
  729. protected:
  730. // TODO
  731. // -------------------------------------------------------------------
  732. public:
  733. bool init(const char* const filename, const char* const name)
  734. {
  735. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  736. // ---------------------------------------------------------------
  737. // first checks
  738. if (pData->client != nullptr)
  739. {
  740. pData->engine->setLastError("Plugin client is already registered");
  741. return false;
  742. }
  743. if (filename == nullptr || filename[0] == '\0')
  744. {
  745. pData->engine->setLastError("null filename");
  746. return false;
  747. }
  748. // ---------------------------------------------------------------
  749. // open DLL
  750. int ret = fRw.init(filename);
  751. if (ret != 0)
  752. {
  753. if (ret == -1)
  754. pData->engine->setLastError(lib_error(filename));
  755. else
  756. pData->engine->setLastError("Not a valid ReWire application");
  757. return false;
  758. }
  759. // ---------------------------------------------------------------
  760. // get info
  761. long version;
  762. char nameBuf[STR_MAX+1];
  763. carla_zeroChar(nameBuf, STR_MAX+1);
  764. fRw.RWDEFGetDeviceNameAndVersion(&version, nameBuf);
  765. if (nameBuf[0] == '\0')
  766. {
  767. pData->engine->setLastError("ReWire application has no name");
  768. return false;
  769. }
  770. fLabel = carla_strdup(nameBuf);
  771. if (name != nullptr && name[0] != '\0')
  772. pData->name = pData->engine->getUniquePluginName(name);
  773. else
  774. pData->name = pData->engine->getUniquePluginName(nameBuf);
  775. pData->filename = carla_strdup(filename);
  776. // ---------------------------------------------------------------
  777. // register client
  778. pData->client = pData->engine->addClient(this);
  779. if (pData->client == nullptr || ! pData->client->isOk())
  780. {
  781. pData->engine->setLastError("Failed to register plugin client");
  782. return false;
  783. }
  784. // ---------------------------------------------------------------
  785. // initialize app
  786. RwOpenInfo info;
  787. info.size1 = sizeof(RwOpenInfo);
  788. info.size2 = 12;
  789. info.bufferSize = static_cast<rlong>(pData->engine->getBufferSize());
  790. info.sampleRate = static_cast<rlong>(pData->engine->getSampleRate());
  791. ret = fRw.RWDEFOpenDevice(&info);
  792. carla_stdout("RW open ret = %i", ret);
  793. // TODO check ret
  794. fIsOpen = true;
  795. // ---------------------------------------------------------------
  796. // load plugin settings
  797. {
  798. // set default options
  799. pData->options = 0x0;
  800. pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  801. pData->options |= PLUGIN_OPTION_USE_CHUNKS;
  802. // TODO
  803. if (getMidiInCount() > 0)
  804. {
  805. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  806. pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  807. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  808. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  809. }
  810. // set identifier string
  811. CarlaString identifier("ReWire/");
  812. identifier += fLabel;
  813. pData->identifier = identifier.dup();
  814. // load settings
  815. pData->options = pData->loadSettings(pData->options, getOptionsAvailable());
  816. // ignore settings, we need this anyway
  817. pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  818. pData->options |= PLUGIN_OPTION_USE_CHUNKS;
  819. }
  820. return true;
  821. }
  822. private:
  823. RewireBridge fRw;
  824. RwAudioInInfo fRwAudioIn;
  825. RwAudioOutInfo fRwAudioOut;
  826. bool fIsOpen;
  827. bool fIsPanelLaunched;
  828. const char* fLabel;
  829. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ReWirePlugin)
  830. };
  831. CARLA_BACKEND_END_NAMESPACE
  832. #endif // WANT_REWIRE
  833. // -------------------------------------------------------------------------------------------------------------------
  834. CARLA_BACKEND_START_NAMESPACE
  835. CarlaPlugin* CarlaPlugin::newReWire(const Initializer& init)
  836. {
  837. carla_debug("CarlaPlugin::newReWire({%p, \"%s\", \"%s\"})", init.engine, init.filename, init.name);
  838. #ifdef WANT_REWIRE
  839. ReWirePlugin* const plugin(new ReWirePlugin(init.engine, init.id));
  840. if (! plugin->init(init.filename, init.name))
  841. {
  842. delete plugin;
  843. return nullptr;
  844. }
  845. plugin->reload();
  846. if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack())
  847. {
  848. init.engine->setLastError("Carla's rack mode can only work with Stereo ReWire applications, sorry!");
  849. delete plugin;
  850. return nullptr;
  851. }
  852. return plugin;
  853. #else
  854. init.engine->setLastError("ReWire support not available");
  855. return nullptr;
  856. #endif
  857. }
  858. CARLA_BACKEND_END_NAMESPACE
  859. // -------------------------------------------------------------------------------------------------------------------