1
votes

I am trying to generate a graph showcasing amplitudes of a wave file.

I have read the file bytes, then converted to hex via little endian and then converted the values to decimals.

But even if the sound is 16bit and thus value should range between (-32768, 32768), but the decimal values I get are going above this value and reaching 65000;

An example might explain my situation better:

Byte from File: (121, -2) Taking two values since mono i.e. numChannels = 1, Therefore blockAlign = 2

Little-endian Value: 87 FE

Hex Value(big-endian): FE87

Decimal: 65159

I even consider making Hex as -FE87 since the byte has a negative value but I think they do not work like that.

This statement I believe is the culprit but I can't figure it out. "16-bit samples are stored as 2's-complement signed integers, ranging from -32768 to 32767." http://soundfile.sapp.org/doc/WaveFormat/

Can someone help me with what I am doing wrong, I have spent hours trying to figure it out.

1

1 Answers

0
votes

In two's complement (which Java uses natively, by the way), the sign of a number is determined by the leftmost bit.

When you parse that hex value FE87 and store the result in an int, the leftmost bit is a zero, so the result is positive.

What you want to do is chop off all but the 16 least significant bits. You can do this by casting your int to a short. Now the leftmost bit of the short is a one, meaning the number is negative.

int i = Integer.parseInt("FE87", 16);
System.out.println(i);
short sample = (short) i;
System.out.println(sample);

Output:

65159
-377