Skip to content

Commit

Permalink
Added third parameter for the type of sample getting in to AudioDelay…
Browse files Browse the repository at this point in the history
…Feedback
  • Loading branch information
tomcombriat committed Nov 5, 2024
1 parent 34f9474 commit 9123973
Showing 1 changed file with 47 additions and 34 deletions.
81 changes: 47 additions & 34 deletions AudioDelayFeedback.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ template <uint16_t NUM_BUFFER_SAMPLES, int8_t INTERP_TYPE = LINEAR, typename su=
class AudioDelayFeedback
{

typedef typename IntegerType<sizeof(su)+sizeof(su)>::signed_type return_type;

public:
/** Constructor.
*/
Expand Down Expand Up @@ -69,7 +71,7 @@ class AudioDelayFeedback
@note slower than next(int8_t input, uint16_t delaytime_cells)
*/
inline
typename IntegerType<sizeof(su)+sizeof(su)>::signed_type next(su input)
return_type next(su input)
{
// chooses a different next() function depending on whether the
// the template parameter is LINEAR(default if none provided) or ALLPASS.
Expand All @@ -86,24 +88,24 @@ class AudioDelayFeedback
@note Timing: 4us
*/
inline
typename IntegerType<sizeof(su)+sizeof(su)>::signed_type next(su input, uint16_t delaytime_cells)
return_type next(su input, uint16_t delaytime_cells)
{
//setPin13High();
++write_pos &= (NUM_BUFFER_SAMPLES - 1);
uint16_t read_pos = (write_pos - delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
// < 1us to here
IntegerType<sizeof(su)+sizeof(su)>::signed_type delay_sig = delay_array[read_pos]; // read the delay buffer
return_type delay_sig = delay_array[read_pos]; // read the delay buffer
// with this line, the method takes 18us
//int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127); // feedback clipped
// this line, the whole method takes 4us... Compiler doesn't optimise pow2 divides. Why?
//int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127); // feedback clipped
su feedback_sig = (su) constrain( ((delay_sig * feedback_level)>>7), (1<<((sizeof(su)<<3)-1))-1, -(1<<((sizeof(su)<<3)-1)));
delay_array[write_pos] = (IntegerType<sizeof(su)+sizeof(su)>::signed_type) input + feedback_sig; // write to buffer
su feedback_sig = (su) constrain( ((delay_sig * _feedback_level)>>7), (1<<((sizeof(su)<<3)-1))-1, -(1<<((sizeof(su)<<3)-1)));
delay_array[write_pos] = (return_type) input + feedback_sig; // write to buffer
//setPin13Low();
return delay_sig;
}

///////// STOPPED HERE FOR NOW


/** Input a value to the delay, retrieve the signal in the delay line at the interpolated fractional position delaytime_cells, and add feedback from the output to the input.
@param input the signal input.
Expand All @@ -112,7 +114,7 @@ class AudioDelayFeedback
value of _delaytime_cells.
*/
inline
int16_t next(int8_t input, Q16n16 delaytime_cells)
return_type next(su input, Q16n16 delaytime_cells)
{
//setPin13High();
++write_pos &= (NUM_BUFFER_SAMPLES - 1);
Expand All @@ -121,21 +123,23 @@ class AudioDelayFeedback
uint16_t fraction = (uint16_t) delaytime_cells; // keeps low word

uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
int16_t delay_sig1 = delay_array[read_pos1]; // read the delay buffer
return_type delay_sig1 = delay_array[read_pos1]; // read the delay buffer

uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
int16_t delay_sig2 = delay_array[read_pos2]; // read the delay buffer
return_type delay_sig2 = delay_array[read_pos2]; // read the delay buffer


int16_t difference = delay_sig2 - delay_sig1;
int16_t delay_sig_fraction = (int16_t)((int32_t)((int32_t) fraction * difference) >> 16);
return_type difference = delay_sig2 - delay_sig1;
//int16_t delay_sig_fraction = (int16_t)((int32_t)((int32_t) fraction * difference) >> 16);
return_type delay_sig_fraction = (return_type) ((typename IntegerType<sizeof(return_type)+sizeof(return_type)>::signed_type)fraction * difference) >> 16;

int16_t delay_sig = delay_sig1+delay_sig_fraction;
return_type delay_sig = delay_sig1+delay_sig_fraction;

//int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;

int8_t feedback_sig = (int8_t) min(max((((int16_t)(delay_sig * _feedback_level))>>7),-128),127); // feedback clipped
delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
//int8_t feedback_sig = (int8_t) min(max((((int16_t)(delay_sig * _feedback_level))>>7),-128),127); // feedback clipped
su feedback_sig = (su) constrain( ((delay_sig * _feedback_level)>>7), (1<<((sizeof(su)<<3)-1))-1, -(1<<((sizeof(su)<<3)-1)));
delay_array[write_pos] = (return_type) input + feedback_sig; // write to buffer
//setPin13Low();
return delay_sig;
}
Expand All @@ -145,7 +149,7 @@ class AudioDelayFeedback
@param input the signal input.
*/
inline
void write(int8_t input)
void write(su input)
{
++write_pos &= (NUM_BUFFER_SAMPLES - 1);
delay_array[write_pos] = input;
Expand All @@ -157,7 +161,7 @@ class AudioDelayFeedback
@param input the signal input.
*/
inline
void writeFeedback(int8_t input)
void writeFeedback(su input)
{
delay_array[write_pos] = input;
}
Expand All @@ -169,7 +173,7 @@ class AudioDelayFeedback
@param offset the number of cells behind the ordinary write position where the input will be written.
*/
inline
void write(int8_t input, uint16_t offset)
void write(su input, uint16_t offset)
{
uint16_t _pos = (write_pos + offset) & (NUM_BUFFER_SAMPLES - 1);
delay_array[_pos] = input;
Expand All @@ -181,7 +185,7 @@ class AudioDelayFeedback
@param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
*/
inline
int16_t read(Q16n16 delaytime_cells)
return_type read(Q16n16 delaytime_cells)
{
return read(delaytime_cells, Int2Type<INTERP_TYPE>());
}
Expand All @@ -191,7 +195,7 @@ class AudioDelayFeedback
It doesn't change the stored internal value of _delaytime_cells or feedback the output to the input.
*/
inline
int16_t read()
return_type read()
{
return read(Int2Type<INTERP_TYPE>());
}
Expand Down Expand Up @@ -245,26 +249,29 @@ class AudioDelayFeedback


private:
int16_t delay_array[NUM_BUFFER_SAMPLES];
return_type delay_array[NUM_BUFFER_SAMPLES];
uint16_t write_pos;
int8_t _feedback_level;
uint16_t _delaytime_cells;
Q15n16 _coeff; // for allpass interpolation
su last_in;
return_type last_out;



/** Input a value to the delay and retrieve the signal in the delay line at the position delaytime_cells.
@param in_value the signal input.
*/
inline
int16_t next(int8_t in_value, Int2Type<LINEAR>)
return_type next(su in_value, Int2Type<LINEAR>)
{
++write_pos &= (NUM_BUFFER_SAMPLES - 1);
uint16_t read_pos = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);

int16_t delay_sig = delay_array[read_pos]; // read the delay buffer
int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127); // feedback clipped
delay_array[write_pos] = (int16_t) in_value + feedback_sig; // write to buffer
return_type delay_sig = delay_array[read_pos]; // read the delay buffer
//int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)/128),-128),127); // feedback clipped
su feedback_sig = (su) constrain( ((delay_sig * _feedback_level)>>7), (1<<((sizeof(su)<<3)-1))-1, -(1<<((sizeof(su)<<3)-1)));
delay_array[write_pos] = (return_type) in_value + feedback_sig; // write to buffer

return delay_sig;
}
Expand All @@ -279,7 +286,7 @@ class AudioDelayFeedback
@note Timing: 10us
*/
inline
int16_t next(int8_t input, Int2Type<ALLPASS>)
return_type next(su input, Int2Type<ALLPASS>)
{
/*
http://www.scandalis.com/Jarrah/Documents/DelayLine.pdf
Expand All @@ -292,19 +299,24 @@ class AudioDelayFeedback
= coeff * (in-last_out) + last_in
*/
//setPin13High();

/* I think these should **not** be static
static int8_t last_in;
static int16_t last_out;

*/

++write_pos &= (NUM_BUFFER_SAMPLES - 1);

uint16_t read_pos1 = (write_pos - _delaytime_cells) & (NUM_BUFFER_SAMPLES - 1);
int16_t delay_sig = delay_array[read_pos1]; // read the delay buffer
return_type delay_sig = delay_array[read_pos1]; // read the delay buffer

int16_t interp = (int16_t)(_coeff * ((int16_t)input - last_out)>>16) + last_in; // Q15n16*Q15n0 + Q15n0 = Q15n16 + Q15n0 = Q15n16
//int16_t interp = (int16_t)(_coeff * ((int16_t)input - last_out)>>16) + last_in; // Q15n16*Q15n0 + Q15n0 = Q15n16 + Q15n0 = Q15n16
return_type interp = (return_type)(_coeff * ((return_type)input - last_out)>>(sizeof(su)<<4)) + last_in;
delay_sig += interp;

int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127); // feedback clipped
delay_array[write_pos] = (int16_t) input + feedback_sig; // write to buffer
//int8_t feedback_sig = (int8_t) min(max(((delay_sig * _feedback_level)>>7),-128),127); // feedback clipped
su feedback_sig = (su) constrain( ((delay_sig * _feedback_level)>>7), (1<<((sizeof(su)<<3)-1))-1, -(1<<((sizeof(su)<<3)-1)));
delay_array[write_pos] = (return_type) input + feedback_sig; // write to buffer

last_in = input;
last_out = delay_sig;
Expand Down Expand Up @@ -374,24 +386,25 @@ class AudioDelayFeedback
@param delaytime_cells indicates the delay time in terms of cells in the delay buffer.
*/
inline
int16_t read(Q16n16 delaytime_cells, Int2Type<LINEAR>)
return_type read(Q16n16 delaytime_cells, Int2Type<LINEAR>)
{
uint16_t index = (Q16n16)delaytime_cells >> 16;
uint16_t fraction = (uint16_t) delaytime_cells; // keeps low word

uint16_t read_pos1 = (write_pos - index) & (NUM_BUFFER_SAMPLES - 1);
int16_t delay_sig1 = delay_array[read_pos1]; // read the delay buffer
return_type delay_sig1 = delay_array[read_pos1]; // read the delay buffer

uint16_t read_pos2 = (write_pos - (index+1)) & (NUM_BUFFER_SAMPLES - 1);
int16_t delay_sig2 = delay_array[read_pos2]; // read the delay buffer
return_type delay_sig2 = delay_array[read_pos2]; // read the delay buffer

/*
int16_t difference = delay_sig2 - delay_sig1;
int16_t delay_sig_fraction = ((int32_t) fraction * difference) >> 16;
int16_t delay_sig = delay_sig1+delay_sig_fraction;
*/
int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;
//int16_t delay_sig = delay_sig1 + ((int32_t)delay_sig2*fraction)>>16;
return_type delay_sig = delay_sig1 + ((typename IntegerType<sizeof(return_type)+sizeof(return_type)>::signed_type)delay_sig2*fraction)>>16;

return delay_sig;
}
Expand Down

0 comments on commit 9123973

Please sign in to comment.