# Preventing clipping in audio signal processing

I'm developing an FPGA upsampler for my DAC project. The last thing I can't figure out is how to prevent clipping which can obviously happen during the band limited interpolation.

• And what should I try to prevent it?
• I can attenuate the input signal a bit before filtering, but how much?
• And how does existing commercial oversampling DACs deal with clipping?
• This question is interesting, but not very good. Claiming something is "obvious" but not explaining how that could be, not defining what exactly you want to do, and where problems arise. If you want upvotes on your next question, give a more precise problem description! – Marcus Müller Jan 11 '17 at 22:55
• @MarcusMüller, try this infinite set of samples: $$x[n] = \begin{cases} (-1)^n \qquad & n \le 0 \\ \\ (-1)^{n-1} \qquad & n > 0 \\ \end{cases}$$ and interpolate this mofo as good as you can (better and better approximation of a $\operatorname{sinc}(\cdot)$ function). the input samples are all limited in amplitude: $$\Big|x[n] \Big| \le 1$$ but something kinda nasty happens between $x$ and $x$. – robert bristow-johnson Jan 12 '17 at 5:15
• i'll bet that the existing ΣΔ DACs give it about 6 dB of headroom and analog clip after that. maybe even soft clip. – robert bristow-johnson Jan 12 '17 at 5:18

# Is clipping obviously happening?

clipping which can obviously happen during the band limited interpolation.

I don't think it's obvious at all! You should ask yourself: How can clipping happen?

Right, clipping happens when you use a size-limited data type for data that might exceed that size.

Now, you claim that interpolation could lead to that. But what you're inherently saying is that you didn't take the effect of your interpolation algorithm into account when designing your signal processing – on an FPGA, the bitwidth $B$ at each processing step is yours to define, and if you see clipping, that is a sign that you chose a width that's too small.

Interpolation, if you think about it, should not give you "unexpectedly high" amplitudes; it might, depending on how you do it, increase the average amplitude by some factor, but since we aim to be bandlimited, there can't be wild fluctuations between the (scaled) input samples, and that would be necessary to introduce "dynamic range exceeding" samples. So, with a constant factor one can easily deal: simply round & cut off the "gained" lower bits; they contain "exactness" that your signal didn't have when it entered the interpolator. You might want to add a few bits after every computational step to account for numeric precision, but you don't really increase the dynamic range.

Generally, if you sensibly design your interpolator, there's no reason the output of it should have a larger bitwidth than the input. So, go and design wisely :)

# Different kinds of "interpolation"

Now, you forgot to mention which kind of interpolator you're referring to, so I'll just assume you haven't chosen one yet. I'll furthermore postulate everything will be fixed-point. I guess I haven't seen anything like this being done with floating point in FPGA, exactly for the reasons I'll explain below (namely, that you can essentially keep the dynamic range of the input without sacrificing a lot of FPGA real estate to floating point).

## Integer factor interpolation

For fixed, integer interpolations by factor $M$, you'd typically just use a fixed-point FIR as interpolator. Imagine simply adding $M-1$ zeros between each input sample, and then low-pass filtering that. Obviously, the power (i.e. average energy per sample) then gets reduced by $\frac 1M$ – since only that part of the samples has energy at all. That means that you can design a FIR filter that has an overall gain $g=2^p$, and use bitwidening multiplication (from $B$ for its input to $B+p$) to apply the taps, and afterward the accumulation just keep the upper $B$ bits. The choice of $p$ depends on how much ressources you want to spend on making the fixed-point FIR work like a real-valued one.

In practice, you'd not first add zeros, but implement this as a polyphase structure. In even more practice, you'd be likely to use an existing IP core – every major FPGA vendor has their own FIR implementations, and there's plenty opencores, and all the better ones do exactly this.

Imagine you do a $M$-polyphase decomposition of your interpolation FIR. Each of these components is bound to give the maximum value if fed with a signal that is a multiple of that component itself (Cauchy-Schwarz inequality: $|<a,b>|^2\le ||a||\cdot ||b||$ becomes equality because of bilinearity if $b=\alpha a$: \begin{align} |<a,\alpha a>|^2 &= |\alpha<a,a>|^2\\ &= \alpha^2 |<a,a>|^2\\ &= \alpha^2 ||a||^2 \\ &\mathbf= ||a||\cdot \alpha^2||a||\\ &= ||a|| \cdot ||\alpha a||\\ &= ||a|| \cdot ||b||\quad \forall \alpha\in \mathbb R \text) \end{align}

Now choose $\alpha_i = \frac{n_\text{maxint}}{\max(v_i)}$ for each polyphase compononent $v_i$, and you'll find the maximum amplitude your filter might ever produce to be $max(\alpha_0^2||v_0||, \ldots,\alpha_{M-1}^2 ||v_{M-1}||)$. So, you can easily find the maximum value you need to represent. Choose that as your accumulator bitwidth.

Or go lower, since any reasonable bandwidth-limiting interpolation filter will not have great overshoot.

## Rational-rate $R=\frac MN,\, M>N$ resampling

If aiming for a rational-rate resampler, ie. rate $R=\frac MN$, you would do the same – just that you concatenate an $M$-interpolating FIR with a $N$-decimating FIR, and apply the same logic. And, again, in fact you'd do a polyphase implementation (which allows you to cleverly decimate by $M$ first and interpolate by $N$ after, and only use the "sharper" one of both); or you'd realistically just use an IP core.

## Adjustable rate $M$ interpolation

For on-the-fly adjustable rates, you'd often use a CIC (cascaded integrator-comb) – which is in fact an IIR (which do not generally have the bounded-input->bounded output property of FIRs), but which has all the mathematical properties of a FIR, so that you're on the safe side, too.

## arbitrary resampling

If doing an arbitrary, non-rational resampling (eg. between two clock domains driven from independent oscillators that might or might not match), well, that is an application-specific problem, but I'm so fond of these that I'd say you'd probably use a polyphase filterbank-based arbitrary resampler. That works by interpolating linearly between outputs of different filters (choosing different filters for each output sample) to match the real resampling ratio as closely as possible.

An introduction to these would clearly exceed the scope of this answer, but for that, and all the basics of it as well as the polyphase stuff mentioned above, I suppose, you'd simply go to the primary source: f. harris, "Multirate Signal Processing for Communication Systems", Upper Saddle River, NJ: Prentice Hall, Inc. 2004.

# Edit: Conclusion

Since you're starting to try to bring counterexamples:

The point of this is: When you design an interpolator, it's up to you to keep the bitwidth sufficient and choose well-behaved filters.

Hence: To avoid clipping, simply calculate the bitwidth you'll need after an operation and use that. This applies to any operation, not just interpolation.

Harsh truth of DSP: If something goes mathematically wrong, it's your fault, since you usually could have seen that coming!

• We can take as an extreme case a full-scale (in terms of input bit width) rectangular wave and apply interpolation filter to it. Filter produce some "ringing" which increases output amplitude noticeably. – e_asphyx Jan 11 '17 at 23:42
• As said, you can quite easily calculate the maximum amplitude that comes out of an interpolating FIR. In essence,get every polyphase component of a $M$-decomposition of that FIR, and multiply point-wise each with component·max_int/max(itself), because that yields the maximum output power (Cauchy-Schwarz inequality becomes equality). You just reserve enough bits for that case. Also, if you properly design your interpolation filter, the overshoot will be very small (and also, not that bad to actually clip away), since then that filter would be designed let exactly the input spectrum through. – Marcus Müller Jan 11 '17 at 23:56