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
31KB

  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. #include "CarlaEngineInternal.hpp"
  18. #include "CarlaPlugin.hpp"
  19. #include "CarlaMIDI.h"
  20. #include "CarlaMathUtils.hpp"
  21. // -----------------------------------------------------------------------
  22. CARLA_BACKEND_START_NAMESPACE
  23. #if 0
  24. } // Fix editor indentation
  25. #endif
  26. // -----------------------------------------------------------------------
  27. // EngineControlEvent
  28. void EngineControlEvent::dumpToMidiData(const uint8_t channel, uint8_t& size, uint8_t data[3]) const noexcept
  29. {
  30. size = 0;
  31. switch (type)
  32. {
  33. case kEngineControlEventTypeNull:
  34. break;
  35. case kEngineControlEventTypeParameter:
  36. if (param >= MAX_MIDI_VALUE)
  37. {
  38. // out of bounds. do nothing
  39. }
  40. else if (MIDI_IS_CONTROL_BANK_SELECT(param))
  41. {
  42. size = 3;
  43. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
  44. data[1] = MIDI_CONTROL_BANK_SELECT;
  45. data[2] = uint8_t(carla_fixValue<float>(0.0f, float(MAX_MIDI_VALUE-1), value));
  46. }
  47. else
  48. {
  49. size = 3;
  50. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
  51. data[1] = static_cast<uint8_t>(param);
  52. data[2] = uint8_t(carla_fixValue<float>(0.0f, 1.0f, value) * float(MAX_MIDI_VALUE-1));
  53. }
  54. break;
  55. case kEngineControlEventTypeMidiBank:
  56. size = 3;
  57. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
  58. data[1] = MIDI_CONTROL_BANK_SELECT;
  59. data[2] = uint8_t(carla_fixValue<uint16_t>(0, MAX_MIDI_VALUE-1, param));
  60. break;
  61. case kEngineControlEventTypeMidiProgram:
  62. size = 2;
  63. data[0] = static_cast<uint8_t>(MIDI_STATUS_PROGRAM_CHANGE | (channel & MIDI_CHANNEL_BIT));
  64. data[1] = uint8_t(carla_fixValue<uint16_t>(0, MAX_MIDI_VALUE-1, param));
  65. break;
  66. case kEngineControlEventTypeAllSoundOff:
  67. size = 2;
  68. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
  69. data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  70. break;
  71. case kEngineControlEventTypeAllNotesOff:
  72. size = 2;
  73. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
  74. data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  75. break;
  76. }
  77. }
  78. // -----------------------------------------------------------------------
  79. // EngineEvent
  80. void EngineEvent::fillFromMidiData(const uint8_t size, const uint8_t* const data) noexcept
  81. {
  82. if (size == 0 || data == nullptr || data[0] < MIDI_STATUS_NOTE_OFF)
  83. {
  84. type = kEngineEventTypeNull;
  85. channel = 0;
  86. return;
  87. }
  88. // get channel
  89. channel = uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data));
  90. // get status
  91. const uint8_t midiStatus(uint8_t(MIDI_GET_STATUS_FROM_DATA(data)));
  92. if (midiStatus == MIDI_STATUS_CONTROL_CHANGE)
  93. {
  94. type = kEngineEventTypeControl;
  95. const uint8_t midiControl(data[1]);
  96. if (MIDI_IS_CONTROL_BANK_SELECT(midiControl))
  97. {
  98. CARLA_SAFE_ASSERT_INT(size == 3, size);
  99. const uint8_t midiBank(data[2]);
  100. ctrl.type = kEngineControlEventTypeMidiBank;
  101. ctrl.param = midiBank;
  102. ctrl.value = 0.0f;
  103. }
  104. else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF)
  105. {
  106. CARLA_SAFE_ASSERT_INT(size == 2, size);
  107. ctrl.type = kEngineControlEventTypeAllSoundOff;
  108. ctrl.param = 0;
  109. ctrl.value = 0.0f;
  110. }
  111. else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF)
  112. {
  113. CARLA_SAFE_ASSERT_INT(size == 2, size);
  114. ctrl.type = kEngineControlEventTypeAllNotesOff;
  115. ctrl.param = 0;
  116. ctrl.value = 0.0f;
  117. }
  118. else
  119. {
  120. CARLA_SAFE_ASSERT_INT2(size == 3, size, midiControl);
  121. const uint8_t midiValue(carla_fixValue<uint8_t>(0, 127, data[2])); // ensures 0.0<->1.0 value range
  122. ctrl.type = kEngineControlEventTypeParameter;
  123. ctrl.param = midiControl;
  124. ctrl.value = float(midiValue)/127.0f;
  125. }
  126. }
  127. else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE)
  128. {
  129. CARLA_SAFE_ASSERT_INT2(size == 2, size, data[1]);
  130. type = kEngineEventTypeControl;
  131. const uint8_t midiProgram(data[1]);
  132. ctrl.type = kEngineControlEventTypeMidiProgram;
  133. ctrl.param = midiProgram;
  134. ctrl.value = 0.0f;
  135. }
  136. else
  137. {
  138. type = kEngineEventTypeMidi;
  139. midi.port = 0;
  140. midi.size = size;
  141. if (size > EngineMidiEvent::kDataSize)
  142. {
  143. midi.dataExt = data;
  144. std::memset(midi.data, 0, sizeof(uint8_t)*EngineMidiEvent::kDataSize);
  145. }
  146. else
  147. {
  148. midi.data[0] = midiStatus;
  149. uint8_t i=1;
  150. for (; i < midi.size; ++i)
  151. midi.data[i] = data[i];
  152. for (; i < EngineMidiEvent::kDataSize; ++i)
  153. midi.data[i] = 0;
  154. midi.dataExt = nullptr;
  155. }
  156. }
  157. }
  158. // -----------------------------------------------------------------------
  159. // EngineOptions
  160. EngineOptions::EngineOptions() noexcept
  161. #ifdef CARLA_OS_LINUX
  162. : processMode(ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS),
  163. transportMode(ENGINE_TRANSPORT_MODE_JACK),
  164. #else
  165. : processMode(ENGINE_PROCESS_MODE_CONTINUOUS_RACK),
  166. transportMode(ENGINE_TRANSPORT_MODE_INTERNAL),
  167. #endif
  168. forceStereo(false),
  169. preferPluginBridges(false),
  170. preferUiBridges(true),
  171. uisAlwaysOnTop(true),
  172. maxParameters(MAX_DEFAULT_PARAMETERS),
  173. uiBridgesTimeout(4000),
  174. audioNumPeriods(2),
  175. audioBufferSize(512),
  176. audioSampleRate(44100),
  177. audioDevice(nullptr),
  178. binaryDir(nullptr),
  179. resourceDir(nullptr),
  180. frontendWinId(0) {}
  181. EngineOptions::~EngineOptions() noexcept
  182. {
  183. if (audioDevice != nullptr)
  184. {
  185. delete[] audioDevice;
  186. audioDevice = nullptr;
  187. }
  188. if (binaryDir != nullptr)
  189. {
  190. delete[] binaryDir;
  191. binaryDir = nullptr;
  192. }
  193. if (resourceDir != nullptr)
  194. {
  195. delete[] resourceDir;
  196. resourceDir = nullptr;
  197. }
  198. }
  199. // -----------------------------------------------------------------------
  200. // EngineTimeInfoBBT
  201. EngineTimeInfoBBT::EngineTimeInfoBBT() noexcept
  202. : bar(0),
  203. beat(0),
  204. tick(0),
  205. barStartTick(0.0),
  206. beatsPerBar(0.0f),
  207. beatType(0.0f),
  208. ticksPerBeat(0.0),
  209. beatsPerMinute(0.0) {}
  210. // -----------------------------------------------------------------------
  211. // EngineTimeInfo
  212. EngineTimeInfo::EngineTimeInfo() noexcept
  213. : playing(false),
  214. frame(0),
  215. usecs(0),
  216. valid(0x0) {}
  217. void EngineTimeInfo::clear() noexcept
  218. {
  219. playing = false;
  220. frame = 0;
  221. usecs = 0;
  222. valid = 0x0;
  223. }
  224. bool EngineTimeInfo::operator==(const EngineTimeInfo& timeInfo) const noexcept
  225. {
  226. if (timeInfo.playing != playing || timeInfo.frame != frame || timeInfo.valid != valid)
  227. return false;
  228. if ((valid & kValidBBT) == 0)
  229. return true;
  230. if (timeInfo.bbt.beatsPerMinute != bbt.beatsPerMinute)
  231. return false;
  232. return true;
  233. }
  234. bool EngineTimeInfo::operator!=(const EngineTimeInfo& timeInfo) const noexcept
  235. {
  236. return !operator==(timeInfo);
  237. }
  238. // -----------------------------------------------------------------------
  239. // EngineRackBuffers
  240. EngineRackBuffers::EngineRackBuffers(const uint32_t bufferSize)
  241. : lastConnectionId(0)
  242. {
  243. resize(bufferSize);
  244. }
  245. EngineRackBuffers::~EngineRackBuffers() noexcept
  246. {
  247. clear();
  248. }
  249. void EngineRackBuffers::clear() noexcept
  250. {
  251. lastConnectionId = 0;
  252. if (in[0] != nullptr)
  253. {
  254. delete[] in[0];
  255. in[0] = nullptr;
  256. }
  257. if (in[1] != nullptr)
  258. {
  259. delete[] in[1];
  260. in[1] = nullptr;
  261. }
  262. if (out[0] != nullptr)
  263. {
  264. delete[] out[0];
  265. out[0] = nullptr;
  266. }
  267. if (out[1] != nullptr)
  268. {
  269. delete[] out[1];
  270. out[1] = nullptr;
  271. }
  272. connectedIn1.clear();
  273. connectedIn2.clear();
  274. connectedOut1.clear();
  275. connectedOut2.clear();
  276. usedConnections.clear();
  277. }
  278. void EngineRackBuffers::resize(const uint32_t bufferSize)
  279. {
  280. if (bufferSize > 0)
  281. {
  282. in[0] = new float[bufferSize];
  283. in[1] = new float[bufferSize];
  284. out[0] = new float[bufferSize];
  285. out[1] = new float[bufferSize];
  286. }
  287. else
  288. {
  289. in[0] = nullptr;
  290. in[1] = nullptr;
  291. out[0] = nullptr;
  292. out[1] = nullptr;
  293. }
  294. }
  295. bool EngineRackBuffers::connect(CarlaEngine* const engine, const int groupA, const int portA, const int groupB, const int portB) noexcept
  296. {
  297. CARLA_SAFE_ASSERT_RETURN(engine != nullptr, false);
  298. CARLA_SAFE_ASSERT_RETURN(groupA != groupB, false);
  299. CARLA_SAFE_ASSERT_RETURN(groupA >= RACK_PATCHBAY_GROUP_CARLA && groupA < RACK_PATCHBAY_GROUP_MAX, false);
  300. CARLA_SAFE_ASSERT_RETURN(groupB >= RACK_PATCHBAY_GROUP_CARLA && groupB < RACK_PATCHBAY_GROUP_MAX, false);
  301. CARLA_SAFE_ASSERT_RETURN(portA >= 0, false);
  302. CARLA_SAFE_ASSERT_RETURN(portB >= 0, false);
  303. int carlaPort, otherPort;
  304. if (groupA == RACK_PATCHBAY_GROUP_CARLA)
  305. {
  306. carlaPort = portA;
  307. otherPort = portB;
  308. }
  309. else
  310. {
  311. CARLA_SAFE_ASSERT_RETURN(groupB == RACK_PATCHBAY_GROUP_CARLA, false);
  312. carlaPort = portB;
  313. otherPort = portA;
  314. }
  315. bool makeConnection = false;
  316. switch (carlaPort)
  317. {
  318. case RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1:
  319. connectLock.enter();
  320. connectedIn1.append(otherPort);
  321. connectLock.leave();
  322. makeConnection = true;
  323. break;
  324. case RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2:
  325. connectLock.enter();
  326. connectedIn2.append(otherPort);
  327. connectLock.leave();
  328. makeConnection = true;
  329. break;
  330. case RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1:
  331. connectLock.enter();
  332. connectedOut1.append(otherPort);
  333. connectLock.leave();
  334. makeConnection = true;
  335. break;
  336. case RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2:
  337. connectLock.enter();
  338. connectedOut2.append(otherPort);
  339. connectLock.leave();
  340. makeConnection = true;
  341. break;
  342. case RACK_PATCHBAY_CARLA_PORT_MIDI_IN:
  343. makeConnection = engine->connectRackMidiInPort(otherPort);
  344. break;
  345. case RACK_PATCHBAY_CARLA_PORT_MIDI_OUT:
  346. makeConnection = engine->connectRackMidiOutPort(otherPort);
  347. break;
  348. }
  349. if (! makeConnection)
  350. {
  351. engine->setLastError("Invalid rack connection");
  352. return false;
  353. }
  354. ConnectionToId connectionToId;
  355. connectionToId.id = lastConnectionId;
  356. connectionToId.groupA = groupA;
  357. connectionToId.portA = portA;
  358. connectionToId.groupB = groupB;
  359. connectionToId.portB = portB;
  360. char strBuf[STR_MAX+1];
  361. strBuf[STR_MAX] = '\0';
  362. std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", groupA, portA, groupB, portB);
  363. engine->callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, lastConnectionId, 0, 0, 0.0f, strBuf);
  364. usedConnections.append(connectionToId);
  365. ++lastConnectionId;
  366. return true;
  367. }
  368. const char* const* EngineRackBuffers::getConnections() const
  369. {
  370. if (usedConnections.count() == 0)
  371. return nullptr;
  372. LinkedList<const char*> connList;
  373. char strBuf[STR_MAX+1];
  374. for (LinkedList<ConnectionToId>::Itenerator it=usedConnections.begin(); it.valid(); it.next())
  375. {
  376. const ConnectionToId& connection(it.getValue());
  377. CARLA_SAFE_ASSERT_CONTINUE(connection.groupA != connection.groupB);
  378. CARLA_SAFE_ASSERT_CONTINUE(connection.groupA >= RACK_PATCHBAY_GROUP_CARLA && connection.groupA < RACK_PATCHBAY_GROUP_MAX);
  379. CARLA_SAFE_ASSERT_CONTINUE(connection.groupB >= RACK_PATCHBAY_GROUP_CARLA && connection.groupB < RACK_PATCHBAY_GROUP_MAX);
  380. CARLA_SAFE_ASSERT_CONTINUE(connection.portA >= 0);
  381. CARLA_SAFE_ASSERT_CONTINUE(connection.portB >= 0);
  382. int carlaPort, otherPort;
  383. if (connection.groupA == RACK_PATCHBAY_GROUP_CARLA)
  384. {
  385. carlaPort = connection.portA;
  386. otherPort = connection.portB;
  387. }
  388. else
  389. {
  390. CARLA_SAFE_ASSERT_CONTINUE(connection.groupB == RACK_PATCHBAY_GROUP_CARLA);
  391. carlaPort = connection.portB;
  392. otherPort = connection.portA;
  393. }
  394. switch (carlaPort)
  395. {
  396. case RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1:
  397. case RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2:
  398. std::sprintf(strBuf, "AudioIn:%i", otherPort+1);
  399. connList.append(carla_strdup(strBuf));
  400. connList.append(carla_strdup((carlaPort == RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1) ? "Carla:AudioIn1" : "Carla:AudioIn2"));
  401. break;
  402. case RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1:
  403. case RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2:
  404. connList.append(carla_strdup((carlaPort == RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1) ? "Carla:AudioOut1" : "Carla:AudioOut2"));
  405. std::sprintf(strBuf, "AudioOut:%i", otherPort+1);
  406. connList.append(carla_strdup(strBuf));
  407. break;
  408. case RACK_PATCHBAY_CARLA_PORT_MIDI_IN:
  409. std::sprintf(strBuf, "MidiIn:%i", otherPort+1);
  410. connList.append(carla_strdup(strBuf));
  411. connList.append(carla_strdup("Carla:MidiIn"));
  412. break;
  413. case RACK_PATCHBAY_CARLA_PORT_MIDI_OUT:
  414. connList.append(carla_strdup("Carla:MidiOut"));
  415. std::sprintf(strBuf, "MidiOut:%i", otherPort+1);
  416. connList.append(carla_strdup(strBuf));
  417. break;
  418. }
  419. }
  420. const size_t connCount(connList.count());
  421. if (connCount == 0)
  422. return nullptr;
  423. const char** const retConns = new const char*[connCount+1];
  424. for (size_t i=0; i < connCount; ++i)
  425. retConns[i] = connList.getAt(i);
  426. retConns[connCount] = nullptr;
  427. connList.clear();
  428. return retConns;
  429. }
  430. // -----------------------------------------------------------------------
  431. // EnginePatchbayBuffers
  432. EnginePatchbayBuffers::EnginePatchbayBuffers(const uint32_t bufferSize)
  433. {
  434. resize(bufferSize);
  435. }
  436. EnginePatchbayBuffers::~EnginePatchbayBuffers() noexcept
  437. {
  438. clear();
  439. }
  440. void EnginePatchbayBuffers::clear() noexcept
  441. {
  442. }
  443. void EnginePatchbayBuffers::resize(const uint32_t /*bufferSize*/)
  444. {
  445. }
  446. bool EnginePatchbayBuffers::connect(CarlaEngine* const engine, const int, const int, const int, const int) noexcept
  447. {
  448. CARLA_SAFE_ASSERT_RETURN(engine != nullptr, false);
  449. return false;
  450. }
  451. const char* const* EnginePatchbayBuffers::getConnections() const
  452. {
  453. return nullptr;
  454. }
  455. // -----------------------------------------------------------------------
  456. // InternalAudio
  457. EngineInternalAudio::EngineInternalAudio() noexcept
  458. : isReady(false),
  459. usePatchbay(false),
  460. inCount(0),
  461. outCount(0)
  462. {
  463. rack = nullptr;
  464. }
  465. EngineInternalAudio::~EngineInternalAudio() noexcept
  466. {
  467. CARLA_SAFE_ASSERT(! isReady);
  468. CARLA_SAFE_ASSERT(rack == nullptr);
  469. }
  470. void EngineInternalAudio::initPatchbay() noexcept
  471. {
  472. if (usePatchbay)
  473. {
  474. CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
  475. // TODO
  476. }
  477. else
  478. {
  479. CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);
  480. rack->lastConnectionId = 0;
  481. rack->usedConnections.clear();
  482. }
  483. }
  484. void EngineInternalAudio::clear() noexcept
  485. {
  486. isReady = false;
  487. inCount = 0;
  488. outCount = 0;
  489. if (usePatchbay)
  490. {
  491. CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
  492. delete patchbay;
  493. patchbay = nullptr;
  494. }
  495. else
  496. {
  497. CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);
  498. delete rack;
  499. rack = nullptr;
  500. }
  501. }
  502. void EngineInternalAudio::create(const uint32_t bufferSize)
  503. {
  504. if (usePatchbay)
  505. {
  506. CARLA_SAFE_ASSERT_RETURN(patchbay == nullptr,);
  507. patchbay = new EnginePatchbayBuffers(bufferSize);
  508. }
  509. else
  510. {
  511. CARLA_SAFE_ASSERT_RETURN(rack == nullptr,);
  512. rack = new EngineRackBuffers(bufferSize);
  513. }
  514. isReady = true;
  515. }
  516. void EngineInternalAudio::resize(const uint32_t bufferSize)
  517. {
  518. if (usePatchbay)
  519. {
  520. CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
  521. patchbay->resize(bufferSize);
  522. }
  523. else
  524. {
  525. CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);
  526. rack->resize(bufferSize);
  527. }
  528. }
  529. bool EngineInternalAudio::connect(CarlaEngine* const engine, const int groupA, const int portA, const int groupB, const int portB) noexcept
  530. {
  531. if (usePatchbay)
  532. {
  533. CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr, nullptr);
  534. return patchbay->connect(engine, groupA, portA, groupB, portB);
  535. }
  536. else
  537. {
  538. CARLA_SAFE_ASSERT_RETURN(rack != nullptr, nullptr);
  539. return rack->connect(engine, groupA, portA, groupB, portB);
  540. }
  541. }
  542. const char* const* EngineInternalAudio::getConnections() const
  543. {
  544. if (usePatchbay)
  545. {
  546. CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr, nullptr);
  547. return patchbay->getConnections();
  548. }
  549. else
  550. {
  551. CARLA_SAFE_ASSERT_RETURN(rack != nullptr, nullptr);
  552. return rack->getConnections();
  553. }
  554. }
  555. // -----------------------------------------------------------------------
  556. // InternalEvents
  557. EngineInternalEvents::EngineInternalEvents() noexcept
  558. : in(nullptr),
  559. out(nullptr) {}
  560. EngineInternalEvents::~EngineInternalEvents() noexcept
  561. {
  562. CARLA_SAFE_ASSERT(in == nullptr);
  563. CARLA_SAFE_ASSERT(out == nullptr);
  564. }
  565. // -----------------------------------------------------------------------
  566. // InternalTime
  567. EngineInternalTime::EngineInternalTime() noexcept
  568. : playing(false),
  569. frame(0) {}
  570. // -----------------------------------------------------------------------
  571. // NextAction
  572. EngineNextAction::EngineNextAction() noexcept
  573. : opcode(kEnginePostActionNull),
  574. pluginId(0),
  575. value(0) {}
  576. EngineNextAction::~EngineNextAction() noexcept
  577. {
  578. CARLA_SAFE_ASSERT(opcode == kEnginePostActionNull);
  579. }
  580. void EngineNextAction::ready() noexcept
  581. {
  582. mutex.lock();
  583. mutex.unlock();
  584. }
  585. // -----------------------------------------------------------------------
  586. // EnginePluginData
  587. void EnginePluginData::clear() noexcept
  588. {
  589. plugin = nullptr;
  590. insPeak[0] = insPeak[1] = 0.0f;
  591. outsPeak[0] = outsPeak[1] = 0.0f;
  592. }
  593. // -----------------------------------------------------------------------
  594. // CarlaEngineProtectedData
  595. CarlaEngineProtectedData::CarlaEngineProtectedData(CarlaEngine* const engine)
  596. : osc(engine),
  597. thread(engine),
  598. oscData(nullptr),
  599. callback(nullptr),
  600. callbackPtr(nullptr),
  601. fileCallback(nullptr),
  602. fileCallbackPtr(nullptr),
  603. hints(0x0),
  604. bufferSize(0),
  605. sampleRate(0.0),
  606. aboutToClose(false),
  607. curPluginCount(0),
  608. maxPluginNumber(0),
  609. nextPluginId(0),
  610. plugins(nullptr) {}
  611. CarlaEngineProtectedData::~CarlaEngineProtectedData() noexcept
  612. {
  613. CARLA_SAFE_ASSERT(curPluginCount == 0);
  614. CARLA_SAFE_ASSERT(maxPluginNumber == 0);
  615. CARLA_SAFE_ASSERT(nextPluginId == 0);
  616. CARLA_SAFE_ASSERT(plugins == nullptr);
  617. }
  618. // -----------------------------------------------------------------------
  619. void CarlaEngineProtectedData::doPluginRemove() noexcept
  620. {
  621. CARLA_SAFE_ASSERT_RETURN(curPluginCount > 0,);
  622. CARLA_SAFE_ASSERT_RETURN(nextAction.pluginId < curPluginCount,);
  623. --curPluginCount;
  624. // move all plugins 1 spot backwards
  625. for (unsigned int i=nextAction.pluginId; i < curPluginCount; ++i)
  626. {
  627. CarlaPlugin* const plugin(plugins[i+1].plugin);
  628. CARLA_SAFE_ASSERT_BREAK(plugin != nullptr);
  629. plugin->setId(i);
  630. plugins[i].plugin = plugin;
  631. plugins[i].insPeak[0] = 0.0f;
  632. plugins[i].insPeak[1] = 0.0f;
  633. plugins[i].outsPeak[0] = 0.0f;
  634. plugins[i].outsPeak[1] = 0.0f;
  635. }
  636. const unsigned int id(curPluginCount);
  637. // reset last plugin (now removed)
  638. plugins[id].plugin = nullptr;
  639. plugins[id].insPeak[0] = 0.0f;
  640. plugins[id].insPeak[1] = 0.0f;
  641. plugins[id].outsPeak[0] = 0.0f;
  642. plugins[id].outsPeak[1] = 0.0f;
  643. }
  644. void CarlaEngineProtectedData::doPluginsSwitch() noexcept
  645. {
  646. CARLA_SAFE_ASSERT_RETURN(curPluginCount >= 2,);
  647. const unsigned int idA(nextAction.pluginId);
  648. const unsigned int idB(nextAction.value);
  649. CARLA_SAFE_ASSERT_RETURN(idA < curPluginCount,);
  650. CARLA_SAFE_ASSERT_RETURN(idB < curPluginCount,);
  651. CARLA_SAFE_ASSERT_RETURN(plugins[idA].plugin != nullptr,);
  652. CARLA_SAFE_ASSERT_RETURN(plugins[idB].plugin != nullptr,);
  653. #if 0
  654. std::swap(plugins[idA].plugin, plugins[idB].plugin);
  655. #else
  656. CarlaPlugin* const tmp(plugins[idA].plugin);
  657. plugins[idA].plugin = plugins[idB].plugin;
  658. plugins[idB].plugin = tmp;
  659. #endif
  660. }
  661. void CarlaEngineProtectedData::doNextPluginAction(const bool unlock) noexcept
  662. {
  663. switch (nextAction.opcode)
  664. {
  665. case kEnginePostActionNull:
  666. break;
  667. case kEnginePostActionZeroCount:
  668. curPluginCount = 0;
  669. break;
  670. case kEnginePostActionRemovePlugin:
  671. doPluginRemove();
  672. break;
  673. case kEnginePostActionSwitchPlugins:
  674. doPluginsSwitch();
  675. break;
  676. }
  677. nextAction.opcode = kEnginePostActionNull;
  678. nextAction.pluginId = 0;
  679. nextAction.value = 0;
  680. if (unlock)
  681. nextAction.mutex.unlock();
  682. }
  683. // -----------------------------------------------------------------------
  684. #ifndef BUILD_BRIDGE
  685. void CarlaEngineProtectedData::processRack(float* inBufReal[2], float* outBuf[2], const uint32_t frames, const bool isOffline)
  686. {
  687. CARLA_SAFE_ASSERT_RETURN(bufEvents.in != nullptr,);
  688. CARLA_SAFE_ASSERT_RETURN(bufEvents.out != nullptr,);
  689. // safe copy
  690. float inBuf0[frames];
  691. float inBuf1[frames];
  692. float* inBuf[2] = { inBuf0, inBuf1 };
  693. // initialize audio inputs
  694. FLOAT_COPY(inBuf0, inBufReal[0], frames);
  695. FLOAT_COPY(inBuf1, inBufReal[1], frames);
  696. // initialize audio outputs (zero)
  697. FLOAT_CLEAR(outBuf[0], frames);
  698. FLOAT_CLEAR(outBuf[1], frames);
  699. // initialize event outputs (zero)
  700. carla_zeroStruct<EngineEvent>(bufEvents.out, kMaxEngineEventInternalCount);
  701. bool processed = false;
  702. uint32_t oldAudioInCount = 0;
  703. uint32_t oldMidiOutCount = 0;
  704. // process plugins
  705. for (unsigned int i=0; i < curPluginCount; ++i)
  706. {
  707. CarlaPlugin* const plugin = plugins[i].plugin;
  708. if (plugin == nullptr || ! plugin->isEnabled() || ! plugin->tryLock(isOffline))
  709. continue;
  710. if (processed)
  711. {
  712. // initialize audio inputs (from previous outputs)
  713. FLOAT_COPY(inBuf0, outBuf[0], frames);
  714. FLOAT_COPY(inBuf1, outBuf[1], frames);
  715. // initialize audio outputs (zero)
  716. FLOAT_CLEAR(outBuf[0], frames);
  717. FLOAT_CLEAR(outBuf[1], frames);
  718. // if plugin has no midi out, add previous events
  719. if (oldMidiOutCount == 0 && bufEvents.in[0].type != kEngineEventTypeNull)
  720. {
  721. if (bufEvents.out[0].type != kEngineEventTypeNull)
  722. {
  723. // TODO: carefully add to input, sorted events
  724. }
  725. // else nothing needed
  726. }
  727. else
  728. {
  729. // initialize event inputs from previous outputs
  730. carla_copyStruct<EngineEvent>(bufEvents.in, bufEvents.out, kMaxEngineEventInternalCount);
  731. // initialize event outputs (zero)
  732. carla_zeroStruct<EngineEvent>(bufEvents.out, kMaxEngineEventInternalCount);
  733. }
  734. }
  735. oldAudioInCount = plugin->getAudioInCount();
  736. oldMidiOutCount = plugin->getMidiOutCount();
  737. // process
  738. plugin->initBuffers();
  739. plugin->process(inBuf, outBuf, frames);
  740. plugin->unlock();
  741. // if plugin has no audio inputs, add input buffer
  742. if (oldAudioInCount == 0)
  743. {
  744. FLOAT_ADD(outBuf[0], inBuf0, frames);
  745. FLOAT_ADD(outBuf[1], inBuf1, frames);
  746. }
  747. // set peaks
  748. {
  749. EnginePluginData& pluginData(plugins[i]);
  750. #ifdef HAVE_JUCE
  751. float tmpMin, tmpMax;
  752. if (oldAudioInCount > 0)
  753. {
  754. FloatVectorOperations::findMinAndMax(inBuf0, static_cast<int>(frames), tmpMin, tmpMax);
  755. pluginData.insPeak[0] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);
  756. FloatVectorOperations::findMinAndMax(inBuf1, static_cast<int>(frames), tmpMin, tmpMax);
  757. pluginData.insPeak[1] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);
  758. }
  759. else
  760. {
  761. pluginData.insPeak[0] = 0.0f;
  762. pluginData.insPeak[1] = 0.0f;
  763. }
  764. if (plugin->getAudioOutCount() > 0)
  765. {
  766. FloatVectorOperations::findMinAndMax(outBuf[0], static_cast<int>(frames), tmpMin, tmpMax);
  767. pluginData.outsPeak[0] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);
  768. FloatVectorOperations::findMinAndMax(outBuf[1], static_cast<int>(frames), tmpMin, tmpMax);
  769. pluginData.outsPeak[1] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);
  770. }
  771. else
  772. {
  773. pluginData.outsPeak[0] = 0.0f;
  774. pluginData.outsPeak[1] = 0.0f;
  775. }
  776. #else
  777. float peak1, peak2;
  778. if (oldAudioInCount > 0)
  779. {
  780. peak1 = peak2 = 0.0f;
  781. for (uint32_t k=0; k < frames; ++k)
  782. {
  783. peak1 = carla_max<float>(peak1, std::fabs(inBuf0[k]), 1.0f);
  784. peak2 = carla_max<float>(peak2, std::fabs(inBuf1[k]), 1.0f);
  785. }
  786. pluginData.insPeak[0] = peak1;
  787. pluginData.insPeak[1] = peak2;
  788. }
  789. else
  790. {
  791. pluginData.insPeak[0] = 0.0f;
  792. pluginData.insPeak[1] = 0.0f;
  793. }
  794. if (plugin->getAudioOutCount() > 0)
  795. {
  796. peak1 = peak2 = 0.0f;
  797. for (uint32_t k=0; k < frames; ++k)
  798. {
  799. peak1 = carla_max<float>(peak1, std::fabs(outBuf[0][k]), 1.0f);
  800. peak2 = carla_max<float>(peak2, std::fabs(outBuf[1][k]), 1.0f);
  801. }
  802. pluginData.outsPeak[0] = peak1;
  803. pluginData.outsPeak[1] = peak2;
  804. }
  805. else
  806. {
  807. pluginData.outsPeak[0] = 0.0f;
  808. pluginData.outsPeak[1] = 0.0f;
  809. }
  810. #endif
  811. }
  812. processed = true;
  813. }
  814. }
  815. void CarlaEngineProtectedData::processRackFull(float** const inBuf, const uint32_t inCount, float** const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline)
  816. {
  817. EngineRackBuffers* const rack(bufAudio.rack);
  818. const CarlaCriticalSectionScope _cs2(rack->connectLock);
  819. // connect input buffers
  820. if (rack->connectedIn1.count() == 0)
  821. {
  822. FLOAT_CLEAR(rack->in[0], nframes);
  823. }
  824. else
  825. {
  826. bool first = true;
  827. for (LinkedList<int>::Itenerator it = rack->connectedIn1.begin(); it.valid(); it.next())
  828. {
  829. const int& port(it.getValue());
  830. CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(inCount));
  831. if (first)
  832. {
  833. FLOAT_COPY(rack->in[0], inBuf[port], nframes);
  834. first = false;
  835. }
  836. else
  837. {
  838. FLOAT_ADD(rack->in[0], inBuf[port], nframes);
  839. }
  840. }
  841. if (first)
  842. FLOAT_CLEAR(rack->in[0], nframes);
  843. }
  844. if (rack->connectedIn2.count() == 0)
  845. {
  846. FLOAT_CLEAR(rack->in[1], nframes);
  847. }
  848. else
  849. {
  850. bool first = true;
  851. for (LinkedList<int>::Itenerator it = rack->connectedIn2.begin(); it.valid(); it.next())
  852. {
  853. const int& port(it.getValue());
  854. CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(inCount));
  855. if (first)
  856. {
  857. FLOAT_COPY(rack->in[1], inBuf[port], nframes);
  858. first = false;
  859. }
  860. else
  861. {
  862. FLOAT_ADD(rack->in[1], inBuf[port], nframes);
  863. }
  864. }
  865. if (first)
  866. FLOAT_CLEAR(rack->in[1], nframes);
  867. }
  868. FLOAT_CLEAR(rack->out[0], nframes);
  869. FLOAT_CLEAR(rack->out[1], nframes);
  870. // process
  871. processRack(rack->in, rack->out, nframes, isOffline);
  872. // connect output buffers
  873. if (rack->connectedOut1.count() != 0)
  874. {
  875. for (LinkedList<int>::Itenerator it = rack->connectedOut1.begin(); it.valid(); it.next())
  876. {
  877. const int& port(it.getValue());
  878. CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(outCount));
  879. FLOAT_ADD(outBuf[port], rack->out[0], nframes);
  880. }
  881. }
  882. if (rack->connectedOut2.count() != 0)
  883. {
  884. for (LinkedList<int>::Itenerator it = rack->connectedOut2.begin(); it.valid(); it.next())
  885. {
  886. const int& port(it.getValue());
  887. CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(outCount));
  888. FLOAT_ADD(outBuf[port], rack->out[1], nframes);
  889. }
  890. }
  891. }
  892. #endif
  893. // -----------------------------------------------------------------------
  894. // ScopedActionLock
  895. CarlaEngineProtectedData::ScopedActionLock::ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const unsigned int pluginId, const unsigned int value, const bool lockWait) noexcept
  896. : fData(data)
  897. {
  898. fData->nextAction.mutex.lock();
  899. CARLA_SAFE_ASSERT_RETURN(fData->nextAction.opcode == kEnginePostActionNull,);
  900. fData->nextAction.opcode = action;
  901. fData->nextAction.pluginId = pluginId;
  902. fData->nextAction.value = value;
  903. if (lockWait)
  904. {
  905. // block wait for unlock on processing side
  906. carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId);
  907. fData->nextAction.mutex.lock();
  908. carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId);
  909. }
  910. else
  911. {
  912. fData->doNextPluginAction(false);
  913. }
  914. }
  915. CarlaEngineProtectedData::ScopedActionLock::~ScopedActionLock() noexcept
  916. {
  917. fData->nextAction.mutex.unlock();
  918. }
  919. // -----------------------------------------------------------------------
  920. CARLA_BACKEND_END_NAMESPACE