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.

1115 lines
33KB

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