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.

497 lines
13KB

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