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.

423 lines
14KB

  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 "CarlaEngineInternal.hpp"
  18. #include "CarlaEngineUtils.hpp"
  19. #include "CarlaMathUtils.hpp"
  20. #include "CarlaMIDI.h"
  21. #include "lv2/lv2.h"
  22. CARLA_BACKEND_START_NAMESPACE
  23. // -----------------------------------------------------------------------
  24. // Fallback data
  25. static const EngineEvent kFallbackEngineEvent = { kEngineEventTypeNull, 0, 0, {{ kEngineControlEventTypeNull, 0, 0.0f }} };
  26. static CarlaEngineEventCV kFallbackEngineEventCV = { nullptr, (uint32_t)-1, 0.0f };
  27. // -----------------------------------------------------------------------
  28. // Carla Engine port (Abstract)
  29. CarlaEnginePort::CarlaEnginePort(const CarlaEngineClient& client, const bool isInputPort, const uint32_t indexOffset) noexcept
  30. : kClient(client),
  31. kIsInput(isInputPort),
  32. kIndexOffset(indexOffset)
  33. {
  34. carla_debug("CarlaEnginePort::CarlaEnginePort(%s)", bool2str(isInputPort));
  35. }
  36. CarlaEnginePort::~CarlaEnginePort() noexcept
  37. {
  38. carla_debug("CarlaEnginePort::~CarlaEnginePort()");
  39. }
  40. void CarlaEnginePort::setMetaData(const char*, const char*, const char*)
  41. {
  42. }
  43. // -----------------------------------------------------------------------
  44. // Carla Engine Audio port
  45. CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEngineClient& client, const bool isInputPort, const uint32_t indexOffset) noexcept
  46. : CarlaEnginePort(client, isInputPort, indexOffset),
  47. fBuffer(nullptr)
  48. {
  49. carla_debug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInputPort));
  50. }
  51. CarlaEngineAudioPort::~CarlaEngineAudioPort() noexcept
  52. {
  53. carla_debug("CarlaEngineAudioPort::~CarlaEngineAudioPort()");
  54. }
  55. void CarlaEngineAudioPort::initBuffer() noexcept
  56. {
  57. }
  58. // -----------------------------------------------------------------------
  59. // Carla Engine CV port
  60. CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngineClient& client, const bool isInputPort, const uint32_t indexOffset) noexcept
  61. : CarlaEnginePort(client, isInputPort, indexOffset),
  62. fBuffer(nullptr),
  63. fMinimum(-1.0f),
  64. fMaximum(1.0f)
  65. {
  66. carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInputPort));
  67. }
  68. CarlaEngineCVPort::~CarlaEngineCVPort() noexcept
  69. {
  70. carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()");
  71. }
  72. void CarlaEngineCVPort::initBuffer() noexcept
  73. {
  74. }
  75. void CarlaEngineCVPort::setRange(const float min, const float max) noexcept
  76. {
  77. fMinimum = min;
  78. fMaximum = max;
  79. char strBufMin[STR_MAX];
  80. char strBufMax[STR_MAX];
  81. carla_zeroChars(strBufMin, STR_MAX);
  82. carla_zeroChars(strBufMax, STR_MAX);
  83. {
  84. const CarlaScopedLocale csl;
  85. std::snprintf(strBufMin, STR_MAX-1, "%f", static_cast<double>(min));
  86. std::snprintf(strBufMax, STR_MAX-1, "%f", static_cast<double>(max));
  87. }
  88. setMetaData(LV2_CORE__minimum, strBufMin, "");
  89. setMetaData(LV2_CORE__maximum, strBufMax, "");
  90. }
  91. // -----------------------------------------------------------------------
  92. // Carla Engine Event port
  93. CarlaEngineEventPort::ProtectedData::ProtectedData(const EngineProcessMode pm) noexcept
  94. : buffer(nullptr),
  95. processMode(pm),
  96. cvs()
  97. {
  98. if (processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  99. {
  100. buffer = new EngineEvent[kMaxEngineEventInternalCount];
  101. carla_zeroStructs(buffer, kMaxEngineEventInternalCount);
  102. }
  103. }
  104. CarlaEngineEventPort::ProtectedData::~ProtectedData() noexcept
  105. {
  106. for (LinkedList<CarlaEngineEventCV>::Itenerator it = cvs.begin2(); it.valid(); it.next())
  107. delete it.getValue(kFallbackEngineEventCV).cvPort;
  108. cvs.clear();
  109. if (processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  110. {
  111. CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,);
  112. delete[] buffer;
  113. buffer = nullptr;
  114. }
  115. }
  116. CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngineClient& client, const bool isInputPort, const uint32_t indexOffset) noexcept
  117. : CarlaEnginePort(client, isInputPort, indexOffset),
  118. pData(new ProtectedData(client.getEngine().getProccessMode()))
  119. {
  120. carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInputPort));
  121. }
  122. CarlaEngineEventPort::~CarlaEngineEventPort() noexcept
  123. {
  124. carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()");
  125. delete pData;
  126. }
  127. void CarlaEngineEventPort::addCVSource(CarlaEngineCVPort* const port, const uint32_t portIndexOffset) noexcept
  128. {
  129. CARLA_SAFE_ASSERT_RETURN(port != nullptr,);
  130. CARLA_SAFE_ASSERT_RETURN(port->isInput(),);
  131. carla_debug("CarlaEngineEventPort::addCVSource(%p)", port);
  132. const CarlaEngineEventCV ecv { port, portIndexOffset, 0.0f };
  133. pData->cvs.append(ecv);
  134. }
  135. void CarlaEngineEventPort::removeCVSource(const uint32_t portIndexOffset) noexcept
  136. {
  137. carla_debug("CarlaEngineEventPort::removeCVSource(%u)", portIndexOffset);
  138. for (LinkedList<CarlaEngineEventCV>::Itenerator it = pData->cvs.begin2(); it.valid(); it.next())
  139. {
  140. CarlaEngineEventCV& ecv(it.getValue(kFallbackEngineEventCV));
  141. if (ecv.indexOffset == portIndexOffset)
  142. {
  143. pData->cvs.remove(it);
  144. break;
  145. }
  146. }
  147. }
  148. void CarlaEngineEventPort::mixWithCvBuffer(const float* const buffer,
  149. const uint32_t frames,
  150. const uint32_t indexOffset) noexcept
  151. {
  152. CARLA_SAFE_ASSERT_RETURN(pData->buffer != nullptr,)
  153. CARLA_SAFE_ASSERT_RETURN(kIsInput,);
  154. uint32_t eventIndex = 0;
  155. float v, min, max;
  156. for (; eventIndex < kMaxEngineEventInternalCount; ++eventIndex)
  157. {
  158. if (pData->buffer[eventIndex].type == kEngineEventTypeNull)
  159. break;
  160. }
  161. if (eventIndex == kMaxEngineEventInternalCount)
  162. return;
  163. for (LinkedList<CarlaEngineEventCV>::Itenerator it = pData->cvs.begin2(); it.valid(); it.next())
  164. {
  165. CarlaEngineEventCV& ecv(it.getValue(kFallbackEngineEventCV));
  166. if (ecv.indexOffset != indexOffset)
  167. continue;
  168. CARLA_SAFE_ASSERT_RETURN(ecv.cvPort != nullptr,);
  169. float previousValue = ecv.previousValue;
  170. ecv.cvPort->getRange(min, max);
  171. for (uint32_t i=0; i<frames; i+=32)
  172. {
  173. v = buffer[i];
  174. if (carla_isNotEqual(v, previousValue))
  175. {
  176. previousValue = v;
  177. EngineEvent& event(pData->buffer[eventIndex++]);
  178. event.type = kEngineEventTypeControl;
  179. event.time = i;
  180. event.channel = 0xFF;
  181. event.ctrl.type = kEngineControlEventTypeParameter;
  182. event.ctrl.param = static_cast<uint16_t>(indexOffset);
  183. event.ctrl.value = carla_fixedValue(0.0f, 1.0f, (v - min) / (max - min));
  184. }
  185. }
  186. ecv.previousValue = previousValue;
  187. break;
  188. }
  189. }
  190. void CarlaEngineEventPort::initBuffer() noexcept
  191. {
  192. if (pData->processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->processMode == ENGINE_PROCESS_MODE_BRIDGE)
  193. pData->buffer = kClient.getEngine().getInternalEventBuffer(kIsInput);
  194. else if (pData->processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! kIsInput)
  195. carla_zeroStructs(pData->buffer, kMaxEngineEventInternalCount);
  196. }
  197. uint32_t CarlaEngineEventPort::getEventCount() const noexcept
  198. {
  199. CARLA_SAFE_ASSERT_RETURN(kIsInput, 0);
  200. CARLA_SAFE_ASSERT_RETURN(pData->buffer != nullptr, 0);
  201. CARLA_SAFE_ASSERT_RETURN(pData->processMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && pData->processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0);
  202. uint32_t i=0;
  203. for (; i < kMaxEngineEventInternalCount; ++i)
  204. {
  205. if (pData->buffer[i].type == kEngineEventTypeNull)
  206. break;
  207. }
  208. return i;
  209. }
  210. const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) const noexcept
  211. {
  212. CARLA_SAFE_ASSERT_RETURN(kIsInput, kFallbackEngineEvent);
  213. CARLA_SAFE_ASSERT_RETURN(pData->buffer != nullptr, kFallbackEngineEvent);
  214. CARLA_SAFE_ASSERT_RETURN(pData->processMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && pData->processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent);
  215. CARLA_SAFE_ASSERT_RETURN(index < kMaxEngineEventInternalCount, kFallbackEngineEvent);
  216. return pData->buffer[index];
  217. }
  218. const EngineEvent& CarlaEngineEventPort::getEventUnchecked(const uint32_t index) const noexcept
  219. {
  220. return pData->buffer[index];
  221. }
  222. bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl) noexcept
  223. {
  224. return writeControlEvent(time, channel, ctrl.type, ctrl.param, ctrl.value);
  225. }
  226. bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) noexcept
  227. {
  228. CARLA_SAFE_ASSERT_RETURN(! kIsInput, false);
  229. CARLA_SAFE_ASSERT_RETURN(pData->buffer != nullptr, false);
  230. CARLA_SAFE_ASSERT_RETURN(pData->processMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && pData->processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false);
  231. CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false);
  232. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  233. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f);
  234. if (type == kEngineControlEventTypeParameter) {
  235. CARLA_SAFE_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param));
  236. }
  237. for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
  238. {
  239. EngineEvent& event(pData->buffer[i]);
  240. if (event.type != kEngineEventTypeNull)
  241. continue;
  242. event.type = kEngineEventTypeControl;
  243. event.time = time;
  244. event.channel = channel;
  245. event.ctrl.type = type;
  246. event.ctrl.param = param;
  247. event.ctrl.value = carla_fixedValue<float>(0.0f, 1.0f, value);
  248. return true;
  249. }
  250. carla_stderr2("CarlaEngineEventPort::writeControlEvent() - buffer full");
  251. return false;
  252. }
  253. bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t size, const uint8_t* const data) noexcept
  254. {
  255. return writeMidiEvent(time, uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)), size, data);
  256. }
  257. bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) noexcept
  258. {
  259. CARLA_SAFE_ASSERT(midi.port == kIndexOffset);
  260. return writeMidiEvent(time, channel, midi.size, midi.data);
  261. }
  262. bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t size, const uint8_t* const data) noexcept
  263. {
  264. CARLA_SAFE_ASSERT_RETURN(! kIsInput, false);
  265. CARLA_SAFE_ASSERT_RETURN(pData->buffer != nullptr, false);
  266. CARLA_SAFE_ASSERT_RETURN(pData->processMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && pData->processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false);
  267. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  268. CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false);
  269. CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);
  270. for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
  271. {
  272. EngineEvent& event(pData->buffer[i]);
  273. if (event.type != kEngineEventTypeNull)
  274. continue;
  275. event.time = time;
  276. event.channel = channel;
  277. const uint8_t status(uint8_t(MIDI_GET_STATUS_FROM_DATA(data)));
  278. if (status == MIDI_STATUS_CONTROL_CHANGE)
  279. {
  280. CARLA_SAFE_ASSERT_RETURN(size >= 2, true);
  281. switch (data[1])
  282. {
  283. case MIDI_CONTROL_BANK_SELECT:
  284. case MIDI_CONTROL_BANK_SELECT__LSB:
  285. CARLA_SAFE_ASSERT_RETURN(size >= 3, true);
  286. event.type = kEngineEventTypeControl;
  287. event.ctrl.type = kEngineControlEventTypeMidiBank;
  288. event.ctrl.param = data[2];
  289. event.ctrl.value = 0.0f;
  290. return true;
  291. case MIDI_CONTROL_ALL_SOUND_OFF:
  292. event.type = kEngineEventTypeControl;
  293. event.ctrl.type = kEngineControlEventTypeAllSoundOff;
  294. event.ctrl.param = 0;
  295. event.ctrl.value = 0.0f;
  296. return true;
  297. case MIDI_CONTROL_ALL_NOTES_OFF:
  298. event.type = kEngineEventTypeControl;
  299. event.ctrl.type = kEngineControlEventTypeAllNotesOff;
  300. event.ctrl.param = 0;
  301. event.ctrl.value = 0.0f;
  302. return true;
  303. }
  304. }
  305. if (status == MIDI_STATUS_PROGRAM_CHANGE)
  306. {
  307. CARLA_SAFE_ASSERT_RETURN(size >= 2, true);
  308. event.type = kEngineEventTypeControl;
  309. event.ctrl.type = kEngineControlEventTypeMidiProgram;
  310. event.ctrl.param = data[1];
  311. event.ctrl.value = 0.0f;
  312. return true;
  313. }
  314. event.type = kEngineEventTypeMidi;
  315. event.midi.size = size;
  316. if (kIndexOffset < 0xFF /* uint8_t max */)
  317. {
  318. event.midi.port = static_cast<uint8_t>(kIndexOffset);
  319. }
  320. else
  321. {
  322. event.midi.port = 0;
  323. carla_safe_assert_uint("kIndexOffset < 0xFF", __FILE__, __LINE__, kIndexOffset);
  324. }
  325. event.midi.data[0] = status;
  326. uint8_t j=1;
  327. for (; j < size; ++j)
  328. event.midi.data[j] = data[j];
  329. for (; j < EngineMidiEvent::kDataSize; ++j)
  330. event.midi.data[j] = 0;
  331. return true;
  332. }
  333. carla_stderr2("CarlaEngineEventPort::writeMidiEvent() - buffer full");
  334. return false;
  335. }
  336. // -----------------------------------------------------------------------
  337. CARLA_BACKEND_END_NAMESPACE