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.

250 lines
8.2KB

  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 "CarlaEngineInternal.hpp"
  18. #include "CarlaMathUtils.hpp"
  19. #include "CarlaMIDI.h"
  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 isInputPort) noexcept
  31. : fEngine(engine),
  32. fIsInput(isInputPort)
  33. {
  34. carla_debug("CarlaEnginePort::CarlaEnginePort(%s)", bool2str(isInputPort));
  35. }
  36. CarlaEnginePort::~CarlaEnginePort() noexcept
  37. {
  38. carla_debug("CarlaEnginePort::~CarlaEnginePort()");
  39. }
  40. // -----------------------------------------------------------------------
  41. // Carla Engine Audio port
  42. CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEngine& engine, const bool isInputPort) noexcept
  43. : CarlaEnginePort(engine, isInputPort),
  44. fBuffer(nullptr)
  45. {
  46. carla_debug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInputPort));
  47. }
  48. CarlaEngineAudioPort::~CarlaEngineAudioPort() noexcept
  49. {
  50. carla_debug("CarlaEngineAudioPort::~CarlaEngineAudioPort()");
  51. }
  52. void CarlaEngineAudioPort::initBuffer() noexcept
  53. {
  54. }
  55. // -----------------------------------------------------------------------
  56. // Carla Engine CV port
  57. CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngine& engine, const bool isInputPort) noexcept
  58. : CarlaEnginePort(engine, isInputPort),
  59. fBuffer(nullptr)
  60. {
  61. carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInputPort));
  62. }
  63. CarlaEngineCVPort::~CarlaEngineCVPort() noexcept
  64. {
  65. carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()");
  66. }
  67. void CarlaEngineCVPort::initBuffer() noexcept
  68. {
  69. }
  70. // -----------------------------------------------------------------------
  71. // Carla Engine Event port
  72. CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool isInputPort) noexcept
  73. : CarlaEnginePort(engine, isInputPort),
  74. fBuffer(nullptr),
  75. fProcessMode(engine.getProccessMode())
  76. {
  77. carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInputPort));
  78. if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY)
  79. fBuffer = new EngineEvent[kMaxEngineEventInternalCount];
  80. }
  81. CarlaEngineEventPort::~CarlaEngineEventPort() noexcept
  82. {
  83. carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()");
  84. if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY)
  85. {
  86. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,);
  87. delete[] fBuffer;
  88. fBuffer = nullptr;
  89. }
  90. }
  91. void CarlaEngineEventPort::initBuffer() noexcept
  92. {
  93. if (fProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || fProcessMode == ENGINE_PROCESS_MODE_BRIDGE)
  94. fBuffer = fEngine.getInternalEventBuffer(fIsInput);
  95. else if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fIsInput)
  96. carla_zeroStruct<EngineEvent>(fBuffer, kMaxEngineEventInternalCount);
  97. }
  98. uint32_t CarlaEngineEventPort::getEventCount() const noexcept
  99. {
  100. CARLA_SAFE_ASSERT_RETURN(fIsInput, 0);
  101. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0);
  102. CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0);
  103. uint32_t i=0;
  104. for (; i < kMaxEngineEventInternalCount; ++i)
  105. {
  106. if (fBuffer[i].type == kEngineEventTypeNull)
  107. break;
  108. }
  109. return i;
  110. }
  111. const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) const noexcept
  112. {
  113. CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackEngineEvent);
  114. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent);
  115. CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent);
  116. CARLA_SAFE_ASSERT_RETURN(index < kMaxEngineEventInternalCount, kFallbackEngineEvent);
  117. return fBuffer[index];
  118. }
  119. const EngineEvent& CarlaEngineEventPort::getEventUnchecked(const uint32_t index) const noexcept
  120. {
  121. return fBuffer[index];
  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(! fIsInput, false);
  126. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false);
  127. CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != 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. // FIXME? should not fix range if midi-program
  135. const float fixedValue(carla_fixValue<float>(0.0f, 1.0f, value));
  136. for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
  137. {
  138. EngineEvent& event(fBuffer[i]);
  139. if (event.type != kEngineEventTypeNull)
  140. continue;
  141. event.type = kEngineEventTypeControl;
  142. event.time = time;
  143. event.channel = channel;
  144. event.ctrl.type = type;
  145. event.ctrl.param = param;
  146. event.ctrl.value = fixedValue;
  147. return true;
  148. }
  149. carla_stderr2("CarlaEngineEventPort::writeControlEvent() - buffer full");
  150. return false;
  151. }
  152. bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl) noexcept
  153. {
  154. return writeControlEvent(time, channel, ctrl.type, ctrl.param, ctrl.value);
  155. }
  156. 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
  157. {
  158. CARLA_SAFE_ASSERT_RETURN(! fIsInput, false);
  159. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false);
  160. CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false);
  161. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  162. CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false);
  163. CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);
  164. for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
  165. {
  166. EngineEvent& event(fBuffer[i]);
  167. if (event.type != kEngineEventTypeNull)
  168. continue;
  169. event.type = kEngineEventTypeMidi;
  170. event.time = time;
  171. event.channel = channel;
  172. event.midi.port = port;
  173. event.midi.size = size;
  174. event.midi.data[0] = uint8_t(MIDI_GET_STATUS_FROM_DATA(data));
  175. uint8_t j=1;
  176. for (; j < size; ++j)
  177. event.midi.data[j] = data[j];
  178. for (; j < EngineMidiEvent::kDataSize; ++j)
  179. event.midi.data[j] = 0;
  180. return true;
  181. }
  182. carla_stderr2("CarlaEngineEventPort::writeMidiEvent() - buffer full");
  183. return false;
  184. }
  185. bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t size, const uint8_t* const data) noexcept
  186. {
  187. return writeMidiEvent(time, uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)), 0, size, data);
  188. }
  189. bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) noexcept
  190. {
  191. return writeMidiEvent(time, channel, midi.port, midi.size, midi.data);
  192. }
  193. // -----------------------------------------------------------------------
  194. CARLA_BACKEND_END_NAMESPACE