3
$\begingroup$

I'm trying to get a handle on the importance of the error feedback term in noise shaping operation in typical audio dither algorithms.

I'm thinking in terms of four signals. The original signal, the output (quantised) signal, the dither signal, and the error signal (the difference between output and original).

A simple approach would be to generate white noise and apply a filter to it to generate a coloured dither signal, add this to the original signal, quantise to the output signal, and disregard the error signal. It appears to be a fairly common approach to use white (unfiltered) or violet (differentiated) noise functions in this configuration.

Another approach I see implemented is to take the error signal and filter that and add white noise to define the dither signal, then add it to the original, quantise, and calculate the next error term for the filter. This implies a tight loop for the data flow -- we cannot compute a new error term without resolving the previous one -- making it hard to use SIMD efficiently.

From those I can infer a third option -- forgo the noise altogether and simply filter and reintegrate the error signal directly. I suppose this comes with some risk of modulation artefacts related to but distinct from the artefacts introduced by quantisation without any dither or shaping at all; however, I suspect this might be how it's done in some high-frequency 1-bit cases.

The point I'm unclear on is that complex filters which attempt to model the threshold of human hearing appear to come under the title of 'noise shaping', and this implies (supported by implementations I have seen) use of the error feedback term.

Is it a flawed or misguided approach to forgo the error feedback but still use the complex filter on white noise for the dither function? Is the error signal genuinely offering something important here?

$\endgroup$
  • $\begingroup$ With approach 2, since you are filtering the error signal, not using a tight loop would simply imply that your filter has a slightly greater delay, and thus a requirement to handle the error feedback appropriately for stability. $\endgroup$ – hotpaw2 Apr 4 '14 at 19:20
  • $\begingroup$ @hotpaw2, if I add a delay then the separation between the mistake and the compensation grows, and (eg., 8-sample delay) after 170us (6kHz) I wonder what information I would actually be preserving. $\endgroup$ – sh1 Apr 4 '14 at 19:55
  • $\begingroup$ Noise shaping generally preserves DC and/or low frequency information at the cost of increasing high frequency quantization noise. $\endgroup$ – hotpaw2 Apr 4 '14 at 20:10
  • $\begingroup$ @hotpaw2, What I mean is I don't know how much value remains in the error information when it's been removed so far from the moment it occurred. I also don't know how to correct the filter design, but that's a separate issue. $\endgroup$ – sh1 Apr 5 '14 at 3:00
  • $\begingroup$ At DC, the error term remains valuable even when removed very far (seconds, minutes) from the quantization. $\endgroup$ – hotpaw2 Apr 5 '14 at 3:14
2
$\begingroup$

i dunno what a "Lipshitz filter" is but i do know who Stanley Lipshitz is. now, i don't know for sure what Stanley would say to you, but the best advice i got from him is that it does little good to color the additive dither if you are also using error feedback. if there is no noise shaping feedback, probably the simplest way to get triangular PDF dither is to generate good, independent, rectangular PDF random numbers $v[n]$ and run that through a differentiator.

$$ d[n] = v[n] - v[n-1] $$

the result is high-pass in the spectrum and triangular PDF. if $\Delta$ is the step size of the quantization, $\frac{\Delta^2}{12}$ is the variance (or power) of raw quantizer, but you have two more of them due to your dither and $\frac{\Delta^2}{4}$ is the total power due to the entire dithered quantizer. a 4.77 dB increase in quantization error, but the quantization is fully decoupled from both the mean and variance of the input signal. although this is the same quantization power that you would get from adding two independent random numbers, i think you would prefer that much of the power is steered to higher frequencies (but not all of it, the spectrum of the raw quantizer is still flat).

if you're planning on error feedback, i think the best advice is either use white, triangular PDF dither (requires adding two independently generated rectangular PDF random numbers) and error feedback (designing a good feedback filter takes a bit).

or no dither (if the quantization step size is very small) and error feedback. the simplest no-trivial example of this is "fraction saving" where you simply hack off the low-order bits (the floor() function) and add those bits back in (zero-extended on the left) to the next sample before that sample is quantized (with the floor() function). it has infinite S/N ratio at DC and totally kills any limit cycle in feedback filters (like biquads) that get the filter stuck on a DC value even when the input goes to zero. i've done that a lot.

$\endgroup$
  • $\begingroup$ Regarding 'Lipshitz filter', I lifted the coefficients from SoX, along with the name, and stuck the word 'filter' on the end. That's probably not the way to name something, really, is it. $\endgroup$ – sh1 Apr 6 '14 at 22:39
  • $\begingroup$ I did start out my investigation with the intentention to see how far dither shaping without feedback (with differentiation as my baseline 'shape') could go, as I wanted to avoid unjustifiable computational complexity (battery drain) in mobile audio applications. It looks like the differentiator is going to be the right answer if I don't stumble into an error feedback filter that can handle an 8-tap delay. $\endgroup$ – sh1 Apr 6 '14 at 23:53
  • $\begingroup$ probably, a "Lipshitz filter" a feedback filter designed to be perceptually minimum in the shape of the spectrum of the quantization error. could well be called a "Wannamaker filter", too. anyway, are you saying that your error feedback filter is a sum of weighted values of the past 8 net quantization errors? probably the best (minimally audible) noise transfer function you might get from that is heavy on the high-pass side. i dunno what you would do with an 8-tap all-pole filter. probably all high-pass. $\endgroup$ – robert bristow-johnson Apr 7 '14 at 0:11
  • $\begingroup$ I mean my filter must be blind to the previous 7 error values to get good utilisation out of SIMD and ILP. If I refer to the error from the previous sample then I lose a lot (not all) of the parallelism. Effectively it would demand a filter with a 1 tap, seven zero taps, and then whatever remaining taps might salvage the situation. $\endgroup$ – sh1 Apr 7 '14 at 3:34
  • $\begingroup$ so is this one single channel? SIMD is two simultaneous threads that are executing identical instructions. why can't one thread be one channel and the other thread be the other channel? i don't get why SIMD precludes recursive noise shaping. dunno what ILP is. is it "In Line Programming"? i don't get why that precludes efficient pipelining of instructions. what is this, a SHArC or something else? $\endgroup$ – robert bristow-johnson Apr 8 '14 at 1:55
1
$\begingroup$

To get a feel for how to answer my own question I made a -90dB test tone ramp, and applied different processes to it, and plotted the spectrogram with SoX. The z axis is shifted up from the default to make things clearer.

First, the conventional approach (the second one described in my question) of filtering the error and adding this to the signal (shaping) before adding dither and quantising to calculate the new error:

Lipshitz-shaped error

Now to see what happens when we try to avoid reference to the error term, we apply the Lipshitz filter to white noise and use that as the dither before quantisation and discard the error:

Lipshitz-shaped white noise dither

What's obvious here is that while the noise floor can be raised in the same place as it's raised in the noise-shaping approach, it seems to hit a limit below which it cannot be lowered.

This is as one might expect, as it's subject to quantisation noise and the only thing special about the signal we're filtering is that it starts out white so that the quantisation noise isn't correlated.

So to complete the picture, we try removing the dither pattern and applying noise shaping in isolation:

Lipshitz-shaped, no dither

Oops! Obviously not a good idea.

So in answer of my own question, if you are going to dither and not noise-shape, there is limited value in using a complex transfer function for the dither pattern, because the quantisation noise floor still exists with dither and the regions that might come out especially clear with shaping are not accessible with plain dither.

That said, there must still be some merit in shaping the dither function, because I can at least reduce the noise in the low frequency region by using violet noise rather than white, and I don't know how far beyond that the theoretical limits of unshaped dither extend. So this answer is incomplete.


Correction: Originally I messed up a coefficient in the middle image (shaped white noise). I've updated the image, and things work better than before, but the same basic conclusion can still be drawn.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.