Test Your EQ (Engineering Quotient)

EQ #35

In reference to EQ #34 (See below) – The original implementor’s solution was to change the $offset value to 0xFF. Why did this work?

The following pseudocode represents an implementation of a single-pole low-pass IIR filter, using 16-bit input and output values and a 24-bit internal accumulator and a filter coefficient of 1/256:

#The 32-bit accumulator holds 16 integer
# and 16 fractional bits
$acc = 0x00000000;

# The input value is a 16-bit integer.
$input = 0xFFFF;

# Offset used for rounding the accumulator
# to 24 bits.
$offset = 0x80;

while (1) {
# acc = (255*acc + input)/256
$acc -= ($acc >> 8);
$acc += ($input << 8) + $offset; # limit acc to 24 bits $acc &= 0xFFFFFF00; # output is integer part of acc $output = $acc >> 16;

An implementor of this filter complained that “the output never reaches 0xFFFF.”

Changing the $offset value to 0xFF effectively adds a bias to each input sample, which averages out to 0x00007F00 in the accumulator. The effect of this is to add the required rounding offset to the accumulator so that truncating the LSBs to create the 16-bit output value comes up with the correct answer.


Advertise Here

Don't miss out on upcoming issues of Circuit Cellar. Subscribe today!

Note: We’ve made the October 2017 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.