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.

CarlaEnginePorts.cpp 9.5KB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2014 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 "CarlaEngineUtils.hpp"
  18. #include "CarlaMathUtils.hpp"
  19. #include "CarlaMIDI.h"
  20. CARLA_BACKEND_START_NAMESPACE
  21. // -----------------------------------------------------------------------
  22. // Fallback data
  23. static const EngineEvent kFallbackEngineEvent = { kEngineEventTypeNull, 0, 0, {{ kEngineControlEventTypeNull, 0, 0.0f }} };
  24. // -----------------------------------------------------------------------
  25. // Carla Engine port (Abstract)
  26. CarlaEnginePort::CarlaEnginePort(const CarlaEngineClient& client, const bool isInputPort) noexcept
  27. : kClient(client),
  28. kIsInput(isInputPort)
  29. {
  30. carla_debug("CarlaEnginePort::CarlaEnginePort(%s)", bool2str(isInputPort));
  31. }
  32. CarlaEnginePort::~CarlaEnginePort() noexcept
  33. {
  34. carla_debug("CarlaEnginePort::~CarlaEnginePort()");
  35. }
  36. // -----------------------------------------------------------------------
  37. // Carla Engine Audio port
  38. CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEngineClient& client, const bool isInputPort) noexcept
  39. : CarlaEnginePort(client, isInputPort),
  40. fBuffer(nullptr)
  41. {
  42. carla_debug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInputPort));
  43. }
  44. CarlaEngineAudioPort::~CarlaEngineAudioPort() noexcept
  45. {
  46. carla_debug("CarlaEngineAudioPort::~CarlaEngineAudioPort()");
  47. }
  48. void CarlaEngineAudioPort::initBuffer() noexcept
  49. {
  50. }
  51. // -----------------------------------------------------------------------
  52. // Carla Engine CV port
  53. CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngineClient& client, const bool isInputPort) noexcept
  54. : CarlaEnginePort(client, isInputPort),
  55. fBuffer(nullptr)
  56. {
  57. carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInputPort));
  58. }
  59. CarlaEngineCVPort::~CarlaEngineCVPort() noexcept
  60. {
  61. carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()");
  62. }
  63. void CarlaEngineCVPort::initBuffer() noexcept
  64. {
  65. }
  66. // -----------------------------------------------------------------------
  67. // Carla Engine Event port
  68. CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngineClient& client, const bool isInputPort) noexcept
  69. : CarlaEnginePort(client, isInputPort),
  70. fBuffer(nullptr),
  71. kProcessMode(client.getEngine().getProccessMode())
  72. {
  73. carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInputPort));
  74. if (kProcessMode == ENGINE_PROCESS_MODE_PATCHBAY)
  75. fBuffer = new EngineEvent[kMaxEngineEventInternalCount];
  76. }
  77. CarlaEngineEventPort::~CarlaEngineEventPort() noexcept
  78. {
  79. carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()");
  80. if (kProcessMode == ENGINE_PROCESS_MODE_PATCHBAY)
  81. {
  82. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,);
  83. delete[] fBuffer;
  84. fBuffer = nullptr;
  85. }
  86. }
  87. void CarlaEngineEventPort::initBuffer() noexcept
  88. {
  89. if (kProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == ENGINE_PROCESS_MODE_BRIDGE)
  90. fBuffer = kClient.getEngine().getInternalEventBuffer(kIsInput);
  91. else if (kProcessMode == ENGINE_PROCESS_MODE_PATCHBAY && ! kIsInput)
  92. carla_zeroStruct<EngineEvent>(fBuffer, kMaxEngineEventInternalCount);
  93. }
  94. uint32_t CarlaEngineEventPort::getEventCount() const noexcept
  95. {
  96. CARLA_SAFE_ASSERT_RETURN(kIsInput, 0);
  97. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0);
  98. CARLA_SAFE_ASSERT_RETURN(kProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && kProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0);
  99. uint32_t i=0;
  100. for (; i < kMaxEngineEventInternalCount; ++i)
  101. {
  102. if (fBuffer[i].type == kEngineEventTypeNull)
  103. break;
  104. }
  105. return i;
  106. }
  107. const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) const noexcept
  108. {
  109. CARLA_SAFE_ASSERT_RETURN(kIsInput, kFallbackEngineEvent);
  110. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent);
  111. CARLA_SAFE_ASSERT_RETURN(kProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && kProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent);
  112. CARLA_SAFE_ASSERT_RETURN(index < kMaxEngineEventInternalCount, kFallbackEngineEvent);
  113. return fBuffer[index];
  114. }
  115. const EngineEvent& CarlaEngineEventPort::getEventUnchecked(const uint32_t index) const noexcept
  116. {
  117. return fBuffer[index];
  118. }
  119. bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl) noexcept
  120. {
  121. return writeControlEvent(time, channel, ctrl.type, ctrl.param, ctrl.value);
  122. }
  123. bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) noexcept
  124. {
  125. CARLA_SAFE_ASSERT_RETURN(! kIsInput, false);
  126. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false);
  127. CARLA_SAFE_ASSERT_RETURN(kProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && kProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false);
  128. CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false);
  129. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  130. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f);
  131. if (type == kEngineControlEventTypeParameter) {
  132. CARLA_SAFE_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param));
  133. }
  134. for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
  135. {
  136. EngineEvent& event(fBuffer[i]);
  137. if (event.type != kEngineEventTypeNull)
  138. continue;
  139. event.type = kEngineEventTypeControl;
  140. event.time = time;
  141. event.channel = channel;
  142. event.ctrl.type = type;
  143. event.ctrl.param = param;
  144. event.ctrl.value = carla_fixValue<float>(0.0f, 1.0f, value);
  145. return true;
  146. }
  147. carla_stderr2("CarlaEngineEventPort::writeControlEvent() - buffer full");
  148. return false;
  149. }
  150. bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t size, const uint8_t* const data) noexcept
  151. {
  152. return writeMidiEvent(time, uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)), 0, size, data);
  153. }
  154. bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) noexcept
  155. {
  156. return writeMidiEvent(time, channel, midi.port, midi.size, midi.data);
  157. }
  158. bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data) noexcept
  159. {
  160. CARLA_SAFE_ASSERT_RETURN(! kIsInput, false);
  161. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false);
  162. CARLA_SAFE_ASSERT_RETURN(kProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && kProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false);
  163. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  164. CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false);
  165. CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);
  166. for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
  167. {
  168. EngineEvent& event(fBuffer[i]);
  169. if (event.type != kEngineEventTypeNull)
  170. continue;
  171. event.time = time;
  172. event.channel = channel;
  173. const uint8_t status(uint8_t(MIDI_GET_STATUS_FROM_DATA(data)));
  174. if (status == MIDI_STATUS_CONTROL_CHANGE)
  175. {
  176. CARLA_SAFE_ASSERT_RETURN(size >= 3, true);
  177. switch (data[1])
  178. {
  179. case MIDI_CONTROL_BANK_SELECT:
  180. case MIDI_CONTROL_BANK_SELECT__LSB:
  181. event.type = kEngineEventTypeControl;
  182. event.ctrl.type = kEngineControlEventTypeMidiBank;
  183. event.ctrl.param = data[2];
  184. event.ctrl.value = 0.0f;
  185. return true;
  186. case MIDI_CONTROL_ALL_SOUND_OFF:
  187. event.type = kEngineEventTypeControl;
  188. event.ctrl.type = kEngineControlEventTypeAllSoundOff;
  189. event.ctrl.param = 0;
  190. event.ctrl.value = 0.0f;
  191. return true;
  192. case MIDI_CONTROL_ALL_NOTES_OFF:
  193. event.type = kEngineEventTypeControl;
  194. event.ctrl.type = kEngineControlEventTypeAllNotesOff;
  195. event.ctrl.param = 0;
  196. event.ctrl.value = 0.0f;
  197. return true;
  198. }
  199. }
  200. if (status == MIDI_STATUS_PROGRAM_CHANGE)
  201. {
  202. CARLA_SAFE_ASSERT_RETURN(size == 2, true);
  203. event.type = kEngineEventTypeControl;
  204. event.ctrl.type = kEngineControlEventTypeMidiBank;
  205. event.ctrl.param = data[1];
  206. event.ctrl.value = 0.0f;
  207. return true;
  208. }
  209. event.type = kEngineEventTypeMidi;
  210. event.midi.port = port;
  211. event.midi.size = size;
  212. event.midi.data[0] = status;
  213. uint8_t j=1;
  214. for (; j < size; ++j)
  215. event.midi.data[j] = data[j];
  216. for (; j < EngineMidiEvent::kDataSize; ++j)
  217. event.midi.data[j] = 0;
  218. return true;
  219. }
  220. carla_stderr2("CarlaEngineEventPort::writeMidiEvent() - buffer full");
  221. return false;
  222. }
  223. // -----------------------------------------------------------------------
  224. CARLA_BACKEND_END_NAMESPACE