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.

CarlaEngineData.cpp 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2021 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 "CarlaEngine.hpp"
  18. #include "CarlaMathUtils.hpp"
  19. #include "CarlaMIDI.h"
  20. CARLA_BACKEND_START_NAMESPACE
  21. // -----------------------------------------------------------------------
  22. // EngineControlEvent
  23. uint8_t EngineControlEvent::convertToMidiData(const uint8_t channel, uint8_t data[3]) const noexcept
  24. {
  25. switch (type)
  26. {
  27. case kEngineControlEventTypeNull:
  28. break;
  29. case kEngineControlEventTypeParameter:
  30. CARLA_SAFE_ASSERT_RETURN(param < MAX_MIDI_VALUE, 0);
  31. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
  32. if (MIDI_IS_CONTROL_BANK_SELECT(param))
  33. {
  34. data[1] = MIDI_CONTROL_BANK_SELECT;
  35. if (midiValue >= 0)
  36. data[2] = uint8_t(midiValue);
  37. else
  38. data[2] = uint8_t(carla_fixedValue<float>(0.0f, static_cast<float>(MAX_MIDI_VALUE-1), normalizedValue));
  39. }
  40. else
  41. {
  42. data[1] = static_cast<uint8_t>(param);
  43. if (midiValue >= 0)
  44. data[2] = uint8_t(midiValue);
  45. else
  46. data[2] = uint8_t(carla_fixedValue<float>(0.0f, 1.0f, normalizedValue) * static_cast<float>(MAX_MIDI_VALUE-1) + 0.5f);
  47. }
  48. return 3;
  49. case kEngineControlEventTypeMidiBank:
  50. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
  51. data[1] = MIDI_CONTROL_BANK_SELECT;
  52. data[2] = uint8_t(carla_fixedValue<uint16_t>(0, MAX_MIDI_VALUE-1, param));
  53. return 3;
  54. case kEngineControlEventTypeMidiProgram:
  55. data[0] = static_cast<uint8_t>(MIDI_STATUS_PROGRAM_CHANGE | (channel & MIDI_CHANNEL_BIT));
  56. data[1] = uint8_t(carla_fixedValue<uint16_t>(0, MAX_MIDI_VALUE-1, param));
  57. return 2;
  58. case kEngineControlEventTypeAllSoundOff:
  59. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
  60. data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  61. return 2;
  62. case kEngineControlEventTypeAllNotesOff:
  63. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
  64. data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  65. return 2;
  66. }
  67. return 0;
  68. }
  69. // -----------------------------------------------------------------------
  70. // EngineEvent
  71. void EngineEvent::fillFromMidiData(const uint8_t size, const uint8_t* const data, const uint8_t midiPortOffset) noexcept
  72. {
  73. if (size == 0 || data == nullptr || data[0] < MIDI_STATUS_NOTE_OFF)
  74. {
  75. type = kEngineEventTypeNull;
  76. channel = 0;
  77. return;
  78. }
  79. // get channel
  80. channel = uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data));
  81. // get status
  82. const uint8_t midiStatus(uint8_t(MIDI_GET_STATUS_FROM_DATA(data)));
  83. if (midiStatus == MIDI_STATUS_CONTROL_CHANGE)
  84. {
  85. CARLA_SAFE_ASSERT_RETURN(size >= 2,);
  86. type = kEngineEventTypeControl;
  87. const uint8_t midiControl(data[1]);
  88. if (MIDI_IS_CONTROL_BANK_SELECT(midiControl))
  89. {
  90. CARLA_SAFE_ASSERT_RETURN(size >= 3,);
  91. const uint8_t midiBank(data[2]);
  92. ctrl.type = kEngineControlEventTypeMidiBank;
  93. ctrl.param = midiBank;
  94. ctrl.midiValue = -1;
  95. ctrl.normalizedValue = 0.0f;
  96. ctrl.handled = true;
  97. }
  98. else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF)
  99. {
  100. ctrl.type = kEngineControlEventTypeAllSoundOff;
  101. ctrl.param = 0;
  102. ctrl.midiValue = -1;
  103. ctrl.normalizedValue = 0.0f;
  104. ctrl.handled = true;
  105. }
  106. else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF)
  107. {
  108. ctrl.type = kEngineControlEventTypeAllNotesOff;
  109. ctrl.param = 0;
  110. ctrl.midiValue = -1;
  111. ctrl.normalizedValue = 0.0f;
  112. ctrl.handled = true;
  113. }
  114. else
  115. {
  116. CARLA_SAFE_ASSERT_RETURN(size >= 3,);
  117. // ensures 0.0<->1.0 value range
  118. const int8_t midiValue = static_cast<int8_t>(carla_fixedValue<uint8_t>(0, 127, data[2]));
  119. ctrl.type = kEngineControlEventTypeParameter;
  120. ctrl.param = midiControl;
  121. ctrl.midiValue = midiValue;
  122. ctrl.normalizedValue = float(midiValue)/127.0f;
  123. ctrl.handled = false;
  124. }
  125. }
  126. else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE)
  127. {
  128. CARLA_SAFE_ASSERT_RETURN(size >= 2,);
  129. type = kEngineEventTypeControl;
  130. const uint8_t midiProgram(data[1]);
  131. ctrl.type = kEngineControlEventTypeMidiProgram;
  132. ctrl.param = midiProgram;
  133. ctrl.midiValue = -1;
  134. ctrl.normalizedValue = 0.0f;
  135. ctrl.handled = true;
  136. }
  137. else
  138. {
  139. type = kEngineEventTypeMidi;
  140. midi.port = midiPortOffset;
  141. midi.size = size;
  142. if (size > EngineMidiEvent::kDataSize)
  143. {
  144. midi.dataExt = data;
  145. std::memset(midi.data, 0, sizeof(uint8_t)*EngineMidiEvent::kDataSize);
  146. }
  147. else
  148. {
  149. midi.data[0] = midiStatus;
  150. uint8_t i=1;
  151. for (; i < size; ++i)
  152. midi.data[i] = data[i];
  153. for (; i < EngineMidiEvent::kDataSize; ++i)
  154. midi.data[i] = 0;
  155. midi.dataExt = nullptr;
  156. }
  157. }
  158. }
  159. // -----------------------------------------------------------------------
  160. // EngineOptions
  161. EngineOptions::EngineOptions() noexcept
  162. #ifdef CARLA_OS_LINUX
  163. : processMode(ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS),
  164. transportMode(ENGINE_TRANSPORT_MODE_JACK),
  165. #else
  166. : processMode(ENGINE_PROCESS_MODE_PATCHBAY),
  167. transportMode(ENGINE_TRANSPORT_MODE_INTERNAL),
  168. #endif
  169. transportExtra(nullptr),
  170. forceStereo(false),
  171. resetXruns(false),
  172. preferPluginBridges(false),
  173. #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
  174. preferUiBridges(false),
  175. #else
  176. preferUiBridges(true),
  177. #endif
  178. uisAlwaysOnTop(true),
  179. pluginsAreStandalone(false),
  180. bgColor(0x000000ff),
  181. fgColor(0xffffffff),
  182. uiScale(1.0f),
  183. maxParameters(MAX_DEFAULT_PARAMETERS),
  184. uiBridgesTimeout(4000),
  185. audioBufferSize(512),
  186. audioSampleRate(44100),
  187. audioTripleBuffer(false),
  188. audioDriver(nullptr),
  189. audioDevice(nullptr),
  190. #ifndef BUILD_BRIDGE
  191. # ifdef CARLA_OS_WIN
  192. oscEnabled(false),
  193. # else
  194. oscEnabled(true),
  195. # endif
  196. oscPortTCP(22752),
  197. oscPortUDP(22752),
  198. #endif
  199. pathAudio(nullptr),
  200. pathMIDI(nullptr),
  201. pathLADSPA(nullptr),
  202. pathDSSI(nullptr),
  203. pathLV2(nullptr),
  204. pathVST2(nullptr),
  205. pathVST3(nullptr),
  206. pathSF2(nullptr),
  207. pathSFZ(nullptr),
  208. pathJSFX(nullptr),
  209. binaryDir(nullptr),
  210. resourceDir(nullptr),
  211. clientNamePrefix(nullptr),
  212. preventBadBehaviour(false),
  213. frontendWinId(0)
  214. #ifndef CARLA_OS_WIN
  215. , wine()
  216. #endif
  217. {
  218. }
  219. EngineOptions::~EngineOptions() noexcept
  220. {
  221. if (audioDriver != nullptr)
  222. {
  223. delete[] audioDriver;
  224. audioDriver = nullptr;
  225. }
  226. if (audioDevice != nullptr)
  227. {
  228. delete[] audioDevice;
  229. audioDevice = nullptr;
  230. }
  231. if (pathAudio != nullptr)
  232. {
  233. delete[] pathAudio;
  234. pathAudio = nullptr;
  235. }
  236. if (pathMIDI != nullptr)
  237. {
  238. delete[] pathMIDI;
  239. pathMIDI = nullptr;
  240. }
  241. if (pathLADSPA != nullptr)
  242. {
  243. delete[] pathLADSPA;
  244. pathLADSPA = nullptr;
  245. }
  246. if (pathDSSI != nullptr)
  247. {
  248. delete[] pathDSSI;
  249. pathDSSI = nullptr;
  250. }
  251. if (pathLV2 != nullptr)
  252. {
  253. delete[] pathLV2;
  254. pathLV2 = nullptr;
  255. }
  256. if (pathVST2 != nullptr)
  257. {
  258. delete[] pathVST2;
  259. pathVST2 = nullptr;
  260. }
  261. if (pathVST3 != nullptr)
  262. {
  263. delete[] pathVST3;
  264. pathVST3 = nullptr;
  265. }
  266. if (pathSF2 != nullptr)
  267. {
  268. delete[] pathSF2;
  269. pathSF2 = nullptr;
  270. }
  271. if (pathSFZ != nullptr)
  272. {
  273. delete[] pathSFZ;
  274. pathSFZ = nullptr;
  275. }
  276. if (pathJSFX != nullptr)
  277. {
  278. delete[] pathJSFX;
  279. pathJSFX = nullptr;
  280. }
  281. if (binaryDir != nullptr)
  282. {
  283. delete[] binaryDir;
  284. binaryDir = nullptr;
  285. }
  286. if (resourceDir != nullptr)
  287. {
  288. delete[] resourceDir;
  289. resourceDir = nullptr;
  290. }
  291. if (clientNamePrefix != nullptr)
  292. {
  293. delete[] clientNamePrefix;
  294. clientNamePrefix = nullptr;
  295. }
  296. }
  297. #ifndef CARLA_OS_WIN
  298. EngineOptions::Wine::Wine() noexcept
  299. : executable(nullptr),
  300. autoPrefix(true),
  301. fallbackPrefix(nullptr),
  302. rtPrio(true),
  303. baseRtPrio(15),
  304. serverRtPrio(10) {}
  305. EngineOptions::Wine::~Wine() noexcept
  306. {
  307. if (executable != nullptr)
  308. {
  309. delete[] executable;
  310. executable = nullptr;
  311. }
  312. if (fallbackPrefix != nullptr)
  313. {
  314. delete[] fallbackPrefix;
  315. fallbackPrefix = nullptr;
  316. }
  317. }
  318. #endif
  319. // -----------------------------------------------------------------------
  320. // EngineTimeInfoBBT
  321. EngineTimeInfoBBT::EngineTimeInfoBBT() noexcept
  322. : valid(false),
  323. bar(0),
  324. beat(0),
  325. tick(0.0),
  326. barStartTick(0.0),
  327. beatsPerBar(0.0f),
  328. beatType(0.0f),
  329. ticksPerBeat(0.0),
  330. beatsPerMinute(0.0) {}
  331. EngineTimeInfoBBT::EngineTimeInfoBBT(const EngineTimeInfoBBT& bbt) noexcept
  332. : valid(bbt.valid),
  333. bar(bbt.bar),
  334. beat(bbt.beat),
  335. tick(bbt.tick),
  336. barStartTick(bbt.barStartTick),
  337. beatsPerBar(bbt.beatsPerBar),
  338. beatType(bbt.beatType),
  339. ticksPerBeat(bbt.ticksPerBeat),
  340. beatsPerMinute(bbt.beatsPerMinute) {}
  341. void EngineTimeInfoBBT::clear() noexcept
  342. {
  343. valid = false;
  344. bar = 0;
  345. beat = 0;
  346. tick = 0.0;
  347. barStartTick = 0.0;
  348. beatsPerBar = 0.0f;
  349. beatType = 0.0f;
  350. ticksPerBeat = 0.0;
  351. beatsPerMinute = 0.0;
  352. }
  353. // -----------------------------------------------------------------------
  354. // EngineTimeInfo
  355. EngineTimeInfo::EngineTimeInfo() noexcept
  356. : playing(false),
  357. frame(0),
  358. usecs(0),
  359. bbt() {}
  360. void EngineTimeInfo::clear() noexcept
  361. {
  362. playing = false;
  363. frame = 0;
  364. usecs = 0;
  365. bbt.clear();
  366. }
  367. EngineTimeInfo::EngineTimeInfo(const EngineTimeInfo& info) noexcept
  368. : playing(info.playing),
  369. frame(info.frame),
  370. usecs(info.usecs),
  371. bbt(info.bbt) {}
  372. EngineTimeInfo& EngineTimeInfo::operator=(const EngineTimeInfo& info) noexcept
  373. {
  374. playing = info.playing;
  375. frame = info.frame;
  376. usecs = info.usecs;
  377. bbt.valid = info.bbt.valid;
  378. bbt.bar = info.bbt.bar;
  379. bbt.beat = info.bbt.beat;
  380. bbt.tick = info.bbt.tick;
  381. bbt.barStartTick = info.bbt.barStartTick;
  382. bbt.beatsPerBar = info.bbt.beatsPerBar;
  383. bbt.beatType = info.bbt.beatType;
  384. bbt.ticksPerBeat = info.bbt.ticksPerBeat;
  385. bbt.beatsPerMinute = info.bbt.beatsPerMinute;
  386. return *this;
  387. }
  388. bool EngineTimeInfo::compareIgnoringRollingFrames(const EngineTimeInfo& timeInfo, const uint32_t maxFrames) const noexcept
  389. {
  390. if (timeInfo.playing != playing || timeInfo.bbt.valid != bbt.valid)
  391. return false;
  392. if (bbt.valid)
  393. {
  394. if (carla_isNotEqual(timeInfo.bbt.beatsPerBar, bbt.beatsPerBar))
  395. return false;
  396. if (carla_isNotEqual(timeInfo.bbt.beatsPerMinute, bbt.beatsPerMinute))
  397. return false;
  398. }
  399. // frame matches, nothing else to compare
  400. if (timeInfo.frame == frame)
  401. return true;
  402. // if we went back in time, so a case of reposition
  403. if (frame > timeInfo.frame)
  404. return false;
  405. // not playing, so don't bother checking transport
  406. // assume frame changed, likely playback has stopped
  407. if (! playing)
  408. return false;
  409. // if we are within expected bounds, assume we are rolling normally
  410. if (frame + maxFrames <= timeInfo.frame)
  411. return true;
  412. // out of bounds, another reposition
  413. return false;
  414. }
  415. bool EngineTimeInfo::operator==(const EngineTimeInfo& timeInfo) const noexcept
  416. {
  417. if (timeInfo.playing != playing || timeInfo.frame != frame || timeInfo.bbt.valid != bbt.valid)
  418. return false;
  419. if (! bbt.valid)
  420. return true;
  421. if (carla_isNotEqual(timeInfo.bbt.beatsPerBar, bbt.beatsPerBar))
  422. return false;
  423. if (carla_isNotEqual(timeInfo.bbt.beatsPerMinute, bbt.beatsPerMinute))
  424. return false;
  425. return true;
  426. }
  427. bool EngineTimeInfo::operator!=(const EngineTimeInfo& timeInfo) const noexcept
  428. {
  429. return !operator==(timeInfo);
  430. }
  431. // -----------------------------------------------------------------------
  432. CARLA_BACKEND_END_NAMESPACE