[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