Ross Levis wrote:
> I hope someone can help me!! I need to read the header of a binary audio
> file (FLAC) which uses non-standard portions of bits for numeric fields. It
> also uses Big Endian. I have a function to convert normal 16 & 32 bit
> integers from little to big endian, but bit divisions in numbers is beyond
> me.
>
> Here is the structure in bits.
>
> <20> SampleRate
> <3> Channels
> <5> BitsPerSample
> <36> TotalSamples
>
> This adds up to 64 bits (8 bytes). Given an array [1..8] of byte, can
> someone please help me obtain the value of these 4 fields.
The layout of your array is like this:
ssssssss ssssssss sssscccb bbbbtttt tttttttt tttttttt tttttttt tttttttt
Put a comment like that in your source code and refer to it.
SampleRate is 20 bits. Divided by eight bits per byte gives two full
bytes plus half the next.
SampleRate := (Data[1] shl 12) // make room for Data[2..3]
or (Data[2] shl 4) // make room for Data[3]
or (Data[3] shr 4); // eliminate cccb
That grabs the upper four bits of Data[3] and shifts them into the first
four positions, which are where they need to be in SampleRate. Doing
that implicitly throws away the first four bits.
Channels := (Data[3] shr 1) // eliminate b
and $7; // select only the first three bits.
// $7 = (2^3) - 1
BitsPerSample := ((Data[3] and $1) // select only the first bit
shl 4) // make room for Data[4]
or (Data[4] shr 4); // eliminate tttt
TotalSamples := (Int64(Data[4] and $f) // select the first four bits
// $f = (2^4) - 1
shl 32) // make room for Data[5..8]
or (Data[5] shl 24) // make room for Data[6..8]
or (Data[6] shl 16) // make room for Data[7..8]
or (Data[7] shl 8) // make room for Data[8]
or Data[8];
TotalSamples needs to be an Int64, but the rest can all be Integer.
--
Rob
_______________________________________________
Delphi mailing list -> [email protected]
http://lists.elists.org/cgi-bin/mailman/listinfo/delphi