Login / Register 0 items | $0.00 New @ KVR
14 posts since 22 May, 2006

Postby pizzafilms; Wed Jun 14, 2017 7:05 am All Pass filter tuning help

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 samples
float buff0 = buffer[bufferIndex];
float buff1 = buffer[bufferIndexPlus1];
float x = (buff0 + buff1) * 0.5f;

// run it through the all pass filter
float y = -a * x + z1;
z1 = y * a + x;

// put it back in the buffer
buffer[bufferIndex] = y;

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

What am I missing?
2247 posts since 17 Apr, 2005, from S.E. TN

Postby JCJR; Wed Jun 14, 2017 11:56 am Re: All Pass filter tuning help

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.
944 posts since 1 Dec, 2004

Postby MadBrain; Wed Jun 14, 2017 3:38 pm Re: All Pass filter tuning help

See John Dattorro's classic paper on this

(I read it, and I got an industrial-strength delay line for physical models from it!)
User avatar
Music Engineer
3753 posts since 8 Mar, 2004, from Berlin, Germany

Postby Music Engineer; Tue Jun 20, 2017 6:44 am Re: All Pass filter tuning help

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.
User avatar
Max M.
239 posts since 20 Apr, 2005, from Moscow, Russian Federation

Postby Max M.; Wed Jun 21, 2017 11:21 pm Re: All Pass filter tuning help

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)
4840 posts since 11 Feb, 2006, from Helsinki, Finland

Postby mystran; Fri Jun 23, 2017 12:51 pm Re: All Pass filter tuning help

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).
Image <- plugins | forum

Moderator: Moderators (Main)

Return to DSP and Plug-in Development