Re: Problems with byte swapping in audio code

Bj|rn Englund <[email protected]> Sat, 12 Apr 2003 13:01:25 +0200
Newsgroups gmane.comp.video.ogle.devel
Message-ID <[email protected]>
Fri Apr 11 2003, Dave Chapman wrote:
> Björn,
> 
> I am attempting to add 24-bit/96KHz LPCM audio support to ogle and the 
> latest version of my patch is included at the end of this mail (are 
> attachments allowed on this list?).

yes, if they are less than 100 KB.
 

> I will eventually do things in a better way (probing for audio device 
> capabilities and converting the audio inside ogle), but the attached 
> patch works.  However, I am confused about why it is working!.

So am I ;)
 
> Also, I think that I can confirm that 24-bit audio is stored as 3 bytes 
> per sample in the stream (not 4 bytes as the comment in decode_lpcm.c 
> states).
> 


> Does this make any sense to you?  Can you identify where this 
> byte-swapping is happenning?  I am using an Intel Pentium-3 machine for 
> my testing.
> 

I looked a bit at this and after listening and comparing the data values
I have come to the conclusion that the data format is a bit more complicated
than a simple interleaved 24 bit stream.

It seems that the samples come in blocks of 12 bytes (probably to
simplify reading/converting to 16bit).
If we call the different bytes of a sample L2,L1,L0 for the left sample
and R2, R1, R0 for the right sample where L2/R2 is the most significant
part (L2 bit 23-16, L1 bit 15-8, L0 bit 7-0), the data format is like this:

Byte         0   1   2   3   4   5   6   7   8   9   10  11  
Sample_frame 0               1               0       1
Data         L2  L1  R2  R1  L2  L1  R2  R1  L0  R0  L0  R0

So there are 2 sample_frames in each 12 bytes
(each with a left and right channel).
To get the 16 most significant bits you just read the stream as
normal 16bit audio for the first 8 bytes and skip the 4 last which contains
the least significant bits.
I'm not 100% sure about the order of the last 4 bytes but I assume they
are left/right/left/right interleaved as the rest of the data.

So a simple conversion (not accurate) from 24bit/96kHz to 16bit/48kHz is to 
read the first 4 bytes from every 12 byte block and skip the rest.

Even if you have a soundcard capable of 24/96 you need to
do some converting because the audio driver will probably
take the data as 32bit words (of which 24 bits are used).

/Björn