简体   繁体   中英

Ignoring Leftmost Bit in Four Bytes

First an explanation of why:

I have a list of links to a variety of MP3 links and I'm trying to read the ID3 information for these files quickly. I'm only downloading the first 1500 or so bytes and trying to ana yze the data within this chunk. I came across ID3Lib, but I could only get it to work on completely downloaded files and didn't notice any support for Streams. (If I'm wrong in this, feel free to point that out)

So basically, I'm left trying to parse the ID3 tag by myself. The size of the tag can be determined from four bytes near the start of the file. From the ID3 site:

The ID3v2 tag size is encoded with four bytes where the most significant bit (bit 7) is set to zero in every byte, making a total of 28 bits. The zeroed bits are ignored, so a 257 bytes long tag is represented as $00 00 02 01.

So basically:

00000000 00000000 00000010 00000001

becomes

0000 00000000 00000001 00000001

I'm not too familiar with bit level operations and was wondering if someone could shed some insight on an elegant solution to ignore the leftmost bit of each of these four bytes? I'm trying to pull a base 10 integer from it, so that works as well.

Cheers, -Josh

If you've got the four individual bytes, you'd want:

int value = ((byte1 & 0x7f) << 21) |
            ((byte2 & 0x7f) << 14) |
            ((byte3 & 0x7f) << 7) |
            ((byte4 & 0x7f) << 0);

If you've got it in a single int already:

int value = ((value & 0x7f000000) >> 3) |
            ((value & 0x7f0000) >> 2) |
            ((value & 0x7f00) >> 1) |
            (value & 0x7f);

To clear the most significant bit, AND with 127 (0x7F), this takes all bits apart from the MSB.

int tag1 = tag1Byte & 0x7F;  // this is the first one read from the file
int tag2 = tag2Byte & 0x7F;
int tag3 = tag3Byte & 0x7F;
int tag4 = tag4Byte & 0x7F;  // this is the last one

To convert this into a single number, realize that each tag value is a base 128 digit. So, the least signifiant is multipled by 128^0 (1), the next 128^1 (128), the third significant (128^2) and so on.

int tagLength = tag4+(tag3<<7)+(tag2<<14)+(tag1<<21)

You mention you want to conver this to base 10. You can then convert this to base 10, say for printing, using int to string conversion:

String base10 = String.valueOf(tagLength);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM