12 #ifndef AUDIODELAY_FEEDBACK_H_
13 #define AUDIODELAY_FEEDBACK_H_
21 #include "mozzi_utils.h"
24 enum interpolation_types {LINEAR,ALLPASS};
39 template <u
int16_t NUM_BUFFER_SAMPLES,
int8_t INTERP_TYPE = LINEAR>
55 AudioDelayFeedback(uint16_t delaytime_cells): write_pos(0), _feedback_level(0), _delaytime_cells(delaytime_cells)
65 AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level): write_pos(0), _feedback_level(feedback_level), _delaytime_cells(delaytime_cells)
92 int16_t
next(int8_t input, uint16_t delaytime_cells)
95 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
96 uint16_t read_pos = (write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
98 int16_t delay_sig = delay_array[read_pos];
102 int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127);
103 delay_array[write_pos] = (int16_t) input + feedback_sig;
120 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
123 uint16_t fraction = (uint16_t) delaytime_cells;
125 uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
126 int16_t delay_sig1 = delay_array[read_pos1];
128 uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
129 int16_t delay_sig2 = delay_array[read_pos2];
132 int16_t difference = delay_sig2 - delay_sig1;
133 int16_t delay_sig_fraction = (int16_t)((int32_t)((int32_t) fraction * difference) >> 16);
135 int16_t delay_sig = delay_sig1+delay_sig_fraction;
139 int8_t feedback_sig = (int8_t) min(max((((int16_t)(delay_sig * _feedback_level))>>7),-128),127);
140 delay_array[write_pos] = (int16_t) input + feedback_sig;
152 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
153 delay_array[write_pos] = input;
164 delay_array[write_pos] = input;
174 void write(int8_t input, uint16_t offset)
176 (write_pos + offset) &= (NUM_BUFFER_SAMPLES - 1);
177 delay_array[write_pos] = input;
210 _delaytime_cells = (uint16_t) delaytime_cells;
244 _feedback_level = feedback_level;
250 int16_t delay_array[NUM_BUFFER_SAMPLES];
252 int8_t _feedback_level;
253 uint16_t _delaytime_cells;
264 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
265 uint16_t read_pos = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
267 int16_t delay_sig = delay_array[read_pos];
268 int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127);
269 delay_array[write_pos] = (int16_t) in_value + feedback_sig;
297 static int8_t last_in;
298 static int16_t last_out;
300 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
302 uint16_t read_pos1 = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
303 int16_t delay_sig = delay_array[read_pos1];
305 int16_t interp = (int16_t)(_coeff * ((int16_t)input - last_out)>>16) + last_in;
308 int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127);
309 delay_array[write_pos] = (int16_t) input + feedback_sig;
312 last_out = delay_sig;
329 _delaytime_cells = delaytime_cells>>16;
331 Q15n16 dminus1squared = (dminus1)*(dminus1)>>16;
332 _coeff = -(dminus1>>1) + (dminus1squared>>2) - (((dminus1squared*dminus1)>>16)>>3);
341 _delaytime_cells = (uint16_t) delaytime_cells;
343 float fraction = delaytime_cells - _delaytime_cells;
346 float alpha_ = 1.0f + fraction;
347 if ( alpha_ < 0.5f ) {
353 _delaytime_cells += 1;
354 if ( _delaytime_cells >= NUM_BUFFER_SAMPLES ) _delaytime_cells -= NUM_BUFFER_SAMPLES;
381 uint16_t index = (
Q16n16)delaytime_cells >> 16;
382 uint16_t fraction = (uint16_t) delaytime_cells;
384 uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
385 int16_t delay_sig1 = delay_array[read_pos1];
387 uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
388 int16_t delay_sig2 = delay_array[read_pos2];
396 int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;
409 #endif // #ifndef AUDIODELAY_FEEDBACK_H_
int16_t next(int8_t input, uint16_t delaytime_cells)
Input a value to the delay, retrieve the signal in the delay line at the position delaytime_cells...
void write(int8_t input)
Input a value to the delay but don't change the delay time or retrieve the output signal...
Audio delay line with feedback for comb filter, flange, chorus and short echo effects.
void write(int8_t input, uint16_t offset)
Input a value to the delay at an offset from the current write position.
void setFeedbackLevel(int8_t feedback_level)
Set the feedback gain.
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767...
int16_t read(Q16n16 delaytime_cells)
Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
Q15n16 float_to_Q15n16(float a)
Convert float to Q15n16 fix.
Enables you to instantiate a template based on an integer value.
AudioDelayFeedback()
Constructor.
void writeFeedback(int8_t input)
Input a value to the delay but don't advance the write position, change the delay time or retrieve th...
void setDelayTimeCells(float delaytime_cells)
Set delay time expressed in samples, fractional float for an interpolating delay. ...
#define Q15n16_FIX1
1 in Q15n16 format
int16_t read()
Retrieve the signal in the delay line at the current stored delaytime_cells.
AudioDelayFeedback(uint16_t delaytime_cells)
Constructor.
void setDelayTimeCells(Q16n16 delaytime_cells)
Set delay time expressed in samples, fractional Q16n16 for an interpolating delay.
Q16n0 Q16n16_to_Q16n0(Q16n16 a)
Convert Q16n16 fixed to Q16n0 uint16_t.
int16_t next(int8_t input)
Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells...
int16_t next(int8_t input, Q16n16 delaytime_cells)
Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional posi...
void setDelayTimeCells(uint16_t delaytime_cells)
Set delay time expressed in samples.
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level)
Constructor.