Where would we be without people like you on this list!  Many thanks Rob.
It works!

Regards,
Ross.
 
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf
Of Rob Kennedy
Sent: Monday, 14 January 2008 6:55 a.m.
To: Borland's Delphi Discussion List
Subject: Re: non-standard bit numbers

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

Reply via email to