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.

583 lines
17KB

  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef BUILD_BRIDGE
  18. # error This file should not be compiled if not building bridge
  19. #endif
  20. #include "CarlaEngineInternal.hpp"
  21. #include "CarlaPlugin.hpp"
  22. #include "CarlaBackendUtils.hpp"
  23. #include "CarlaBridgeUtils.hpp"
  24. #include "CarlaMIDI.h"
  25. #include "jackbridge/JackBridge.hpp"
  26. #include <cerrno>
  27. #include <ctime>
  28. CARLA_BACKEND_START_NAMESPACE
  29. #if 0
  30. } // Fix editor indentation
  31. #endif
  32. // -------------------------------------------------------------------
  33. template<typename T>
  34. bool jackbridge_shm_map2(char* shm, T*& value)
  35. {
  36. value = (T*)jackbridge_shm_map(shm, sizeof(T));
  37. return (value != nullptr);
  38. }
  39. struct BridgeAudioPool {
  40. CarlaString filename;
  41. float* data;
  42. char shm[32];
  43. BridgeAudioPool()
  44. : data(nullptr)
  45. {
  46. carla_zeroChar(shm, 32);
  47. jackbridge_shm_init(shm);
  48. }
  49. ~BridgeAudioPool()
  50. {
  51. // should be cleared by now
  52. CARLA_ASSERT(data == nullptr);
  53. clear();
  54. }
  55. bool attach()
  56. {
  57. jackbridge_shm_attach(shm, filename);
  58. return jackbridge_shm_is_valid(shm);
  59. }
  60. void clear()
  61. {
  62. filename.clear();
  63. data = nullptr;
  64. if (jackbridge_shm_is_valid(shm))
  65. jackbridge_shm_close(shm);
  66. }
  67. CARLA_DECLARE_NON_COPY_STRUCT(BridgeAudioPool)
  68. };
  69. struct BridgeControl : public RingBufferControl<StackRingBuffer> {
  70. CarlaString filename;
  71. BridgeShmControl* data;
  72. char shm[32];
  73. BridgeControl()
  74. : RingBufferControl(nullptr),
  75. data(nullptr)
  76. {
  77. carla_zeroChar(shm, 32);
  78. jackbridge_shm_init(shm);
  79. }
  80. ~BridgeControl()
  81. {
  82. // should be cleared by now
  83. CARLA_ASSERT(data == nullptr);
  84. clear();
  85. }
  86. bool attach()
  87. {
  88. jackbridge_shm_attach(shm, filename);
  89. return jackbridge_shm_is_valid(shm);
  90. }
  91. void clear()
  92. {
  93. filename.clear();
  94. data = nullptr;
  95. if (jackbridge_shm_is_valid(shm))
  96. jackbridge_shm_close(shm);
  97. }
  98. bool mapData()
  99. {
  100. CARLA_ASSERT(data == nullptr);
  101. if (jackbridge_shm_map2<BridgeShmControl>(shm, data))
  102. {
  103. setRingBuffer(&data->ringBuffer, false);
  104. return true;
  105. }
  106. return false;
  107. }
  108. PluginBridgeOpcode readOpcode()
  109. {
  110. return static_cast<PluginBridgeOpcode>(readInt());
  111. }
  112. CARLA_DECLARE_NON_COPY_STRUCT(BridgeControl)
  113. };
  114. struct BridgeTime {
  115. CarlaString filename;
  116. BridgeTimeInfo* info;
  117. char shm[32];
  118. BridgeTime()
  119. : info(nullptr)
  120. {
  121. carla_zeroChar(shm, 32);
  122. jackbridge_shm_init(shm);
  123. }
  124. ~BridgeTime()
  125. {
  126. // should be cleared by now
  127. CARLA_ASSERT(info == nullptr);
  128. clear();
  129. }
  130. bool attach()
  131. {
  132. jackbridge_shm_attach(shm, filename);
  133. return jackbridge_shm_is_valid(shm);
  134. }
  135. void clear()
  136. {
  137. filename.clear();
  138. info = nullptr;
  139. if (jackbridge_shm_is_valid(shm))
  140. jackbridge_shm_close(shm);
  141. }
  142. bool mapData()
  143. {
  144. CARLA_ASSERT(info == nullptr);
  145. return jackbridge_shm_map2<BridgeTimeInfo>(shm, info);
  146. }
  147. CARLA_DECLARE_NON_COPY_STRUCT(BridgeTime)
  148. };
  149. // -------------------------------------------------------------------
  150. class CarlaEngineBridge : public CarlaEngine,
  151. public CarlaThread
  152. {
  153. public:
  154. CarlaEngineBridge(const char* const audioBaseName, const char* const controlBaseName, const char* const timeBaseName)
  155. : CarlaEngine(),
  156. CarlaThread("CarlaEngineBridge"),
  157. fIsRunning(false)
  158. {
  159. carla_debug("CarlaEngineBridge::CarlaEngineBridge()");
  160. fShmAudioPool.filename = "/carla-bridge_shm_";
  161. fShmAudioPool.filename += audioBaseName;
  162. fShmControl.filename = "/carla-bridge_shc_";
  163. fShmControl.filename += controlBaseName;
  164. fShmTime.filename = "/carla-bridge_sht_";
  165. fShmTime.filename += timeBaseName;
  166. }
  167. ~CarlaEngineBridge() override
  168. {
  169. carla_debug("CarlaEngineBridge::~CarlaEngineBridge()");
  170. }
  171. // -------------------------------------
  172. // CarlaEngine virtual calls
  173. bool init(const char* const clientName) override
  174. {
  175. carla_debug("CarlaEngineBridge::init(\"%s\")", clientName);
  176. // SHM Audio Pool
  177. {
  178. if (! fShmAudioPool.attach())
  179. {
  180. carla_stdout("Failed to open or create shared memory file #1");
  181. return false;
  182. }
  183. }
  184. // SHM Control
  185. {
  186. if (! fShmControl.attach())
  187. {
  188. carla_stdout("Failed to open or create shared memory file #2");
  189. // clear
  190. fShmAudioPool.clear();
  191. return false;
  192. }
  193. if (! fShmControl.mapData())
  194. {
  195. carla_stdout("Failed to map shared memory file #2");
  196. // clear
  197. fShmControl.clear();
  198. fShmAudioPool.clear();
  199. return false;
  200. }
  201. }
  202. // SHM Transport
  203. {
  204. if (! fShmTime.attach())
  205. {
  206. carla_stdout("Failed to open or create shared memory file #3");
  207. // clear
  208. fShmControl.clear();
  209. fShmAudioPool.clear();
  210. return false;
  211. }
  212. if (! fShmTime.mapData())
  213. {
  214. carla_stdout("Failed to map shared memory file #3");
  215. // clear
  216. fShmTime.clear();
  217. fShmControl.clear();
  218. fShmAudioPool.clear();
  219. return false;
  220. }
  221. }
  222. // Read values from memory
  223. PluginBridgeOpcode opcode;
  224. opcode = fShmControl.readOpcode();
  225. CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeOpcodeNull, opcode);
  226. const uint32_t structSize = fShmControl.readUInt();
  227. CARLA_SAFE_ASSERT_INT2(structSize == sizeof(BridgeShmControl), structSize, sizeof(BridgeShmControl));
  228. carla_stderr("Struct Size: %i", structSize);
  229. opcode = fShmControl.readOpcode();
  230. CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeOpcodeSetBufferSize, opcode);
  231. pData->bufferSize = fShmControl.readUInt();
  232. carla_stderr("BufferSize: %i", pData->bufferSize);
  233. opcode = fShmControl.readOpcode();
  234. CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeOpcodeSetSampleRate, opcode);
  235. pData->sampleRate = fShmControl.readFloat();
  236. carla_stderr("SampleRate: %f", pData->sampleRate);
  237. CarlaThread::startThread();
  238. CarlaEngine::init(clientName);
  239. return true;
  240. }
  241. bool close() override
  242. {
  243. carla_debug("CarlaEnginePlugin::close()");
  244. CarlaEngine::close();
  245. CarlaThread::stopThread(6000);
  246. fShmTime.clear();
  247. fShmControl.clear();
  248. fShmAudioPool.clear();
  249. return true;
  250. }
  251. bool isRunning() const noexcept override
  252. {
  253. return fIsRunning;
  254. }
  255. bool isOffline() const noexcept override
  256. {
  257. return false;
  258. }
  259. EngineType getType() const noexcept override
  260. {
  261. return kEngineTypeBridge;
  262. }
  263. const char* getCurrentDriverName() const noexcept
  264. {
  265. return "Bridge";
  266. }
  267. // -------------------------------------
  268. // CarlaThread virtual calls
  269. void run() override
  270. {
  271. fIsRunning = true;
  272. // TODO - set RT permissions
  273. carla_debug("CarlaEngineBridge::run()");
  274. for (; ! shouldThreadExit();)
  275. {
  276. if (! jackbridge_sem_timedwait(&fShmControl.data->runServer, 5))
  277. {
  278. if (errno == ETIMEDOUT)
  279. {
  280. fIsRunning = false;
  281. signalThreadShouldExit();
  282. return;
  283. }
  284. }
  285. for (; fShmControl.isDataAvailable();)
  286. {
  287. const PluginBridgeOpcode opcode(fShmControl.readOpcode());
  288. if (opcode != kPluginBridgeOpcodeProcess) {
  289. carla_debug("CarlaEngineBridge::run() - got opcode: %s", PluginBridgeOpcode2str(opcode));
  290. }
  291. switch (opcode)
  292. {
  293. case kPluginBridgeOpcodeNull:
  294. break;
  295. case kPluginBridgeOpcodeSetAudioPool: {
  296. const int64_t poolSize(fShmControl.readLong());
  297. CARLA_SAFE_ASSERT_BREAK(poolSize > 0);
  298. fShmAudioPool.data = (float*)jackbridge_shm_map(fShmAudioPool.shm, static_cast<size_t>(poolSize));
  299. break;
  300. }
  301. case kPluginBridgeOpcodeSetBufferSize: {
  302. const uint32_t bufferSize(fShmControl.readUInt());
  303. bufferSizeChanged(bufferSize);
  304. break;
  305. }
  306. case kPluginBridgeOpcodeSetSampleRate: {
  307. const float sampleRate(fShmControl.readFloat());
  308. sampleRateChanged(sampleRate);
  309. break;
  310. }
  311. case kPluginBridgeOpcodeSetParameter: {
  312. const int32_t index(fShmControl.readInt());
  313. const float value(fShmControl.readFloat());
  314. CarlaPlugin* const plugin(getPluginUnchecked(0));
  315. if (plugin != nullptr && plugin->isEnabled())
  316. {
  317. plugin->setParameterValueByRealIndex(index, value, false, false, false);
  318. //if (index >= 0)
  319. // plugin->postponeRtEvent(kPluginPostRtEventParameterChange, index, 0, value);
  320. }
  321. break;
  322. }
  323. case kPluginBridgeOpcodeSetProgram: {
  324. const int32_t index(fShmControl.readInt());
  325. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  326. CarlaPlugin* const plugin(getPluginUnchecked(0));
  327. if (plugin != nullptr && plugin->isEnabled())
  328. {
  329. plugin->setProgram(index, false, false, false);
  330. //plugin->postponeRtEvent(kPluginPostRtEventProgramChange, index, 0, 0.0f);
  331. }
  332. break;
  333. }
  334. case kPluginBridgeOpcodeSetMidiProgram: {
  335. const int32_t index(fShmControl.readInt());
  336. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  337. CarlaPlugin* const plugin(getPluginUnchecked(0));
  338. if (plugin != nullptr && plugin->isEnabled())
  339. {
  340. plugin->setMidiProgram(index, false, false, false);
  341. //plugin->postponeRtEvent(kPluginPostRtEventMidiProgramChange, index, 0, 0.0f);
  342. }
  343. break;
  344. }
  345. case kPluginBridgeOpcodeMidiEvent: {
  346. const int64_t time(fShmControl.readLong());
  347. const int32_t size(fShmControl.readInt());
  348. CARLA_SAFE_ASSERT_BREAK(time >= 0);
  349. CARLA_SAFE_ASSERT_BREAK(size > 0 && size <= 4);
  350. uint8_t data[size];
  351. for (int32_t i=0; i < size; ++i)
  352. data[i] = static_cast<uint8_t>(fShmControl.readChar());
  353. CARLA_SAFE_ASSERT_BREAK(pData->bufEvents.in != nullptr);
  354. for (ushort i=0; i < kMaxEngineEventInternalCount; ++i)
  355. {
  356. EngineEvent& event(pData->bufEvents.in[i]);
  357. if (event.type != kEngineEventTypeNull)
  358. continue;
  359. event.fillFromMidiData(static_cast<uint8_t>(size), data);
  360. break;
  361. }
  362. break;
  363. }
  364. case kPluginBridgeOpcodeProcess: {
  365. CARLA_SAFE_ASSERT_BREAK(fShmAudioPool.data != nullptr);
  366. CarlaPlugin* const plugin(getPluginUnchecked(0));
  367. BridgeTimeInfo* const bridgeInfo(fShmTime.info);
  368. CARLA_SAFE_ASSERT_BREAK(bridgeInfo != nullptr);
  369. if (plugin != nullptr && plugin->isEnabled() && plugin->tryLock(true)) // FIXME - always lock?
  370. {
  371. const uint32_t inCount(plugin->getAudioInCount());
  372. const uint32_t outCount(plugin->getAudioOutCount());
  373. float* inBuffer[inCount];
  374. float* outBuffer[outCount];
  375. for (uint32_t i=0; i < inCount; ++i)
  376. inBuffer[i] = fShmAudioPool.data + i*pData->bufferSize;
  377. for (uint32_t i=0; i < outCount; ++i)
  378. outBuffer[i] = fShmAudioPool.data + (i+inCount)*pData->bufferSize;
  379. EngineTimeInfo& timeInfo(pData->timeInfo);
  380. timeInfo.playing = bridgeInfo->playing;
  381. timeInfo.frame = bridgeInfo->frame;
  382. timeInfo.usecs = bridgeInfo->usecs;
  383. timeInfo.valid = bridgeInfo->valid;
  384. if (timeInfo.valid & EngineTimeInfo::kValidBBT)
  385. {
  386. timeInfo.bbt.bar = bridgeInfo->bar;
  387. timeInfo.bbt.beat = bridgeInfo->beat;
  388. timeInfo.bbt.tick = bridgeInfo->tick;
  389. timeInfo.bbt.beatsPerBar = bridgeInfo->beatsPerBar;
  390. timeInfo.bbt.beatType = bridgeInfo->beatType;
  391. timeInfo.bbt.ticksPerBeat = bridgeInfo->ticksPerBeat;
  392. timeInfo.bbt.beatsPerMinute = bridgeInfo->beatsPerMinute;
  393. timeInfo.bbt.barStartTick = bridgeInfo->barStartTick;
  394. }
  395. plugin->initBuffers();
  396. plugin->process(inBuffer, outBuffer, pData->bufferSize);
  397. plugin->unlock();
  398. }
  399. // clear buffer
  400. CARLA_SAFE_ASSERT_BREAK(pData->bufEvents.in != nullptr);
  401. if (pData->bufEvents.in[0].type != kEngineEventTypeNull)
  402. carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kMaxEngineEventInternalCount);
  403. break;
  404. }
  405. case kPluginBridgeOpcodeQuit:
  406. signalThreadShouldExit();
  407. fIsRunning = false;
  408. break;
  409. }
  410. }
  411. if (! jackbridge_sem_post(&fShmControl.data->runClient))
  412. carla_stderr2("Could not post to semaphore");
  413. }
  414. fIsRunning = false;
  415. }
  416. private:
  417. BridgeAudioPool fShmAudioPool;
  418. BridgeControl fShmControl;
  419. BridgeTime fShmTime;
  420. volatile bool fIsRunning;
  421. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineBridge)
  422. };
  423. // -----------------------------------------
  424. CarlaEngine* CarlaEngine::newBridge(const char* const audioBaseName, const char* const controlBaseName, const char* const timeBaseName)
  425. {
  426. return new CarlaEngineBridge(audioBaseName, controlBaseName, timeBaseName);
  427. }
  428. CARLA_BACKEND_END_NAMESPACE
  429. // -----------------------------------------------------------------------
  430. // Extra stuff for linking purposes
  431. CARLA_BACKEND_START_NAMESPACE
  432. CarlaEngine* CarlaEngine::newRtAudio(const AudioApi) { return nullptr; }
  433. unsigned int CarlaEngine::getRtAudioApiCount() { return 0; }
  434. const char* CarlaEngine::getRtAudioApiName(const unsigned int) { return nullptr; }
  435. const char* const* CarlaEngine::getRtAudioApiDeviceNames(const unsigned int) { return nullptr; }
  436. const EngineDriverDeviceInfo* CarlaEngine::getRtAudioDeviceInfo(const unsigned int, const char* const) { return nullptr; }
  437. #ifdef HAVE_JUCE
  438. CarlaEngine* CarlaEngine::newJuce(const AudioApi) { return nullptr; }
  439. unsigned int CarlaEngine::getJuceApiCount() { return 0; }
  440. const char* CarlaEngine::getJuceApiName(const unsigned int) { return nullptr; }
  441. const char* const* CarlaEngine::getJuceApiDeviceNames(const unsigned int) { return nullptr; }
  442. const EngineDriverDeviceInfo* CarlaEngine::getJuceDeviceInfo(const unsigned int, const char* const) { return nullptr; }
  443. #endif
  444. CARLA_BACKEND_END_NAMESPACE
  445. // -----------------------------------------------------------------------
  446. #if defined(CARLA_OS_WIN) && ! defined(__WINE__)
  447. extern "C" __declspec (dllexport)
  448. #else
  449. extern "C" __attribute__ ((visibility("default")))
  450. #endif
  451. void carla_register_native_plugin_carla();
  452. void carla_register_native_plugin_carla(){}
  453. // -----------------------------------------------------------------------