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.

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