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.

274 lines
9.0KB

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