Thanks for the info guys!

Originally Posted by

**MarkT**
Perhaps you scaled the maximum coefficient to 32767 - that's not right.

I did do this initially. But I also tried some much smaller scales (e.g coefficient*0xF) and they all distorted as well. But yes it does seem like clipping, so I will definitely try your approach of normalisation in my Python script and see if that works.

Originally Posted by

**Nominal Animal**
Multiply the coefficients by 32768 (=215) to scale them to 16-bit first, then add 65536 (=216) to each negative value (converting the signed to unsigned using two's complement format, as used here in the filter).

Originally Posted by

**Nominal Animal**
Finally, use

Code:

mod(round(filter*32768 + 65536), 65536)

to get the unsigned 16-bit coefficients you need to populate the array with.

Nominal Animal, are you able to explain the conversion to unsigned to me more fully? This definitely looks like it could be the difference between my coefficients (I just kept any negative short ints) vs the ones from lopass_1000_44100.h which are all hex.

Here is the Python script I wrote:

Code:

# Python script to generate FIR coefficients
from scipy import signal
numtaps = 150
f = 300
coeffs = signal.firwin(numtaps, f, pass_zero='lowpass', fs=44117)
# scale to 16 bit integers
coeffs = [int(x * 0x7fff) for x in coeffs]
# print C array for copy/paste
print("// Low pass filter, cutoff frequency " + str(f) +"Hz.")
print("#define n_coeffs " + str(numtaps))
print("const short coeff_p[n_coeffs] = {", end="")
lineLength = 15
strings = [str(x) for x in coeffs]
print(",\n ".join([", ".join(strings[i:i+lineLength]) for i in range(0,len(strings),lineLength)]), end="")
print("};")