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.

626 lines
16KB

  1. /*
  2. * Carla Engine
  3. * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_ENGINE_INTERNAL_HPP_INCLUDED
  18. #define CARLA_ENGINE_INTERNAL_HPP_INCLUDED
  19. #include "CarlaEngine.hpp"
  20. #include "CarlaEngineOsc.hpp"
  21. #include "CarlaEngineThread.hpp"
  22. #include "CarlaPlugin.hpp"
  23. #include "CarlaMutex.hpp"
  24. #include "List.hpp"
  25. #ifdef HAVE_JUCE
  26. # include "juce_audio_basics.h"
  27. using juce::FloatVectorOperations;
  28. #endif
  29. // -----------------------------------------------------------------------
  30. // Engine helper macro, sets lastError and returns false/NULL
  31. #define CARLA_SAFE_ASSERT_RETURN_ERR(cond, err) if (cond) pass(); else { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return false; }
  32. #define CARLA_SAFE_ASSERT_RETURN_ERRN(cond, err) if (cond) pass(); else { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return nullptr; }
  33. // -----------------------------------------------------------------------
  34. // Float operations
  35. #ifdef HAVE_JUCE
  36. # define FLOAT_ADD(bufDst, bufSrc, frames) FloatVectorOperations::add(bufDst, bufSrc, frames)
  37. # define FLOAT_COPY(bufDst, bufSrc, frames) FloatVectorOperations::copy(bufDst, bufSrc, frames)
  38. # define FLOAT_CLEAR(buf, frames) FloatVectorOperations::clear(buf, frames)
  39. #else
  40. # define FLOAT_ADD(bufDst, bufSrc, frames) carla_addFloat(bufDst, bufSrc, frames)
  41. # define FLOAT_COPY(bufDst, bufSrc, frames) carla_copyFloat(bufDst, bufSrc, frames)
  42. # define FLOAT_CLEAR(buf, frames) carla_zeroFloat(buf, frames)
  43. #endif
  44. // -----------------------------------------------------------------------
  45. CARLA_BACKEND_START_NAMESPACE
  46. #if 0
  47. } // Fix editor indentation
  48. #endif
  49. // -----------------------------------------------------------------------
  50. static inline
  51. const char* EngineType2Str(const EngineType type)
  52. {
  53. switch (type)
  54. {
  55. case kEngineTypeNull:
  56. return "kEngineTypeNull";
  57. case kEngineTypeJack:
  58. return "kEngineTypeJack";
  59. case kEngineTypeJuce:
  60. return "kEngineTypeJuce";
  61. case kEngineTypeRtAudio:
  62. return "kEngineTypeRtAudio";
  63. case kEngineTypePlugin:
  64. return "kEngineTypePlugin";
  65. case kEngineTypeBridge:
  66. return "kEngineTypeBridge";
  67. }
  68. carla_stderr("CarlaBackend::EngineType2Str(%i) - invalid type", type);
  69. return nullptr;
  70. }
  71. static inline
  72. const char* EnginePortType2Str(const EnginePortType type)
  73. {
  74. switch (type)
  75. {
  76. case kEnginePortTypeNull:
  77. return "kEnginePortTypeNull";
  78. case kEnginePortTypeAudio:
  79. return "kEnginePortTypeAudio";
  80. case kEnginePortTypeCV:
  81. return "kEnginePortTypeCV";
  82. case kEnginePortTypeEvent:
  83. return "kEnginePortTypeEvent";
  84. }
  85. carla_stderr("CarlaBackend::EnginePortType2Str(%i) - invalid type", type);
  86. return nullptr;
  87. }
  88. static inline
  89. const char* EngineEventType2Str(const EngineEventType type)
  90. {
  91. switch (type)
  92. {
  93. case kEngineEventTypeNull:
  94. return "kEngineEventTypeNull";
  95. case kEngineEventTypeControl:
  96. return "kEngineEventTypeControl";
  97. case kEngineEventTypeMidi:
  98. return "kEngineEventTypeMidi";
  99. }
  100. carla_stderr("CarlaBackend::EngineEventType2Str(%i) - invalid type", type);
  101. return nullptr;
  102. }
  103. static inline
  104. const char* EngineControlEventType2Str(const EngineControlEventType type)
  105. {
  106. switch (type)
  107. {
  108. case kEngineControlEventTypeNull:
  109. return "kEngineNullEvent";
  110. case kEngineControlEventTypeParameter:
  111. return "kEngineControlEventTypeParameter";
  112. case kEngineControlEventTypeMidiBank:
  113. return "kEngineControlEventTypeMidiBank";
  114. case kEngineControlEventTypeMidiProgram:
  115. return "kEngineControlEventTypeMidiProgram";
  116. case kEngineControlEventTypeAllSoundOff:
  117. return "kEngineControlEventTypeAllSoundOff";
  118. case kEngineControlEventTypeAllNotesOff:
  119. return "kEngineControlEventTypeAllNotesOff";
  120. }
  121. carla_stderr("CarlaBackend::EngineControlEventType2Str(%i) - invalid type", type);
  122. return nullptr;
  123. }
  124. // -----------------------------------------------------------------------
  125. const unsigned short kEngineMaxInternalEventCount = 512;
  126. enum EnginePostAction {
  127. kEnginePostActionNull,
  128. kEnginePostActionZeroCount,
  129. kEnginePostActionRemovePlugin,
  130. kEnginePostActionSwitchPlugins
  131. };
  132. struct EnginePluginData {
  133. CarlaPlugin* plugin;
  134. float insPeak[2];
  135. float outsPeak[2];
  136. void clear()
  137. {
  138. plugin = nullptr;
  139. insPeak[0] = insPeak[1] = 0.0f;
  140. outsPeak[0] = outsPeak[1] = 0.0f;
  141. }
  142. };
  143. // -----------------------------------------------------------------------
  144. enum RackPatchbayGroupIds {
  145. RACK_PATCHBAY_GROUP_CARLA = -1,
  146. RACK_PATCHBAY_GROUP_AUDIO_IN = 0,
  147. RACK_PATCHBAY_GROUP_AUDIO_OUT = 1,
  148. RACK_PATCHBAY_GROUP_MIDI_IN = 2,
  149. RACK_PATCHBAY_GROUP_MIDI_OUT = 3,
  150. RACK_PATCHBAY_GROUP_MAX = 4
  151. };
  152. enum RackPatchbayPortIds {
  153. RACK_PATCHBAY_PORT_AUDIO_IN1 = -1,
  154. RACK_PATCHBAY_PORT_AUDIO_IN2 = -2,
  155. RACK_PATCHBAY_PORT_AUDIO_OUT1 = -3,
  156. RACK_PATCHBAY_PORT_AUDIO_OUT2 = -4,
  157. RACK_PATCHBAY_PORT_MIDI_IN = -5,
  158. RACK_PATCHBAY_PORT_MIDI_OUT = -6,
  159. RACK_PATCHBAY_PORT_MAX = -7
  160. };
  161. struct PortNameToId {
  162. int portId;
  163. char name[STR_MAX+1];
  164. };
  165. struct ConnectionToId {
  166. int id;
  167. int portOut;
  168. int portIn;
  169. };
  170. // -----------------------------------------------------------------------
  171. struct EngineRackBuffers {
  172. float* in[2];
  173. float* out[2];
  174. // connections stuff
  175. List<uint> connectedIns[2];
  176. List<uint> connectedOuts[2];
  177. CarlaMutex connectLock;
  178. int lastConnectionId;
  179. List<ConnectionToId> usedConnections;
  180. EngineRackBuffers(const uint32_t bufferSize)
  181. : lastConnectionId(0)
  182. {
  183. resize(bufferSize);
  184. }
  185. ~EngineRackBuffers()
  186. {
  187. clear();
  188. }
  189. void clear()
  190. {
  191. lastConnectionId = 0;
  192. if (in[0] != nullptr)
  193. {
  194. delete[] in[0];
  195. in[0] = nullptr;
  196. }
  197. if (in[1] != nullptr)
  198. {
  199. delete[] in[1];
  200. in[1] = nullptr;
  201. }
  202. if (out[0] != nullptr)
  203. {
  204. delete[] out[0];
  205. out[0] = nullptr;
  206. }
  207. if (out[1] != nullptr)
  208. {
  209. delete[] out[1];
  210. out[1] = nullptr;
  211. }
  212. connectedIns[0].clear();
  213. connectedIns[1].clear();
  214. connectedOuts[0].clear();
  215. connectedOuts[1].clear();
  216. usedConnections.clear();
  217. }
  218. void resize(const uint32_t bufferSize)
  219. {
  220. if (bufferSize > 0)
  221. {
  222. in[0] = new float[bufferSize];
  223. in[1] = new float[bufferSize];
  224. out[0] = new float[bufferSize];
  225. out[1] = new float[bufferSize];
  226. }
  227. else
  228. {
  229. in[0] = nullptr;
  230. in[1] = nullptr;
  231. out[0] = nullptr;
  232. out[1] = nullptr;
  233. }
  234. }
  235. };
  236. struct EnginePatchbayBuffers {
  237. EnginePatchbayBuffers(const uint32_t bufferSize)
  238. {
  239. resize(bufferSize);
  240. }
  241. ~EnginePatchbayBuffers()
  242. {
  243. clear();
  244. }
  245. void clear()
  246. {
  247. }
  248. void resize(const uint32_t /*bufferSize*/)
  249. {
  250. }
  251. };
  252. // -----------------------------------------------------------------------
  253. struct CarlaEngineProtectedData {
  254. CarlaEngineOsc osc;
  255. CarlaEngineThread thread;
  256. const CarlaOscData* oscData;
  257. EngineCallbackFunc callback;
  258. void* callbackPtr;
  259. unsigned int hints;
  260. uint32_t bufferSize;
  261. double sampleRate;
  262. bool aboutToClose; // don't re-activate thread if true
  263. unsigned int curPluginCount; // number of plugins loaded (0...max)
  264. unsigned int maxPluginNumber; // number of plugins allowed (0, 16, 99 or 255)
  265. unsigned int nextPluginId; // invalid if == maxPluginNumber
  266. CarlaString lastError;
  267. CarlaString name;
  268. EngineOptions options;
  269. EngineTimeInfo timeInfo;
  270. EnginePluginData* plugins;
  271. #ifndef BUILD_BRIDGE
  272. struct InternalAudio {
  273. bool isReady;
  274. bool usePatchbay;
  275. uint inCount;
  276. uint outCount;
  277. union {
  278. EngineRackBuffers* rack;
  279. EnginePatchbayBuffers* patchbay;
  280. };
  281. InternalAudio() noexcept
  282. : isReady(false),
  283. usePatchbay(false),
  284. inCount(0),
  285. outCount(0)
  286. {
  287. rack = nullptr;
  288. }
  289. ~InternalAudio()
  290. {
  291. CARLA_ASSERT(! isReady);
  292. CARLA_ASSERT(rack == nullptr);
  293. }
  294. void initPatchbay()
  295. {
  296. if (usePatchbay)
  297. {
  298. CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
  299. }
  300. else
  301. {
  302. CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);
  303. rack->lastConnectionId = 0;
  304. rack->usedConnections.clear();
  305. }
  306. }
  307. void clear()
  308. {
  309. isReady = false;
  310. inCount = 0;
  311. outCount = 0;
  312. if (usePatchbay)
  313. {
  314. CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
  315. delete patchbay;
  316. patchbay = nullptr;
  317. }
  318. else
  319. {
  320. CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);
  321. delete rack;
  322. rack = nullptr;
  323. }
  324. }
  325. void create(const uint32_t bufferSize)
  326. {
  327. if (usePatchbay)
  328. {
  329. CARLA_SAFE_ASSERT_RETURN(patchbay == nullptr,);
  330. patchbay = new EnginePatchbayBuffers(bufferSize);
  331. }
  332. else
  333. {
  334. CARLA_SAFE_ASSERT_RETURN(rack == nullptr,);
  335. rack = new EngineRackBuffers(bufferSize);
  336. }
  337. isReady = true;
  338. }
  339. void resize(const uint32_t bufferSize)
  340. {
  341. if (usePatchbay)
  342. {
  343. CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
  344. patchbay->resize(bufferSize);
  345. }
  346. else
  347. {
  348. CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);
  349. rack->resize(bufferSize);
  350. }
  351. }
  352. } bufAudio;
  353. #endif
  354. struct InternalEvents {
  355. EngineEvent* in;
  356. EngineEvent* out;
  357. InternalEvents() noexcept
  358. : in(nullptr),
  359. out(nullptr) {}
  360. ~InternalEvents()
  361. {
  362. CARLA_ASSERT(in == nullptr);
  363. CARLA_ASSERT(out == nullptr);
  364. }
  365. } bufEvents;
  366. struct InternalTime {
  367. bool playing;
  368. uint64_t frame;
  369. InternalTime() noexcept
  370. : playing(false),
  371. frame(0) {}
  372. } time;
  373. struct NextAction {
  374. EnginePostAction opcode;
  375. unsigned int pluginId;
  376. unsigned int value;
  377. CarlaMutex mutex;
  378. NextAction() noexcept
  379. : opcode(kEnginePostActionNull),
  380. pluginId(0),
  381. value(0) {}
  382. ~NextAction()
  383. {
  384. CARLA_ASSERT(opcode == kEnginePostActionNull);
  385. }
  386. void ready() noexcept
  387. {
  388. mutex.lock();
  389. mutex.unlock();
  390. }
  391. } nextAction;
  392. CarlaEngineProtectedData(CarlaEngine* const engine)
  393. : osc(engine),
  394. thread(engine),
  395. oscData(nullptr),
  396. callback(nullptr),
  397. callbackPtr(nullptr),
  398. hints(0x0),
  399. bufferSize(0),
  400. sampleRate(0.0),
  401. aboutToClose(false),
  402. curPluginCount(0),
  403. maxPluginNumber(0),
  404. nextPluginId(0),
  405. plugins(nullptr) {}
  406. #ifdef CARLA_PROPER_CPP11_SUPPORT
  407. CarlaEngineProtectedData() = delete;
  408. CARLA_DECLARE_NON_COPY_STRUCT(CarlaEngineProtectedData)
  409. #endif
  410. ~CarlaEngineProtectedData()
  411. {
  412. CARLA_ASSERT(curPluginCount == 0);
  413. CARLA_ASSERT(maxPluginNumber == 0);
  414. CARLA_ASSERT(nextPluginId == 0);
  415. CARLA_ASSERT(plugins == nullptr);
  416. }
  417. void doPluginRemove()
  418. {
  419. CARLA_ASSERT(curPluginCount > 0);
  420. CARLA_ASSERT(nextAction.pluginId < curPluginCount);
  421. --curPluginCount;
  422. // move all plugins 1 spot backwards
  423. for (unsigned int i=nextAction.pluginId; i < curPluginCount; ++i)
  424. {
  425. CarlaPlugin* const plugin(plugins[i+1].plugin);
  426. CARLA_SAFE_ASSERT_BREAK(plugin != nullptr);
  427. plugin->setId(i);
  428. plugins[i].plugin = plugin;
  429. plugins[i].insPeak[0] = 0.0f;
  430. plugins[i].insPeak[1] = 0.0f;
  431. plugins[i].outsPeak[0] = 0.0f;
  432. plugins[i].outsPeak[1] = 0.0f;
  433. }
  434. const unsigned int id(curPluginCount);
  435. // reset last plugin (now removed)
  436. plugins[id].plugin = nullptr;
  437. plugins[id].insPeak[0] = 0.0f;
  438. plugins[id].insPeak[1] = 0.0f;
  439. plugins[id].outsPeak[0] = 0.0f;
  440. plugins[id].outsPeak[1] = 0.0f;
  441. }
  442. void doPluginsSwitch()
  443. {
  444. CARLA_ASSERT(curPluginCount >= 2);
  445. const unsigned int idA(nextAction.pluginId);
  446. const unsigned int idB(nextAction.value);
  447. CARLA_ASSERT(idA < curPluginCount);
  448. CARLA_ASSERT(idB < curPluginCount);
  449. CARLA_ASSERT(plugins[idA].plugin != nullptr);
  450. CARLA_ASSERT(plugins[idB].plugin != nullptr);
  451. #if 0
  452. std::swap(plugins[idA].plugin, plugins[idB].plugin);
  453. #else
  454. CarlaPlugin* const tmp(plugins[idA].plugin);
  455. plugins[idA].plugin = plugins[idB].plugin;
  456. plugins[idB].plugin = tmp;
  457. #endif
  458. }
  459. void doNextPluginAction(const bool unlock) noexcept
  460. {
  461. switch (nextAction.opcode)
  462. {
  463. case kEnginePostActionNull:
  464. break;
  465. case kEnginePostActionZeroCount:
  466. curPluginCount = 0;
  467. break;
  468. case kEnginePostActionRemovePlugin:
  469. doPluginRemove();
  470. break;
  471. case kEnginePostActionSwitchPlugins:
  472. doPluginsSwitch();
  473. break;
  474. }
  475. nextAction.opcode = kEnginePostActionNull;
  476. nextAction.pluginId = 0;
  477. nextAction.value = 0;
  478. if (unlock)
  479. nextAction.mutex.unlock();
  480. }
  481. #ifndef BUILD_BRIDGE
  482. // the base, where plugins run
  483. void processRack(float* inBufReal[2], float* outBuf[2], const uint32_t nframes, const bool isOffline);
  484. // extended, will call processRack() in the middle
  485. void processRackFull(float** const inBuf, const uint32_t inCount, float** const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline);
  486. #endif
  487. class ScopedActionLock
  488. {
  489. public:
  490. ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const unsigned int pluginId, const unsigned int value, const bool lockWait)
  491. : fData(data)
  492. {
  493. fData->nextAction.mutex.lock();
  494. CARLA_ASSERT(fData->nextAction.opcode == kEnginePostActionNull);
  495. fData->nextAction.opcode = action;
  496. fData->nextAction.pluginId = pluginId;
  497. fData->nextAction.value = value;
  498. if (lockWait)
  499. {
  500. // block wait for unlock on processing side
  501. carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId);
  502. fData->nextAction.mutex.lock();
  503. carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId);
  504. }
  505. else
  506. {
  507. fData->doNextPluginAction(false);
  508. }
  509. }
  510. ~ScopedActionLock() noexcept
  511. {
  512. fData->nextAction.mutex.unlock();
  513. }
  514. private:
  515. CarlaEngineProtectedData* const fData;
  516. };
  517. };
  518. // -----------------------------------------------------------------------
  519. CARLA_BACKEND_END_NAMESPACE
  520. #endif // CARLA_ENGINE_INTERNAL_HPP_INCLUDED