Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
a906b2f5
Commit
a906b2f5
authored
Feb 20, 2001
by
Renaud Dartus
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* Move ac3 globals variables into structures
* Adding authors * Prepared to add asm imdct and downmix
parent
1c5f8330
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
648 additions
and
569 deletions
+648
-569
Makefile.in
Makefile.in
+2
-1
src/ac3_decoder/ac3_bit_allocate.c
src/ac3_decoder/ac3_bit_allocate.c
+87
-110
src/ac3_decoder/ac3_bit_stream.h
src/ac3_decoder/ac3_bit_stream.h
+2
-1
src/ac3_decoder/ac3_decoder.c
src/ac3_decoder/ac3_decoder.c
+14
-5
src/ac3_decoder/ac3_decoder.h
src/ac3_decoder/ac3_decoder.h
+63
-2
src/ac3_decoder/ac3_decoder_thread.c
src/ac3_decoder/ac3_decoder_thread.c
+3
-7
src/ac3_decoder/ac3_downmix.c
src/ac3_decoder/ac3_downmix.c
+54
-284
src/ac3_decoder/ac3_downmix.h
src/ac3_decoder/ac3_downmix.h
+37
-0
src/ac3_decoder/ac3_downmix_c.c
src/ac3_decoder/ac3_downmix_c.c
+150
-0
src/ac3_decoder/ac3_exponent.c
src/ac3_decoder/ac3_exponent.c
+3
-1
src/ac3_decoder/ac3_imdct.c
src/ac3_decoder/ac3_imdct.c
+106
-99
src/ac3_decoder/ac3_internal.h
src/ac3_decoder/ac3_internal.h
+3
-3
src/ac3_decoder/ac3_mantissa.c
src/ac3_decoder/ac3_mantissa.c
+43
-51
src/ac3_decoder/ac3_parse.c
src/ac3_decoder/ac3_parse.c
+78
-3
src/ac3_decoder/ac3_rematrix.c
src/ac3_decoder/ac3_rematrix.c
+3
-2
No files found.
Makefile.in
View file @
a906b2f5
...
...
@@ -218,7 +218,8 @@ AC3_DECODER = src/ac3_decoder/ac3_decoder_thread.o \
src/ac3_decoder/ac3_mantissa.o
\
src/ac3_decoder/ac3_rematrix.o
\
src/ac3_decoder/ac3_imdct.o
\
src/ac3_decoder/ac3_downmix.o
src/ac3_decoder/ac3_downmix.o
\
src/ac3_decoder/ac3_downmix_c.o
LPCM_DECODER
=
src/lpcm_decoder/lpcm_decoder_thread.o
\
src/lpcm_decoder/lpcm_decoder.o
...
...
src/ac3_decoder/ac3_bit_allocate.c
View file @
a906b2f5
...
...
@@ -3,7 +3,9 @@
*****************************************************************************
* Copyright (C) 2000 VideoLAN
*
* Authors:
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* 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
...
...
@@ -25,49 +27,40 @@
#include "ac3_decoder.h"
#include "ac3_internal.h"
/*
static inline s16 logadd (s16 a, s16 b);
static s16 calc_lowcomp (s16 a, s16 b0, s16 b1, s16 bin);
static inline u16 min (s16 a, s16 b);
static inline u16 max (s16 a, s16 b);
*/
static
void
ba_compute_psd
(
s16
start
,
s16
end
,
s16
exps
[],
s16
psd
[],
s16
bndpsd
[]);
static
void
ba_compute_psd
(
bit_allocate_t
*
p_bit
,
s16
start
,
s16
end
,
s16
exps
[]);
static
void
ba_compute_excitation
(
s16
start
,
s16
end
,
s16
fgain
,
s16
fastleak
,
s16
slowleak
,
s16
is_lfe
,
s16
bndpsd
[],
s16
excite
[]);
static
void
ba_compute_mask
(
s16
start
,
s16
end
,
u16
fscod
,
static
void
ba_compute_excitation
(
bit_allocate_t
*
p_bit
,
s16
start
,
s16
end
,
s16
fgain
,
s16
fastleak
,
s16
slowleak
,
s16
is_lfe
);
static
void
ba_compute_mask
(
bit_allocate_t
*
p_bit
,
s16
start
,
s16
end
,
u16
fscod
,
u16
deltbae
,
u16
deltnseg
,
u16
deltoffst
[],
u16
deltba
[],
u16
deltlen
[],
s16
excite
[],
s16
mask
[]);
static
void
ba_compute_bap
(
s16
start
,
s16
end
,
s16
snroffset
,
s16
psd
[],
s16
mask
[],
s16
bap
[]);
u16
deltba
[],
u16
deltlen
[]);
static
void
ba_compute_bap
(
bit_allocate_t
*
p_bit
,
s16
start
,
s16
end
,
s16
snroffset
,
s16
bap
[]);
/* Misc LUTs for bit allocation process */
static
s16
slowdec
[]
=
{
0x0f
,
0x11
,
0x13
,
0x15
};
static
s16
fastdec
[]
=
{
0x3f
,
0x53
,
0x67
,
0x7b
};
static
s16
slowgain
[]
=
{
0x540
,
0x4d8
,
0x478
,
0x410
};
static
s16
dbpbtab
[]
=
{
0x000
,
0x700
,
0x900
,
0xb00
};
static
const
s16
slowdec
[]
=
{
0x0f
,
0x11
,
0x13
,
0x15
};
static
const
s16
fastdec
[]
=
{
0x3f
,
0x53
,
0x67
,
0x7b
};
static
const
s16
slowgain
[]
=
{
0x540
,
0x4d8
,
0x478
,
0x410
};
static
const
s16
dbpbtab
[]
=
{
0x000
,
0x700
,
0x900
,
0xb00
};
static
u16
floortab
[]
=
{
0x2f0
,
0x2b0
,
0x270
,
0x230
,
0x1f0
,
0x170
,
0x0f0
,
0xf800
};
static
s16
fastgain
[]
=
{
0x080
,
0x100
,
0x180
,
0x200
,
0x280
,
0x300
,
0x380
,
0x400
};
static
const
u16
floortab
[]
=
{
0x2f0
,
0x2b0
,
0x270
,
0x230
,
0x1f0
,
0x170
,
0x0f0
,
0xf800
};
static
const
s16
fastgain
[]
=
{
0x080
,
0x100
,
0x180
,
0x200
,
0x280
,
0x300
,
0x380
,
0x400
};
static
s16
bndtab
[]
=
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
static
const
s16
bndtab
[]
=
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
31
,
34
,
37
,
40
,
43
,
46
,
49
,
55
,
61
,
67
,
73
,
79
,
85
,
97
,
109
,
121
,
133
,
157
,
181
,
205
,
229
};
static
s16
bndsz
[]
=
{
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
static
const
s16
bndsz
[]
=
{
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
6
,
6
,
6
,
6
,
6
,
6
,
12
,
12
,
12
,
12
,
24
,
24
,
24
,
24
,
24
};
static
s16
masktab
[]
=
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
static
const
s16
masktab
[]
=
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
28
,
28
,
29
,
29
,
29
,
30
,
30
,
30
,
31
,
31
,
31
,
32
,
32
,
32
,
33
,
33
,
33
,
34
,
34
,
34
,
35
,
35
,
35
,
35
,
35
,
35
,
36
,
36
,
36
,
36
,
36
,
36
,
37
,
37
,
37
,
...
...
@@ -85,7 +78,7 @@ static s16 masktab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
49
,
49
,
49
,
49
,
49
,
49
,
49
,
49
,
49
,
49
,
49
,
49
,
49
,
0
,
0
,
0
};
static
s16
latab
[]
=
{
0x0040
,
0x003f
,
0x003e
,
0x003d
,
0x003c
,
0x003b
,
0x003a
,
0x0039
,
static
const
s16
latab
[]
=
{
0x0040
,
0x003f
,
0x003e
,
0x003d
,
0x003c
,
0x003b
,
0x003a
,
0x0039
,
0x0038
,
0x0037
,
0x0036
,
0x0035
,
0x0034
,
0x0034
,
0x0033
,
0x0032
,
0x0031
,
0x0030
,
0x002f
,
0x002f
,
0x002e
,
0x002d
,
0x002c
,
0x002c
,
0x002b
,
0x002a
,
0x0029
,
0x0029
,
0x0028
,
0x0027
,
0x0026
,
0x0026
,
...
...
@@ -119,7 +112,7 @@ static s16 latab[] = { 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0000
};
static
s16
hth
[][
50
]
=
{{
0x04d0
,
0x04d0
,
0x0440
,
0x0400
,
0x03e0
,
0x03c0
,
0x03b0
,
0x03b0
,
static
const
s16
hth
[][
50
]
=
{{
0x04d0
,
0x04d0
,
0x0440
,
0x0400
,
0x03e0
,
0x03c0
,
0x03b0
,
0x03b0
,
0x03a0
,
0x03a0
,
0x03a0
,
0x03a0
,
0x03a0
,
0x0390
,
0x0390
,
0x0390
,
0x0380
,
0x0380
,
0x0370
,
0x0370
,
0x0360
,
0x0360
,
0x0350
,
0x0350
,
0x0340
,
0x0340
,
0x0330
,
0x0320
,
0x0310
,
0x0300
,
0x02f0
,
0x02f0
,
...
...
@@ -144,21 +137,11 @@ static s16 hth[][50] = {{ 0x04d0, 0x04d0, 0x0440, 0x0400, 0x03e0, 0x03c0, 0x03b0
0x0450
,
0x04e0
}};
static
s16
baptab
[]
=
{
0
,
1
,
1
,
1
,
1
,
1
,
2
,
2
,
3
,
3
,
3
,
4
,
4
,
5
,
5
,
6
,
static
const
s16
baptab
[]
=
{
0
,
1
,
1
,
1
,
1
,
1
,
2
,
2
,
3
,
3
,
3
,
4
,
4
,
5
,
5
,
6
,
6
,
6
,
6
,
7
,
7
,
7
,
7
,
8
,
8
,
8
,
8
,
9
,
9
,
9
,
9
,
10
,
10
,
10
,
10
,
11
,
11
,
11
,
11
,
12
,
12
,
12
,
12
,
13
,
13
,
13
,
13
,
14
,
14
,
14
,
14
,
14
,
14
,
14
,
14
,
15
,
15
,
15
,
15
,
15
,
15
,
15
,
15
,
15
};
static
s16
sdecay
;
static
s16
fdecay
;
static
s16
sgain
;
static
s16
dbknee
;
static
s16
floor
;
static
s16
psd
[
256
];
static
s16
bndpsd
[
256
];
static
s16
excite
[
256
];
static
s16
mask
[
256
];
static
__inline__
u16
max
(
s16
a
,
s16
b
)
{
return
(
a
>
b
?
a
:
b
);
...
...
@@ -218,11 +201,11 @@ void bit_allocate (ac3dec_t * p_ac3dec)
return
;
/* Do some setup before we do the bit alloc */
sdecay
=
slowdec
[
p_ac3dec
->
audblk
.
sdcycod
];
fdecay
=
fastdec
[
p_ac3dec
->
audblk
.
fdcycod
];
sgain
=
slowgain
[
p_ac3dec
->
audblk
.
sgaincod
];
dbknee
=
dbpbtab
[
p_ac3dec
->
audblk
.
dbpbcod
];
floor
=
floortab
[
p_ac3dec
->
audblk
.
floorcod
];
p_ac3dec
->
bit_allocate
.
sdecay
=
slowdec
[
p_ac3dec
->
audblk
.
sdcycod
];
p_ac3dec
->
bit_allocate
.
fdecay
=
fastdec
[
p_ac3dec
->
audblk
.
fdcycod
];
p_ac3dec
->
bit_allocate
.
sgain
=
slowgain
[
p_ac3dec
->
audblk
.
sgaincod
];
p_ac3dec
->
bit_allocate
.
dbknee
=
dbpbtab
[
p_ac3dec
->
audblk
.
dbpbcod
];
p_ac3dec
->
bit_allocate
.
floor
=
floortab
[
p_ac3dec
->
audblk
.
floorcod
];
/* if all the SNR offset constants are zero then the whole block is zero */
if
(
!
p_ac3dec
->
audblk
.
csnroffst
&&
!
p_ac3dec
->
audblk
.
fsnroffst
[
0
]
&&
...
...
@@ -239,24 +222,22 @@ void bit_allocate (ac3dec_t * p_ac3dec)
start
=
0
;
end
=
p_ac3dec
->
audblk
.
endmant
[
i
]
;
fgain
=
fastgain
[
p_ac3dec
->
audblk
.
fgaincod
[
i
]];
snroffset
=
(((
p_ac3dec
->
audblk
.
csnroffst
-
15
)
<<
4
)
+
p_ac3dec
->
audblk
.
fsnroffst
[
i
])
<<
2
;
snroffset
=
(((
p_ac3dec
->
audblk
.
csnroffst
-
15
)
<<
4
)
+
p_ac3dec
->
audblk
.
fsnroffst
[
i
])
<<
2
;
fastleak
=
0
;
slowleak
=
0
;
ba_compute_psd
(
start
,
end
,
p_ac3dec
->
audblk
.
fbw_exp
[
i
],
psd
,
bndpsd
);
ba_compute_psd
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
p_ac3dec
->
audblk
.
fbw_exp
[
i
]
);
ba_compute_excitation
(
start
,
end
,
fgain
,
fastleak
,
slowleak
,
0
,
bndpsd
,
excite
);
ba_compute_excitation
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
fgain
,
fastleak
,
slowleak
,
0
);
ba_compute_mask
(
start
,
end
,
p_ac3dec
->
syncinfo
.
fscod
,
ba_compute_mask
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
p_ac3dec
->
syncinfo
.
fscod
,
p_ac3dec
->
audblk
.
deltbae
[
i
],
p_ac3dec
->
audblk
.
deltnseg
[
i
],
p_ac3dec
->
audblk
.
deltoffst
[
i
],
p_ac3dec
->
audblk
.
deltba
[
i
],
p_ac3dec
->
audblk
.
deltlen
[
i
]
,
excite
,
mask
);
p_ac3dec
->
audblk
.
deltlen
[
i
]);
ba_compute_bap
(
start
,
end
,
snroffset
,
psd
,
mask
,
p_ac3dec
->
audblk
.
fbw_bap
[
i
]);
ba_compute_bap
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
snroffset
,
p_ac3dec
->
audblk
.
fbw_bap
[
i
]);
}
if
(
p_ac3dec
->
audblk
.
cplinu
)
{
...
...
@@ -267,20 +248,18 @@ void bit_allocate (ac3dec_t * p_ac3dec)
fastleak
=
(
p_ac3dec
->
audblk
.
cplfleak
<<
8
)
+
768
;
slowleak
=
(
p_ac3dec
->
audblk
.
cplsleak
<<
8
)
+
768
;
ba_compute_psd
(
start
,
end
,
p_ac3dec
->
audblk
.
cpl_exp
,
psd
,
bndpsd
);
ba_compute_psd
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
p_ac3dec
->
audblk
.
cpl_exp
);
ba_compute_excitation
(
start
,
end
,
fgain
,
fastleak
,
slowleak
,
0
,
bndpsd
,
excite
);
ba_compute_excitation
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
fgain
,
fastleak
,
slowleak
,
0
);
ba_compute_mask
(
start
,
end
,
p_ac3dec
->
syncinfo
.
fscod
,
ba_compute_mask
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
p_ac3dec
->
syncinfo
.
fscod
,
p_ac3dec
->
audblk
.
cpldeltbae
,
p_ac3dec
->
audblk
.
cpldeltnseg
,
p_ac3dec
->
audblk
.
cpldeltoffst
,
p_ac3dec
->
audblk
.
cpldeltba
,
p_ac3dec
->
audblk
.
cpldeltlen
,
excite
,
mask
);
p_ac3dec
->
audblk
.
cpldeltlen
);
ba_compute_bap
(
start
,
end
,
snroffset
,
psd
,
mask
,
p_ac3dec
->
audblk
.
cpl_bap
);
ba_compute_bap
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
snroffset
,
p_ac3dec
->
audblk
.
cpl_bap
);
}
if
(
p_ac3dec
->
bsi
.
lfeon
)
{
...
...
@@ -291,29 +270,25 @@ void bit_allocate (ac3dec_t * p_ac3dec)
fastleak
=
0
;
slowleak
=
0
;
ba_compute_psd
(
start
,
end
,
p_ac3dec
->
audblk
.
lfe_exp
,
psd
,
bndpsd
);
ba_compute_psd
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
p_ac3dec
->
audblk
.
lfe_exp
);
ba_compute_excitation
(
start
,
end
,
fgain
,
fastleak
,
slowleak
,
1
,
bndpsd
,
excite
);
ba_compute_excitation
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
fgain
,
fastleak
,
slowleak
,
1
);
ba_compute_mask
(
start
,
end
,
p_ac3dec
->
syncinfo
.
fscod
,
2
,
0
,
0
,
0
,
0
,
excite
,
mask
);
ba_compute_mask
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
p_ac3dec
->
syncinfo
.
fscod
,
2
,
0
,
0
,
0
,
0
);
ba_compute_bap
(
start
,
end
,
snroffset
,
psd
,
mask
,
p_ac3dec
->
audblk
.
lfe_bap
);
ba_compute_bap
(
&
p_ac3dec
->
bit_allocate
,
start
,
end
,
snroffset
,
p_ac3dec
->
audblk
.
lfe_bap
);
}
}
static
void
ba_compute_psd
(
s16
start
,
s16
end
,
s16
exps
[],
s16
psd
[],
s16
bndpsd
[])
static
void
ba_compute_psd
(
bit_allocate_t
*
p_bit
,
s16
start
,
s16
end
,
s16
exps
[])
{
int
bin
,
i
,
j
,
k
;
s16
lastbin
=
0
;
/* Map the exponents into dBs */
for
(
bin
=
start
;
bin
<
end
;
bin
++
)
{
psd
[
bin
]
=
(
3072
-
(
exps
[
bin
]
<<
7
));
p
_bit
->
p
sd
[
bin
]
=
(
3072
-
(
exps
[
bin
]
<<
7
));
}
/* Integrate the psd function over each bit allocation band */
...
...
@@ -322,11 +297,11 @@ static void ba_compute_psd (s16 start, s16 end, s16 exps[], s16 psd[],
do
{
lastbin
=
min
(
bndtab
[
k
]
+
bndsz
[
k
],
end
);
bndpsd
[
k
]
=
psd
[
j
];
p_bit
->
bndpsd
[
k
]
=
p_bit
->
psd
[
j
];
j
++
;
for
(
i
=
j
;
i
<
lastbin
;
i
++
)
{
bndpsd
[
k
]
=
logadd
(
bndpsd
[
k
],
psd
[
j
]);
p_bit
->
bndpsd
[
k
]
=
logadd
(
p_bit
->
bndpsd
[
k
],
p_bit
->
psd
[
j
]);
j
++
;
}
...
...
@@ -334,9 +309,8 @@ static void ba_compute_psd (s16 start, s16 end, s16 exps[], s16 psd[],
}
while
(
end
>
lastbin
);
}
static
void
ba_compute_excitation
(
s16
start
,
s16
end
,
s16
fgain
,
s16
fastleak
,
s16
slowleak
,
s16
is_lfe
,
s16
bndpsd
[],
s16
excite
[])
static
void
ba_compute_excitation
(
bit_allocate_t
*
p_bit
,
s16
start
,
s16
end
,
s16
fgain
,
s16
fastleak
,
s16
slowleak
,
s16
is_lfe
)
{
int
bin
;
s16
bndstrt
;
...
...
@@ -349,22 +323,24 @@ static void ba_compute_excitation (s16 start, s16 end,s16 fgain, s16 fastleak,
bndend
=
masktab
[
end
-
1
]
+
1
;
if
(
bndstrt
==
0
)
{
/* For fbw and lfe channels */
lowcomp
=
calc_lowcomp
(
lowcomp
,
bndpsd
[
0
],
bndpsd
[
1
],
0
);
excite
[
0
]
=
bndpsd
[
0
]
-
fgain
-
lowcomp
;
lowcomp
=
calc_lowcomp
(
lowcomp
,
bndpsd
[
1
],
bndpsd
[
2
],
1
);
excite
[
1
]
=
bndpsd
[
1
]
-
fgain
-
lowcomp
;
lowcomp
=
calc_lowcomp
(
lowcomp
,
p_bit
->
bndpsd
[
0
],
p_bit
->
bndpsd
[
1
],
0
);
p_bit
->
excite
[
0
]
=
p_bit
->
bndpsd
[
0
]
-
fgain
-
lowcomp
;
lowcomp
=
calc_lowcomp
(
lowcomp
,
p_bit
->
bndpsd
[
1
],
p_bit
->
bndpsd
[
2
],
1
);
p_bit
->
excite
[
1
]
=
p_bit
->
bndpsd
[
1
]
-
fgain
-
lowcomp
;
begin
=
7
;
/* Note: Do not call calc_lowcomp() for the last band of the lfe channel, (bin = 6) */
for
(
bin
=
2
;
bin
<
7
;
bin
++
)
{
if
(
!
(
is_lfe
&&
(
bin
==
6
)))
lowcomp
=
calc_lowcomp
(
lowcomp
,
bndpsd
[
bin
],
bndpsd
[
bin
+
1
],
bin
);
fastleak
=
bndpsd
[
bin
]
-
fgain
;
slowleak
=
bndpsd
[
bin
]
-
sgain
;
excite
[
bin
]
=
fastleak
-
lowcomp
;
lowcomp
=
calc_lowcomp
(
lowcomp
,
p_bit
->
bndpsd
[
bin
],
p_bit
->
bndpsd
[
bin
+
1
],
bin
);
fastleak
=
p_bit
->
bndpsd
[
bin
]
-
fgain
;
slowleak
=
p_bit
->
bndpsd
[
bin
]
-
p_bit
->
sgain
;
p_bit
->
excite
[
bin
]
=
fastleak
-
lowcomp
;
if
(
!
(
is_lfe
&&
(
bin
==
6
)))
{
if
(
bndpsd
[
bin
]
<=
bndpsd
[
bin
+
1
])
{
if
(
p_bit
->
bndpsd
[
bin
]
<=
p_bit
->
bndpsd
[
bin
+
1
])
{
begin
=
bin
+
1
;
break
;
}
...
...
@@ -373,12 +349,13 @@ static void ba_compute_excitation (s16 start, s16 end,s16 fgain, s16 fastleak,
for
(
bin
=
begin
;
bin
<
min
(
bndend
,
22
);
bin
++
)
{
if
(
!
(
is_lfe
&&
(
bin
==
6
)))
lowcomp
=
calc_lowcomp
(
lowcomp
,
bndpsd
[
bin
],
bndpsd
[
bin
+
1
],
bin
);
fastleak
-=
fdecay
;
fastleak
=
max
(
fastleak
,
bndpsd
[
bin
]
-
fgain
);
slowleak
-=
sdecay
;
slowleak
=
max
(
slowleak
,
bndpsd
[
bin
]
-
sgain
);
excite
[
bin
]
=
max
(
fastleak
-
lowcomp
,
slowleak
);
lowcomp
=
calc_lowcomp
(
lowcomp
,
p_bit
->
bndpsd
[
bin
],
p_bit
->
bndpsd
[
bin
+
1
],
bin
);
fastleak
-=
p_bit
->
fdecay
;
fastleak
=
max
(
fastleak
,
p_bit
->
bndpsd
[
bin
]
-
fgain
);
slowleak
-=
p_bit
->
sdecay
;
slowleak
=
max
(
slowleak
,
p_bit
->
bndpsd
[
bin
]
-
p_bit
->
sgain
);
p_bit
->
excite
[
bin
]
=
max
(
fastleak
-
lowcomp
,
slowleak
);
}
begin
=
22
;
}
else
{
/* For coupling channel */
...
...
@@ -386,17 +363,17 @@ static void ba_compute_excitation (s16 start, s16 end,s16 fgain, s16 fastleak,
}
for
(
bin
=
begin
;
bin
<
bndend
;
bin
++
)
{
fastleak
-=
fdecay
;
fastleak
=
max
(
fastleak
,
bndpsd
[
bin
]
-
fgain
);
slowleak
-=
sdecay
;
slowleak
=
max
(
slowleak
,
bndpsd
[
bin
]
-
sgain
);
excite
[
bin
]
=
max
(
fastleak
,
slowleak
)
;
fastleak
-=
p_bit
->
fdecay
;
fastleak
=
max
(
fastleak
,
p_bit
->
bndpsd
[
bin
]
-
fgain
);
slowleak
-=
p_bit
->
sdecay
;
slowleak
=
max
(
slowleak
,
p_bit
->
bndpsd
[
bin
]
-
p_bit
->
sgain
);
p_bit
->
excite
[
bin
]
=
max
(
fastleak
,
slowleak
)
;
}
}
static
void
ba_compute_mask
(
s16
start
,
s16
end
,
u16
fscod
,
u16
deltbae
,
u16
delt
nseg
,
u16
deltoffst
[],
u16
deltba
[],
u16
delt
len
[],
s16
excite
[],
s16
mask
[])
static
void
ba_compute_mask
(
bit_allocate_t
*
p_bit
,
s16
start
,
s16
end
,
u16
fscod
,
u16
delt
bae
,
u16
deltnseg
,
u16
deltoffst
[],
u16
delt
ba
[],
u16
deltlen
[])
{
int
bin
,
k
;
s16
bndstrt
;
...
...
@@ -408,10 +385,10 @@ static void ba_compute_mask (s16 start, s16 end, u16 fscod, u16 deltbae,
/* Compute the masking curve */
for
(
bin
=
bndstrt
;
bin
<
bndend
;
bin
++
)
{
if
(
bndpsd
[
bin
]
<
dbknee
)
{
excite
[
bin
]
+=
((
dbknee
-
bndpsd
[
bin
])
>>
2
);
if
(
p_bit
->
bndpsd
[
bin
]
<
p_bit
->
dbknee
)
{
p_bit
->
excite
[
bin
]
+=
((
p_bit
->
dbknee
-
p_bit
->
bndpsd
[
bin
])
>>
2
);
}
mask
[
bin
]
=
max
(
excite
[
bin
],
hth
[
fscod
][
bin
]);
p_bit
->
mask
[
bin
]
=
max
(
p_bit
->
excite
[
bin
],
hth
[
fscod
][
bin
]);
}
/* Perform delta bit modulation if necessary */
...
...
@@ -427,15 +404,15 @@ static void ba_compute_mask (s16 start, s16 end, u16 fscod, u16 deltbae,
delta
=
(
deltba
[
seg
]
-
4
)
<<
7
;
}
for
(
k
=
0
;
k
<
deltlen
[
seg
];
k
++
)
{
mask
[
band
]
+=
delta
;
p_bit
->
mask
[
band
]
+=
delta
;
band
++
;
}
}
}
}
static
void
ba_compute_bap
(
s16
start
,
s16
end
,
s16
snroffset
,
s16
psd
[]
,
s16
mask
[],
s16
bap
[])
static
void
ba_compute_bap
(
bit_allocate_t
*
p_bit
,
s16
start
,
s16
end
,
s16
snroffset
,
s16
bap
[])
{
int
i
,
j
,
k
;
s16
lastbin
=
0
;
...
...
@@ -447,16 +424,16 @@ static void ba_compute_bap (s16 start, s16 end, s16 snroffset, s16 psd[],
do
{
lastbin
=
min
(
bndtab
[
j
]
+
bndsz
[
j
],
end
);
mask
[
j
]
-=
snroffset
;
mask
[
j
]
-=
floor
;
p_bit
->
mask
[
j
]
-=
snroffset
;
p_bit
->
mask
[
j
]
-=
p_bit
->
floor
;
if
(
mask
[
j
]
<
0
)
mask
[
j
]
=
0
;
if
(
p_bit
->
mask
[
j
]
<
0
)
p_bit
->
mask
[
j
]
=
0
;
mask
[
j
]
&=
0x1fe0
;
mask
[
j
]
+=
floor
;
p_bit
->
mask
[
j
]
&=
0x1fe0
;
p_bit
->
mask
[
j
]
+=
p_bit
->
floor
;
for
(
k
=
i
;
k
<
lastbin
;
k
++
)
{
address
=
(
p
sd
[
i
]
-
mask
[
j
])
>>
5
;
address
=
(
p
_bit
->
psd
[
i
]
-
p_bit
->
mask
[
j
])
>>
5
;
address
=
min
(
63
,
max
(
0
,
address
));
bap
[
i
]
=
baptab
[
address
];
i
++
;
...
...
src/ac3_decoder/ac3_bit_stream.h
View file @
a906b2f5
...
...
@@ -3,7 +3,8 @@
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
*
* Authors: Renaud Dartus <reno@videolan.org>
* Authors: Michel Lespinasse <walken@zoy.org>
* Renaud Dartus <reno@videolan.org>
*
*
* This program is free software; you can redistribute it and/or modify
...
...
src/ac3_decoder/ac3_decoder.c
View file @
a906b2f5
...
...
@@ -3,7 +3,9 @@
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* 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,17 +21,24 @@
* 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 "int_types.h"
#include "ac3_decoder.h"
#include "ac3_internal.h"
#include <stdio.h>
void
imdct_init
(
imdct_t
*
p_imdct
);
int
ac3_init
(
ac3dec_t
*
p_ac3dec
)
{
//p_ac3dec->bit_stream.buffer = 0;
//p_ac3dec->bit_stream.i_available = 0;
p_ac3dec
->
mantissa
.
lfsr_state
=
1
;
/* dither_gen initialization */
imdct_init
(
&
p_ac3dec
->
imdct
);
return
0
;
}
...
...
@@ -39,7 +48,7 @@ int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer)
if
(
parse_bsi
(
p_ac3dec
))
return
1
;
for
(
i
=
0
;
i
<
6
;
i
++
)
{
if
(
parse_audblk
(
p_ac3dec
,
i
))
return
1
;
...
...
@@ -49,8 +58,8 @@ int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer)
mantissa_unpack
(
p_ac3dec
);
if
(
p_ac3dec
->
bsi
.
acmod
==
0x2
)
rematrix
(
p_ac3dec
);
imdct
(
p_ac3dec
);
downmix
(
p_ac3dec
,
buffer
);
imdct
(
p_ac3dec
,
buffer
);
//
downmix (p_ac3dec, buffer);
buffer
+=
2
*
256
;
}
...
...
src/ac3_decoder/ac3_decoder.h
View file @
a906b2f5
...
...
@@ -3,8 +3,8 @@
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
*
Michel Kaempf <maxx@via.ecp.fr
>
* 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
...
...
@@ -355,6 +355,63 @@ typedef struct ac3_bit_stream_s
unsigned
int
total_bits_read
;
/* temporary */
}
ac3_bit_stream_t
;
typedef
struct
bit_allocate_s
{
s16
psd
[
256
];
s16
bndpsd
[
256
];
s16
excite
[
256
];
s16
mask
[
256
];
s16
sdecay
;
s16
fdecay
;
s16
sgain
;
s16
dbknee
;
s16
floor
;
}
bit_allocate_t
;
/* These store the persistent state of the packed mantissas */
typedef
struct
mantissa_s
{
float
q_1
[
2
];
float
q_2
[
2
];
float
q_4
[
1
];
s32
q_1_pointer
;
s32
q_2_pointer
;
s32
q_4_pointer
;
u16
lfsr_state
;
}
mantissa_t
;
typedef
struct
complex_s
{
float
real
;
float
imag
;
}
complex_t
;
#define N 512
typedef
struct
imdct_s
{
complex_t
buf
[
N
/
4
];
/* Delay buffer for time domain interleaving */
float
delay
[
6
][
256
];
/* Twiddle factors for IMDCT */
float
xcos1
[
N
/
4
];
float
xsin1
[
N
/
4
];
float
xcos2
[
N
/
8
];
float
xsin2
[
N
/
8
];
/* Twiddle factor LUT */
complex_t
*
w
[
7
];
complex_t
w_1
[
1
];
complex_t
w_2
[
2
];
complex_t
w_4
[
4
];
complex_t
w_8
[
8
];
complex_t
w_16
[
16
];
complex_t
w_32
[
32
];
complex_t
w_64
[
64
];
}
imdct_t
;
struct
ac3dec_s
{
/*
...
...
@@ -373,6 +430,10 @@ struct ac3dec_s
stream_coeffs_t
coeffs
;
stream_samples_t
samples
;
bit_allocate_t
bit_allocate
;
mantissa_t
mantissa
;
imdct_t
imdct
;
};
/**** ac3 decoder inline functions ****/
...
...
src/ac3_decoder/ac3_decoder_thread.c
View file @
a906b2f5
...
...
@@ -2,9 +2,9 @@
* ac3_decoder_thread.c: ac3 decoder thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder_thread.c,v 1.2
4 2001/02/11 01:15:10 sam
Exp $
* $Id: ac3_decoder_thread.c,v 1.2
5 2001/02/20 12:06:28 reno
Exp $
*
* Authors:
* Authors:
Michel Lespinasse <walken@zoy.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
...
...
@@ -164,9 +164,6 @@ static void RunThread (ac3dec_thread_t * p_ac3dec)
intf_DbgMsg
(
"ac3dec debug: running ac3 decoder thread (%p) (pid == %i)"
,
p_ac3dec
,
getpid
());
/* FIXME ! Qu'est-ce que c'est que ce bordel !?!?!?!? --Meuuh */
//msleep (INPUT_PTS_DELAY);
/* Initializing the ac3 decoder thread */
if
(
InitThread
(
p_ac3dec
))
/* XXX?? */
{
...
...
@@ -210,7 +207,7 @@ static void RunThread (ac3dec_thread_t * p_ac3dec)
{
if
(
p_byte_stream
->
p_byte
>=
p_byte_stream
->
p_end
)
{
ac3_byte_stream_next
(
p_byte_stream
);
ac3_byte_stream_next
(
p_byte_stream
);
}
p_byte_stream
->
p_byte
++
;
}
...
...
@@ -326,7 +323,6 @@ static void EndThread (ac3dec_thread_t * p_ac3dec)
void
ac3_byte_stream_next
(
ac3_byte_stream_t
*
p_byte_stream
)
{
ac3dec_thread_t
*
p_ac3dec
=
p_byte_stream
->
info
;
/* We are looking for the next TS packet that contains real data,
* and not just a PES header */
do
...
...
src/ac3_decoder/ac3_downmix.c
View file @
a906b2f5
...
...
@@ -3,7 +3,9 @@
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* 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
...
...
@@ -25,302 +27,70 @@
#include "ac3_decoder.h"
#include "ac3_internal.h"
#define NORM 16384
typedef
struct
prefs_s
{
u16
use_dolby_surround
;
u16
dual_mono_channel_select
;
}
prefs_t
;
prefs_t
global_prefs
=
{
0
,
0
};
#include "ac3_downmix.h"
/* Pre-scaled downmix coefficients */
static
float
cmixlev_lut
[
4
]
=
{
0
.
2928
,
0
.
2468
,
0
.
2071
,
0
.
2468
};
static
float
smixlev_lut
[
4
]
=
{
0
.
2928
,
0
.
2071
,
0
.
0
,
0
.
2071
};
static
const
float
cmixlev_lut
[
4
]
=
{
0
.
2928
,
0
.
2468
,
0
.
2071
,
0
.
2468
};
static
const
float
smixlev_lut
[
4
]
=
{
0
.
2928
,
0
.
2071
,
0
.
0
,
0
.
2071
};
/* Downmix into _two_ channels...other downmix modes aren't implemented
* to reduce complexity. Realistically, there aren't many machines around
* with > 2 channel output anyways */
void
downmix
(
ac3dec_t
*
p_ac3dec
,
s16
*
out_buf
)
int
__inline__
downmix
(
ac3dec_t
*
p_ac3dec
,
s16
*
out_buf
)
{
int
j
;
float
right_tmp
;
float
left_tmp
;
float
clev
,
slev
;
float
*
centre
=
0
,
*
left
=
0
,
*
right
=
0
,
*
left_sur
=
0
,
*
right_sur
=
0
;
/*
if (p_ac3dec->bsi.acmod > 7)
intf_ErrMsg( "ac3dec: (downmix) invalid acmod number" );
*/
/* There are two main cases, with or without Dolby Surround */
if
(
global_prefs
.
use_dolby_surround
)
{
switch
(
p_ac3dec
->
bsi
.
acmod
)
{
case
7
:
/* 3/2 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
centre
=
p_ac3dec
->
samples
.
channel
[
1
];
right
=
p_ac3dec
->
samples
.
channel
[
2
];
left_sur
=
p_ac3dec
->
samples
.
channel
[
3
];
right_sur
=
p_ac3dec
->
samples
.
channel
[
4
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
2265
f
*
*
left_sur
++
+
0
.
2265
f
*
*
right_sur
++
;
left_tmp
=
-
1
*
right_tmp
;
right_tmp
+=
0
.
3204
f
*
*
right
++
+
0
.
2265
f
*
*
centre
;
left_tmp
+=
0
.
3204
f
*
*
left
++
+
0
.
2265
f
*
*
centre
++
;
*
(
out_buf
++
)
=
left_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
6
:
/* 2/2 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
right
=
p_ac3dec
->
samples
.
channel
[
1
];
left_sur
=
p_ac3dec
->
samples
.
channel
[
2
];
right_sur
=
p_ac3dec
->
samples
.
channel
[
3
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
2265
f
*
*
left_sur
++
+
0
.
2265
f
*
*
right_sur
++
;
left_tmp
=
-
1
*
right_tmp
;
right_tmp
+=
0
.
3204
f
*
*
right
++
;
left_tmp
+=
0
.
3204
f
*
*
left
++
;
*
(
out_buf
++
)
=
left_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
5
:
/* 3/1 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
centre
=
p_ac3dec
->
samples
.
channel
[
1
];
right
=
p_ac3dec
->
samples
.
channel
[
2
];
/* Mono surround */
right_sur
=
p_ac3dec
->
samples
.
channel
[
3
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
2265
f
*
*
right_sur
++
;
left_tmp
=
-
right_tmp
;
right_tmp
+=
0
.
3204
f
*
*
right
++
+
0
.
2265
f
*
*
centre
;
left_tmp
+=
0
.
3204
f
*
*
left
++
+
0
.
2265
f
*
*
centre
++
;
*
(
out_buf
++
)
=
left_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
4
:
/* 2/1 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
right
=
p_ac3dec
->
samples
.
channel
[
1
];
/* Mono surround */
right_sur
=
p_ac3dec
->
samples
.
channel
[
2
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
2265
f
*
*
right_sur
++
;
left_tmp
=
-
right_tmp
;
right_tmp
+=
0
.
3204
f
*
*
right
++
;
left_tmp
+=
0
.
3204
f
*
*
left
++
;
*
(
out_buf
++
)
=
left_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
3
:
/* 3/0 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
centre
=
p_ac3dec
->
samples
.
channel
[
1
];
right
=
p_ac3dec
->
samples
.
channel
[
2
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
3204
f
*
*
right
++
+
0
.
2265
f
*
*
centre
;
left_tmp
=
0
.
3204
f
*
*
left
++
+
0
.
2265
f
*
*
centre
++
;
*
(
out_buf
++
)
=
left_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
2
:
/* 2/0 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
right
=
p_ac3dec
->
samples
.
channel
[
1
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
*
(
out_buf
++
)
=
*
(
left
++
)
*
NORM
;
*
(
out_buf
++
)
=
*
(
right
++
)
*
NORM
;
}
break
;
case
1
:
/* 1/0 */
/* Mono program! */
right
=
p_ac3dec
->
samples
.
channel
[
0
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
7071
f
*
*
right
++
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
0
:
/* 1+1 */
/* Dual mono, output selected by user */
right
=
p_ac3dec
->
samples
.
channel
[
global_prefs
.
dual_mono_channel_select
];
dm_par_t
dm_par
;
float
*
center
=
0
;
dm_par
.
clev
=
0
.
0
;
dm_par
.
slev
=
0
.
0
;
dm_par
.
unit
=
1
.
0
;
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
7071
f
*
*
right
++
;
if
(
p_ac3dec
->
bsi
.
acmod
&
0x1
)
/* have center */
dm_par
.
clev
=
cmixlev_lut
[
p_ac3dec
->
bsi
.
cmixlev
];
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
}
}
else
{
/* Non-Dolby surround downmixes */
switch
(
p_ac3dec
->
bsi
.
acmod
)
{
case
7
:
/* 3/2 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
centre
=
p_ac3dec
->
samples
.
channel
[
1
];
right
=
p_ac3dec
->
samples
.
channel
[
2
];
left_sur
=
p_ac3dec
->
samples
.
channel
[
3
];
right_sur
=
p_ac3dec
->
samples
.
channel
[
4
];
if
(
p_ac3dec
->
bsi
.
acmod
&
0x4
)
/* have surround channels */
dm_par
.
slev
=
smixlev_lut
[
p_ac3dec
->
bsi
.
surmixlev
];
clev
=
cmixlev_lut
[
p_ac3dec
->
bsi
.
cmixlev
];
slev
=
smixlev_lut
[
p_ac3dec
->
bsi
.
surmixlev
];
dm_par
.
unit
/=
1
.
0
+
dm_par
.
clev
+
dm_par
.
slev
;
dm_par
.
clev
*=
dm_par
.
unit
;
dm_par
.
slev
*=
dm_par
.
unit
;
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
4142
f
*
*
right
++
+
clev
*
*
centre
+
slev
*
*
right_sur
++
;
left_tmp
=
0
.
4142
f
*
*
left
++
+
clev
*
*
centre
++
+
slev
*
*
left_sur
++
;
*
(
out_buf
++
)
=
left_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
6
:
/* 2/2 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
right
=
p_ac3dec
->
samples
.
channel
[
1
];
left_sur
=
p_ac3dec
->
samples
.
channel
[
2
];
right_sur
=
p_ac3dec
->
samples
.
channel
[
3
];
slev
=
smixlev_lut
[
p_ac3dec
->
bsi
.
surmixlev
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
4142
f
*
*
right
++
+
slev
*
*
right_sur
++
;
left_tmp
=
0
.
4142
f
*
*
left
++
+
slev
*
*
left_sur
++
;
*
(
out_buf
++
)
=
left_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
5
:
/* 3/1 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
centre
=
p_ac3dec
->
samples
.
channel
[
1
];
right
=
p_ac3dec
->
samples
.
channel
[
2
];
/* Mono surround */
right_sur
=
p_ac3dec
->
samples
.
channel
[
3
];
clev
=
cmixlev_lut
[
p_ac3dec
->
bsi
.
cmixlev
];
slev
=
smixlev_lut
[
p_ac3dec
->
bsi
.
surmixlev
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
4142
f
*
*
right
++
+
clev
*
*
centre
+
slev
*
*
right_sur
;
left_tmp
=
0
.
4142
f
*
*
left
++
+
clev
*
*
centre
++
+
slev
*
*
right_sur
++
;
*
(
out_buf
++
)
=
left_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
4
:
/* 2/1 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
right
=
p_ac3dec
->
samples
.
channel
[
1
];
/* Mono surround */
right_sur
=
p_ac3dec
->
samples
.
channel
[
2
];
slev
=
smixlev_lut
[
p_ac3dec
->
bsi
.
surmixlev
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
4142
f
*
*
right
++
+
slev
*
*
right_sur
;
left_tmp
=
0
.
4142
f
*
*
left
++
+
slev
*
*
right_sur
++
;
*
(
out_buf
++
)
=
left_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
3
:
/* 3/0 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
centre
=
p_ac3dec
->
samples
.
channel
[
1
];
right
=
p_ac3dec
->
samples
.
channel
[
2
];
clev
=
cmixlev_lut
[
p_ac3dec
->
bsi
.
cmixlev
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
4142
f
*
*
right
++
+
clev
*
*
centre
;
left_tmp
=
0
.
4142
f
*
*
left
++
+
clev
*
*
centre
++
;
*
(
out_buf
++
)
=
left_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
2
:
/* 2/0 */
left
=
p_ac3dec
->
samples
.
channel
[
0
];
right
=
p_ac3dec
->
samples
.
channel
[
1
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
*
(
out_buf
++
)
=
*
(
left
++
)
*
NORM
;
*
(
out_buf
++
)
=
*
(
right
++
)
*
NORM
;
}
break
;
case
1
:
/* 1/0 */
/* Mono program! */
right
=
p_ac3dec
->
samples
.
channel
[
0
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
7071
f
*
*
right
++
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
case
0
:
/* 1+1 */
/* Dual mono, output selected by user */
right
=
p_ac3dec
->
samples
.
channel
[
global_prefs
.
dual_mono_channel_select
];
for
(
j
=
0
;
j
<
256
;
j
++
)
{
right_tmp
=
0
.
7071
f
*
*
right
++
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
*
(
out_buf
++
)
=
right_tmp
*
NORM
;
}
break
;
}
}
/*
if (p_ac3dec->bsi.acmod > 7)
intf_ErrMsg( "ac3dec: (downmix) invalid acmod number" );
*/
switch
(
p_ac3dec
->
bsi
.
acmod
)
{
case
7
:
// 3/2
downmix_3f_2r_to_2ch_c
(
p_ac3dec
->
samples
.
channel
[
0
],
&
dm_par
);
break
;
case
6
:
// 2/2
downmix_2f_2r_to_2ch_c
(
p_ac3dec
->
samples
.
channel
[
0
],
&
dm_par
);
break
;
case
5
:
// 3/1
downmix_3f_1r_to_2ch_c
(
p_ac3dec
->
samples
.
channel
[
0
],
&
dm_par
);
break
;
case
4
:
// 2/1
downmix_2f_1r_to_2ch_c
(
p_ac3dec
->
samples
.
channel
[
0
],
&
dm_par
);
break
;
case
3
:
// 3/0
downmix_3f_0r_to_2ch_c
(
p_ac3dec
->
samples
.
channel
[
0
],
&
dm_par
);
break
;
case
2
:
break
;
default:
// 1/0
if
(
p_ac3dec
->
bsi
.
acmod
==
1
)
center
=
p_ac3dec
->
samples
.
channel
[
0
];
else
if
(
p_ac3dec
->
bsi
.
acmod
==
0
)
center
=
p_ac3dec
->
samples
.
channel
[
0
];
/* FIXME */
stream_sample_1ch_to_s16_c
(
out_buf
,
center
);
return
1
;
}
return
0
;
}
src/ac3_decoder/ac3_downmix.h
0 → 100644
View file @
a906b2f5
/*****************************************************************************
* ac3_downmix.h: ac3 downmix functions
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
*
* Authors: 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define NORM 16384
typedef
struct
dm_par_s
{
float
unit
;
float
clev
;
float
slev
;
}
dm_par_t
;
void
downmix_3f_2r_to_2ch_c
(
float
*
samples
,
dm_par_t
*
dm_par
);
void
downmix_3f_1r_to_2ch_c
(
float
*
samples
,
dm_par_t
*
dm_par
);
void
downmix_2f_2r_to_2ch_c
(
float
*
samples
,
dm_par_t
*
dm_par
);
void
downmix_2f_1r_to_2ch_c
(
float
*
samples
,
dm_par_t
*
dm_par
);
void
downmix_3f_0r_to_2ch_c
(
float
*
samples
,
dm_par_t
*
dm_par
);
void
stream_sample_2ch_to_s16_c
(
s16
*
s16_samples
,
float
*
left
,
float
*
right
);
void
stream_sample_1ch_to_s16_c
(
s16
*
s16_samples
,
float
*
center
);
src/ac3_decoder/ac3_downmix_c.c
0 → 100644
View file @
a906b2f5
/*****************************************************************************
* ac3_downmix_c.c: ac3 downmix functions
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
*
* Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* 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 "int_types.h"
#include "ac3_decoder.h"
#include "ac3_internal.h"
#include "ac3_bit_stream.h"
#include "ac3_downmix.h"
void
__inline__
downmix_3f_2r_to_2ch_c
(
float
*
samples
,
dm_par_t
*
dm_par
)
{
int
i
;
float
*
left
,
*
right
,
*
center
,
*
left_sur
,
*
right_sur
;
float
left_tmp
,
right_tmp
;
left
=
samples
;
center
=
samples
+
256
;
right
=
samples
+
256
*
2
;
left_sur
=
samples
+
256
*
3
;
right_sur
=
samples
+
256
*
4
;
for
(
i
=
0
;
i
<
256
;
i
++
)
{
left_tmp
=
dm_par
->
unit
*
*
left
+
dm_par
->
clev
*
*
center
+
dm_par
->
slev
*
*
left_sur
++
;
right_tmp
=
dm_par
->
unit
*
*
right
++
+
dm_par
->
clev
*
*
center
+
dm_par
->
slev
*
*
right_sur
++
;
*
left
++
=
left_tmp
;
*
center
++
=
right_tmp
;
}
}
void
__inline__
downmix_2f_2r_to_2ch_c
(
float
*
samples
,
dm_par_t
*
dm_par
)
{
int
i
;
float
*
left
,
*
right
,
*
left_sur
,
*
right_sur
;
float
left_tmp
,
right_tmp
;
left
=
&
samples
[
0
];
right
=
&
samples
[
256
];
left_sur
=
&
samples
[
512
];
right_sur
=
&
samples
[
768
];
for
(
i
=
0
;
i
<
256
;
i
++
)
{
left_tmp
=
dm_par
->
unit
*
*
left
+
dm_par
->
slev
*
*
left_sur
++
;
right_tmp
=
dm_par
->
unit
*
*
right
+
dm_par
->
slev
*
*
right_sur
++
;
*
left
++
=
left_tmp
;
*
right
++
=
right_tmp
;
}
}
void
__inline__
downmix_3f_1r_to_2ch_c
(
float
*
samples
,
dm_par_t
*
dm_par
)
{
int
i
;
float
*
left
,
*
right
,
*
center
,
*
right_sur
;
float
left_tmp
,
right_tmp
;
left
=
&
samples
[
0
];
right
=
&
samples
[
512
];
center
=
&
samples
[
256
];
right_sur
=
&
samples
[
768
];
for
(
i
=
0
;
i
<
256
;
i
++
)
{
left_tmp
=
dm_par
->
unit
*
*
left
+
dm_par
->
clev
*
*
center
-
dm_par
->
slev
*
*
right_sur
;
right_tmp
=
dm_par
->
unit
*
*
right
++
+
dm_par
->
clev
*
*
center
+
dm_par
->
slev
*
*
right_sur
++
;
*
left
++
=
left_tmp
;
*
center
++
=
right_tmp
;
}
}
void
__inline__
downmix_2f_1r_to_2ch_c
(
float
*
samples
,
dm_par_t
*
dm_par
)
{
int
i
;
float
*
left
,
*
right
,
*
right_sur
;
float
left_tmp
,
right_tmp
;
left
=
&
samples
[
0
];
right
=
&
samples
[
256
];
right_sur
=
&
samples
[
512
];
for
(
i
=
0
;
i
<
256
;
i
++
)
{
left_tmp
=
dm_par
->
unit
*
*
left
-
dm_par
->
slev
*
*
right_sur
;
right_tmp
=
dm_par
->
unit
*
*
right
+
dm_par
->
slev
*
*
right_sur
++
;
*
left
++
=
left_tmp
;
*
right
++
=
right_tmp
;
}
}
void
__inline__
downmix_3f_0r_to_2ch_c
(
float
*
samples
,
dm_par_t
*
dm_par
)
{
int
i
;
float
*
left
,
*
right
,
*
center
;
float
left_tmp
,
right_tmp
;
left
=
&
samples
[
0
];
center
=
&
samples
[
256
];
right
=
&
samples
[
512
];
for
(
i
=
0
;
i
<
256
;
i
++
)
{
left_tmp
=
dm_par
->
unit
*
*
left
+
dm_par
->
clev
*
*
center
;
right_tmp
=
dm_par
->
unit
*
*
right
++
+
dm_par
->
clev
*
*
center
;
*
left
++
=
left_tmp
;
*
center
++
=
right_tmp
;
}
}
void
__inline__
stream_sample_2ch_to_s16_c
(
s16
*
out_buf
,
float
*
left
,
float
*
right
)
{
int
i
;
for
(
i
=
0
;
i
<
256
;
i
++
)
{
*
out_buf
++
=
(
s16
)
(
*
left
++
*
NORM
);
*
out_buf
++
=
(
s16
)
(
*
right
++
*
NORM
);
}
}
void
__inline__
stream_sample_1ch_to_s16_c
(
s16
*
out_buf
,
float
*
center
)
{
int
i
;
float
tmp
;
for
(
i
=
0
;
i
<
256
;
i
++
)
{
*
out_buf
++
=
tmp
=
(
s16
)
(
0
.
7071
f
*
*
center
++
*
NORM
);
*
out_buf
++
=
tmp
*
NORM
;
}
}
src/ac3_decoder/ac3_exponent.c
View file @
a906b2f5
...
...
@@ -3,7 +3,9 @@
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* 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
...
...
src/ac3_decoder/ac3_imdct.c
View file @
a906b2f5
...
...
@@ -3,7 +3,9 @@
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* 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,28 +21,23 @@
* 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 <math.h>
#include <stdio.h>
#include "int_types.h"
#include "ac3_decoder.h"
#include "ac3_internal.h"
void
imdct_do_256
(
float
x
[],
float
y
[],
float
delay
[]);
void
imdct_do_512
(
float
x
[],
float
y
[],
float
delay
[]);
typedef
struct
complex_s
{
float
real
;
float
imag
;
}
complex_t
;
#define N 512
#include "ac3_downmix.h"
static
complex_t
buf
[
N
/
4
];
void
imdct_do_256
(
imdct_t
*
p_imdct
,
float
x
[],
float
y
[],
int
id
);
void
imdct_do_512
(
imdct_t
*
p_imdct
,
float
x
[],
float
y
[],
int
id
);
/* 128 point bit-reverse LUT */
static
u8
bit_reverse_512
[]
=
{
static
const
u8
bit_reverse_512
[]
=
{
0x00
,
0x40
,
0x20
,
0x60
,
0x10
,
0x50
,
0x30
,
0x70
,
0x08
,
0x48
,
0x28
,
0x68
,
0x18
,
0x58
,
0x38
,
0x78
,
0x04
,
0x44
,
0x24
,
0x64
,
0x14
,
0x54
,
0x34
,
0x74
,
...
...
@@ -58,7 +55,7 @@ static u8 bit_reverse_512[] = {
0x07
,
0x47
,
0x27
,
0x67
,
0x17
,
0x57
,
0x37
,
0x77
,
0x0f
,
0x4f
,
0x2f
,
0x6f
,
0x1f
,
0x5f
,
0x3f
,
0x7f
};
static
u8
bit_reverse_256
[]
=
{
static
const
u8
bit_reverse_256
[]
=
{
0x00
,
0x20
,
0x10
,
0x30
,
0x08
,
0x28
,
0x18
,
0x38
,
0x04
,
0x24
,
0x14
,
0x34
,
0x0c
,
0x2c
,
0x1c
,
0x3c
,
0x02
,
0x22
,
0x12
,
0x32
,
0x0a
,
0x2a
,
0x1a
,
0x3a
,
...
...
@@ -68,25 +65,6 @@ static u8 bit_reverse_256[] = {
0x03
,
0x23
,
0x13
,
0x33
,
0x0b
,
0x2b
,
0x1b
,
0x3b
,
0x07
,
0x27
,
0x17
,
0x37
,
0x0f
,
0x2f
,
0x1f
,
0x3f
};
/* Twiddle factor LUT */
static
complex_t
*
w
[
7
];
static
complex_t
w_1
[
1
];
static
complex_t
w_2
[
2
];
static
complex_t
w_4
[
4
];
static
complex_t
w_8
[
8
];
static
complex_t
w_16
[
16
];
static
complex_t
w_32
[
32
];
static
complex_t
w_64
[
64
];
/* Twiddle factors for IMDCT */
static
float
xcos1
[
N
/
4
];
static
float
xsin1
[
N
/
4
];
static
float
xcos2
[
N
/
8
];
static
float
xsin2
[
N
/
8
];
/* Delay buffer for time domain interleaving */
static
float
delay
[
6
][
256
];
/* Windowing function for Modified DCT - Thank you acroread */
static
float
window
[]
=
{
0
.
00014
,
0
.
00024
,
0
.
00037
,
0
.
00051
,
0
.
00067
,
0
.
000
86
,
0
.
00107
,
0
.
00130
,
...
...
@@ -141,33 +119,32 @@ static __inline__ complex_t cmplx_mult(complex_t a, complex_t b)
return
ret
;
}
static
void
imdct_init
(
void
)
__attribute__
((
__constructor__
));
static
void
imdct_init
(
void
)
void
imdct_init
(
imdct_t
*
p_imdct
)
{
int
i
,
k
;
complex_t
angle_step
;
complex_t
current_angle
;
/* Twiddle factors to turn IFFT into IMDCT */
for
(
i
=
0
;
i
<
N
/
4
;
i
++
)
{
xcos1
[
i
]
=
-
cos
(
2
*
M_PI
*
(
8
*
i
+
1
)
/
(
8
*
N
))
;
xsin1
[
i
]
=
-
sin
(
2
*
M_PI
*
(
8
*
i
+
1
)
/
(
8
*
N
))
;
p_imdct
->
xcos1
[
i
]
=
-
cos
(
2
*
M_PI
*
(
8
*
i
+
1
)
/
(
8
*
N
))
;
p_imdct
->
xsin1
[
i
]
=
-
sin
(
2
*
M_PI
*
(
8
*
i
+
1
)
/
(
8
*
N
))
;
}
/* More twiddle factors to turn IFFT into IMDCT */
for
(
i
=
0
;
i
<
N
/
8
;
i
++
)
{
xcos2
[
i
]
=
-
cos
(
2
*
M_PI
*
(
8
*
i
+
1
)
/
(
4
*
N
))
;
xsin2
[
i
]
=
-
sin
(
2
*
M_PI
*
(
8
*
i
+
1
)
/
(
4
*
N
))
;
p_imdct
->
xcos2
[
i
]
=
-
cos
(
2
*
M_PI
*
(
8
*
i
+
1
)
/
(
4
*
N
))
;
p_imdct
->
xsin2
[
i
]
=
-
sin
(
2
*
M_PI
*
(
8
*
i
+
1
)
/
(
4
*
N
))
;
}
/* Canonical twiddle factors for FFT */
w
[
0
]
=
w_1
;
w
[
1
]
=
w_2
;
w
[
2
]
=
w_4
;
w
[
3
]
=
w_8
;
w
[
4
]
=
w_16
;
w
[
5
]
=
w_32
;
w
[
6
]
=
w_64
;
p_imdct
->
w
[
0
]
=
p_imdct
->
w_1
;
p_imdct
->
w
[
1
]
=
p_imdct
->
w_2
;
p_imdct
->
w
[
2
]
=
p_imdct
->
w_4
;
p_imdct
->
w
[
3
]
=
p_imdct
->
w_8
;
p_imdct
->
w
[
4
]
=
p_imdct
->
w_16
;
p_imdct
->
w
[
5
]
=
p_imdct
->
w_32
;
p_imdct
->
w
[
6
]
=
p_imdct
->
w_64
;
for
(
i
=
0
;
i
<
7
;
i
++
)
{
angle_step
.
real
=
cos
(
-
2
.
0
f
*
M_PI
/
(
1
<<
(
i
+
1
)));
...
...
@@ -177,21 +154,53 @@ static void imdct_init(void)
current_angle
.
imag
=
0
.
0
f
;
for
(
k
=
0
;
k
<
1
<<
i
;
k
++
)
{
w
[
i
][
k
]
=
current_angle
;
p_imdct
->
w
[
i
][
k
]
=
current_angle
;
current_angle
=
cmplx_mult
(
current_angle
,
angle_step
);
}
}
}
void
imdct
(
ac3dec_t
*
p_ac3dec
)
void
imdct
(
ac3dec_t
*
p_ac3dec
,
s16
*
buffer
)
{
int
i
;
int
i
,
i_stream_done
;
int
doable
=
0
;
void
(
*
do_imdct
)(
imdct_t
*
p_imdct
,
float
x
[],
float
y
[],
int
id
);
/* Test if dm in frequency is doable */
if
(
!
(
doable
=
p_ac3dec
->
audblk
.
blksw
[
0
])
)
do_imdct
=
imdct_do_512
;
else
do_imdct
=
imdct_do_256
;
/* Downmix in the frequency domain if all the channes use the same imdct */
for
(
i
=
0
;
i
<
p_ac3dec
->
bsi
.
nfchans
;
i
++
)
{
if
(
doable
!=
p_ac3dec
->
audblk
.
blksw
[
i
]
)
{
do_imdct
=
NULL
;
break
;
}
}
if
(
do_imdct
)
{
i_stream_done
=
downmix
(
p_ac3dec
,
buffer
);
do_imdct
(
&
p_ac3dec
->
imdct
,
p_ac3dec
->
coeffs
.
fbw
[
0
],
p_ac3dec
->
samples
.
channel
[
0
],
0
);
do_imdct
(
&
p_ac3dec
->
imdct
,
p_ac3dec
->
coeffs
.
fbw
[
1
],
p_ac3dec
->
samples
.
channel
[
1
],
1
);
}
else
{
for
(
i
=
0
;
i
<
p_ac3dec
->
bsi
.
nfchans
;
i
++
)
{
if
(
p_ac3dec
->
audblk
.
blksw
[
i
])
imdct_do_256
(
&
p_ac3dec
->
imdct
,
p_ac3dec
->
coeffs
.
fbw
[
i
],
p_ac3dec
->
samples
.
channel
[
i
],
i
);
else
imdct_do_512
(
&
p_ac3dec
->
imdct
,
p_ac3dec
->
coeffs
.
fbw
[
i
],
p_ac3dec
->
samples
.
channel
[
i
],
i
);
}
i_stream_done
=
downmix
(
p_ac3dec
,
buffer
);
}
for
(
i
=
0
;
i
<
p_ac3dec
->
bsi
.
nfchans
;
i
++
)
{
if
(
p_ac3dec
->
audblk
.
blksw
[
i
])
imdct_do_256
(
p_ac3dec
->
coeffs
.
fbw
[
i
],
p_ac3dec
->
samples
.
channel
[
i
],
delay
[
i
]);
else
imdct_do_512
(
p_ac3dec
->
coeffs
.
fbw
[
i
],
p_ac3dec
->
samples
.
channel
[
i
],
delay
[
i
]);
if
(
!
i_stream_done
)
/* We have to stream sample */
{
stream_sample_2ch_to_s16_c
(
buffer
,
p_ac3dec
->
samples
.
channel
[
0
],
p_ac3dec
->
samples
.
channel
[
1
]);
}
/* XXX?? We don't bother with the IMDCT for the LFE as it's currently
...
...
@@ -200,8 +209,7 @@ void imdct (ac3dec_t * p_ac3dec)
// imdct_do_512(coeffs->lfe,samples->channel[5],delay[5]);
}
void
imdct_do_512
(
float
x
[],
float
y
[],
float
delay
[])
void
imdct_do_512
(
imdct_t
*
p_imdct
,
float
x
[],
float
y
[],
int
id
)
{
int
i
,
k
;
int
p
,
q
;
...
...
@@ -222,15 +230,15 @@ imdct_do_512(float x[],float y[],float delay[])
/* Pre IFFT complex multiply plus IFFT cmplx conjugate */
for
(
i
=
0
;
i
<
N
/
4
;
i
++
)
{
/* z[i] = (X[N/2-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) ; */
buf
[
i
].
real
=
(
x
[
N
/
2
-
2
*
i
-
1
]
*
xcos1
[
i
])
-
(
x
[
2
*
i
]
*
xsin1
[
i
]);
buf
[
i
].
imag
=
-
((
x
[
2
*
i
]
*
xcos1
[
i
])
+
(
x
[
N
/
2
-
2
*
i
-
1
]
*
xsin1
[
i
]));
p_imdct
->
buf
[
i
].
real
=
(
x
[
N
/
2
-
2
*
i
-
1
]
*
p_imdct
->
xcos1
[
i
])
-
(
x
[
2
*
i
]
*
p_imdct
->
xsin1
[
i
]);
p_imdct
->
buf
[
i
].
imag
=
-
((
x
[
2
*
i
]
*
p_imdct
->
xcos1
[
i
])
+
(
x
[
N
/
2
-
2
*
i
-
1
]
*
p_imdct
->
xsin1
[
i
]));
}
/* Bit reversed shuffling */
for
(
i
=
0
;
i
<
N
/
4
;
i
++
)
{
k
=
bit_reverse_512
[
i
];
if
(
k
<
i
)
swap_cmplx
(
&
buf
[
i
],
&
buf
[
k
]);
swap_cmplx
(
&
p_imdct
->
buf
[
i
],
&
p_imdct
->
buf
[
k
]);
}
/* FFT Merge */
...
...
@@ -242,14 +250,14 @@ imdct_do_512(float x[],float y[],float delay[])
for
(
i
=
0
;
i
<
128
;
i
+=
two_m_plus_one
)
{
p
=
k
+
i
;
q
=
p
+
two_m
;
tmp_a_r
=
buf
[
p
].
real
;
tmp_a_i
=
buf
[
p
].
imag
;
tmp_b_r
=
buf
[
q
].
real
*
w
[
m
][
k
].
real
-
buf
[
q
].
imag
*
w
[
m
][
k
].
imag
;
tmp_b_i
=
buf
[
q
].
imag
*
w
[
m
][
k
].
real
+
buf
[
q
].
real
*
w
[
m
][
k
].
imag
;
buf
[
p
].
real
=
tmp_a_r
+
tmp_b_r
;
buf
[
p
].
imag
=
tmp_a_i
+
tmp_b_i
;
buf
[
q
].
real
=
tmp_a_r
-
tmp_b_r
;
buf
[
q
].
imag
=
tmp_a_i
-
tmp_b_i
;
tmp_a_r
=
p_imdct
->
buf
[
p
].
real
;
tmp_a_i
=
p_imdct
->
buf
[
p
].
imag
;
tmp_b_r
=
p_imdct
->
buf
[
q
].
real
*
p_imdct
->
w
[
m
][
k
].
real
-
p_imdct
->
buf
[
q
].
imag
*
p_imdct
->
w
[
m
][
k
].
imag
;
tmp_b_i
=
p_imdct
->
buf
[
q
].
imag
*
p_imdct
->
w
[
m
][
k
].
real
+
p_imdct
->
buf
[
q
].
real
*
p_imdct
->
w
[
m
][
k
].
imag
;
p_imdct
->
buf
[
p
].
real
=
tmp_a_r
+
tmp_b_r
;
p_imdct
->
buf
[
p
].
imag
=
tmp_a_i
+
tmp_b_i
;
p_imdct
->
buf
[
q
].
real
=
tmp_a_r
-
tmp_b_r
;
p_imdct
->
buf
[
q
].
imag
=
tmp_a_i
-
tmp_b_i
;
}
}
}
...
...
@@ -257,42 +265,41 @@ imdct_do_512(float x[],float y[],float delay[])
/* Post IFFT complex multiply plus IFFT complex conjugate*/
for
(
i
=
0
;
i
<
N
/
4
;
i
++
)
{
/* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
tmp_a_r
=
buf
[
i
].
real
;
tmp_a_i
=
-
buf
[
i
].
imag
;
buf
[
i
].
real
=
(
tmp_a_r
*
xcos1
[
i
])
-
(
tmp_a_i
*
xsin1
[
i
]);
buf
[
i
].
imag
=
(
tmp_a_r
*
xsin1
[
i
])
+
(
tmp_a_i
*
xcos1
[
i
]);
tmp_a_r
=
p_imdct
->
buf
[
i
].
real
;
tmp_a_i
=
-
p_imdct
->
buf
[
i
].
imag
;
p_imdct
->
buf
[
i
].
real
=
(
tmp_a_r
*
p_imdct
->
xcos1
[
i
])
-
(
tmp_a_i
*
p_imdct
->
xsin1
[
i
]);
p_imdct
->
buf
[
i
].
imag
=
(
tmp_a_r
*
p_imdct
->
xsin1
[
i
])
+
(
tmp_a_i
*
p_imdct
->
xcos1
[
i
]);
}
y_ptr
=
y
;
delay_ptr
=
delay
;
delay_ptr
=
p_imdct
->
delay
[
id
]
;
window_ptr
=
window
;
/* Window and convert to real valued signal */
for
(
i
=
0
;
i
<
N
/
8
;
i
++
)
{
*
y_ptr
++
=
2
.
0
f
*
(
-
buf
[
N
/
8
+
i
].
imag
*
*
window_ptr
++
+
*
delay_ptr
++
);
*
y_ptr
++
=
2
.
0
f
*
(
buf
[
N
/
8
-
i
-
1
].
real
*
*
window_ptr
++
+
*
delay_ptr
++
);
*
y_ptr
++
=
2
.
0
f
*
(
-
p_imdct
->
buf
[
N
/
8
+
i
].
imag
*
*
window_ptr
++
+
*
delay_ptr
++
);
*
y_ptr
++
=
2
.
0
f
*
(
p_imdct
->
buf
[
N
/
8
-
i
-
1
].
real
*
*
window_ptr
++
+
*
delay_ptr
++
);
}
for
(
i
=
0
;
i
<
N
/
8
;
i
++
)
{
*
y_ptr
++
=
2
.
0
f
*
(
-
buf
[
i
].
real
*
*
window_ptr
++
+
*
delay_ptr
++
);
*
y_ptr
++
=
2
.
0
f
*
(
buf
[
N
/
4
-
i
-
1
].
imag
*
*
window_ptr
++
+
*
delay_ptr
++
);
*
y_ptr
++
=
2
.
0
f
*
(
-
p_imdct
->
buf
[
i
].
real
*
*
window_ptr
++
+
*
delay_ptr
++
);
*
y_ptr
++
=
2
.
0
f
*
(
p_imdct
->
buf
[
N
/
4
-
i
-
1
].
imag
*
*
window_ptr
++
+
*
delay_ptr
++
);
}
/* The trailing edge of the window goes into the delay line */
delay_ptr
=
delay
;
delay_ptr
=
p_imdct
->
delay
[
id
]
;
for
(
i
=
0
;
i
<
N
/
8
;
i
++
)
{
*
delay_ptr
++
=
-
buf
[
N
/
8
+
i
].
real
*
*--
window_ptr
;
*
delay_ptr
++
=
buf
[
N
/
8
-
i
-
1
].
imag
*
*--
window_ptr
;
*
delay_ptr
++
=
-
p_imdct
->
buf
[
N
/
8
+
i
].
real
*
*--
window_ptr
;
*
delay_ptr
++
=
p_imdct
->
buf
[
N
/
8
-
i
-
1
].
imag
*
*--
window_ptr
;
}
for
(
i
=
0
;
i
<
N
/
8
;
i
++
)
{
*
delay_ptr
++
=
buf
[
i
].
imag
*
*--
window_ptr
;
*
delay_ptr
++
=
-
buf
[
N
/
4
-
i
-
1
].
real
*
*--
window_ptr
;
*
delay_ptr
++
=
p_imdct
->
buf
[
i
].
imag
*
*--
window_ptr
;
*
delay_ptr
++
=
-
p_imdct
->
buf
[
N
/
4
-
i
-
1
].
real
*
*--
window_ptr
;
}
}
void
imdct_do_256
(
float
x
[],
float
y
[],
float
delay
[])
void
imdct_do_256
(
imdct_t
*
p_imdct
,
float
x
[],
float
y
[],
int
id
)
{
int
i
,
k
;
int
p
,
q
;
...
...
@@ -307,8 +314,8 @@ imdct_do_256(float x[],float y[],float delay[])
complex_t
*
buf_1
,
*
buf_2
;
buf_1
=
&
buf
[
0
];
buf_2
=
&
buf
[
64
];
buf_1
=
&
p_imdct
->
buf
[
0
];
buf_2
=
&
p_imdct
->
buf
[
64
];
/* Pre IFFT complex multiply plus IFFT cmplx conjugate */
for
(
k
=
0
;
k
<
N
/
8
;
k
++
)
{
...
...
@@ -319,11 +326,11 @@ imdct_do_256(float x[],float y[],float delay[])
q
=
2
*
(
2
*
k
);
/* Z1[k] = (X1[N/4-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
buf_1
[
k
].
real
=
x
[
p
]
*
xcos2
[
k
]
-
x
[
q
]
*
xsin2
[
k
];
buf_1
[
k
].
imag
=
-
(
x
[
q
]
*
xcos2
[
k
]
+
x
[
p
]
*
xsin2
[
k
]);
buf_1
[
k
].
real
=
x
[
p
]
*
p_imdct
->
xcos2
[
k
]
-
x
[
q
]
*
p_imdct
->
xsin2
[
k
];
buf_1
[
k
].
imag
=
-
(
x
[
q
]
*
p_imdct
->
xcos2
[
k
]
+
x
[
p
]
*
p_imdct
->
xsin2
[
k
]);
/* Z2[k] = (X2[N/4-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
buf_2
[
k
].
real
=
x
[
p
+
1
]
*
xcos2
[
k
]
-
x
[
q
+
1
]
*
xsin2
[
k
];
buf_2
[
k
].
imag
=
-
(
x
[
q
+
1
]
*
xcos2
[
k
]
+
x
[
p
+
1
]
*
xsin2
[
k
]);
buf_2
[
k
].
real
=
x
[
p
+
1
]
*
p_imdct
->
xcos2
[
k
]
-
x
[
q
+
1
]
*
p_imdct
->
xsin2
[
k
];
buf_2
[
k
].
imag
=
-
(
x
[
q
+
1
]
*
p_imdct
->
xcos2
[
k
]
+
x
[
p
+
1
]
*
p_imdct
->
xsin2
[
k
]);
}
/* IFFT Bit reversed shuffling */
...
...
@@ -347,8 +354,8 @@ imdct_do_256(float x[],float y[],float delay[])
/* Do block 1 */
tmp_a_r
=
buf_1
[
p
].
real
;
tmp_a_i
=
buf_1
[
p
].
imag
;
tmp_b_r
=
buf_1
[
q
].
real
*
w
[
m
][
k
].
real
-
buf_1
[
q
].
imag
*
w
[
m
][
k
].
imag
;
tmp_b_i
=
buf_1
[
q
].
imag
*
w
[
m
][
k
].
real
+
buf_1
[
q
].
real
*
w
[
m
][
k
].
imag
;
tmp_b_r
=
buf_1
[
q
].
real
*
p_imdct
->
w
[
m
][
k
].
real
-
buf_1
[
q
].
imag
*
p_imdct
->
w
[
m
][
k
].
imag
;
tmp_b_i
=
buf_1
[
q
].
imag
*
p_imdct
->
w
[
m
][
k
].
real
+
buf_1
[
q
].
real
*
p_imdct
->
w
[
m
][
k
].
imag
;
buf_1
[
p
].
real
=
tmp_a_r
+
tmp_b_r
;
buf_1
[
p
].
imag
=
tmp_a_i
+
tmp_b_i
;
buf_1
[
q
].
real
=
tmp_a_r
-
tmp_b_r
;
...
...
@@ -357,8 +364,8 @@ imdct_do_256(float x[],float y[],float delay[])
/* Do block 2 */
tmp_a_r
=
buf_2
[
p
].
real
;
tmp_a_i
=
buf_2
[
p
].
imag
;
tmp_b_r
=
buf_2
[
q
].
real
*
w
[
m
][
k
].
real
-
buf_2
[
q
].
imag
*
w
[
m
][
k
].
imag
;
tmp_b_i
=
buf_2
[
q
].
imag
*
w
[
m
][
k
].
real
+
buf_2
[
q
].
real
*
w
[
m
][
k
].
imag
;
tmp_b_r
=
buf_2
[
q
].
real
*
p_imdct
->
w
[
m
][
k
].
real
-
buf_2
[
q
].
imag
*
p_imdct
->
w
[
m
][
k
].
imag
;
tmp_b_i
=
buf_2
[
q
].
imag
*
p_imdct
->
w
[
m
][
k
].
real
+
buf_2
[
q
].
real
*
p_imdct
->
w
[
m
][
k
].
imag
;
buf_2
[
p
].
real
=
tmp_a_r
+
tmp_b_r
;
buf_2
[
p
].
imag
=
tmp_a_i
+
tmp_b_i
;
buf_2
[
q
].
real
=
tmp_a_r
-
tmp_b_r
;
...
...
@@ -372,13 +379,13 @@ imdct_do_256(float x[],float y[],float delay[])
/* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
tmp_a_r
=
buf_1
[
i
].
real
;
tmp_a_i
=
-
buf_1
[
i
].
imag
;
buf_1
[
i
].
real
=
(
tmp_a_r
*
xcos2
[
i
])
-
(
tmp_a_i
*
xsin2
[
i
]);
buf_1
[
i
].
imag
=
(
tmp_a_r
*
xsin2
[
i
])
+
(
tmp_a_i
*
xcos2
[
i
]);
buf_1
[
i
].
real
=
(
tmp_a_r
*
p_imdct
->
xcos2
[
i
])
-
(
tmp_a_i
*
p_imdct
->
xsin2
[
i
]);
buf_1
[
i
].
imag
=
(
tmp_a_r
*
p_imdct
->
xsin2
[
i
])
+
(
tmp_a_i
*
p_imdct
->
xcos2
[
i
]);
/* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
tmp_a_r
=
buf_2
[
i
].
real
;
tmp_a_i
=
-
buf_2
[
i
].
imag
;
buf_2
[
i
].
real
=
(
tmp_a_r
*
xcos2
[
i
])
-
(
tmp_a_i
*
xsin2
[
i
]);
buf_2
[
i
].
imag
=
(
tmp_a_r
*
xsin2
[
i
])
+
(
tmp_a_i
*
xcos2
[
i
]);
buf_2
[
i
].
real
=
(
tmp_a_r
*
p_imdct
->
xcos2
[
i
])
-
(
tmp_a_i
*
p_imdct
->
xsin2
[
i
]);
buf_2
[
i
].
imag
=
(
tmp_a_r
*
p_imdct
->
xsin2
[
i
])
+
(
tmp_a_i
*
p_imdct
->
xcos2
[
i
]);
}
/* Window and convert to real valued signal */
...
...
@@ -395,7 +402,7 @@ imdct_do_256(float x[],float y[],float delay[])
/* Overlap and add */
for
(
i
=
0
;
i
<
N
/
2
;
i
++
)
{
y
[
i
]
=
2
*
(
y
[
i
]
+
delay
[
i
]);
delay
[
i
]
=
y
[
N
/
2
+
i
];
y
[
i
]
=
2
*
(
y
[
i
]
+
p_imdct
->
delay
[
id
]
[
i
]);
p_imdct
->
delay
[
id
]
[
i
]
=
y
[
N
/
2
+
i
];
}
}
src/ac3_decoder/ac3_internal.h
View file @
a906b2f5
...
...
@@ -3,7 +3,7 @@
*****************************************************************************
* Copyright (C) 2000 VideoLAN
*
* Authors:
* Authors:
Michel Lespinasse <walken@zoy.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
...
...
@@ -36,13 +36,13 @@
void
bit_allocate
(
ac3dec_t
*
);
/* ac3_downmix.c */
void
downmix
(
ac3dec_t
*
,
s16
*
);
int
downmix
(
ac3dec_t
*
,
s16
*
);
/* ac3_exponent.c */
int
exponent_unpack
(
ac3dec_t
*
);
/* ac3_imdct.c */
void
imdct
(
ac3dec_t
*
p_ac3dec
);
void
imdct
(
ac3dec_t
*
p_ac3dec
,
s16
*
buffer
);
/* ac3_mantissa.c */
void
mantissa_unpack
(
ac3dec_t
*
);
...
...
src/ac3_decoder/ac3_mantissa.c
View file @
a906b2f5
...
...
@@ -4,6 +4,7 @@
* Copyright (C) 1999, 2000, 2001 VideoLAN
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* Renaud Dartus <reno@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
...
...
@@ -36,21 +37,21 @@
#define Q0 ((-2 << 15) / 3.0)
#define Q1 (0)
#define Q2 ((2 << 15) / 3.0)
static
float
q_1_0
[
32
]
=
static
const
float
q_1_0
[
32
]
=
{
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q2
,
Q2
,
Q2
,
Q2
,
Q2
,
Q2
,
Q2
,
Q2
,
Q2
,
0
,
0
,
0
,
0
,
0
};
static
float
q_1_1
[
32
]
=
static
const
float
q_1_1
[
32
]
=
{
Q0
,
Q0
,
Q0
,
Q1
,
Q1
,
Q1
,
Q2
,
Q2
,
Q2
,
Q0
,
Q0
,
Q0
,
Q1
,
Q1
,
Q1
,
Q2
,
Q2
,
Q2
,
Q0
,
Q0
,
Q0
,
Q1
,
Q1
,
Q1
,
Q2
,
Q2
,
Q2
,
0
,
0
,
0
,
0
,
0
};
static
float
q_1_2
[
32
]
=
static
const
float
q_1_2
[
32
]
=
{
Q0
,
Q1
,
Q2
,
Q0
,
Q1
,
Q2
,
Q0
,
Q1
,
Q2
,
Q0
,
Q1
,
Q2
,
Q0
,
Q1
,
Q2
,
Q0
,
Q1
,
Q2
,
...
...
@@ -66,7 +67,7 @@ static float q_1_2[ 32 ] =
#define Q2 (0)
#define Q3 ((2 << 15) / 5.0)
#define Q4 ((4 << 15) / 5.0)
static
float
q_2_0
[
128
]
=
static
const
float
q_2_0
[
128
]
=
{
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
...
...
@@ -75,7 +76,7 @@ static float q_2_0[ 128 ] =
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
0
,
0
,
0
};
static
float
q_2_1
[
128
]
=
static
const
float
q_2_1
[
128
]
=
{
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q2
,
Q2
,
Q2
,
Q2
,
Q2
,
Q3
,
Q3
,
Q3
,
Q3
,
Q3
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q2
,
Q2
,
Q2
,
Q2
,
Q2
,
Q3
,
Q3
,
Q3
,
Q3
,
Q3
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
...
...
@@ -84,7 +85,7 @@ static float q_2_1[ 128 ] =
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q2
,
Q2
,
Q2
,
Q2
,
Q2
,
Q3
,
Q3
,
Q3
,
Q3
,
Q3
,
Q4
,
Q4
,
Q4
,
Q4
,
Q4
,
0
,
0
,
0
};
static
float
q_2_2
[
128
]
=
static
const
float
q_2_2
[
128
]
=
{
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
...
...
@@ -110,7 +111,7 @@ static float q_2_2[ 128 ] =
#define Q8 ((6 << 15) / 11.0)
#define Q9 ((8 << 15) / 11.0)
#define QA ((10 << 15) / 11.0)
static
float
q_4_0
[
128
]
=
static
const
float
q_4_0
[
128
]
=
{
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q0
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
Q1
,
...
...
@@ -125,7 +126,7 @@ static float q_4_0[ 128 ] =
QA
,
QA
,
QA
,
QA
,
QA
,
QA
,
QA
,
QA
,
QA
,
QA
,
QA
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
static
float
q_4_1
[
128
]
=
static
const
float
q_4_1
[
128
]
=
{
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
Q5
,
Q6
,
Q7
,
Q8
,
Q9
,
QA
,
Q0
,
Q1
,
Q2
,
Q3
,
Q4
,
Q5
,
Q6
,
Q7
,
Q8
,
Q9
,
QA
,
...
...
@@ -154,14 +155,14 @@ static float q_4_1[ 128 ] =
/* Lookup tables of 0.16 two's complement quantization values */
static
float
q_3
[
8
]
=
static
const
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
};
static
float
q_5
[
16
]
=
static
const
float
q_5
[
16
]
=
{
(
-
14
<<
15
)
/
15
.
0
,
(
-
12
<<
15
)
/
15
.
0
,
(
-
10
<<
15
)
/
15
.
0
,
(
-
8
<<
15
)
/
15
.
0
,
(
-
6
<<
15
)
/
15
.
0
,
(
-
4
<<
15
)
/
15
.
0
,
...
...
@@ -171,22 +172,14 @@ static float q_5[16] =
0
};
/* These store the persistent state of the packed mantissas */
static
float
q_1
[
2
];
static
float
q_2
[
2
];
static
float
q_4
[
1
];
static
s32
q_1_pointer
;
static
s32
q_2_pointer
;
static
s32
q_4_pointer
;
/* Conversion from bap to number of bits in the mantissas
* zeros account for cases 0,1,2,4 which are special cased */
static
u16
qnttztab
[
16
]
=
static
const
u16
qnttztab
[
16
]
=
{
0
,
0
,
0
,
3
,
0
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
14
,
16
};
static
float
exp_lut
[
25
]
=
static
const
float
exp_lut
[
25
]
=
{
6.10351562500000000000000000e-05
,
3.05175781250000000000000000e-05
,
...
...
@@ -215,7 +208,7 @@ static float exp_lut[ 25 ] =
3.63797880709171295166015625e-12
,
};
const
u16
dither_lut
[
256
]
=
static
const
u16
dither_lut
[
256
]
=
{
0x0000
,
0xa011
,
0xe033
,
0x4022
,
0x6077
,
0xc066
,
0x8044
,
0x2055
,
0xc0ee
,
0x60ff
,
0x20dd
,
0x80cc
,
0xa099
,
0x0088
,
0x40aa
,
0xe0bb
,
...
...
@@ -251,14 +244,13 @@ const u16 dither_lut[256] =
0x8bf4
,
0x2be5
,
0x6bc7
,
0xcbd6
,
0xeb83
,
0x4b92
,
0x0bb0
,
0xaba1
};
u16
lfsr_state
=
1
;
static
__inline__
u16
dither_gen
(
void
)
static
__inline__
u16
dither_gen
(
mantissa_t
*
p_mantissa
)
{
s16
state
;
state
=
dither_lut
[
lfsr_state
>>
8
]
^
(
lfsr_state
<<
8
);
lfsr_state
=
(
u16
)
state
;
state
=
dither_lut
[
p_mantissa
->
lfsr_state
>>
8
]
^
(
p_mantissa
->
lfsr_state
<<
8
);
p_mantissa
->
lfsr_state
=
(
u16
)
state
;
return
(
(
state
*
(
s32
)
(
0
.
707106
*
256
.
0
))
>>
8
);
}
...
...
@@ -274,75 +266,75 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
case
0
:
if
(
p_ac3dec
->
audblk
.
dithflag
[
exp
])
{
return
(
dither_gen
()
*
exp_lut
[
exp
]
);
return
(
dither_gen
(
&
p_ac3dec
->
mantissa
)
*
exp_lut
[
exp
]
);
}
return
(
0
);
case
1
:
if
(
q_1_pointer
>=
0
)
if
(
p_ac3dec
->
mantissa
.
q_1_pointer
>=
0
)
{
return
(
q_1
[
q_1_pointer
--
]
*
exp_lut
[
exp
]);
return
(
p_ac3dec
->
mantissa
.
q_1
[
p_ac3dec
->
mantissa
.
q_1_pointer
--
]
*
exp_lut
[
exp
]);
}
if
((
group_code
=
bitstream_get
(
&
(
p_ac3dec
->
bit_stream
),
5
))
>=
27
)
{
intf_
ErrMsg
(
"ac3dec error: invalid mantissa"
);
intf_
WarnMsg
(
1
,
"ac3dec error: invalid mantissa"
);
}
q_1
[
1
]
=
q_1_1
[
group_code
];
q_1
[
0
]
=
q_1_2
[
group_code
];
p_ac3dec
->
mantissa
.
q_1
[
1
]
=
q_1_1
[
group_code
];
p_ac3dec
->
mantissa
.
q_1
[
0
]
=
q_1_2
[
group_code
];
q_1_pointer
=
1
;
p_ac3dec
->
mantissa
.
q_1_pointer
=
1
;
return
(
q_1_0
[
group_code
]
*
exp_lut
[
exp
]);
case
2
:
if
(
q_2_pointer
>=
0
)
if
(
p_ac3dec
->
mantissa
.
q_2_pointer
>=
0
)
{
return
(
q_2
[
q_2_pointer
--
]
*
exp_lut
[
exp
]);
return
(
p_ac3dec
->
mantissa
.
q_2
[
p_ac3dec
->
mantissa
.
q_2_pointer
--
]
*
exp_lut
[
exp
]);
}
if
((
group_code
=
bitstream_get
(
&
(
p_ac3dec
->
bit_stream
),
7
))
>=
125
)
{
intf_
ErrMsg
(
"ac3dec error: invalid mantissa"
);
intf_
WarnMsg
(
1
,
"ac3dec error: invalid mantissa"
);
}
q_2
[
1
]
=
q_2_1
[
group_code
];
q_2
[
0
]
=
q_2_2
[
group_code
];
p_ac3dec
->
mantissa
.
q_2
[
1
]
=
q_2_1
[
group_code
];
p_ac3dec
->
mantissa
.
q_2
[
0
]
=
q_2_2
[
group_code
];
q_2_pointer
=
1
;
p_ac3dec
->
mantissa
.
q_2_pointer
=
1
;
return
(
q_2_0
[
group_code
]
*
exp_lut
[
exp
]);
case
3
:
if
((
group_code
=
bitstream_get
(
&
(
p_ac3dec
->
bit_stream
),
3
))
>=
7
)
{
intf_
ErrMsg
(
"ac3dec error: invalid mantissa"
);
intf_
WarnMsg
(
1
,
"ac3dec error: invalid mantissa"
);
}
return
(
q_3
[
group_code
]
*
exp_lut
[
exp
]);
case
4
:
if
(
q_4_pointer
>=
0
)
if
(
p_ac3dec
->
mantissa
.
q_4_pointer
>=
0
)
{
return
(
q_4
[
q_4_pointer
--
]
*
exp_lut
[
exp
]);
return
(
p_ac3dec
->
mantissa
.
q_4
[
p_ac3dec
->
mantissa
.
q_4_pointer
--
]
*
exp_lut
[
exp
]);
}
if
((
group_code
=
bitstream_get
(
&
(
p_ac3dec
->
bit_stream
),
7
))
>=
121
)
{
intf_
ErrMsg
(
"ac3dec error: invalid mantissa"
);
intf_
WarnMsg
(
1
,
"ac3dec error: invalid mantissa"
);
}
q_4
[
0
]
=
q_4_1
[
group_code
];
p_ac3dec
->
mantissa
.
q_4
[
0
]
=
q_4_1
[
group_code
];
q_4_pointer
=
0
;
p_ac3dec
->
mantissa
.
q_4_pointer
=
0
;
return
(
q_4_0
[
group_code
]
*
exp_lut
[
exp
]);
case
5
:
if
((
group_code
=
bitstream_get
(
&
(
p_ac3dec
->
bit_stream
),
4
))
>=
15
)
{
intf_
ErrMsg
(
"ac3dec error: invalid mantissa"
);
intf_
WarnMsg
(
1
,
"ac3dec error: invalid mantissa"
);
}
return
(
q_5
[
group_code
]
*
exp_lut
[
exp
]);
...
...
@@ -394,7 +386,7 @@ static __inline__ void uncouple_channel (ac3dec_t * p_ac3dec, u32 ch)
* 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
()
*
p_ac3dec
->
coeffs
.
fbw
[
ch
][
i
]
=
cpl_coord
*
dither_gen
(
&
p_ac3dec
->
mantissa
)
*
exp_lut
[
p_ac3dec
->
audblk
.
cpl_exp
[
i
]];
}
else
{
p_ac3dec
->
coeffs
.
fbw
[
ch
][
i
]
=
cpl_coord
*
p_ac3dec
->
audblk
.
cplfbw
[
i
];
...
...
@@ -408,10 +400,10 @@ void mantissa_unpack (ac3dec_t * p_ac3dec)
{
int
i
,
j
;
q_1_pointer
=
-
1
;
q_2_pointer
=
-
1
;
q_4_pointer
=
-
1
;
p_ac3dec
->
mantissa
.
q_1_pointer
=
-
1
;
p_ac3dec
->
mantissa
.
q_2_pointer
=
-
1
;
p_ac3dec
->
mantissa
.
q_4_pointer
=
-
1
;
if
(
p_ac3dec
->
audblk
.
cplinu
)
{
/* 1 */
...
...
src/ac3_decoder/ac3_parse.c
View file @
a906b2f5
...
...
@@ -4,6 +4,7 @@
* Copyright (C) 1999, 2000, 2001 VideoLAN
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
* Renaud Dartus <reno@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
...
...
@@ -31,7 +32,7 @@
#include "ac3_bit_stream.h"
/* Misc LUT */
static
u16
nfchans
[]
=
{
2
,
1
,
2
,
3
,
3
,
4
,
4
,
5
};
static
const
u16
nfchans
[]
=
{
2
,
1
,
2
,
3
,
3
,
4
,
4
,
5
};
struct
frmsize_s
{
...
...
@@ -39,7 +40,7 @@ struct frmsize_s
u16
frm_size
[
3
];
};
static
struct
frmsize_s
frmsizecod_tbl
[]
=
static
const
struct
frmsize_s
frmsizecod_tbl
[]
=
{
{
32
,{
64
,
69
,
96
}
},
{
32
,{
64
,
70
,
96
}
},
...
...
@@ -80,7 +81,7 @@ static struct frmsize_s frmsizecod_tbl[] =
{
640
,{
1280
,
1393
,
1920
}
},
{
640
,{
1280
,
1394
,
1920
}
}};
static
int
fscod_tbl
[]
=
{
48000
,
44100
,
32000
};
static
const
int
fscod_tbl
[]
=
{
48000
,
44100
,
32000
};
/* Some internal functions */
void
parse_bsi_stats
(
ac3dec_t
*
p_ac3dec
);
...
...
@@ -264,6 +265,10 @@ int parse_bsi (ac3dec_t * p_ac3dec)
}
}
#ifdef STATS
parse_bsi_stats
(
p_ac3dec
);
#endif
return
0
;
}
...
...
@@ -692,6 +697,10 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
}
}
#ifdef STATS
// parse_audblk_stats(p_ac3dec);
#endif
return
0
;
}
...
...
@@ -716,3 +725,69 @@ void parse_auxdata (ac3dec_t * p_ac3dec)
/* Get the crc */
bitstream_get
(
&
(
p_ac3dec
->
bit_stream
),
16
);
}
void
parse_bsi_stats
(
ac3dec_t
*
p_ac3dec
)
/*Some stats */
{
struct
mixlev_s
{
float
clev
;
char
*
desc
;
};
static
const
char
*
service_ids
[
8
]
=
{
"CM"
,
"ME"
,
"VI"
,
"HI"
,
"D"
,
"C"
,
"E"
,
"VO"
};
/*
static const struct mixlev_s cmixlev_tbl[4] =
{
{0.707, "(-3.0 dB)"}, {0.595, "(-4.5 dB)"},
{0.500, "(-6.0 dB)"}, {1.0, "Invalid"}
};
static const struct mixlev_s smixlev_tbl[4] =
{
{0.707, "(-3.0 dB)"}, {0.500, "(-6.0 dB)"},
{ 0.0, "off "}, { 1.0, "Invalid"}
};
*/
static
int
i
;
if
(
!
i
)
{
/* if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1))
printf("CentreMixLevel %s ",cmixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
if (p_ac3dec->bsi.acmod & 0x4)
printf("SurMixLevel %s",smixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
*/
intf_Msg
(
"(ac3dec_parsebsi) %s %d.%d Mode"
,
service_ids
[
p_ac3dec
->
bsi
.
bsmod
],
p_ac3dec
->
bsi
.
nfchans
,
p_ac3dec
->
bsi
.
lfeon
);
}
i
++
;
if
(
i
>
100
)
i
=
0
;
}
void
parse_audblk_stats
(
ac3dec_t
*
p_ac3dec
)
{
char
*
exp_strat_tbl
[
4
]
=
{
"R "
,
"D15 "
,
"D25 "
,
"D45 "
};
u32
i
;
intf_ErrMsg
(
"(ac3dec_parseaudblk) "
);
intf_ErrMsg
(
"%s "
,
p_ac3dec
->
audblk
.
cplinu
?
"cpl on"
:
"cpl off"
);
intf_ErrMsg
(
"%s "
,
p_ac3dec
->
audblk
.
baie
?
"bai"
:
" "
);
intf_ErrMsg
(
"%s "
,
p_ac3dec
->
audblk
.
snroffste
?
"snroffst"
:
" "
);
intf_ErrMsg
(
"%s "
,
p_ac3dec
->
audblk
.
deltbaie
?
"deltba"
:
" "
);
intf_ErrMsg
(
"%s "
,
p_ac3dec
->
audblk
.
phsflginu
?
"phsflg"
:
" "
);
intf_ErrMsg
(
"(%s %s %s %s %s) "
,
exp_strat_tbl
[
p_ac3dec
->
audblk
.
chexpstr
[
0
]],
exp_strat_tbl
[
p_ac3dec
->
audblk
.
chexpstr
[
1
]],
exp_strat_tbl
[
p_ac3dec
->
audblk
.
chexpstr
[
2
]],
exp_strat_tbl
[
p_ac3dec
->
audblk
.
chexpstr
[
3
]],
exp_strat_tbl
[
p_ac3dec
->
audblk
.
chexpstr
[
4
]]);
intf_ErrMsg
(
"["
);
for
(
i
=
0
;
i
<
p_ac3dec
->
bsi
.
nfchans
;
i
++
)
intf_ErrMsg
(
"%1d"
,
p_ac3dec
->
audblk
.
blksw
[
i
]);
intf_ErrMsg
(
"]"
);
intf_ErrMsg
(
"
\n
"
);
}
src/ac3_decoder/ac3_rematrix.c
View file @
a906b2f5
...
...
@@ -3,7 +3,8 @@
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
* Authors:
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
*
* 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
...
...
@@ -30,7 +31,7 @@ struct rematrix_band_s {
u32
end
;
};
static
struct
rematrix_band_s
rematrix_band
[]
=
{
{
13
,
24
},
{
25
,
36
},
{
37
,
60
},
{
61
,
252
}};
static
const
struct
rematrix_band_s
rematrix_band
[]
=
{
{
13
,
24
},
{
25
,
36
},
{
37
,
60
},
{
61
,
252
}};
static
__inline__
u32
min
(
u32
a
,
u32
b
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment