Shop OBEX P1 Docs P2 Docs Learn Events
8-bit to 12-bit scaling — Parallax Forums

8-bit to 12-bit scaling

Hello all,

I am trying to find an elegant and simple way to scale a 8-bit value, to a 12-bit value. I made up a simple spreadsheet to help me figure out what would work, but I cant figure out what will work. On my spreadsheet I converted the 8-bit value, to a percentage, then took that percentage and scaled it up to a 12-bit value.
X = ("8-bit value"/255)*100
"12-bit value" = (X / 100)*4095

Would someone have a simple way to take a 8-bit value, and up scale it to a 12-bit value?

I did figure out that I need to shift the bits to the left 4 places, but that is as far as I have been able to figure out.

Thanks TC

Comments

  • evanhevanh Posts: 15,126
    edited 2017-12-05 12:58
    X = (value << 4) OR ((value >> 4) AND 15)

    ie: Top most bits are repeated at the bottom. If you wanted, say, 8 bits to 24 bits, it's X = (value << 16) OR (value << 8 ) OR value
  • TCTC Posts: 1,019
    That is great. simple and elegant. Thank you evanh.
  • Or the even clearer:
    X := value * 16
    (spin)
    X = value * 16 ;
    (C)

    Of course if you want FF to map to FFF, you'll need something like
    X = value * 0xfff / 0xff ;
    X := value * $FFF / $FF
    depending on language.
  • I am still totally confused as to why you need 12-bits as no matter the scheme used, whether a simple bit shift, or even mixing in msbs, you still end up with 256 distinct values, not 4096. If you converted a stream or buffer then it is possible to upscale a few more bits since you can imagine a constant 50% lsb dither could resolve as "half-a-bit" over time etc. \

    @evanh - the "AND 15" is redundant since it is an 8-bit value and there are no extra bits to mask off.
    @Mark_T - shifting bits is always way more efficient as the Prop natively supports that whereas multiplication is much slower. Besides, I think bit shift is clearer for bit ops.
  • evanhevanh Posts: 15,126
    edited 2017-12-06 08:28
    I am still totally confused as to why you need 12-bits as no matter the scheme used, whether a simple bit shift, or even mixing in msbs, you still end up with 256 distinct values, not 4096.
    It is of value just to fill the full dynamic range. If the bottom bits are not controlled then either they are left set or unset, neither of which is entirely ideal.

    If you converted a stream or buffer then it is possible to upscale a few more bits since you can imagine a constant 50% lsb dither could resolve as "half-a-bit" over time etc.
    Yep, that's always a nice bonus if it's an option. Simply sum 'em all together and, voilà, extra depth for the cost of blurring.
  • Indeed, for filtering FIR or IIR, the more bits the merrier . Floating point will take care of that, but with integers we have to provide fractional bits by shifting up. Averaging without the factional bits actually loses information contained in bit bobble, because integer division truncates and biases the filter output toward zero.
  • You would avoid division in a fix-point implementation of DSP - just multiply and shifts. In fact for IIR just multiplies by
    constants of low bit-count is usually good enough as there is considerable scope for adjusting filter coefficients
    unless the stage has exceptionally high Q or high pass-band flatness is needed. FIR is much more expensive to calculate
    as coefficients have to be more precise and there are many more of them (but fewer issues of stability).

    I forget who, someone has posted a clever tool for Prop FIR code generation that commons up intermediate results
    of the multiplies between coefficients in an FIR filter, which trades space for speed.
  • evanhevanh Posts: 15,126
    Thanks Phil, I must put some effort into fully understanding all that.

    Tracy and Mark: The objective here is to gain extra bit depth. Don't do any dividing or shifting.

    Sum of 16 consecutive samples gives 4 bits extra depth, job done.

Sign In or Register to comment.