On Jun 22, 2010, at 21:27, Ilia Ternovich wrote: > Thank you very much! But how to deal with endianness in the case of > bit stream? Some blocks (for example MinBlockSize) require 16bits > (simply swap first and second), some block (e.g.MinFrameSize) require > 3 byte-array to be reverted. > > Finally totalSamples is stored in 5 bytes ( only last 4 bits from > first one byte are used). It was a real issue to make it little-endian > (here is how I did it: > http://code.google.com/p/sharpflac/source/browse/trunk/SharpFlac/ > Blocks/StreamInfo.cs). > > So to make stream little endian, I can't simple get each 4 bytes of > the stream one by one and revert them... > > Anyways I've managed to decode StreamInfo, VorbisComments,SeekPoints > and Application blocks without bitStream implementation. But I'd be > really pleased if anyone pointed me out how to deal with endianness.
Just because you've been able to hack around without a bitStream implementation doesn't mean you're doing it right! :-) I took a look at your code, and you're calling GetEndianBytes(adr, ofs, n); with n > 1, and that's wrong. You cannot look ahead in a stream, and so your code is already doing things in a way that is not to spec. You then use array indexes and bit shift operators to build multi-byte values. What's worse, I see that your code is looking at (contentOffset - 1), which is really bad. What you need to do is write a bitStream function. It should only read each byte from the stream once and completely deal with all 8 bits before dealing with the next byte. You should never look ahead beyond the current byte. Instead, you need a long long accumulator to hold the totalSamples, which is over 32 bits. Each time you read a byte, add 8 to your bit count, and shift any existing bits in your accumulator around to make room for the new bits. When pulling values out of the accumulator, you do that based upon the number of bits requested. In other words, instead of: GetEndianBytes(streamArray, streamOffset, numBytes); ... you should implement: (long long)GetBigEndianStreamBits(streamHandle, outputAddressPointer, (unsigned)numBits); The return value will have to be 64-bit to handle totalSamples. The nice thing is that you won't need any indexing or bit shifting, because GetBigEndianStreamBits() will directly return the value you ask for, based upon the number of bits requested. I mean, you can continue to try and hack things, or you can simply write your stream parser the way it's supposed to be implemented. The good news is that if you do it right, then your code is portable to situations where you have a real stream, such as over the internet. Your code hack so far will only work with files, not with real streams (and it's not really working completely, anyway). It's really not that hard. I've written MPEG metadata parsers in less than a day. Once you implement the bit function, the rest is super easy. Just don't try to map the exact stream structure into a literal C struct. Brian Willoughby Sound Consulting _______________________________________________ Flac-dev mailing list [email protected] http://lists.xiph.org/mailman/listinfo/flac-dev
