Scaling byte to short

  • Thread starter Thread starter _Andy_
  • Start date Start date
A

_Andy_

I'm looking for the alogithm to take a piece of 8-bit audio data, and
scale it to a 16-bit short. I got as far as:

private static short ByteToShort(byte b)
{
int word = 0;
word |= ( ( b & 0x01 ) << 1 );
word |= ( ( b & 0x02 ) << 2 );
word |= ( ( b & 0x04 ) << 3 );
word |= ( ( b & 0x08 ) << 4 );
word |= ( ( b & 0x10 ) << 5 );
word |= ( ( b & 0x20 ) << 6 );
word |= ( ( b & 0x40 ) << 7 );
word |= ( ( b & 0x80 ) << 8 );
if( b < 0 )
return (short) ( word - 32768 );
else
return (short) ( word );
}

(The "word" was originally a "short", but I kept getting CS0675).

The wall has got a hole in about the size of my head, so your help
would be appreciated!

Rgds,
 
private static short ByteToShort(byte b)

Why don't you just assign the byte to the short or int? Both short and
int can hold any values that a byte can [0-255].

if( b < 0 )
return (short) ( word - 32768 );

Since a byte is unsigned, that will never happen. If you want to treat
the byte as signed, use sbyte instead.



Mattias
 
Look at his code again. It does not take a byte value in the range 0-255 and
turn it into a (u)short in the range 0-255. It takes each bit position
within the source byte and maps it into 2 adjacent bit positions in the
resulting (u)short. A cast cannot replicate this behavior.

To the original poster: I would suggest to you that when processing image
data, one "standard" way of doing this is simply to replicate the byte into
both byte positions of the word. If you want to make sure that you only use
the positive range of a signed 16 bit value, you can then shift right by one
bit. Or if you want to use the full range of a signed 16 bit value, you can
xor by 0x8000.

private static short ByteToShort(byte b)
{
return (short)(((b << 8) | b) ^ 0x8000); // use full range of signed
16 bit value
}

If you really want to stick with the mathematical outcome of the method
you've got now, I would suggest using a simple lookup table of 256
(u)shorts.

Mattias Sjögren said:
private static short ByteToShort(byte b)

Why don't you just assign the byte to the short or int? Both short and
int can hold any values that a byte can [0-255].

if( b < 0 )
return (short) ( word - 32768 );

Since a byte is unsigned, that will never happen. If you want to treat
the byte as signed, use sbyte instead.



Mattias
 
private static short ByteToShort(byte b)

Why don't you just assign the byte to the short or int? Both short and
int can hold any values that a byte can [0-255].

if( b < 0 )
return (short) ( word - 32768 );

Since a byte is unsigned, that will never happen. If you want to treat
the byte as signed, use sbyte instead.

Yeah, I realised that while debugging - changing to sbyte didn't solve
it.

I couldn't simply cast as it's audio data I'm playing with (I needed
to preserve the waveform). Anyway, I've just sovled it. That's the
last time I do any bit arithmetic... ;)

Thanks,

Andy
 
Look at his code again. It does not take a byte value in the range 0-255 and
turn it into a (u)short in the range 0-255. It takes each bit position
within the source byte and maps it into 2 adjacent bit positions in the
resulting (u)short. A cast cannot replicate this behavior.

To the original poster: I would suggest to you that when processing image
data, one "standard" way of doing this is simply to replicate the byte into
both byte positions of the word. If you want to make sure that you only use
the positive range of a signed 16 bit value, you can then shift right by one
bit. Or if you want to use the full range of a signed 16 bit value, you can
xor by 0x8000.

private static short ByteToShort(byte b)
{
return (short)(((b << 8) | b) ^ 0x8000); // use full range of signed
16 bit value
}

If you really want to stick with the mathematical outcome of the method
you've got now, I would suggest using a simple lookup table of 256
(u)shorts.

Many thanks Ted, I arrived at pretty much the same formula! I could
have done with you about 4 hours ago! :)

Rgds,
 
Back
Top