## All Pass filter tuning help

pizzafilms
KVRer

14 posts since 22 May, 2006
I've been playing around with a Karplus-Strong algorithm and the simplest implementation suffers from tuning issues because of the buffer size being integer based when it really should be a float.

Code: Select all
`freq = 440.0;bufferSize = (sampleRate / freq) = ( 48000.0 / 440.0) = 109.090909`

I've read that adding an All Pass filter in the K-S loop is good way to tune the pitch. What I' not sure about is how to tune that All Pass filter.

I've read that to get a delay of N samples, a is calculated as (1.0 - N) / (1.0 + N). So in my example case, I need a delay of 0.090909, so a would equal (1.0 - 0.090909) / (1.0 + 0.090909) or 0.83333.

So the init code looks like:

Code: Select all
`float fBufferSize = sampleRate / freq;int bufferSize = (int)fBufferSize;float delay = fBufferSize - (float)bufferSize;a = (1.0f - delay) / (1.0f + delay);z1 = 0.0f;`

And then my K-S sample loop looks like this:

Code: Select all
`// average two of the samplesfloat buff0 = buffer[bufferIndex];float buff1 = buffer[bufferIndexPlus1];float x = (buff0 + buff1) * 0.5f;// run it through the all pass filterfloat y = -a * x + z1;z1 = y * a + x;// put it back in the bufferbuffer[bufferIndex] = y;`

That indeed changes the pitch, but not correctly. It's off.

What am I missing?
JCJR
KVRAF

2247 posts since 17 Apr, 2005, from S.E. TN
Hi Pizzafilms

Hopefully someone who knows will reply. How is the pitch off?

I never tried a karplus-strong but one characteristic of that typical first-order allpass delay-- So far as I know it delays in time (over the span of one sample) fairly evenly in low and mid frequencies, but all delay settings trend toward zero delay as it nears nyquist.

When reading about it, had guessed maybe this would detune the high harmonics "a fraction of a sample" sharp compared to the fundamental? Which would probably be cool because guitar and other "high tension" string instruments tend to have high harmonics sharp from the fundamental.

But not so cool-- Since each musical pitch would need a different fine-tune fractional delay, the amount of enharmonicity would vary according to whatever accidental amount of fractional sample delay might be required to tune each note?

Maybe real-world practical stringed instruments don't have sufficiently high harmonics to expose this hypothetical issue? Dunno.

OTOH if your delay calculation fails to tune the fundamental, dunno anything about it and maybe someone knows how to help.
KVRian

944 posts since 1 Dec, 2004
See John Dattorro's classic paper on this

(I read it, and I got an industrial-strength delay line for physical models from it!)
Music Engineer
KVRAF

3753 posts since 8 Mar, 2004, from Berlin, Germany
just an idea (i never implemented it, so take it with a grain of salt): a karplus-strong loop typically contains some kind of damping filter in the feedback path. it would seem to me like a sensible approach to evaluate the phase-delay of the damping filter (at the desired fundamental frequency) and then tune the allpass filter delay to a value that takes the damping filter's delay into account as well. maybe, with more complicated (higher order) damping filters, this may even require to shorten the (integer) delay line length? dunno, but something, i'd watch out for.
Max M.
KVRist

239 posts since 20 Apr, 2005, from Moscow, Russian Federation
I suspect you simply have your a sign wrong. For
Code: Select all
`k = (1.0 - N) / (1.0 + N)`

it should be:
Code: Select all
`y = x * k + z;z = y * -k + x;`

A more convenient method though would be to always have your allpass group delay to be 1.+ samples (and reduce the static delay by 1 sample accordingly), e.g. in your case:
Code: Select all
`k = (1.0 - 1.090909) / (1.0 + 1.090909) = -0.0434782192816617`
(to understand why this is better consider/compare the impulse responses of the allpass filters with N≈0 and N≈1)
mystran
KVRAF

4840 posts since 11 Feb, 2006, from Helsinki, Finland
pizzafilms wrote:I've read that adding an All Pass filter in the K-S loop is good way to tune the pitch. What I' not sure about is how to tune that All Pass filter.

All-pass filters will essentially let you tune one harmonic, because the phase response is non-linear, although in most cases if you just use it for fine-tuning (eg. 0.3 to 1.3 samples is sometimes suggested as good range) then it's not too bad.

On "low" frequencies you can use the DC delay pretty much directly and it'll be "good enough" but for sufficiently high fundamental you should probably solve the phase delay for the fundamental frequency. The only way out is to use linear-phase FIR interpolation, but the problem with that then is that you need to make a trade-off between high frequency performance (poor with short filters) vs. minimum delay length (you can't make the delay shorter than the interpolation latency).

Either way, it won't ever be perfect except at one particular frequency. Damping filters can also add their own phase delay if they are low cutoff (for typical "high" frequency damping the phase delay at "low" frequencies is pretty irrelevant).
<- plugins | forum

Moderator: Moderators (Main)