[vlc-devel] LPCM codec
Dean Rasheed
dean_rasheed at hotmail.com
Sun Jul 1 15:15:48 CEST 2007
Hi,
Firstly I would like to say how much I love the VLC Media Player, so
thanks to everyone for all your hard work.
I have been using it on a number of files with LPCM audio in various
formats and I noticed that it doesn't play 20 or 24-bit audio properly
when the number of channels is not 2 (eg. mono or surround).
After some investigation, I think that I have found the correct byte
packing order for data in this format. Basically, the data comes in
chunks with 2 samples from each channel per chunk. The 16 most
significant bits from each sample come first, followed by the last 4
or 8 bits for each sample, at the end of the chunk.
I don't have a development environment set up to build VLC, but I have
looked as lpcm.c and I think that the code below will do the right
thing when i_channels != 2. When i_channels is 2, it should reproduce
the existing code.
I hope this helps.
Cheers,
Dean.
20-bit unpacking
================
int i_channels = p_dec->fmt_out.audio.i_channels;
int i_chunk_size = 5 * i_channels;
while( p_block->i_buffer / i_chunk_size )
{
int i_channel;
for (i_channel = 0; i_channel < i_channels; i_channel++)
{
/* Sample 1 */
p_out[0] = p_block->p_buffer[4*i_channel];
p_out[1] = p_block->p_buffer[4*i_channel + 1];
p_out[2] = p_block->p_buffer[4*i_channels + i_channel] & 0xF0;
/* Sample 2 */
p_out[3] = p_block->p_buffer[4*i_channel + 2];
p_out[4] = p_block->p_buffer[4*i_channel + 3];
p_out[5] = p_block->p_buffer[4*i_channels + i_channel + 8] << 4;
p_out += 6;
}
p_block->i_buffer -= i_chunk_size;
p_block->p_buffer += i_chunk_size;
}
24-bit unpacking
================
int i_channels = p_dec->fmt_out.audio.i_channels;
int i_chunk_size = 6 * i_channels;
while( p_block->i_buffer / i_chunk_size )
{
int i_channel;
for (i_channel = 0; i_channel < i_channels; i_channel++)
{
/* Sample 1 */
p_out[0] = p_block->p_buffer[4*i_channel];
p_out[1] = p_block->p_buffer[4*i_channel + 1];
p_out[2] = p_block->p_buffer[4*i_channels + 2*i_channel];
/* Sample 2 */
p_out[3] = p_block->p_buffer[4*i_channel + 2];
p_out[4] = p_block->p_buffer[4*i_channel + 3];
p_out[5] = p_block->p_buffer[4*i_channels + 2*i_channel + 1];
p_out += 6;
}
p_block->i_buffer -= i_chunk_size;
p_block->p_buffer += i_chunk_size;
}
_________________________________________________________________
Win tickets to the sold out Live Earth concert! http://liveearth.uk.msn.com
_______________________________________________
vlc-devel mailing list
vlc-devel at videolan.org
http://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list