12 #ifndef AUDIODELAY_FEEDBACK_H_
13 #define AUDIODELAY_FEEDBACK_H_
20 enum interpolation_types {LINEAR,ALLPASS};
35 template <uint16_t NUM_BUFFER_SAMPLES, int8_t INTERP_TYPE = LINEAR>
76 return next(input, Int2Type<INTERP_TYPE>());
91 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
92 uint16_t read_pos = (write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
94 int16_t delay_sig = delay_array[read_pos];
98 int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127);
99 delay_array[write_pos] = (int16_t) input + feedback_sig;
116 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
118 uint16_t index = Q16n16_to_Q16n0(delaytime_cells);
119 uint16_t fraction = (uint16_t) delaytime_cells;
121 uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
122 int16_t delay_sig1 = delay_array[read_pos1];
124 uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
125 int16_t delay_sig2 = delay_array[read_pos2];
128 int16_t difference = delay_sig2 - delay_sig1;
129 int16_t delay_sig_fraction = (int16_t)((int32_t)((int32_t) fraction * difference) >> 16);
131 int16_t delay_sig = delay_sig1+delay_sig_fraction;
135 int8_t feedback_sig = (int8_t) min(max((((int16_t)(delay_sig * _feedback_level))>>7),-128),127);
136 delay_array[write_pos] = (int16_t) input + feedback_sig;
148 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
149 delay_array[write_pos] = input;
160 delay_array[write_pos] = input;
170 void write(int8_t input, uint16_t offset)
172 uint16_t _pos = (write_pos + offset) & (NUM_BUFFER_SAMPLES - 1);
173 delay_array[_pos] = input;
184 return read(delaytime_cells, Int2Type<INTERP_TYPE>());
194 return read(Int2Type<INTERP_TYPE>());
206 _delaytime_cells = (uint16_t) delaytime_cells;
218 return setDelayTimeCells(delaytime_cells, Int2Type<INTERP_TYPE>());
230 return setDelayTimeCells(delaytime_cells,
Int2Type<INTERP_TYPE>());
240 _feedback_level = feedback_level;
248 int8_t _feedback_level;
249 uint16_t _delaytime_cells;
258 int16_t next(int8_t in_value, Int2Type<LINEAR>)
260 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
261 uint16_t read_pos = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
263 int16_t delay_sig = delay_array[read_pos];
264 int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127);
265 delay_array[write_pos] = (int16_t) in_value + feedback_sig;
280 int16_t next(int8_t input, Int2Type<ALLPASS>)
293 static int8_t last_in;
294 static int16_t last_out;
296 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
298 uint16_t read_pos1 = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
299 int16_t delay_sig = delay_array[read_pos1];
301 int16_t interp = (int16_t)(_coeff * ((int16_t)input - last_out)>>16) + last_in;
304 int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127);
305 delay_array[write_pos] = (int16_t) input + feedback_sig;
308 last_out = delay_sig;
317 void setDelayTimeCells(Q16n16 delaytime_cells,
Int2Type<ALLPASS>)
325 _delaytime_cells = delaytime_cells>>16;
326 Q15n16 dminus1 = - Q15n16_FIX1 + (uint16_t) delaytime_cells;
327 Q15n16 dminus1squared = (dminus1)*(dminus1)>>16;
328 _coeff = -(dminus1>>1) + (dminus1squared>>2) - (((dminus1squared*dminus1)>>16)>>3);
334 void setDelayTimeCells(
float delaytime_cells,
Int2Type<ALLPASS>)
337 _delaytime_cells = (uint16_t) delaytime_cells;
339 float fraction = delaytime_cells - _delaytime_cells;
342 float alpha_ = 1.0f + fraction;
343 if ( alpha_ < 0.5f ) {
349 _delaytime_cells += 1;
350 if ( _delaytime_cells >= NUM_BUFFER_SAMPLES ) _delaytime_cells -= NUM_BUFFER_SAMPLES;
354 _coeff = float_to_Q15n16((1.f-alpha_)/(1.f+alpha_));
375 int16_t read(Q16n16 delaytime_cells, Int2Type<LINEAR>)
377 uint16_t index = (Q16n16)delaytime_cells >> 16;
378 uint16_t fraction = (uint16_t) delaytime_cells;
380 uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
381 int16_t delay_sig1 = delay_array[read_pos1];
383 uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
384 int16_t delay_sig2 = delay_array[read_pos2];
392 int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;