On Thu, 19 Mar 2009, Trent Piepho wrote:
> Since the driver often needs to use a logarithm from dvb-math to find SNR,
> you have code like this in the driver (from lgdt3305.c):
>         /* report SNR in dB * 10 */
>         *snr = (state->snr / ((1 << 24) / 10));
>
> > The SNR(dB) will be given by:
> >     SNR(dB) = driver_SNR_measure / 256;
>
> For the driver side, also from lgdt3305 which has both formats with an
> ifdef:
>         /* convert from 8.24 fixed-point to 8.8 */
>         *snr = (state->snr) >> 16;
>
> FWIW, converting to decimal to print using only integer math:
>
>       /* decimal fixed point */
>       printf("%d.%d dB\n", snr / 10, snr % 10);
>
>       /* binary fixed point */
>       printf("%d.%02d dB\n", snr >> 8, (snr & 0xff) * 100 >> 8);

One more example, converting SNR into a 32-bit floating point number using
only integer operations.  These don't do negative numbers but if the SNR
format used a sign bit it would be very easy to add, as IEEE 754 floating
point uses a sign bit too.  I would need to think about it more to do 2's
complement.

For binary fixed point the conversion to a float is exact.  For decimal
fixed point it's not.  For example 334 (33.4 dB) will become 33.400002 dB
when converted to floating point.

/* For 8.8 binary fixed point, this is the no-float version of:
 * float snr_to_float(u16 snr) { return snr / 256.0 } */
u32 snr_to_float(u16 snr)
{
        unsigned int e = 23 - __fls(snr);
        return snr ? ((snr << e) & 0x7fffff) | ((142 - e) << 23) : 0;
}

/* For .1 decimal fixed point.  NOTE:  This will overflow the 32-bit
 * intermediate value if SNR is above 1638.3 dB!  This is the no-float
 * version of:
 * float snr_to_float(u16 snr) { return snr / 10.0 } */
u32 snr10_to_float(u16 snr)
{
        unsigned int e = 23 - __fls(snr / 10);
        return snr ? ((((snr << e) + 5) / 10) & 0x7fffff) | (150 - e) << 23 : 0;
}

You'd use the function like this:

        float f;
        *(u32 *)&f = snr_to_float(snr);
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to