• What is your GameDev Story?

This topic is 3852 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Share on other sites
Yeah, for the 4-bit values, just read in a byte, b, then get your values out of it.
blocksize0 = (b & 0xF0) >> 4;
blocksize1 = (b & 0x0F);

For the other one, I guess you can read the next byte and get the bit...
onebit = b >> 7;

I guess endianness could be a factor also. I'm not thinking clearly right now. :-)

Share on other sites
Quote:
 Original post by DrTwoxI can fread parts 1-6 into a struct, which prints the relevent information correctly, but how on earth does one read 7-9? I'm guessing that blocksize_0 and blocksize_1 are read into a single unsigned int and I'm supposed to use bit twiddling to get the relevant information?

Indeed. You mask the information you want, and then shift it downwards by the appropriate amount.

Quote:
 What about 9, the one bit framing_flag. How can you read 1 bit when the smallest size is an 8bit char?

Again, just masking and shifting. However in the case of a single bit (typically a boolean flag), you don't need to do the shift, since after masking you'll either be left with a single 1 bit (which produces a non-zero value), or no 1 bits, which is zero.

Share on other sites
You could also create a structure for the entire header, with a bitfield at the end. Than you would be able to read in the entire structure with one call to fread.

Share on other sites
Quote:
 Original post by caseydYou could also create a structure for the entire header, with a bitfield at the end. Than you would be able to read in the entire structure with one call to fread.

This wont work due to the fact that bit fields are downright useless in C and C++.
"The packing order, and whether or not a bitfield may cross a storage unit boundary, are implementation defined."

That is to say that the fields in a bit field may not necessarily be tightly packed (eg. may contain gaps) in addition to fields being stored in a different order than you specified in the struct definition.

Share on other sites
I believe MSVC supports pragma pack

#pragma pack(push,1) // push one byte packingstruct OggHeader{	unsigned int vorbis_version;	unsigned char audio_channels;	unsigned int audio_sample_rate;	unsigned int bitrate_maximum;	unsigned int bitrate_nominal;	unsigned int bitrate_minimum;	unsigned char blocksize_0 : 4;	unsigned char blocksize_1 : 4;	unsigned char framing_flag : 1;        // should be 23 bytes (int * 5 + char*3)};#pragma pack(pop)int main(int argc, char* argv[]){        // prints "23, 23"	printf ("%d, %d\n", sizeof (unsigned int) * 5 + sizeof(unsigned char)*3, sizeof (OggHeader));	system ("pause");	return 0;}

?

Share on other sites
I'd avoid trying to wrap a structure round that data, mostly because it's not very flexible (and is highly platform and compiler dependant). Here's a couple of functions that let you read arbitrary numbers of bits from an array. Note that I've not done any error checking for going off the end of the data (and I've not tested it, so there may be some bugs but the idea should be clear):

unsigned char *pData;unsigned int nByte = 0;unsigned int nBit = 0;// Read the next bit from the array. Returns either 0 or 1int ReadBit(void){  int result = (pData[nByte] >> nBit) & 1;  nBit++;  // This is a branchless version of: if (nBit > 7) { nByte++; nBit = 0; }  nByte += nBit >> 3;  nBit &= 7;  return result;}// Read a multi-bit value and return it in a signed integerint ReadValue(int NumBits){  int result = 0;  for (int i=0; i < NumBits; i++)  {    result |= ReadBit() << i;  }  return result;}

Share on other sites
Thanks to all for your help, my app works great!

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 9
• 13
• 9
• 9
• 15
• Forum Statistics

• Total Topics
634073
• Total Posts
3015343
×