Commit ef54efe5 authored by Renaud Dartus's avatar Renaud Dartus

* Add dither fix

* Some cosmetic changes
parent d35a29fa
/*****************************************************************************
* ac3_bit_stream.h: getbits functions for the ac3 decoder
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* Copyright (C) 2000, 2001 VideoLAN
*
* Authors: Renaud Dartus <reno@videolan.org>
*
* Authors:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -20,31 +21,25 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
static __inline__ u8 GetByte (ac3_byte_stream_t * p_byte_stream)
{
/* Are there some bytes left in the current buffer ? */
if (p_byte_stream->p_byte >= p_byte_stream->p_end)
{
/* no, switch to next buffer */
ac3_byte_stream_next (p_byte_stream);
}
return *(p_byte_stream->p_byte++);
}
static __inline__ void NeedBits (ac3_bit_stream_t * p_bit_stream, int i_bits)
static __inline__ u32 bitstream_get (ac3_bit_stream_t * p_bit_stream,
u32 num_bits)
{
while (p_bit_stream->i_available < i_bits)
u32 result=0;
while (p_bit_stream->i_available < num_bits)
{
p_bit_stream->buffer |=
((u32)GetByte (&p_bit_stream->byte_stream)) << (24 - p_bit_stream->i_available);
if (p_bit_stream->byte_stream.p_byte >= p_bit_stream->byte_stream.p_end)
{
/* no, switch to next buffer */
ac3_byte_stream_next (&p_bit_stream->byte_stream);
}
p_bit_stream->buffer |=((u32) *(p_bit_stream->byte_stream.p_byte++))
<< (24 - p_bit_stream->i_available);
p_bit_stream->i_available += 8;
}
}
static __inline__ void DumpBits (ac3_bit_stream_t * p_bit_stream, int i_bits)
{
p_bit_stream->buffer <<= i_bits;
p_bit_stream->i_available -= i_bits;
p_bit_stream->total_bits_read += i_bits;
result = p_bit_stream->buffer >> (32 - num_bits);
p_bit_stream->buffer <<= num_bits;
p_bit_stream->i_available -= num_bits;
p_bit_stream->total_bits_read += num_bits;
return result;
}
/*****************************************************************************
* ac3_mantissa.c: ac3 mantissa computation
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* Copyright (C) 1999, 2000, 2001 VideoLAN
*
* Authors:
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Renaud Dartus <reno@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -19,6 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#include "defs.h"
#include <stdio.h> /* "intf_msg.h" */
......@@ -156,7 +158,7 @@ static float q_3[8] =
{
(-6 << 15)/7.0, (-4 << 15)/7.0, (-2 << 15)/7.0,
0 , (2 << 15)/7.0, (4 << 15)/7.0,
(6 << 15)/7.0, 0
(6 << 15)/7.0, 0
};
static float q_5[16] =
......@@ -213,6 +215,54 @@ static float exp_lut[ 25 ] =
3.63797880709171295166015625e-12,
};
const u16 dither_lut[256] =
{
0x0000, 0xa011, 0xe033, 0x4022, 0x6077, 0xc066, 0x8044, 0x2055,
0xc0ee, 0x60ff, 0x20dd, 0x80cc, 0xa099, 0x0088, 0x40aa, 0xe0bb,
0x21cd, 0x81dc, 0xc1fe, 0x61ef, 0x41ba, 0xe1ab, 0xa189, 0x0198,
0xe123, 0x4132, 0x0110, 0xa101, 0x8154, 0x2145, 0x6167, 0xc176,
0x439a, 0xe38b, 0xa3a9, 0x03b8, 0x23ed, 0x83fc, 0xc3de, 0x63cf,
0x8374, 0x2365, 0x6347, 0xc356, 0xe303, 0x4312, 0x0330, 0xa321,
0x6257, 0xc246, 0x8264, 0x2275, 0x0220, 0xa231, 0xe213, 0x4202,
0xa2b9, 0x02a8, 0x428a, 0xe29b, 0xc2ce, 0x62df, 0x22fd, 0x82ec,
0x8734, 0x2725, 0x6707, 0xc716, 0xe743, 0x4752, 0x0770, 0xa761,
0x47da, 0xe7cb, 0xa7e9, 0x07f8, 0x27ad, 0x87bc, 0xc79e, 0x678f,
0xa6f9, 0x06e8, 0x46ca, 0xe6db, 0xc68e, 0x669f, 0x26bd, 0x86ac,
0x6617, 0xc606, 0x8624, 0x2635, 0x0660, 0xa671, 0xe653, 0x4642,
0xc4ae, 0x64bf, 0x249d, 0x848c, 0xa4d9, 0x04c8, 0x44ea, 0xe4fb,
0x0440, 0xa451, 0xe473, 0x4462, 0x6437, 0xc426, 0x8404, 0x2415,
0xe563, 0x4572, 0x0550, 0xa541, 0x8514, 0x2505, 0x6527, 0xc536,
0x258d, 0x859c, 0xc5be, 0x65af, 0x45fa, 0xe5eb, 0xa5c9, 0x05d8,
0xae79, 0x0e68, 0x4e4a, 0xee5b, 0xce0e, 0x6e1f, 0x2e3d, 0x8e2c,
0x6e97, 0xce86, 0x8ea4, 0x2eb5, 0x0ee0, 0xaef1, 0xeed3, 0x4ec2,
0x8fb4, 0x2fa5, 0x6f87, 0xcf96, 0xefc3, 0x4fd2, 0x0ff0, 0xafe1,
0x4f5a, 0xef4b, 0xaf69, 0x0f78, 0x2f2d, 0x8f3c, 0xcf1e, 0x6f0f,
0xede3, 0x4df2, 0x0dd0, 0xadc1, 0x8d94, 0x2d85, 0x6da7, 0xcdb6,
0x2d0d, 0x8d1c, 0xcd3e, 0x6d2f, 0x4d7a, 0xed6b, 0xad49, 0x0d58,
0xcc2e, 0x6c3f, 0x2c1d, 0x8c0c, 0xac59, 0x0c48, 0x4c6a, 0xec7b,
0x0cc0, 0xacd1, 0xecf3, 0x4ce2, 0x6cb7, 0xcca6, 0x8c84, 0x2c95,
0x294d, 0x895c, 0xc97e, 0x696f, 0x493a, 0xe92b, 0xa909, 0x0918,
0xe9a3, 0x49b2, 0x0990, 0xa981, 0x89d4, 0x29c5, 0x69e7, 0xc9f6,
0x0880, 0xa891, 0xe8b3, 0x48a2, 0x68f7, 0xc8e6, 0x88c4, 0x28d5,
0xc86e, 0x687f, 0x285d, 0x884c, 0xa819, 0x0808, 0x482a, 0xe83b,
0x6ad7, 0xcac6, 0x8ae4, 0x2af5, 0x0aa0, 0xaab1, 0xea93, 0x4a82,
0xaa39, 0x0a28, 0x4a0a, 0xea1b, 0xca4e, 0x6a5f, 0x2a7d, 0x8a6c,
0x4b1a, 0xeb0b, 0xab29, 0x0b38, 0x2b6d, 0x8b7c, 0xcb5e, 0x6b4f,
0x8bf4, 0x2be5, 0x6bc7, 0xcbd6, 0xeb83, 0x4b92, 0x0bb0, 0xaba1
};
u16 lfsr_state = 1;
static __inline__ u16 dither_gen (void)
{
s16 state;
state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8);
lfsr_state = (u16) state;
return ( (state * (s32) (0.707106 * 256.0)) >> 8 );
}
/* Fetch an unpacked, left justified, and properly biased/dithered mantissa value */
static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
{
......@@ -222,7 +272,11 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
switch (bap)
{
case 0:
return (0); /* FIXME dither */
if (p_ac3dec->audblk.dithflag[exp])
{
return ( dither_gen() * exp_lut[exp] );
}
return (0);
case 1:
if (q_1_pointer >= 0)
......@@ -230,10 +284,7 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
return (q_1[q_1_pointer--] * exp_lut[exp]);
}
NeedBits (&(p_ac3dec->bit_stream), 5);
group_code = p_ac3dec->bit_stream.buffer >> (32 - 5);
DumpBits (&(p_ac3dec->bit_stream), 5);
if (group_code >= 27)
if ((group_code = bitstream_get(&(p_ac3dec->bit_stream),5)) >= 27)
{
intf_ErrMsg ( "ac3dec error: invalid mantissa" );
}
......@@ -250,11 +301,8 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
{
return (q_2[q_2_pointer--] * exp_lut[exp]);
}
NeedBits (&(p_ac3dec->bit_stream), 7);
group_code = p_ac3dec->bit_stream.buffer >> (32 - 7);
DumpBits (&(p_ac3dec->bit_stream), 7);
if (group_code >= 125)
if ((group_code = bitstream_get(&(p_ac3dec->bit_stream),7)) >= 125)
{
intf_ErrMsg ( "ac3dec error: invalid mantissa" );
}
......@@ -267,11 +315,7 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
return (q_2_0[ group_code ] * exp_lut[exp]);
case 3:
NeedBits (&(p_ac3dec->bit_stream), 3);
group_code = p_ac3dec->bit_stream.buffer >> (32 - 3);
DumpBits (&(p_ac3dec->bit_stream), 3);
if (group_code >= 7)
if ((group_code = bitstream_get(&(p_ac3dec->bit_stream),3)) >= 7)
{
intf_ErrMsg ( "ac3dec error: invalid mantissa" );
}
......@@ -283,11 +327,8 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
{
return (q_4[q_4_pointer--] * exp_lut[exp]);
}
NeedBits (&(p_ac3dec->bit_stream), 7);
group_code = p_ac3dec->bit_stream.buffer >> (32 - 7);
DumpBits (&(p_ac3dec->bit_stream), 7);
if (group_code >= 121)
if ((group_code = bitstream_get(&(p_ac3dec->bit_stream),7)) >= 121)
{
intf_ErrMsg ( "ac3dec error: invalid mantissa" );
}
......@@ -299,11 +340,7 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
return (q_4_0[ group_code ] * exp_lut[exp]);
case 5:
NeedBits (&(p_ac3dec->bit_stream), 4);
group_code = p_ac3dec->bit_stream.buffer >> (32 - 4);
DumpBits (&(p_ac3dec->bit_stream), 4);
if (group_code >= 15)
if ((group_code = bitstream_get(&(p_ac3dec->bit_stream),4)) >= 15)
{
intf_ErrMsg ( "ac3dec error: invalid mantissa" );
}
......@@ -311,42 +348,57 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
return (q_5[group_code] * exp_lut[exp]);
default:
NeedBits (&(p_ac3dec->bit_stream), qnttztab[bap]);
group_code = (((s32)(p_ac3dec->bit_stream.buffer)) >> (32 - qnttztab[bap])) << (16 - qnttztab[bap]);
DumpBits (&(p_ac3dec->bit_stream), qnttztab[bap]);
group_code = bitstream_get(&(p_ac3dec->bit_stream),qnttztab[bap]);
group_code <<= 16 - qnttztab[bap];
return (((s32)group_code) * exp_lut[exp]);
return ((s16)(group_code) * exp_lut[exp]);
}
}
static __inline__ void uncouple_channel (ac3dec_t * p_ac3dec, u32 ch)
{
u32 bnd = 0;
u32 sub_bnd = 0;
u32 i,j;
float cpl_coord = 0;
float cpl_coord = 1.0;
u32 cpl_exp_tmp;
u32 cpl_mant_tmp;
for (i = p_ac3dec->audblk.cplstrtmant; i < p_ac3dec->audblk.cplendmant;)
{
if (!p_ac3dec->audblk.cplbndstrc[bnd])
if (!p_ac3dec->audblk.cplbndstrc[sub_bnd++])
{
cpl_exp_tmp = p_ac3dec->audblk.cplcoexp[ch][bnd] + 3 * p_ac3dec->audblk.mstrcplco[ch];
if (p_ac3dec->audblk.cplcoexp[ch][bnd] == 15)
{
cpl_mant_tmp = (p_ac3dec->audblk.cplcomant[ch][bnd]) << 12;
cpl_mant_tmp = (p_ac3dec->audblk.cplcomant[ch][bnd]) << 11;
}
else
{
cpl_mant_tmp = ((0x10) | p_ac3dec->audblk.cplcomant[ch][bnd]) << 11;
cpl_mant_tmp = ((0x10) | p_ac3dec->audblk.cplcomant[ch][bnd]) << 10;
}
cpl_coord = ((s16)cpl_mant_tmp) * exp_lut[cpl_exp_tmp];
cpl_coord = ((s16)cpl_mant_tmp) * exp_lut[cpl_exp_tmp] * 8.0f;
/* Invert the phase for the right channel if necessary */
if (p_ac3dec->bsi.acmod == 0x02 && p_ac3dec->audblk.phsflginu &&
ch == 1 && p_ac3dec->audblk.phsflg[bnd])
{
cpl_coord *= -1;
}
bnd++;
}
bnd++;
for (j=0;j < 12; j++)
{
p_ac3dec->coeffs.fbw[ch][i] = cpl_coord * p_ac3dec->audblk.cplfbw[i];
/* Get new dither values for each channel if necessary,
* so the channels are uncorrelated */
if (p_ac3dec->audblk.dithflag[ch] && !p_ac3dec->audblk.cpl_bap[i])
{
p_ac3dec->coeffs.fbw[ch][i] = cpl_coord * dither_gen() *
exp_lut[p_ac3dec->audblk.cpl_exp[i]];
} else {
p_ac3dec->coeffs.fbw[ch][i] = cpl_coord * p_ac3dec->audblk.cplfbw[i];
}
i++;
}
}
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment