AnsweredAssumed Answered

Unexpected Floating Point Multiplication Result

Question asked by wrswrsnz on Sep 26, 2013
Latest reply on Oct 7, 2013 by wrswrsnz

Hi,

 

I am getting an unexpected result from floating point multiplication and/or floating point to integer conversion and have likely just done something wrong but can't figure out what it is.

 

Ive always used fixed-point for my IIR and FIR filters and come from the Motorola / Freescale background. I'm currently trying to port an IIR filter from an old DSP56362 design over to the ADSP21469 on a Danville Signal development board. I have passthrough working fine but get some unusual results when trying the multiply the input sample by any fraction (0.5, -0.5, 0.9,1.5).

 

I'm using floating point hard-coded to do this and not yet using the <filter.h> IIR method - this will come next but requires re-calculating the coefficients as the IIR method used for the DSP56362 uses a different type of IIR to the ADSP...

 

After the floating point is done as described below it needs to be converted back to integer for the SPORT. I'm actually looking at the integer value going to the SPORT, not the floating point value so it may well be a conversion issue rather than floating point multiplication or even the compiler optimisation... I'm letting the compiler do all the type conversions - is it safe to do this? It seems odd that integer values work fine but fractional values don't...

 

When I first tried to make the IIR filter go there was no output at all so I stripped it back to just passing the input sample directly to the output.

Next I tried multiplying the input sample by 1 and then -1 and got passthrough and inverted passthrough as expected. (gain = 1)

Next I tried multiplying the input sample by 2 and then -2 and got 6dB gain and inverted 6dB gain - so far everything was as expected. (gain = 2)

Next I tried multiplying the input sample by 0.5 and this is where the problem begins and is probably why the coefficients for my filter aren't working as they're all fractions. (gain = 0.5)

 

When multiplying the input sample by 0.5 I was expecting the output sample to simply be half the input and retain the correct sign but it does not.

I am feeding a 1kHz sine data patern into the DSP so + and - values about 0. This gives a sine patern on the output when the gain = 1.

 

What I get when using any fractional value is a DC offset as though part of the input sample is losing its sign.

 

eg, When gain = 0.5 the output is this.

All output samples have a negative value. The negative part of the sine output is normal, ie it starts at 0 and progresses perfectly to 0.5 x the input value at the negative peak and then progresses normally back to 0. The positive part of the sinewave does not go positive but instead jumps to the full negative peak value of the input sine and then progresses towards negative 0.5 of the input sine then back to the negative peak.

 

Here's some numbers:

0' : output = 0 x input (good) - actual value = 0

90' : output = 0.5 of input (good) - actual value = -0.5

179.99' : output almost back at 0 x input (good) - actual value = 0

180.01' : output = -1 x input (bad, shoud be positive and near 0) - actual value = -1

270' : output = -0.5 of input (bad, should be 0.5 x input (positive)) - actual value = -0.5

359.99' : output = -1 x input (bad, should be positive and near 0) - actual value = -1

 

If I use a gain = -0.5 then the above simply flips into the positive region.

If I multiply the input sample by 0.5 and then by 2 (so the total = 1) then the output is normal again (same as gain = 1) which seems very strange.

I was expecting the output to equal 0.5 of the input to give -6dB gain...

 

Is this a commonly known issue where I've done something wrong or is it normal behaviour? How do I get symetrical data about 0?

 

float LPF_IIR(float Input_sample)

{

     float Output_sample;

 

     Output_sample = Input_Sample * 0.5;

     return(Output_sample);

}

 

void Filter(void)

{

     SP3_Out = LPF_IIR(Sample_R);               // SP3_Out is integer

}

Outcomes