12 #ifndef AUDIODELAY_FEEDBACK_H_ 13 #define AUDIODELAY_FEEDBACK_H_ 24 enum interpolation_types {LINEAR,ALLPASS};
39 template <uint16_t NUM_BUFFER_SAMPLES, int8_t INTERP_TYPE = LINEAR>
40 class AudioDelayFeedback
80 return next(input, Int2Type<INTERP_TYPE>());
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);
122 uint16_t index = Q16n16_to_Q16n0(delaytime_cells);
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 uint16_t _pos = (write_pos + offset) & (NUM_BUFFER_SAMPLES - 1);
177 delay_array[_pos] = input;
188 return read(delaytime_cells, Int2Type<INTERP_TYPE>());
198 return read(Int2Type<INTERP_TYPE>());
210 _delaytime_cells = (uint16_t) delaytime_cells;
222 return setDelayTimeCells(delaytime_cells, Int2Type<INTERP_TYPE>());
234 return setDelayTimeCells(delaytime_cells,
Int2Type<INTERP_TYPE>());
244 _feedback_level = feedback_level;
250 int16_t delay_array[NUM_BUFFER_SAMPLES];
252 int8_t _feedback_level;
253 uint16_t _delaytime_cells;
262 int16_t next(int8_t in_value, Int2Type<LINEAR>)
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;
284 int16_t next(int8_t input, Int2Type<ALLPASS>)
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;
321 void setDelayTimeCells(Q16n16 delaytime_cells,
Int2Type<ALLPASS>)
329 _delaytime_cells = delaytime_cells>>16;
330 Q15n16 dminus1 = - Q15n16_FIX1 + (uint16_t) delaytime_cells;
331 Q15n16 dminus1squared = (dminus1)*(dminus1)>>16;
332 _coeff = -(dminus1>>1) + (dminus1squared>>2) - (((dminus1squared*dminus1)>>16)>>3);
338 void setDelayTimeCells(
float delaytime_cells,
Int2Type<ALLPASS>)
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;
358 _coeff = float_to_Q15n16((1.f-alpha_)/(1.f+alpha_));
379 int16_t read(Q16n16 delaytime_cells, Int2Type<LINEAR>)
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;
void write(int8_t input)
Input a value to the delay but don't change the delay time or retrieve the output signal...
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.
int16_t read(Q16n16 delaytime_cells)
Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
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. ...
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.
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...
AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level)
Constructor.