12 #ifndef AUDIODELAY_FEEDBACK_H_
13 #define AUDIODELAY_FEEDBACK_H_
17 #include "mozzi_utils.h"
19 #include "IntegerType.h"
21 enum interpolation_types {LINEAR,ALLPASS};
37 template <u
int16_t NUM_BUFFER_SAMPLES,
int8_t INTERP_TYPE = LINEAR,
typename su=
int8_t>
41 typedef typename IntegerType<
sizeof(su)+
sizeof(su)>::signed_type return_type;
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 return_type
next(su 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 return_type delay_sig = delay_array[read_pos];
103 su feedback_sig = (su) constrain( ((delay_sig * _feedback_level)>>7), -(1<<((
sizeof(su)<<3)-1)), (1<<((
sizeof(su)<<3)-1))-1);
104 delay_array[write_pos] = (return_type)input + feedback_sig;
121 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
124 uint16_t fraction = (uint16_t) delaytime_cells;
126 uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
127 return_type delay_sig1 = delay_array[read_pos1];
129 uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
130 return_type delay_sig2 = delay_array[read_pos2];
133 return_type difference = delay_sig2 - delay_sig1;
135 return_type delay_sig_fraction = (return_type)((
typename IntegerType<
sizeof(return_type)+
sizeof(return_type)>::signed_type)((
typename IntegerType<
sizeof(return_type)+
sizeof(return_type)>::signed_type)fraction * difference) >> 16);
137 return_type delay_sig = delay_sig1+delay_sig_fraction;
142 su feedback_sig = (su) constrain(((delay_sig * _feedback_level)>>7), -(1<<((
sizeof(su)<<3)-1)), (1<<((
sizeof(su)<<3)-1))-1);
143 delay_array[write_pos] = (return_type) input + feedback_sig;
155 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
156 delay_array[write_pos] = input;
167 delay_array[write_pos] = input;
177 void write(su input, uint16_t offset)
179 uint16_t _pos = (write_pos + offset) & (NUM_BUFFER_SAMPLES - 1);
180 delay_array[_pos] = input;
213 _delaytime_cells = (uint16_t) delaytime_cells;
247 _feedback_level = feedback_level;
253 return_type delay_array[NUM_BUFFER_SAMPLES];
255 int8_t _feedback_level;
256 uint16_t _delaytime_cells;
259 return_type last_out;
269 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
270 uint16_t read_pos = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
272 return_type delay_sig = delay_array[read_pos];
274 su feedback_sig = (su) constrain(((delay_sig * _feedback_level)>>7), -(1<<((
sizeof(su)<<3)-1)), (1<<((
sizeof(su)<<3)-1))-1);
275 delay_array[write_pos] = (return_type) in_value + feedback_sig;
309 ++write_pos &= (NUM_BUFFER_SAMPLES - 1);
311 uint16_t read_pos1 = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
312 return_type delay_sig = delay_array[read_pos1];
315 return_type interp = (return_type)(_coeff * ((return_type)input - last_out)>>(
sizeof(su)<<4)) + last_in;
319 su feedback_sig = (su) constrain(((delay_sig * _feedback_level)>>7), -(1<<((
sizeof(su)<<3)-1)), (1<<((
sizeof(su)<<3)-1))-1);
320 delay_array[write_pos] = (return_type) input + feedback_sig;
323 last_out = delay_sig;
340 _delaytime_cells = delaytime_cells>>16;
342 Q15n16 dminus1squared = (dminus1)*(dminus1)>>16;
343 _coeff = -(dminus1>>1) + (dminus1squared>>2) - (((dminus1squared*dminus1)>>16)>>3);
352 _delaytime_cells = (uint16_t) delaytime_cells;
354 float fraction = delaytime_cells - _delaytime_cells;
357 float alpha_ = 1.0f + fraction;
358 if ( alpha_ < 0.5f ) {
364 _delaytime_cells += 1;
365 if ( _delaytime_cells >= NUM_BUFFER_SAMPLES ) _delaytime_cells -= NUM_BUFFER_SAMPLES;
392 uint16_t index = (
Q16n16)delaytime_cells >> 16;
393 uint16_t fraction = (uint16_t) delaytime_cells;
395 uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
396 return_type delay_sig1 = delay_array[read_pos1];
398 uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
399 return_type delay_sig2 = delay_array[read_pos2];
408 return_type delay_sig = delay_sig1 + ((
typename IntegerType<
sizeof(return_type)+
sizeof(return_type)>::signed_type)delay_sig2*fraction)>>16;
Audio delay line with feedback for comb filter, flange, chorus and short echo effects.
AudioDelayFeedback(uint16_t delaytime_cells)
Constructor.
void setFeedbackLevel(int8_t feedback_level)
Set the feedback gain.
void setDelayTimeCells(Q16n16 delaytime_cells)
Set delay time expressed in samples, fractional Q16n16 for an interpolating delay.
return_type next(su input, uint16_t delaytime_cells)
Input a value to the delay, retrieve the signal in the delay line at the position delaytime_cells,...
void setDelayTimeCells(uint16_t delaytime_cells)
Set delay time expressed in samples.
void write(su input)
Input a value to the delay but don't change the delay time or retrieve the output signal.
return_type next(su input)
Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
AudioDelayFeedback(uint16_t delaytime_cells, int8_t feedback_level)
Constructor.
void write(su input, uint16_t offset)
Input a value to the delay at an offset from the current write position.
return_type read()
Retrieve the signal in the delay line at the current stored delaytime_cells.
void setDelayTimeCells(float delaytime_cells)
Set delay time expressed in samples, fractional float for an interpolating delay.
return_type read(Q16n16 delaytime_cells)
Retrieve the signal in the delay line at the interpolated fractional position delaytime_cells.
AudioDelayFeedback()
Constructor.
void writeFeedback(su input)
Input a value to the delay but don't advance the write position, change the delay time or retrieve th...
return_type next(su input, Q16n16 delaytime_cells)
Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional posi...
Q15n16 float_to_Q15n16(float a)
Convert float to Q15n16 fix.
int32_t Q15n16
signed fractional number using 15 integer bits and 16 fractional bits, represents -32767....
#define Q15n16_FIX1
1 in Q15n16 format
Q16n0 Q16n16_to_Q16n0(Q16n16 a)
Convert Q16n16 fixed to Q16n0 uint16_t.
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535....
Enables you to instantiate a template based on an integer value.
Provides appropriate integer types that can bit the given number of bytes on this platform (at most 6...