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.

CarlaRingBuffer.hpp 6.6KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * Carla Ring Buffer based on dssi-vst code
  3. * Copyright (C) 2004-2010 Chris Cannam <cannam@all-day-breakfast.com>
  4. * Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of
  9. * the License, or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  17. */
  18. #ifndef CARLA_RING_BUFFER_HPP_INCLUDED
  19. #define CARLA_RING_BUFFER_HPP_INCLUDED
  20. #include "CarlaUtils.hpp"
  21. //#ifndef RING_BUFFER_SIZE
  22. #define RING_BUFFER_SIZE 2048
  23. //#endif
  24. // -----------------------------------------------------------------------
  25. // RingBuffer struct
  26. struct RingBuffer {
  27. int32_t head, tail, written;
  28. bool invalidateCommit;
  29. char buf[RING_BUFFER_SIZE];
  30. };
  31. // -----------------------------------------------------------------------
  32. // RingBufferControl class
  33. class RingBufferControl
  34. {
  35. public:
  36. RingBufferControl(RingBuffer* const ringBuf) noexcept
  37. : fRingBuf(ringBuf)
  38. {
  39. if (ringBuf != nullptr)
  40. clear();
  41. }
  42. void clear() noexcept
  43. {
  44. CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr,);
  45. fRingBuf->head = 0;
  46. fRingBuf->tail = 0;
  47. fRingBuf->written = 0;
  48. fRingBuf->invalidateCommit = false;
  49. carla_zeroChar(fRingBuf->buf, RING_BUFFER_SIZE);
  50. }
  51. void setRingBuffer(RingBuffer* const ringBuf, const bool reset) noexcept
  52. {
  53. CARLA_SAFE_ASSERT_RETURN(ringBuf != nullptr,);
  54. CARLA_SAFE_ASSERT_RETURN(ringBuf != fRingBuf,);
  55. fRingBuf = ringBuf;
  56. if (reset)
  57. clear();
  58. }
  59. // -------------------------------------------------------------------
  60. bool commitWrite() noexcept
  61. {
  62. CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr, false);
  63. if (fRingBuf->invalidateCommit)
  64. {
  65. fRingBuf->written = fRingBuf->head;
  66. fRingBuf->invalidateCommit = false;
  67. return false;
  68. }
  69. else
  70. {
  71. fRingBuf->head = fRingBuf->written;
  72. return true;
  73. }
  74. }
  75. bool isDataAvailable() const noexcept
  76. {
  77. CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr, false);
  78. return (fRingBuf->head != fRingBuf->tail);
  79. }
  80. // -------------------------------------------------------------------
  81. char readChar() noexcept
  82. {
  83. char c = '\0';
  84. tryRead(&c, sizeof(char));
  85. return c;
  86. }
  87. int32_t readInt() noexcept
  88. {
  89. int32_t i = 0;
  90. tryRead(&i, sizeof(int32_t));
  91. return i;
  92. }
  93. int64_t readLong() noexcept
  94. {
  95. int64_t l = 0;
  96. tryRead(&l, sizeof(int64_t));
  97. return l;
  98. }
  99. float readFloat() noexcept
  100. {
  101. float f = 0.0f;
  102. tryRead(&f, sizeof(float));
  103. return f;
  104. }
  105. // -------------------------------------------------------------------
  106. void writeChar(const char value) noexcept
  107. {
  108. tryWrite(&value, sizeof(char));
  109. }
  110. void writeInt(const int32_t value) noexcept
  111. {
  112. tryWrite(&value, sizeof(int32_t));
  113. }
  114. void writeLong(const int64_t value) noexcept
  115. {
  116. tryWrite(&value, sizeof(int64_t));
  117. }
  118. void writeFloat(const float value) noexcept
  119. {
  120. tryWrite(&value, sizeof(float));
  121. }
  122. // -------------------------------------------------------------------
  123. protected:
  124. void tryRead(void* const buf, const size_t size) noexcept
  125. {
  126. CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr,);
  127. CARLA_SAFE_ASSERT_RETURN(buf != nullptr,);
  128. CARLA_SAFE_ASSERT_RETURN(size != 0,);
  129. // this should not happen
  130. CARLA_ASSERT(fRingBuf->head >= 0);
  131. CARLA_ASSERT(fRingBuf->tail >= 0);
  132. CARLA_ASSERT(fRingBuf->written >= 0);
  133. // empty
  134. if (fRingBuf->head == fRingBuf->tail)
  135. return;
  136. char* const charbuf(static_cast<char*>(buf));
  137. const size_t head(static_cast<size_t>(fRingBuf->head));
  138. const size_t tail(static_cast<size_t>(fRingBuf->tail));
  139. const size_t wrap((head < tail) ? RING_BUFFER_SIZE : 0);
  140. if (head - tail + wrap < size)
  141. {
  142. carla_stderr2("RingBufferControl::tryRead() - failed");
  143. return;
  144. }
  145. size_t readto = tail + size;
  146. if (readto >= RING_BUFFER_SIZE)
  147. {
  148. readto -= RING_BUFFER_SIZE;
  149. const size_t firstpart(RING_BUFFER_SIZE - tail);
  150. std::memcpy(charbuf, fRingBuf->buf + tail, firstpart);
  151. std::memcpy(charbuf + firstpart, fRingBuf->buf, readto);
  152. }
  153. else
  154. {
  155. std::memcpy(charbuf, fRingBuf->buf + tail, size);
  156. }
  157. fRingBuf->tail = static_cast<int32_t>(readto);
  158. }
  159. void tryWrite(const void* const buf, const size_t size) noexcept
  160. {
  161. CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr,);
  162. CARLA_SAFE_ASSERT_RETURN(buf != nullptr,);
  163. CARLA_SAFE_ASSERT_RETURN(size != 0,);
  164. // this should not happen
  165. CARLA_ASSERT(fRingBuf->head >= 0);
  166. CARLA_ASSERT(fRingBuf->tail >= 0);
  167. CARLA_ASSERT(fRingBuf->written >= 0);
  168. const char* const charbuf(static_cast<const char*>(buf));
  169. const size_t tail(static_cast<size_t>(fRingBuf->tail));
  170. const size_t wrtn(static_cast<size_t>(fRingBuf->written));
  171. const size_t wrap((tail <= wrtn) ? RING_BUFFER_SIZE : 0);
  172. if (tail - wrtn + wrap <= size)
  173. {
  174. carla_stderr2("RingBufferControl::tryWrite() - buffer full!");
  175. fRingBuf->invalidateCommit = true;
  176. return;
  177. }
  178. size_t writeto = wrtn + size;
  179. if (writeto >= RING_BUFFER_SIZE)
  180. {
  181. writeto -= RING_BUFFER_SIZE;
  182. const size_t firstpart(RING_BUFFER_SIZE - wrtn);
  183. std::memcpy(fRingBuf->buf + wrtn, charbuf, firstpart);
  184. std::memcpy(fRingBuf->buf, charbuf + firstpart, writeto);
  185. }
  186. else
  187. {
  188. std::memcpy(fRingBuf->buf + wrtn, charbuf, size);
  189. }
  190. fRingBuf->written = static_cast<int32_t>(writeto);
  191. }
  192. private:
  193. RingBuffer* fRingBuf;
  194. CARLA_PREVENT_HEAP_ALLOCATION
  195. CARLA_DECLARE_NON_COPY_CLASS(RingBufferControl)
  196. };
  197. // -----------------------------------------------------------------------
  198. #endif // CARLA_RING_BUFFER_HPP_INCLUDED