Allpass group delay formula and effect on Karplus-Strong Some introductory questions:


What is the unit of the group delay in a digital filter (is it samples?)
What is $\Omega$ in the equations below (is it $\Omega=2 \pi\frac{f}{f_{sample}} ?) $


If I got any of these wrong, then there is no point reading the rest of this question. Just correct me.

What I want to achieve

I am using a Karplus-Strong algorithm to simulate a steel string. I noticed, that I need to detune the harmonics to higher frequencies, so it really sounds like a steel string (see here). To achive this, I added an allpass to the delay in the feedback loop. 

$$H(z) = \frac{a + z^{-1}}{1 + az^{-1}}$$

However the allpass adds an additional delay and detunes my string (lower). So I tried compensating for that additional delay by subtracting the group delay of the allpass from the main delay. 

The result was: it still detunes, but in the opposite direction.

The allpass delay:

Matt L.  gave me this formula for the group delay

$$\tau_g(\Omega) = \frac{1 - a^2}{1 + 2a \cos(\Omega) + a^2} $$

$$\Delta t = \frac{\tau_g}{f_{sample}}$$

But robert pointed out that it is the phase delay which determines the pitch and gave me this formula:

$$ \tau_\phi(\Omega) \ = \ \frac{1}{\Omega} \arctan\left(\frac{(1-a^2)\sin(\Omega)}{(1+a^2)\cos(\Omega) + 2a} \right) $$

But alas, when I subtract either of the two from the total delay in the feedback loop (i.e. the regular delay plus the allpass) it appears I am overcompensating. There is no problem with posive $a$ which leaves the fundamental undelayed, but for negative $a$ (e.g. $a=-0.93$) the string is about half a semitone too high. 

Edit (1)

I had an error in the formulas which is fixed by now (thanks to Matt L.). Originally my string was tuned too low, after the fix it is too high.

Edit(2)

Meanwhile (thanks to Matt L. and robert) I have little doubt, that my calculations are basically correct. I ran my allpass through scilab and the group delay is reported as apx. 30 samples. With the formulas from Matt and Robert I get values around 31 samples. Hoever, to tune the string correctly (by ear) I must compensate for 24 samples only.

Interestingly Miguel Negrão who did some research on plucked steel strings wrote in his thesis: Generally a negative value of a would have been used, which would have delayed the lower frequencies more than the high frequencies (phase delay), and would require a re-tuning of the main delay in the string loop to keep the string at the same fundamental frequency. In the SupaStrings system case, after some listening tests, a positive value of
a was used instead (non-physical) which keeps the low partials more a less in the same frequency but detunes the high partials down to a lower frequency.

It seems like he faced similar difficulties and couldn't solve them, even though he is quite a brilliant guy.
For the Karplus-Strong algorithm, your primary concern is for phase delay,
$$ \tau_\phi(\omega) \ = \ - \frac{\phi(\omega)}{\omega} $$

rather than group delay.
$$ \tau_g(\omega) \ = \ - \frac{d \phi(\omega)}{d \omega} $$

where
$$ \phi(\omega) \ \triangleq \ \arg \left\{ H(e^{j \omega}) \right\} $$
and $H(z)$ is the transfer function of your filter, and
$$  H(e^{i \omega}) \ = \ \left| H(e^{j \omega}) \right| e^{j \phi(\omega)} $$

For phase delay, it is important to unwrap the phase, which is not necessary for 1st-order APFs.

This is because, for a sinusoid, it's the phase delay that is the actual delay, in units of time, that the filter delays a simple sinusoid.  The group delay is the amount the envelope of the sinusoid is delayed.

For linear-phase filters, $\tau_\phi(\omega)=\tau_g(\omega)$ for all $\omega$ and for any filter $\tau_\phi(0)=\tau_g(0)$.  Phase delay and group delay are not generally the same value in other circumstances.

Now for the 1st-order APF with its pole at $p$:
$$ H(z) \ = \ \frac{1-pz}{z-p}$$
the phase delay in sample units is
$$ \tau_\phi(\omega) \ = \ \frac{1}{\omega} \arctan\left(\frac{(1-p^2)\sin(\omega)}{(1+p^2)\cos(\omega) - 2p} \right) $$
and the group delay in sample units is (same expression MattL gets)
$$ \tau_g(\omega) \ = \ \frac{1-p^2}{1+p^2 - 2p\cos(\omega)} $$

the delay (phase or group) at DC is $\tau_\phi(0) = \tau_g(0) = \frac{1+p}{1-p}$ and we normally have $-1 \le p \le 0$ to get a delay of between 0 and 1 sample.

Now, in the Karplus-Strong algorithm, the frequency of every harmonic (perhaps better called a "partial"), including the 1st harmonic (which we'll call the "fundamental") is the reciprocal of the total loop delay (phase delay) at the frequency of that partial.  That is a circular mathematical relationship.  For the $k$th partial (and assuming normalized sampling frequency $f_s=1$):
$$ f_k \ = \ \frac{k}{n + \tau_\phi(2 \pi f_k)} $$
where $n$ are the integer number of samples in the delay line that is in series with the APF.  Given your fundamental frequency $f_1$, the value of $n$ is $$ n \ = \ \left\lfloor \frac{1}{f_1} \right\rfloor \ = \ \mbox{floor}\left(\frac{1}{f_1}\right) $$
 (Be sure to add 1 sample that is necessary in a digital filter with feedback.)

Now, often we approximate using the DC delay, but to design this exactly, you need to somehow solve that frequency-dependent phase delay at the frequency of each partial.  That's a bitch.  So you would need to solve
$$ \frac{k}{f_k} \ = \ n + \tau_\phi(2 \pi f_k) \ = \ n + \frac{1}{2 \pi f_k} \arctan\left(\frac{(1-p^2)\sin(2 \pi f_k)}{(1+p^2)\cos(2 \pi f_k) - 2p} \right) $$
for $f_k$ given every integer $k$.