19#include "deluge/util/fixedpoint.h"
20#include "deluge/util/functions.h"
23namespace deluge::dsp {
27constexpr q31_t FOLD_MIN = 0.1 * ONE_Q31;
28constexpr q31_t THREE_FOURTHS = 0.75 * ONE_Q31;
29inline q31_t fold(q31_t input, q31_t level) {
36 q31_t max = level >> 8;
40 else if (input < -max) {
44 return 2 * extra - input;
50inline q31_t polynomialOscillatorApproximation(q31_t x) {
53 q31_t x2 = 2 * multiply_32x32_rshift32(x, x);
54 q31_t x3 = 2 * multiply_32x32_rshift32(x2, x);
56 q31_t r1 = 8 * (multiply_32x32_rshift32(THREE_FOURTHS, x) - x3);
58 q31_t r2 = 2 * multiply_32x32_rshift32(r1, r1);
59 q31_t r3 = 2 * multiply_32x32_rshift32(r2, r1);
61 q31_t out = 8 * (multiply_32x32_rshift32(THREE_FOURTHS, r1) - r3);
66inline void foldBufferPolyApproximation(q31_t* startSample, q31_t* endSample, q31_t level) {
67 q31_t* currentSample = startSample;
68 q31_t fold_level = add_saturate(level, FOLD_MIN);
71 q31_t c = *currentSample;
73 q31_t x = lshiftAndSaturateUnknown(multiply_32x32_rshift32(fold_level, c), 8);
76 *currentSample = polynomialOscillatorApproximation(x) >> 7;
79 }
while (currentSample < endSample);
84inline void foldBuffer(q31_t* startSample, q31_t* endSample, q31_t foldLevel) {
85 q31_t* currentSample = startSample;
87 q31_t outs = fold(*currentSample, foldLevel);
89 *currentSample = outs + 4 * multiply_32x32_rshift32(outs, foldLevel);
92 }
while (currentSample < endSample);