]> git.sesse.net Git - vlc/blob - src/ac3_decoder/ac3_exponent.c
96e3c704f6ef18f37bce1fc491b876ed917dc442
[vlc] / src / ac3_decoder / ac3_exponent.c
1 /*****************************************************************************
2  * ac3_exponent.c: ac3 exponent calculations
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  * $Id: ac3_exponent.c,v 1.24 2001/05/14 15:58:04 reno Exp $
6  *
7  * Authors: Michel Kaempf <maxx@via.ecp.fr>
8  *          Michel Lespinasse <walken@zoy.org>
9  *          Aaron Holtzman <aholtzma@engr.uvic.ca>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25 #include "defs.h"
26
27 #include <string.h>                                    /* memcpy(), memset() */
28
29 #include "config.h"
30 #include "common.h"
31 #include "threads.h"
32 #include "mtime.h"
33
34 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
35
36 #include "stream_control.h"
37 #include "input_ext-dec.h"
38
39 #include "audio_output.h"
40
41 #include "ac3_decoder.h"
42
43 #include "ac3_internal.h"
44
45 static const s16 exps_1[128] =
46 {
47     -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,
48     -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,
49      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,
50      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,
51      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,
52      0, 0, 0
53 };
54
55 static const s16 exps_2[128] =
56 {
57     -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,
58     -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,
59     -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,
60     -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,
61     -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,
62      0, 0, 0
63 };
64
65 static const s16 exps_3[128] =
66 {
67     -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,
68     -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,
69     -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,
70     -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,
71     -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,
72      0, 0, 0
73 };
74
75 #define UNPACK_FBW 1 
76 #define UNPACK_CPL 2 
77 #define UNPACK_LFE 4
78
79 static __inline__ int exp_unpack_ch (ac3dec_t * p_ac3dec, u16 type,
80                                      u16 expstr, u16 ngrps, u16 initial_exp,
81                                      u16 exps[], u16 * dest)
82 {
83     u16 i,j;
84     s16 exp_acc;
85
86     if  (expstr == EXP_REUSE)
87     {
88         return 0;
89     }
90
91     /* Handle the initial absolute exponent */
92     exp_acc = initial_exp;
93     j = 0;
94
95     /* In the case of a fbw channel then the initial absolute values is
96      * also an exponent */
97     if (type != UNPACK_CPL)
98     {
99         dest[j++] = exp_acc;
100     }
101
102     /* Loop through the groups and fill the dest array appropriately */
103     switch (expstr)
104     {
105     case EXP_D15:        /* 1 */
106         for (i = 0; i < ngrps; i++)
107         {
108             if (exps[i] > 124)
109             {
110                 intf_ErrMsg ( "ac3dec error: invalid exponent" );
111                 return 1;
112             }
113             exp_acc += (exps_1[exps[i]] /*- 2*/);
114             dest[j++] = exp_acc;
115             exp_acc += (exps_2[exps[i]] /*- 2*/);
116             dest[j++] = exp_acc;
117             exp_acc += (exps_3[exps[i]] /*- 2*/);
118             dest[j++] = exp_acc;
119         }
120         break;
121
122     case EXP_D25:        /* 2 */
123         for (i = 0; i < ngrps; i++)
124         {
125             if (exps[i] > 124)
126             {
127                 intf_ErrMsg ( "ac3dec error: invalid exponent" );
128                 return 1;
129             }
130             exp_acc += (exps_1[exps[i]] /*- 2*/);
131             dest[j++] = exp_acc;
132             dest[j++] = exp_acc;
133             exp_acc += (exps_2[exps[i]] /*- 2*/);
134             dest[j++] = exp_acc;
135             dest[j++] = exp_acc;
136             exp_acc += (exps_3[exps[i]] /*- 2*/);
137             dest[j++] = exp_acc;
138             dest[j++] = exp_acc;
139         }
140         break;
141
142     case EXP_D45:        /* 3 */
143         for (i = 0; i < ngrps; i++)
144         {
145             if (exps[i] > 124)
146             {
147                 intf_ErrMsg ( "ac3dec error: invalid exponent" );
148                 return 1;
149             }
150             exp_acc += (exps_1[exps[i]] /*- 2*/);
151             dest[j++] = exp_acc;
152             dest[j++] = exp_acc;
153             dest[j++] = exp_acc;
154             dest[j++] = exp_acc;
155             exp_acc += (exps_2[exps[i]] /*- 2*/);
156             dest[j++] = exp_acc;
157             dest[j++] = exp_acc;
158             dest[j++] = exp_acc;
159             dest[j++] = exp_acc;
160             exp_acc += (exps_3[exps[i]] /*- 2*/);
161             dest[j++] = exp_acc;
162             dest[j++] = exp_acc;
163             dest[j++] = exp_acc;
164             dest[j++] = exp_acc;
165         }
166         break;
167     }
168
169     return 0;
170 }
171
172 int exponent_unpack (ac3dec_t * p_ac3dec)
173 {
174     u16 i;
175
176     for (i = 0; i < p_ac3dec->bsi.nfchans; i++)
177     {
178         if (exp_unpack_ch (p_ac3dec, UNPACK_FBW, p_ac3dec->audblk.chexpstr[i],
179                            p_ac3dec->audblk.nchgrps[i],
180                            p_ac3dec->audblk.exps[i][0],
181                            &p_ac3dec->audblk.exps[i][1],
182                            p_ac3dec->audblk.fbw_exp[i]))
183         {
184             return 1;
185         }
186     }
187
188     if (p_ac3dec->audblk.cplinu)
189     {
190         if (exp_unpack_ch (p_ac3dec, UNPACK_CPL, p_ac3dec->audblk.cplexpstr,
191                            p_ac3dec->audblk.ncplgrps,
192                            p_ac3dec->audblk.cplabsexp << 1,
193                            p_ac3dec->audblk.cplexps,
194                            &p_ac3dec->audblk.cpl_exp[p_ac3dec->audblk.cplstrtmant]))
195         {
196             return 1;
197         }
198     }
199
200     if (p_ac3dec->bsi.lfeon)
201     {
202         if (exp_unpack_ch (p_ac3dec, UNPACK_LFE, p_ac3dec->audblk.lfeexpstr,
203                            2, p_ac3dec->audblk.lfeexps[0],
204                            &p_ac3dec->audblk.lfeexps[1],
205                            p_ac3dec->audblk.lfe_exp))
206         {
207             return 1;
208         }
209     }
210
211     return 0;
212 }
213