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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2019 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));
  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. bgColor(0x000000ff),
  180. fgColor(0xffffffff),
  181. uiScale(1.0f),
  182. maxParameters(MAX_DEFAULT_PARAMETERS),
  183. uiBridgesTimeout(4000),
  184. audioBufferSize(512),
  185. audioSampleRate(44100),
  186. audioTripleBuffer(false),
  187. audioDriver(nullptr),
  188. audioDevice(nullptr),
  189. #ifndef BUILD_BRIDGE
  190. # ifdef CARLA_OS_WIN
  191. oscEnabled(false),
  192. # else
  193. oscEnabled(true),
  194. # endif
  195. oscPortTCP(22752),
  196. oscPortUDP(22752),
  197. #endif
  198. pathAudio(nullptr),
  199. pathMIDI(nullptr),
  200. pathLADSPA(nullptr),
  201. pathDSSI(nullptr),
  202. pathLV2(nullptr),
  203. pathVST2(nullptr),
  204. pathVST3(nullptr),
  205. pathSF2(nullptr),
  206. pathSFZ(nullptr),
  207. binaryDir(nullptr),
  208. resourceDir(nullptr),
  209. clientNamePrefix(nullptr),
  210. preventBadBehaviour(false),
  211. frontendWinId(0)
  212. #ifndef CARLA_OS_WIN
  213. , wine()
  214. #endif
  215. {
  216. }
  217. EngineOptions::~EngineOptions() noexcept
  218. {
  219. if (audioDriver != nullptr)
  220. {
  221. delete[] audioDriver;
  222. audioDriver = nullptr;
  223. }
  224. if (audioDevice != nullptr)
  225. {
  226. delete[] audioDevice;
  227. audioDevice = nullptr;
  228. }
  229. if (pathAudio != nullptr)
  230. {
  231. delete[] pathAudio;
  232. pathAudio = nullptr;
  233. }
  234. if (pathMIDI != nullptr)
  235. {
  236. delete[] pathMIDI;
  237. pathMIDI = nullptr;
  238. }
  239. if (pathLADSPA != nullptr)
  240. {
  241. delete[] pathLADSPA;
  242. pathLADSPA = nullptr;
  243. }
  244. if (pathDSSI != nullptr)
  245. {
  246. delete[] pathDSSI;
  247. pathDSSI = nullptr;
  248. }
  249. if (pathLV2 != nullptr)
  250. {
  251. delete[] pathLV2;
  252. pathLV2 = nullptr;
  253. }
  254. if (pathVST2 != nullptr)
  255. {
  256. delete[] pathVST2;
  257. pathVST2 = nullptr;
  258. }
  259. if (pathVST3 != nullptr)
  260. {
  261. delete[] pathVST3;
  262. pathVST3 = nullptr;
  263. }
  264. if (pathSF2 != nullptr)
  265. {
  266. delete[] pathSF2;
  267. pathSF2 = nullptr;
  268. }
  269. if (pathSFZ != nullptr)
  270. {
  271. delete[] pathSFZ;
  272. pathSFZ = nullptr;
  273. }
  274. if (binaryDir != nullptr)
  275. {
  276. delete[] binaryDir;
  277. binaryDir = nullptr;
  278. }
  279. if (resourceDir != nullptr)
  280. {
  281. delete[] resourceDir;
  282. resourceDir = nullptr;
  283. }
  284. if (clientNamePrefix != nullptr)
  285. {
  286. delete[] clientNamePrefix;
  287. clientNamePrefix = nullptr;
  288. }
  289. }
  290. #ifndef CARLA_OS_WIN
  291. EngineOptions::Wine::Wine() noexcept
  292. : executable(nullptr),
  293. autoPrefix(true),
  294. fallbackPrefix(nullptr),
  295. rtPrio(true),
  296. baseRtPrio(15),
  297. serverRtPrio(10) {}
  298. EngineOptions::Wine::~Wine() noexcept
  299. {
  300. if (executable != nullptr)
  301. {
  302. delete[] executable;
  303. executable = nullptr;
  304. }
  305. if (fallbackPrefix != nullptr)
  306. {
  307. delete[] fallbackPrefix;
  308. fallbackPrefix = nullptr;
  309. }
  310. }
  311. #endif
  312. // -----------------------------------------------------------------------
  313. // EngineTimeInfoBBT
  314. EngineTimeInfoBBT::EngineTimeInfoBBT() noexcept
  315. : valid(false),
  316. bar(0),
  317. beat(0),
  318. tick(0.0),
  319. barStartTick(0.0),
  320. beatsPerBar(0.0f),
  321. beatType(0.0f),
  322. ticksPerBeat(0.0),
  323. beatsPerMinute(0.0) {}
  324. EngineTimeInfoBBT::EngineTimeInfoBBT(const EngineTimeInfoBBT& bbt) noexcept
  325. : valid(bbt.valid),
  326. bar(bbt.bar),
  327. beat(bbt.beat),
  328. tick(bbt.tick),
  329. barStartTick(bbt.barStartTick),
  330. beatsPerBar(bbt.beatsPerBar),
  331. beatType(bbt.beatType),
  332. ticksPerBeat(bbt.ticksPerBeat),
  333. beatsPerMinute(bbt.beatsPerMinute) {}
  334. void EngineTimeInfoBBT::clear() noexcept
  335. {
  336. valid = false;
  337. bar = 0;
  338. beat = 0;
  339. tick = 0.0;
  340. barStartTick = 0.0;
  341. beatsPerBar = 0.0f;
  342. beatType = 0.0f;
  343. ticksPerBeat = 0.0;
  344. beatsPerMinute = 0.0;
  345. }
  346. // -----------------------------------------------------------------------
  347. // EngineTimeInfo
  348. EngineTimeInfo::EngineTimeInfo() noexcept
  349. : playing(false),
  350. frame(0),
  351. usecs(0),
  352. bbt() {}
  353. void EngineTimeInfo::clear() noexcept
  354. {
  355. playing = false;
  356. frame = 0;
  357. usecs = 0;
  358. bbt.clear();
  359. }
  360. EngineTimeInfo::EngineTimeInfo(const EngineTimeInfo& info) noexcept
  361. : playing(info.playing),
  362. frame(info.frame),
  363. usecs(info.usecs),
  364. bbt(info.bbt) {}
  365. EngineTimeInfo& EngineTimeInfo::operator=(const EngineTimeInfo& info) noexcept
  366. {
  367. playing = info.playing;
  368. frame = info.frame;
  369. usecs = info.usecs;
  370. bbt.valid = info.bbt.valid;
  371. bbt.bar = info.bbt.bar;
  372. bbt.beat = info.bbt.beat;
  373. bbt.tick = info.bbt.tick;
  374. bbt.barStartTick = info.bbt.barStartTick;
  375. bbt.beatsPerBar = info.bbt.beatsPerBar;
  376. bbt.beatType = info.bbt.beatType;
  377. bbt.ticksPerBeat = info.bbt.ticksPerBeat;
  378. bbt.beatsPerMinute = info.bbt.beatsPerMinute;
  379. return *this;
  380. }
  381. bool EngineTimeInfo::compareIgnoringRollingFrames(const EngineTimeInfo& timeInfo, const uint32_t maxFrames) const noexcept
  382. {
  383. if (timeInfo.playing != playing || timeInfo.bbt.valid != bbt.valid)
  384. return false;
  385. if (bbt.valid)
  386. {
  387. if (carla_isNotEqual(timeInfo.bbt.beatsPerBar, bbt.beatsPerBar))
  388. return false;
  389. if (carla_isNotEqual(timeInfo.bbt.beatsPerMinute, bbt.beatsPerMinute))
  390. return false;
  391. }
  392. // frame matches, nothing else to compare
  393. if (timeInfo.frame == frame)
  394. return true;
  395. // if we went back in time, so a case of reposition
  396. if (frame > timeInfo.frame)
  397. return false;
  398. // not playing, so don't bother checking transport
  399. // assume frame changed, likely playback has stopped
  400. if (! playing)
  401. return false;
  402. // if we are within expected bounds, assume we are rolling normally
  403. if (frame + maxFrames <= timeInfo.frame)
  404. return true;
  405. // out of bounds, another reposition
  406. return false;
  407. }
  408. bool EngineTimeInfo::operator==(const EngineTimeInfo& timeInfo) const noexcept
  409. {
  410. if (timeInfo.playing != playing || timeInfo.frame != frame || timeInfo.bbt.valid != bbt.valid)
  411. return false;
  412. if (! bbt.valid)
  413. return true;
  414. if (carla_isNotEqual(timeInfo.bbt.beatsPerBar, bbt.beatsPerBar))
  415. return false;
  416. if (carla_isNotEqual(timeInfo.bbt.beatsPerMinute, bbt.beatsPerMinute))
  417. return false;
  418. return true;
  419. }
  420. bool EngineTimeInfo::operator!=(const EngineTimeInfo& timeInfo) const noexcept
  421. {
  422. return !operator==(timeInfo);
  423. }
  424. // -----------------------------------------------------------------------
  425. CARLA_BACKEND_END_NAMESPACE