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.

dsp.hpp 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. #pragma once
  2. #include <assert.h>
  3. #include <string.h>
  4. #include <samplerate.h>
  5. #include <complex>
  6. #include "math.hpp"
  7. #include "../ext/dr_libs/dr_wav.h"
  8. namespace rack {
  9. /** Useful for storing arrays of samples in ring buffers and casting them to `float*` to be used by interleaved processors, like SampleRateConverter */
  10. template <size_t CHANNELS>
  11. struct Frame {
  12. float samples[CHANNELS];
  13. };
  14. /** Simple FFT implementation
  15. If you need something fast, use pffft, KissFFT, etc instead.
  16. The size N must be a power of 2
  17. */
  18. struct SimpleFFT {
  19. int N;
  20. /** Twiddle factors e^(2pi k/N), interleaved complex numbers */
  21. std::complex<float> *tw;
  22. SimpleFFT(int N, bool inverse) : N(N) {
  23. tw = new std::complex<float>[N];
  24. for (int i = 0; i < N; i++) {
  25. float phase = 2*M_PI * (float)i / N;
  26. if (inverse)
  27. phase *= -1.0;
  28. tw[i] = std::exp(std::complex<float>(0.0, phase));
  29. }
  30. }
  31. ~SimpleFFT() {
  32. delete[] tw;
  33. }
  34. /** Reference naive implementation
  35. x and y are arrays of interleaved complex numbers
  36. y must be size N/s
  37. s is the stride factor for the x array which divides the size N
  38. */
  39. void dft(const std::complex<float> *x, std::complex<float> *y, int s=1) {
  40. for (int k = 0; k < N/s; k++) {
  41. std::complex<float> yk = 0.0;
  42. for (int n = 0; n < N; n += s) {
  43. int m = (n*k) % N;
  44. yk += x[n] * tw[m];
  45. }
  46. y[k] = yk;
  47. }
  48. }
  49. void fft(const std::complex<float> *x, std::complex<float> *y, int s=1) {
  50. if (N/s <= 2) {
  51. // Naive DFT is faster than further FFT recursions at this point
  52. dft(x, y, s);
  53. return;
  54. }
  55. std::complex<float> *e = new std::complex<float>[N/(2*s)]; // Even inputs
  56. std::complex<float> *o = new std::complex<float>[N/(2*s)]; // Odd inputs
  57. fft(x, e, 2*s);
  58. fft(x + s, o, 2*s);
  59. for (int k = 0; k < N/(2*s); k++) {
  60. int m = (k*s) % N;
  61. y[k] = e[k] + tw[m] * o[k];
  62. y[k + N/(2*s)] = e[k] - tw[m] * o[k];
  63. }
  64. delete[] e;
  65. delete[] o;
  66. }
  67. };
  68. typedef void (*stepCallback)(float x, const float y[], float dydt[]);
  69. /** Solve an ODE system using the 1st order Euler method */
  70. inline void stepEuler(stepCallback f, float x, float dx, float y[], int len) {
  71. float k[len];
  72. f(x, y, k);
  73. for (int i = 0; i < len; i++) {
  74. y[i] += dx * k[i];
  75. }
  76. }
  77. /** Solve an ODE system using the 4th order Runge-Kutta method */
  78. inline void stepRK4(stepCallback f, float x, float dx, float y[], int len) {
  79. float k1[len];
  80. float k2[len];
  81. float k3[len];
  82. float k4[len];
  83. float yi[len];
  84. f(x, y, k1);
  85. for (int i = 0; i < len; i++) {
  86. yi[i] = y[i] + k1[i] * dx / 2.0;
  87. }
  88. f(x + dx / 2.0, yi, k2);
  89. for (int i = 0; i < len; i++) {
  90. yi[i] = y[i] + k2[i] * dx / 2.0;
  91. }
  92. f(x + dx / 2.0, yi, k3);
  93. for (int i = 0; i < len; i++) {
  94. yi[i] = y[i] + k3[i] * dx;
  95. }
  96. f(x + dx, yi, k4);
  97. for (int i = 0; i < len; i++) {
  98. y[i] += dx * (k1[i] + 2.0 * k2[i] + 2.0 * k3[i] + k4[i]) / 6.0;
  99. }
  100. }
  101. /** A simple cyclic buffer.
  102. S must be a power of 2.
  103. push() is constant time O(1)
  104. */
  105. template <typename T, int S>
  106. struct RingBuffer {
  107. T data[S];
  108. int start = 0;
  109. int end = 0;
  110. int mask(int i) const {
  111. return i & (S - 1);
  112. }
  113. void push(T t) {
  114. int i = mask(end++);
  115. data[i] = t;
  116. }
  117. T shift() {
  118. return data[mask(start++)];
  119. }
  120. void clear() {
  121. start = end;
  122. }
  123. bool empty() const {
  124. return start >= end;
  125. }
  126. bool full() const {
  127. return end - start >= S;
  128. }
  129. int size() const {
  130. return end - start;
  131. }
  132. int capacity() const {
  133. return S - size();
  134. }
  135. };
  136. /** A cyclic buffer which maintains a valid linear array of size S by keeping a copy of the buffer in adjacent memory.
  137. S must be a power of 2.
  138. push() is constant time O(2) relative to RingBuffer
  139. */
  140. template <typename T, int S>
  141. struct DoubleRingBuffer {
  142. T data[S*2];
  143. int start = 0;
  144. int end = 0;
  145. int mask(int i) const {
  146. return i & (S - 1);
  147. }
  148. void push(T t) {
  149. int i = mask(end++);
  150. data[i] = t;
  151. data[i + S] = t;
  152. }
  153. T shift() {
  154. return data[mask(start++)];
  155. }
  156. void clear() {
  157. start = end;
  158. }
  159. bool empty() const {
  160. return start >= end;
  161. }
  162. bool full() const {
  163. return end - start >= S;
  164. }
  165. int size() const {
  166. return end - start;
  167. }
  168. int capacity() const {
  169. return S - size();
  170. }
  171. /** Returns a pointer to S consecutive elements for appending.
  172. If any data is appended, you must call endIncr afterwards.
  173. Pointer is invalidated when any other method is called.
  174. */
  175. T *endData() {
  176. return &data[mask(end)];
  177. }
  178. void endIncr(int n) {
  179. int e = mask(end);
  180. int e1 = e + n;
  181. int e2 = mini(e1, S);
  182. // Copy data forward
  183. memcpy(data + S + e, data + e, sizeof(T) * (e2 - e));
  184. if (e1 > S) {
  185. // Copy data backward from the doubled block to the main block
  186. memcpy(data, data + S, sizeof(T) * (e1 - S));
  187. }
  188. end += n;
  189. }
  190. /** Returns a pointer to S consecutive elements for consumption
  191. If any data is consumed, call startIncr afterwards.
  192. */
  193. const T *startData() const {
  194. return &data[mask(start)];
  195. }
  196. void startIncr(int n) {
  197. start += n;
  198. }
  199. };
  200. /** A cyclic buffer which maintains a valid linear array of size S by sliding along a larger block of size N.
  201. The linear array of S elements are moved back to the start of the block once it outgrows past the end.
  202. This happens every N - S pushes, so the push() time is O(1 + S / (N - S)).
  203. For example, a float buffer of size 64 in a block of size 1024 is nearly as efficient as RingBuffer.
  204. */
  205. template <typename T, size_t S, size_t N>
  206. struct AppleRingBuffer {
  207. T data[N];
  208. size_t start = 0;
  209. size_t end = 0;
  210. void push(T t) {
  211. data[end++] = t;
  212. if (end >= N) {
  213. // move end block to beginning
  214. memmove(data, &data[N - S], sizeof(T) * S);
  215. start -= N - S;
  216. end = S;
  217. }
  218. }
  219. T shift() {
  220. return data[start++];
  221. }
  222. bool empty() const {
  223. return start >= end;
  224. }
  225. bool full() const {
  226. return end - start >= S;
  227. }
  228. size_t size() const {
  229. return end - start;
  230. }
  231. /** Returns a pointer to S consecutive elements for appending, requesting to append n elements.
  232. */
  233. T *endData(size_t n) {
  234. // TODO
  235. return &data[end];
  236. }
  237. /** Returns a pointer to S consecutive elements for consumption
  238. If any data is consumed, call startIncr afterwards.
  239. */
  240. const T *startData() const {
  241. return &data[start];
  242. }
  243. void startIncr(size_t n) {
  244. // This is valid as long as n < S
  245. start += n;
  246. }
  247. };
  248. template<int CHANNELS>
  249. struct SampleRateConverter {
  250. SRC_STATE *state;
  251. SRC_DATA data;
  252. SampleRateConverter() {
  253. int error;
  254. state = src_new(SRC_SINC_FASTEST, CHANNELS, &error);
  255. assert(!error);
  256. data.src_ratio = 1.0;
  257. data.end_of_input = false;
  258. }
  259. ~SampleRateConverter() {
  260. src_delete(state);
  261. }
  262. /** output_sample_rate / input_sample_rate */
  263. void setRatio(float r) {
  264. src_set_ratio(state, r);
  265. data.src_ratio = r;
  266. }
  267. void setRatioSmooth(float r) {
  268. data.src_ratio = r;
  269. }
  270. /** `in` and `out` are interlaced with the number of channels */
  271. void process(const Frame<CHANNELS> *in, int *inFrames, Frame<CHANNELS> *out, int *outFrames) {
  272. // Old versions of libsamplerate use float* here instead of const float*
  273. data.data_in = (float*) in;
  274. data.input_frames = *inFrames;
  275. data.data_out = (float*) out;
  276. data.output_frames = *outFrames;
  277. src_process(state, &data);
  278. *inFrames = data.input_frames_used;
  279. *outFrames = data.output_frames_gen;
  280. }
  281. void reset() {
  282. src_reset(state);
  283. }
  284. };
  285. /** Perform a direct convolution
  286. x[-len + 1] to x[0] must be defined
  287. */
  288. inline float convolve(const float *x, const float *kernel, int len) {
  289. float y = 0.0;
  290. for (int i = 0; i < len; i++) {
  291. y += x[-i] * kernel[i];
  292. }
  293. return y;
  294. }
  295. inline void blackmanHarrisWindow(float *x, int n) {
  296. const float a0 = 0.35875;
  297. const float a1 = 0.48829;
  298. const float a2 = 0.14128;
  299. const float a3 = 0.01168;
  300. for (int i = 0; i < n; i++) {
  301. x[i] *= a0
  302. - a1 * cosf(2 * M_PI * i / (n - 1))
  303. + a2 * cosf(4 * M_PI * i / (n - 1))
  304. - a3 * cosf(6 * M_PI * i / (n - 1));
  305. }
  306. }
  307. inline void boxcarFIR(float *x, int n, float cutoff) {
  308. for (int i = 0; i < n; i++) {
  309. float t = (float)i / (n - 1) * 2.0 - 1.0;
  310. x[i] = sincf(t * n * cutoff);
  311. }
  312. }
  313. template<int OVERSAMPLE, int QUALITY>
  314. struct Decimator {
  315. DoubleRingBuffer<float, OVERSAMPLE*QUALITY> inBuffer;
  316. float kernel[OVERSAMPLE*QUALITY];
  317. Decimator(float cutoff = 0.9) {
  318. boxcarFIR(kernel, OVERSAMPLE*QUALITY, cutoff * 0.5 / OVERSAMPLE);
  319. blackmanHarrisWindow(kernel, OVERSAMPLE*QUALITY);
  320. // The sum of the kernel should be 1
  321. float sum = 0.0;
  322. for (int i = 0; i < OVERSAMPLE*QUALITY; i++) {
  323. sum += kernel[i];
  324. }
  325. for (int i = 0; i < OVERSAMPLE*QUALITY; i++) {
  326. kernel[i] /= sum;
  327. }
  328. }
  329. float process(float *in) {
  330. memcpy(inBuffer.endData(), in, OVERSAMPLE*sizeof(float));
  331. inBuffer.endIncr(OVERSAMPLE);
  332. float out = convolve(inBuffer.endData() + OVERSAMPLE*QUALITY, kernel, OVERSAMPLE*QUALITY);
  333. // Ignore the ring buffer's start position
  334. return out;
  335. }
  336. };
  337. // Pre-made minBLEP samples in minBLEP.cpp
  338. extern const float minblep_16_32[];
  339. template<int ZERO_CROSSINGS>
  340. struct MinBLEP {
  341. float buf[2*ZERO_CROSSINGS] = {};
  342. int pos = 0;
  343. const float *minblep;
  344. int oversample;
  345. /** Places a discontinuity with magnitude dx at -1 < p <= 0 relative to the current frame */
  346. void jump(float p, float dx) {
  347. if (p <= -1 || 0 < p)
  348. return;
  349. for (int j = 0; j < 2*ZERO_CROSSINGS; j++) {
  350. float minblepIndex = ((float)j - p) * oversample;
  351. int index = (pos + j) % (2*ZERO_CROSSINGS);
  352. buf[index] += dx * (-1.0 + interpf(minblep, minblepIndex));
  353. }
  354. }
  355. float shift() {
  356. float v = buf[pos];
  357. buf[pos] = 0.0;
  358. pos = (pos + 1) % (2*ZERO_CROSSINGS);
  359. return v;
  360. }
  361. };
  362. struct RCFilter {
  363. float c = 0.0;
  364. float xstate[1] = {};
  365. float ystate[1] = {};
  366. // `r` is the ratio between the cutoff frequency and sample rate, i.e. r = f_c / f_s
  367. void setCutoff(float r) {
  368. c = 2.0 / r;
  369. }
  370. void process(float x) {
  371. float y = (x + xstate[0] - ystate[0] * (1 - c)) / (1 + c);
  372. xstate[0] = x;
  373. ystate[0] = y;
  374. }
  375. float lowpass() {
  376. return ystate[0];
  377. }
  378. float highpass() {
  379. return xstate[0] - ystate[0];
  380. }
  381. };
  382. struct PeakFilter {
  383. float state = 0.0;
  384. float c = 0.0;
  385. /** Rate is lambda / sampleRate */
  386. void setRate(float r) {
  387. c = 1.0 - r;
  388. }
  389. void process(float x) {
  390. if (x > state)
  391. state = x;
  392. state *= c;
  393. }
  394. float peak() {
  395. return state;
  396. }
  397. };
  398. struct SlewLimiter {
  399. float rise = 1.0;
  400. float fall = 1.0;
  401. float out = 0.0;
  402. float process(float in) {
  403. float delta = clampf(in - out, -fall, rise);
  404. out += delta;
  405. return out;
  406. }
  407. };
  408. struct SchmittTrigger {
  409. /** 0 unknown, 1 low, 2 high */
  410. int state = 0;
  411. float low = 0.0;
  412. float high = 1.0;
  413. void setThresholds(float low, float high) {
  414. this->low = low;
  415. this->high = high;
  416. }
  417. /** Returns true if triggered */
  418. bool process(float in) {
  419. bool triggered = false;
  420. if (in >= high) {
  421. if (state == 1)
  422. triggered = true;
  423. state = 2;
  424. }
  425. else if (in <= low) {
  426. state = 1;
  427. }
  428. return triggered;
  429. }
  430. void reset() {
  431. state = 0;
  432. }
  433. };
  434. } // namespace rack