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.

173 lines
2.7KB

  1. #pragma once
  2. #include <assert.h>
  3. #include <string.h>
  4. #include <samplerate.h>
  5. namespace rack {
  6. /** S must be a power of 2 */
  7. template <typename T, size_t S>
  8. struct RingBuffer {
  9. T data[S] = {};
  10. size_t start = 0;
  11. size_t end = 0;
  12. size_t mask(size_t i) {
  13. return i & (S - 1);
  14. }
  15. void push(T t) {
  16. size_t i = mask(end++);
  17. data[i] = t;
  18. }
  19. T shift() {
  20. return data[mask(start++)];
  21. }
  22. bool empty() {
  23. return start >= end;
  24. }
  25. bool full() {
  26. return end - start >= S;
  27. }
  28. size_t size() {
  29. return end - start;
  30. }
  31. };
  32. /** S must be a power of 2 */
  33. template <typename T, size_t S>
  34. struct DoubleRingBuffer {
  35. T data[S*2] = {};
  36. size_t start = 0;
  37. size_t end = 0;
  38. size_t mask(size_t i) {
  39. return i & (S - 1);
  40. }
  41. void push(T t) {
  42. size_t i = mask(end++);
  43. data[i] = t;
  44. data[i + S] = t;
  45. }
  46. T shift() {
  47. return data[mask(start++)];
  48. }
  49. bool empty() {
  50. return start >= end;
  51. }
  52. bool full() {
  53. return end - start >= S;
  54. }
  55. size_t size() {
  56. return end - start;
  57. }
  58. };
  59. template <typename T, size_t S, size_t N>
  60. struct AppleRingBuffer {
  61. T data[N] = {};
  62. size_t start = 0;
  63. size_t end = 0;
  64. void push(T t) {
  65. data[end++] = t;
  66. if (end >= N) {
  67. // move end block to beginning
  68. memmove(data, &data[N - S], sizeof(T) * S);
  69. start -= N - S;
  70. end = S;
  71. }
  72. }
  73. T shift() {
  74. return data[start++];
  75. }
  76. bool empty() {
  77. return start >= end;
  78. }
  79. bool full() {
  80. return end - start >= S;
  81. }
  82. size_t size() {
  83. return end - start;
  84. }
  85. };
  86. template <size_t S>
  87. struct SampleRateConverter {
  88. SRC_STATE *state;
  89. SRC_DATA data;
  90. SampleRateConverter() {
  91. int error;
  92. state = src_new(SRC_SINC_FASTEST, 1, &error);
  93. assert(!error);
  94. data.src_ratio = 1.0;
  95. data.end_of_input = false;
  96. }
  97. ~SampleRateConverter() {
  98. src_delete(state);
  99. }
  100. void setRatio(float r) {
  101. data.src_ratio = r;
  102. }
  103. void push(const float *in, int length) {
  104. float out[S];
  105. data.data_in = in;
  106. data.input_frames = length;
  107. data.data_out = out;
  108. data.output_frames = S;
  109. src_process(state, &data);
  110. }
  111. void push(float in) {
  112. push(&in, 1);
  113. }
  114. };
  115. template <size_t OVERSAMPLE>
  116. struct Decimator {
  117. SRC_STATE *state;
  118. SRC_DATA data;
  119. Decimator() {
  120. int error;
  121. state = src_new(SRC_SINC_FASTEST, 1, &error);
  122. assert(!error);
  123. data.data_in = NULL;
  124. data.data_out = NULL;
  125. data.input_frames = OVERSAMPLE;
  126. data.output_frames = 1;
  127. data.end_of_input = false;
  128. data.src_ratio = 1.0 / OVERSAMPLE;
  129. }
  130. ~Decimator() {
  131. src_delete(state);
  132. }
  133. /** input must be length OVERSAMPLE */
  134. float process(float *input) {
  135. float output[1];
  136. data.data_in = input;
  137. data.data_out = output;
  138. src_process(state, &data);
  139. if (data.output_frames_gen > 0) {
  140. return output[0];
  141. }
  142. else {
  143. return 0.0;
  144. }
  145. }
  146. void reset() {
  147. src_reset(state);
  148. }
  149. };
  150. } // namespace rack