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.4KB

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 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)
  37. : fRingBuf(ringBuf)
  38. {
  39. if (ringBuf != nullptr)
  40. clear();
  41. }
  42. void clear()
  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)
  52. {
  53. CARLA_ASSERT(ringBuf != nullptr);
  54. CARLA_ASSERT(ringBuf != fRingBuf);
  55. fRingBuf = ringBuf;
  56. if (reset)
  57. clear();
  58. }
  59. // -------------------------------------------------------------------
  60. bool commitWrite()
  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
  76. {
  77. CARLA_SAFE_ASSERT_RETURN(fRingBuf != nullptr, false);
  78. return (fRingBuf->head != fRingBuf->tail);
  79. }
  80. // -------------------------------------------------------------------
  81. char readChar()
  82. {
  83. char c = 0;
  84. tryRead(&c, sizeof(char));
  85. return c;
  86. }
  87. int32_t readInt()
  88. {
  89. int32_t i = 0;
  90. tryRead(&i, sizeof(int32_t));
  91. return i;
  92. }
  93. int64_t readLong()
  94. {
  95. int64_t l = 0;
  96. tryRead(&l, sizeof(int64_t));
  97. return l;
  98. }
  99. float readFloat()
  100. {
  101. float f = 0.0f;
  102. tryRead(&f, sizeof(float));
  103. return f;
  104. }
  105. // -------------------------------------------------------------------
  106. void writeChar(const char value)
  107. {
  108. tryWrite(&value, sizeof(char));
  109. }
  110. void writeInt(const int32_t value)
  111. {
  112. tryWrite(&value, sizeof(int32_t));
  113. }
  114. void writeLong(const int64_t value)
  115. {
  116. tryWrite(&value, sizeof(int64_t));
  117. }
  118. void writeFloat(const float value)
  119. {
  120. tryWrite(&value, sizeof(float));
  121. }
  122. // -------------------------------------------------------------------
  123. protected:
  124. void tryRead(void* const buf, const size_t size)
  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)
  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