# About the Allpass Filter implementations

The allpass filter is known as a filter which has unity gain at each frequency,
while whose phase response can be arbitrary. There are many types of implementation of the
allpass filter, while some of them seem to be strane of wrong. I would like to introduce
some of them in this article.

## The original Freeverb's allpass implementation

The original Freeverb's reverb implementation is based on the algorithm proposed by Schroeder
and has eight parallel comb filters followed by four series allpass filters. But the allpass
implementation code below in Freeverb seem to be strange.

// FreeverbSource/Components/allpass.hpp
inline float allpass::process(float input)
{
float output;
float bufout;
bufout = buffer[bufidx];
undenormalise(bufout);
output = -input + bufout;
buffer[bufidx] = input + (bufout*feedback);
if(++bufidx>=bufsize) bufidx = 0;
return output;
}

The frequency response of this code (feedback=0.5) is shown below, which should be flat.

After some research, you will notice that the original freeverb's allpass
is just an sum of inverse input plus positive feedback comb filter.
I do not know why Jezar has implemented the allpass filter in this way,
but this is not the true allpass filter. The calculation reduction may be the reason.
In conclusion, the code below sould be the right implementation, whose frequency response is flat.

// FreeverbSource/Components/allpass.hpp
inline float allpass::process(float input)
{
float output;
float bufout;
bufout = buffer[bufidx];
undenormalise(bufout);
*buffer[bufidx] = input + (bufout*feedback);*
*output = -buffer[bufidx]*feedback + bufout;*
if(++bufidx>=bufsize) bufidx = 0;
return output;
}

This strange implementation is decribed
here.
It says that the true allpass filter is obtained if g = (sqrt(5)-1)/2 ~ 0.618
(reciprocal of the golden ratio) while that of freeverb is 0.5.

## The implementation in Freeverb3 library

inline _fv3_float_t process(_fv3_float_t input)
{
if(bufsize == 0) return input;
_fv3_float_t bufout = buffer[bufidx];
UNDENORMAL(bufout);
buffer[bufidx] = input + bufout * feedback;
_fv3_float_t output = bufout - buffer[bufidx] * feedback;
bufidx ++; if(bufidx >= bufsize) bufidx = 0;
return output;
}