# Low pass filtering on short int (16 bit PCM) samples

I am writing software for processing audio given as 16-bit PCM samples. The first stage of the processing involves calculating the energy (or total variation) in a certain frequency range (above a certain cut-off frequency).

What I am currently doing is subtracting the energy of the low-pass filtered signal from the energy of the original signal. I found out that a lot of the processing is dedicated to converting the integer sampels to a floating point representation.

So my question is, is there a technnique for filtering the integer samples without converting them to floating point?

Yes of course, you can apply the filter directly to the integer samples, using fixed point arithmetic.

For example, if you use a FIR filter with coefficients [1 / 3, 1, 1 / 2], and an 8-bit resolution for coefficients, your output will be:

out[n] = (85 * sample[n] + 256 * sample[n - 1] + 128 * sample[n - 2]) >> 8


Two things to take be careful about:

• Coefficients quantization might cause at best slight changes of filter responses, at worst cause filter instabilities. What is your filter type and the value of its coefficients?

• Overflow / Data types / Truncation problems. In the example above, out can exceed the range of a 16-bit integer, so you will have to do some clipping.

• I think sample[n - 1] should be multiplied by 256; otherwise, it is effectively being weighted by $\frac{1}{256}$ instead of $1$. – Jason R Apr 3 '12 at 12:47
• you are right, edited! – pichenettes Apr 3 '12 at 14:31
• @pichenettes Might be good to explain how you arrived at the quantized values, signed vs. unsigned, etc. Up to you. – Jim Clay Apr 3 '12 at 15:07

One some processors, converting a large (but in cache) block of integers to floats before processing them might be faster, due to the elimination of pipeline hazards. You might want to benchmark this.

If you use scaled integer or fixed point arithmetic, the amount of added integer precision you will need in the coefficients and intermediate values is roughly proportional to the ratio between your sample rate and your desired cut-off frequency. You may need to use 24,32,48-bit or more precision integer arithmetic on your 16-bit samples to get down to your desired numerical noise floor level. Some processor instruction sets (ARM, MIPS, etc.) may include 64 bit accumulating arithmetic for just this purpose.