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.

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