]> git.sesse.net Git - vlc/blob - src/ac3_decoder/ac3_exponent.c
Created a small&clean public interface for the ac3 decoder (see ac3_decoder.h)
[vlc] / src / ac3_decoder / ac3_exponent.c
1 #include <stdio.h>                                           /* "intf_msg.h" */
2
3 #include "int_types.h"
4 #include "ac3_decoder.h"
5 #include "ac3_bit_stream.h"
6 #include "ac3_internal.h"
7
8 static const s16 exps_1[128] =
9   { -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
10     -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,
11      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12      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,
13      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
14      0, 0, 0 };
15
16 static const s16 exps_2[128] =
17   { -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
18     -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
19     -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
20     -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
21     -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
22      0, 0, 0 };
23
24 static const s16 exps_3[128] =
25   { -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
26     -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
27     -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
28     -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
29     -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,
30      0, 0, 0 };
31
32 #define UNPACK_FBW 1 
33 #define UNPACK_CPL 2 
34 #define UNPACK_LFE 4
35
36 static __inline__ int exp_unpack_ch (ac3dec_t * p_ac3dec, u16 type,
37                                      u16 expstr, u16 ngrps, u16 initial_exp,
38                                      u16 exps[], u16 * dest)
39 {
40     u16 i,j;
41     s16 exp_acc;
42
43     if  (expstr == EXP_REUSE) {
44         return 0;
45     }
46
47     /* Handle the initial absolute exponent */
48     exp_acc = initial_exp;
49     j = 0;
50
51     /* In the case of a fbw channel then the initial absolute values is
52      * also an exponent */
53     if (type != UNPACK_CPL) {
54         dest[j++] = exp_acc;
55     }
56
57     /* Loop through the groups and fill the dest array appropriately */
58     switch (expstr) {
59     case EXP_D15:       /* 1 */
60         for (i = 0; i < ngrps; i++) {
61             if (exps[i] > 124) {
62                 fprintf (stderr, "ac3dec debug: invalid exponent\n");
63                 return 1;
64             }
65             exp_acc += (exps_1[exps[i]] /*- 2*/);
66             dest[j++] = exp_acc;
67             exp_acc += (exps_2[exps[i]] /*- 2*/);
68             dest[j++] = exp_acc;
69             exp_acc += (exps_3[exps[i]] /*- 2*/);
70             dest[j++] = exp_acc;
71         }
72         break;
73
74     case EXP_D25:       /* 2 */
75         for (i = 0; i < ngrps; i++) {
76             if (exps[i] > 124) {
77                 fprintf (stderr, "ac3dec debug: invalid exponent\n");
78                 return 1;
79             }
80             exp_acc += (exps_1[exps[i]] /*- 2*/);
81             dest[j++] = exp_acc;
82             dest[j++] = exp_acc;
83             exp_acc += (exps_2[exps[i]] /*- 2*/);
84             dest[j++] = exp_acc;
85             dest[j++] = exp_acc;
86             exp_acc += (exps_3[exps[i]] /*- 2*/);
87             dest[j++] = exp_acc;
88             dest[j++] = exp_acc;
89         }
90         break;
91
92     case EXP_D45:       /* 3 */
93         for (i = 0; i < ngrps; i++) {
94             if (exps[i] > 124) {
95                 fprintf (stderr, "ac3dec debug: invalid exponent\n");
96                 return 1;
97             }
98             exp_acc += (exps_1[exps[i]] /*- 2*/);
99             dest[j++] = exp_acc;
100             dest[j++] = exp_acc;
101             dest[j++] = exp_acc;
102             dest[j++] = exp_acc;
103             exp_acc += (exps_2[exps[i]] /*- 2*/);
104             dest[j++] = exp_acc;
105             dest[j++] = exp_acc;
106             dest[j++] = exp_acc;
107             dest[j++] = exp_acc;
108             exp_acc += (exps_3[exps[i]] /*- 2*/);
109             dest[j++] = exp_acc;
110             dest[j++] = exp_acc;
111             dest[j++] = exp_acc;
112             dest[j++] = exp_acc;
113         }
114         break;
115     }
116
117     return 0;
118 }
119
120 int exponent_unpack (ac3dec_t * p_ac3dec)
121 {
122     u16 i;
123
124     for (i = 0; i < p_ac3dec->bsi.nfchans; i++) {
125         if (exp_unpack_ch (p_ac3dec, UNPACK_FBW, p_ac3dec->audblk.chexpstr[i],
126                            p_ac3dec->audblk.nchgrps[i],
127                            p_ac3dec->audblk.exps[i][0],
128                            &p_ac3dec->audblk.exps[i][1],
129                            p_ac3dec->audblk.fbw_exp[i]))
130             return 1;
131     }
132
133     if (p_ac3dec->audblk.cplinu) {
134         if (exp_unpack_ch (p_ac3dec, UNPACK_CPL, p_ac3dec->audblk.cplexpstr,
135                            p_ac3dec->audblk.ncplgrps,
136                            p_ac3dec->audblk.cplabsexp << 1,
137                            p_ac3dec->audblk.cplexps,
138                            &p_ac3dec->audblk.cpl_exp[p_ac3dec->audblk.cplstrtmant]))
139             return 1;
140     }
141
142     if (p_ac3dec->bsi.lfeon) {
143         if (exp_unpack_ch (p_ac3dec, UNPACK_LFE, p_ac3dec->audblk.lfeexpstr,
144                            2, p_ac3dec->audblk.lfeexps[0],
145                            &p_ac3dec->audblk.lfeexps[1],
146                            p_ac3dec->audblk.lfe_exp))
147             return 1;
148     }
149
150     return 0;
151 }