Re: The right way to interpret the content of SNR, signal strength and BER from HVR 4000 Lite

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Mar 19, 2009 at 6:17 PM, Trent Piepho <xyzzy@xxxxxxxxxxxxx> wrote:
> 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);
>

== rant mode on ==
Wow, I think we have lost our minds!

The argument being put forth is based on the relative efficiency of
the multiply versus divide opcodes on modern CPU architectures??  And
that you're going to be able to get an SNR with a higher level of
precision than 0.1 dB?? (if the hardware suggests that it can then
it's LYING to you)

If that is the extent of the compelling argument that can be made,
then so be it.  But after reading this, I'm kind of dumbfounded that
this is the basis for proposing 8.8 format over just sending it back
in 0.1dB increments.  We have officially entered the realm of
"ridiculous".
== rant mode off ==

Devin

-- 
Devin J. Heitmueller
http://www.devinheitmueller.com
AIM: devinheitmueller
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux