18f5875f3SDavid du Colombier /*
2*f30ccc91SDavid du Colombier * libmad - MPEG audio decoder library
3*f30ccc91SDavid du Colombier * Copyright (C) 2000-2004 Underbit Technologies, Inc.
48f5875f3SDavid du Colombier *
5*f30ccc91SDavid du Colombier * This program is free software; you can redistribute it and/or modify
6*f30ccc91SDavid du Colombier * it under the terms of the GNU General Public License as published by
7*f30ccc91SDavid du Colombier * the Free Software Foundation; either version 2 of the License, or
8*f30ccc91SDavid du Colombier * (at your option) any later version.
9*f30ccc91SDavid du Colombier *
10*f30ccc91SDavid du Colombier * This program is distributed in the hope that it will be useful,
11*f30ccc91SDavid du Colombier * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*f30ccc91SDavid du Colombier * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13*f30ccc91SDavid du Colombier * GNU General Public License for more details.
14*f30ccc91SDavid du Colombier *
15*f30ccc91SDavid du Colombier * You should have received a copy of the GNU General Public License
16*f30ccc91SDavid du Colombier * along with this program; if not, write to the Free Software
17*f30ccc91SDavid du Colombier * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*f30ccc91SDavid du Colombier *
19*f30ccc91SDavid du Colombier * $Id: layer3.c,v 1.43 2004/01/23 09:41:32 rob Exp $
208f5875f3SDavid du Colombier */
218f5875f3SDavid du Colombier
22*f30ccc91SDavid du Colombier # ifdef HAVE_CONFIG_H
23*f30ccc91SDavid du Colombier # include "config.h"
24*f30ccc91SDavid du Colombier # endif
25*f30ccc91SDavid du Colombier
26*f30ccc91SDavid du Colombier # include "global.h"
27*f30ccc91SDavid du Colombier
28*f30ccc91SDavid du Colombier # include "fixed.h"
29*f30ccc91SDavid du Colombier # include "bit.h"
30*f30ccc91SDavid du Colombier # include "stream.h"
31*f30ccc91SDavid du Colombier # include "frame.h"
328f5875f3SDavid du Colombier # include "huffman.h"
33*f30ccc91SDavid du Colombier # include "layer3.h"
348f5875f3SDavid du Colombier
35*f30ccc91SDavid du Colombier #define CHAR_BIT 8 /* duh */
368f5875f3SDavid du Colombier
37*f30ccc91SDavid du Colombier /* --- Layer III ----------------------------------------------------------- */
388f5875f3SDavid du Colombier
39*f30ccc91SDavid du Colombier enum {
40*f30ccc91SDavid du Colombier count1table_select = 0x01,
41*f30ccc91SDavid du Colombier scalefac_scale = 0x02,
42*f30ccc91SDavid du Colombier preflag = 0x04,
43*f30ccc91SDavid du Colombier mixed_block_flag = 0x08
448f5875f3SDavid du Colombier };
458f5875f3SDavid du Colombier
46*f30ccc91SDavid du Colombier enum {
47*f30ccc91SDavid du Colombier I_STEREO = 0x1,
48*f30ccc91SDavid du Colombier MS_STEREO = 0x2
498f5875f3SDavid du Colombier };
508f5875f3SDavid du Colombier
51*f30ccc91SDavid du Colombier struct sideinfo {
52*f30ccc91SDavid du Colombier unsigned int main_data_begin;
53*f30ccc91SDavid du Colombier unsigned int private_bits;
548f5875f3SDavid du Colombier
55*f30ccc91SDavid du Colombier unsigned char scfsi[2];
568f5875f3SDavid du Colombier
57*f30ccc91SDavid du Colombier struct granule {
58*f30ccc91SDavid du Colombier struct channel {
59*f30ccc91SDavid du Colombier /* from side info */
60*f30ccc91SDavid du Colombier unsigned short part2_3_length;
61*f30ccc91SDavid du Colombier unsigned short big_values;
62*f30ccc91SDavid du Colombier unsigned short global_gain;
63*f30ccc91SDavid du Colombier unsigned short scalefac_compress;
64*f30ccc91SDavid du Colombier
65*f30ccc91SDavid du Colombier unsigned char flags;
66*f30ccc91SDavid du Colombier unsigned char block_type;
67*f30ccc91SDavid du Colombier unsigned char table_select[3];
68*f30ccc91SDavid du Colombier unsigned char subblock_gain[3];
69*f30ccc91SDavid du Colombier unsigned char region0_count;
70*f30ccc91SDavid du Colombier unsigned char region1_count;
71*f30ccc91SDavid du Colombier
72*f30ccc91SDavid du Colombier /* from main_data */
73*f30ccc91SDavid du Colombier unsigned char scalefac[39]; /* scalefac_l and/or scalefac_s */
74*f30ccc91SDavid du Colombier } ch[2];
75*f30ccc91SDavid du Colombier } gr[2];
76*f30ccc91SDavid du Colombier };
778f5875f3SDavid du Colombier
788f5875f3SDavid du Colombier /*
79*f30ccc91SDavid du Colombier * scalefactor bit lengths
80*f30ccc91SDavid du Colombier * derived from section 2.4.2.7 of ISO/IEC 11172-3
818f5875f3SDavid du Colombier */
82*f30ccc91SDavid du Colombier static
83*f30ccc91SDavid du Colombier struct {
84*f30ccc91SDavid du Colombier unsigned char slen1;
85*f30ccc91SDavid du Colombier unsigned char slen2;
86*f30ccc91SDavid du Colombier } const sflen_table[16] = {
87*f30ccc91SDavid du Colombier { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 },
88*f30ccc91SDavid du Colombier { 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 },
89*f30ccc91SDavid du Colombier { 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 },
90*f30ccc91SDavid du Colombier { 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 }
91*f30ccc91SDavid du Colombier };
928f5875f3SDavid du Colombier
938f5875f3SDavid du Colombier /*
94*f30ccc91SDavid du Colombier * number of LSF scalefactor band values
95*f30ccc91SDavid du Colombier * derived from section 2.4.3.2 of ISO/IEC 13818-3
968f5875f3SDavid du Colombier */
97*f30ccc91SDavid du Colombier static
98*f30ccc91SDavid du Colombier unsigned char const nsfb_table[6][3][4] = {
99*f30ccc91SDavid du Colombier { { 6, 5, 5, 5 },
100*f30ccc91SDavid du Colombier { 9, 9, 9, 9 },
101*f30ccc91SDavid du Colombier { 6, 9, 9, 9 } },
102*f30ccc91SDavid du Colombier
103*f30ccc91SDavid du Colombier { { 6, 5, 7, 3 },
104*f30ccc91SDavid du Colombier { 9, 9, 12, 6 },
105*f30ccc91SDavid du Colombier { 6, 9, 12, 6 } },
106*f30ccc91SDavid du Colombier
107*f30ccc91SDavid du Colombier { { 11, 10, 0, 0 },
108*f30ccc91SDavid du Colombier { 18, 18, 0, 0 },
109*f30ccc91SDavid du Colombier { 15, 18, 0, 0 } },
110*f30ccc91SDavid du Colombier
111*f30ccc91SDavid du Colombier { { 7, 7, 7, 0 },
112*f30ccc91SDavid du Colombier { 12, 12, 12, 0 },
113*f30ccc91SDavid du Colombier { 6, 15, 12, 0 } },
114*f30ccc91SDavid du Colombier
115*f30ccc91SDavid du Colombier { { 6, 6, 6, 3 },
116*f30ccc91SDavid du Colombier { 12, 9, 9, 6 },
117*f30ccc91SDavid du Colombier { 6, 12, 9, 6 } },
118*f30ccc91SDavid du Colombier
119*f30ccc91SDavid du Colombier { { 8, 8, 5, 0 },
120*f30ccc91SDavid du Colombier { 15, 12, 9, 0 },
121*f30ccc91SDavid du Colombier { 6, 18, 9, 0 } }
122*f30ccc91SDavid du Colombier };
123*f30ccc91SDavid du Colombier
124*f30ccc91SDavid du Colombier /*
125*f30ccc91SDavid du Colombier * MPEG-1 scalefactor band widths
126*f30ccc91SDavid du Colombier * derived from Table B.8 of ISO/IEC 11172-3
127*f30ccc91SDavid du Colombier */
128*f30ccc91SDavid du Colombier static
129*f30ccc91SDavid du Colombier unsigned char const sfb_48000_long[] = {
130*f30ccc91SDavid du Colombier 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10,
131*f30ccc91SDavid du Colombier 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192
132*f30ccc91SDavid du Colombier };
133*f30ccc91SDavid du Colombier
134*f30ccc91SDavid du Colombier static
135*f30ccc91SDavid du Colombier unsigned char const sfb_44100_long[] = {
136*f30ccc91SDavid du Colombier 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10,
137*f30ccc91SDavid du Colombier 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158
138*f30ccc91SDavid du Colombier };
139*f30ccc91SDavid du Colombier
140*f30ccc91SDavid du Colombier static
141*f30ccc91SDavid du Colombier unsigned char const sfb_32000_long[] = {
142*f30ccc91SDavid du Colombier 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12,
143*f30ccc91SDavid du Colombier 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26
144*f30ccc91SDavid du Colombier };
145*f30ccc91SDavid du Colombier
146*f30ccc91SDavid du Colombier static
147*f30ccc91SDavid du Colombier unsigned char const sfb_48000_short[] = {
148*f30ccc91SDavid du Colombier 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
149*f30ccc91SDavid du Colombier 6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14,
150*f30ccc91SDavid du Colombier 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66
151*f30ccc91SDavid du Colombier };
152*f30ccc91SDavid du Colombier
153*f30ccc91SDavid du Colombier static
154*f30ccc91SDavid du Colombier unsigned char const sfb_44100_short[] = {
155*f30ccc91SDavid du Colombier 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
156*f30ccc91SDavid du Colombier 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14,
157*f30ccc91SDavid du Colombier 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56
158*f30ccc91SDavid du Colombier };
159*f30ccc91SDavid du Colombier
160*f30ccc91SDavid du Colombier static
161*f30ccc91SDavid du Colombier unsigned char const sfb_32000_short[] = {
162*f30ccc91SDavid du Colombier 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
163*f30ccc91SDavid du Colombier 6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20,
164*f30ccc91SDavid du Colombier 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12
165*f30ccc91SDavid du Colombier };
166*f30ccc91SDavid du Colombier
167*f30ccc91SDavid du Colombier static
168*f30ccc91SDavid du Colombier unsigned char const sfb_48000_mixed[] = {
169*f30ccc91SDavid du Colombier /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
170*f30ccc91SDavid du Colombier /* short */ 4, 4, 4, 6, 6, 6, 6, 6, 6, 10,
171*f30ccc91SDavid du Colombier 10, 10, 12, 12, 12, 14, 14, 14, 16, 16,
172*f30ccc91SDavid du Colombier 16, 20, 20, 20, 26, 26, 26, 66, 66, 66
173*f30ccc91SDavid du Colombier };
174*f30ccc91SDavid du Colombier
175*f30ccc91SDavid du Colombier static
176*f30ccc91SDavid du Colombier unsigned char const sfb_44100_mixed[] = {
177*f30ccc91SDavid du Colombier /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
178*f30ccc91SDavid du Colombier /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 10,
179*f30ccc91SDavid du Colombier 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
180*f30ccc91SDavid du Colombier 18, 22, 22, 22, 30, 30, 30, 56, 56, 56
181*f30ccc91SDavid du Colombier };
182*f30ccc91SDavid du Colombier
183*f30ccc91SDavid du Colombier static
184*f30ccc91SDavid du Colombier unsigned char const sfb_32000_mixed[] = {
185*f30ccc91SDavid du Colombier /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
186*f30ccc91SDavid du Colombier /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 12,
187*f30ccc91SDavid du Colombier 12, 12, 16, 16, 16, 20, 20, 20, 26, 26,
188*f30ccc91SDavid du Colombier 26, 34, 34, 34, 42, 42, 42, 12, 12, 12
189*f30ccc91SDavid du Colombier };
190*f30ccc91SDavid du Colombier
191*f30ccc91SDavid du Colombier /*
192*f30ccc91SDavid du Colombier * MPEG-2 scalefactor band widths
193*f30ccc91SDavid du Colombier * derived from Table B.2 of ISO/IEC 13818-3
194*f30ccc91SDavid du Colombier */
195*f30ccc91SDavid du Colombier static
196*f30ccc91SDavid du Colombier unsigned char const sfb_24000_long[] = {
197*f30ccc91SDavid du Colombier 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
198*f30ccc91SDavid du Colombier 18, 22, 26, 32, 38, 46, 54, 62, 70, 76, 36
199*f30ccc91SDavid du Colombier };
200*f30ccc91SDavid du Colombier
201*f30ccc91SDavid du Colombier static
202*f30ccc91SDavid du Colombier unsigned char const sfb_22050_long[] = {
203*f30ccc91SDavid du Colombier 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
204*f30ccc91SDavid du Colombier 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54
205*f30ccc91SDavid du Colombier };
206*f30ccc91SDavid du Colombier
207*f30ccc91SDavid du Colombier # define sfb_16000_long sfb_22050_long
208*f30ccc91SDavid du Colombier
209*f30ccc91SDavid du Colombier static
210*f30ccc91SDavid du Colombier unsigned char const sfb_24000_short[] = {
211*f30ccc91SDavid du Colombier 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8,
212*f30ccc91SDavid du Colombier 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
213*f30ccc91SDavid du Colombier 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12
214*f30ccc91SDavid du Colombier };
215*f30ccc91SDavid du Colombier
216*f30ccc91SDavid du Colombier static
217*f30ccc91SDavid du Colombier unsigned char const sfb_22050_short[] = {
218*f30ccc91SDavid du Colombier 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6,
219*f30ccc91SDavid du Colombier 6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18,
220*f30ccc91SDavid du Colombier 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18
221*f30ccc91SDavid du Colombier };
222*f30ccc91SDavid du Colombier
223*f30ccc91SDavid du Colombier static
224*f30ccc91SDavid du Colombier unsigned char const sfb_16000_short[] = {
225*f30ccc91SDavid du Colombier 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8,
226*f30ccc91SDavid du Colombier 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
227*f30ccc91SDavid du Colombier 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18
228*f30ccc91SDavid du Colombier };
229*f30ccc91SDavid du Colombier
230*f30ccc91SDavid du Colombier static
231*f30ccc91SDavid du Colombier unsigned char const sfb_24000_mixed[] = {
232*f30ccc91SDavid du Colombier /* long */ 6, 6, 6, 6, 6, 6,
233*f30ccc91SDavid du Colombier /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12,
234*f30ccc91SDavid du Colombier 12, 12, 14, 14, 14, 18, 18, 18, 24, 24,
235*f30ccc91SDavid du Colombier 24, 32, 32, 32, 44, 44, 44, 12, 12, 12
236*f30ccc91SDavid du Colombier };
237*f30ccc91SDavid du Colombier
238*f30ccc91SDavid du Colombier static
239*f30ccc91SDavid du Colombier unsigned char const sfb_22050_mixed[] = {
240*f30ccc91SDavid du Colombier /* long */ 6, 6, 6, 6, 6, 6,
241*f30ccc91SDavid du Colombier /* short */ 6, 6, 6, 6, 6, 6, 8, 8, 8, 10,
242*f30ccc91SDavid du Colombier 10, 10, 14, 14, 14, 18, 18, 18, 26, 26,
243*f30ccc91SDavid du Colombier 26, 32, 32, 32, 42, 42, 42, 18, 18, 18
244*f30ccc91SDavid du Colombier };
245*f30ccc91SDavid du Colombier
246*f30ccc91SDavid du Colombier static
247*f30ccc91SDavid du Colombier unsigned char const sfb_16000_mixed[] = {
248*f30ccc91SDavid du Colombier /* long */ 6, 6, 6, 6, 6, 6,
249*f30ccc91SDavid du Colombier /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12,
250*f30ccc91SDavid du Colombier 12, 12, 14, 14, 14, 18, 18, 18, 24, 24,
251*f30ccc91SDavid du Colombier 24, 30, 30, 30, 40, 40, 40, 18, 18, 18
252*f30ccc91SDavid du Colombier };
253*f30ccc91SDavid du Colombier
254*f30ccc91SDavid du Colombier /*
255*f30ccc91SDavid du Colombier * MPEG 2.5 scalefactor band widths
256*f30ccc91SDavid du Colombier * derived from public sources
257*f30ccc91SDavid du Colombier */
258*f30ccc91SDavid du Colombier # define sfb_12000_long sfb_16000_long
259*f30ccc91SDavid du Colombier # define sfb_11025_long sfb_12000_long
260*f30ccc91SDavid du Colombier
261*f30ccc91SDavid du Colombier static
262*f30ccc91SDavid du Colombier unsigned char const sfb_8000_long[] = {
263*f30ccc91SDavid du Colombier 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32,
264*f30ccc91SDavid du Colombier 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2
265*f30ccc91SDavid du Colombier };
266*f30ccc91SDavid du Colombier
267*f30ccc91SDavid du Colombier # define sfb_12000_short sfb_16000_short
268*f30ccc91SDavid du Colombier # define sfb_11025_short sfb_12000_short
269*f30ccc91SDavid du Colombier
270*f30ccc91SDavid du Colombier static
271*f30ccc91SDavid du Colombier unsigned char const sfb_8000_short[] = {
272*f30ccc91SDavid du Colombier 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 16,
273*f30ccc91SDavid du Colombier 16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36,
274*f30ccc91SDavid du Colombier 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26
275*f30ccc91SDavid du Colombier };
276*f30ccc91SDavid du Colombier
277*f30ccc91SDavid du Colombier # define sfb_12000_mixed sfb_16000_mixed
278*f30ccc91SDavid du Colombier # define sfb_11025_mixed sfb_12000_mixed
279*f30ccc91SDavid du Colombier
280*f30ccc91SDavid du Colombier /* the 8000 Hz short block scalefactor bands do not break after
281*f30ccc91SDavid du Colombier the first 36 frequency lines, so this is probably wrong */
282*f30ccc91SDavid du Colombier static
283*f30ccc91SDavid du Colombier unsigned char const sfb_8000_mixed[] = {
284*f30ccc91SDavid du Colombier /* long */ 12, 12, 12,
285*f30ccc91SDavid du Colombier /* short */ 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16,
286*f30ccc91SDavid du Colombier 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36,
287*f30ccc91SDavid du Colombier 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26
288*f30ccc91SDavid du Colombier };
289*f30ccc91SDavid du Colombier
290*f30ccc91SDavid du Colombier static
291*f30ccc91SDavid du Colombier struct {
292*f30ccc91SDavid du Colombier unsigned char const *l;
293*f30ccc91SDavid du Colombier unsigned char const *s;
294*f30ccc91SDavid du Colombier unsigned char const *m;
295*f30ccc91SDavid du Colombier } const sfbwidth_table[9] = {
296*f30ccc91SDavid du Colombier { sfb_48000_long, sfb_48000_short, sfb_48000_mixed },
297*f30ccc91SDavid du Colombier { sfb_44100_long, sfb_44100_short, sfb_44100_mixed },
298*f30ccc91SDavid du Colombier { sfb_32000_long, sfb_32000_short, sfb_32000_mixed },
299*f30ccc91SDavid du Colombier { sfb_24000_long, sfb_24000_short, sfb_24000_mixed },
300*f30ccc91SDavid du Colombier { sfb_22050_long, sfb_22050_short, sfb_22050_mixed },
301*f30ccc91SDavid du Colombier { sfb_16000_long, sfb_16000_short, sfb_16000_mixed },
302*f30ccc91SDavid du Colombier { sfb_12000_long, sfb_12000_short, sfb_12000_mixed },
303*f30ccc91SDavid du Colombier { sfb_11025_long, sfb_11025_short, sfb_11025_mixed },
304*f30ccc91SDavid du Colombier { sfb_8000_long, sfb_8000_short, sfb_8000_mixed }
305*f30ccc91SDavid du Colombier };
306*f30ccc91SDavid du Colombier
307*f30ccc91SDavid du Colombier /*
308*f30ccc91SDavid du Colombier * scalefactor band preemphasis (used only when preflag is set)
309*f30ccc91SDavid du Colombier * derived from Table B.6 of ISO/IEC 11172-3
310*f30ccc91SDavid du Colombier */
311*f30ccc91SDavid du Colombier static
312*f30ccc91SDavid du Colombier unsigned char const pretab[22] = {
313*f30ccc91SDavid du Colombier 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0
314*f30ccc91SDavid du Colombier };
315*f30ccc91SDavid du Colombier
316*f30ccc91SDavid du Colombier /*
317*f30ccc91SDavid du Colombier * table for requantization
318*f30ccc91SDavid du Colombier *
319*f30ccc91SDavid du Colombier * rq_table[x].mantissa * 2^(rq_table[x].exponent) = x^(4/3)
320*f30ccc91SDavid du Colombier */
321*f30ccc91SDavid du Colombier static
322*f30ccc91SDavid du Colombier struct fixedfloat {
323*f30ccc91SDavid du Colombier unsigned long mantissa; // : 27;
324*f30ccc91SDavid du Colombier unsigned short exponent; // : 5;
325*f30ccc91SDavid du Colombier } const rq_table[8207] = {
326*f30ccc91SDavid du Colombier # include "rq_table.dat"
327*f30ccc91SDavid du Colombier };
328*f30ccc91SDavid du Colombier
329*f30ccc91SDavid du Colombier /*
330*f30ccc91SDavid du Colombier * fractional powers of two
331*f30ccc91SDavid du Colombier * used for requantization and joint stereo decoding
332*f30ccc91SDavid du Colombier *
333*f30ccc91SDavid du Colombier * root_table[3 + x] = 2^(x/4)
334*f30ccc91SDavid du Colombier */
335*f30ccc91SDavid du Colombier static
336*f30ccc91SDavid du Colombier mad_fixed_t const root_table[7] = {
337*f30ccc91SDavid du Colombier MAD_F(0x09837f05) /* 2^(-3/4) == 0.59460355750136 */,
338*f30ccc91SDavid du Colombier MAD_F(0x0b504f33) /* 2^(-2/4) == 0.70710678118655 */,
339*f30ccc91SDavid du Colombier MAD_F(0x0d744fcd) /* 2^(-1/4) == 0.84089641525371 */,
340*f30ccc91SDavid du Colombier MAD_F(0x10000000) /* 2^( 0/4) == 1.00000000000000 */,
341*f30ccc91SDavid du Colombier MAD_F(0x1306fe0a) /* 2^(+1/4) == 1.18920711500272 */,
342*f30ccc91SDavid du Colombier MAD_F(0x16a09e66) /* 2^(+2/4) == 1.41421356237310 */,
343*f30ccc91SDavid du Colombier MAD_F(0x1ae89f99) /* 2^(+3/4) == 1.68179283050743 */
344*f30ccc91SDavid du Colombier };
345*f30ccc91SDavid du Colombier
346*f30ccc91SDavid du Colombier /*
347*f30ccc91SDavid du Colombier * coefficients for aliasing reduction
348*f30ccc91SDavid du Colombier * derived from Table B.9 of ISO/IEC 11172-3
349*f30ccc91SDavid du Colombier *
350*f30ccc91SDavid du Colombier * c[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 }
351*f30ccc91SDavid du Colombier * cs[i] = 1 / sqrt(1 + c[i]^2)
352*f30ccc91SDavid du Colombier * ca[i] = c[i] / sqrt(1 + c[i]^2)
353*f30ccc91SDavid du Colombier */
354*f30ccc91SDavid du Colombier static
355*f30ccc91SDavid du Colombier mad_fixed_t const cs[8] = {
356*f30ccc91SDavid du Colombier +MAD_F(0x0db84a81) /* +0.857492926 */, +MAD_F(0x0e1b9d7f) /* +0.881741997 */,
357*f30ccc91SDavid du Colombier +MAD_F(0x0f31adcf) /* +0.949628649 */, +MAD_F(0x0fbba815) /* +0.983314592 */,
358*f30ccc91SDavid du Colombier +MAD_F(0x0feda417) /* +0.995517816 */, +MAD_F(0x0ffc8fc8) /* +0.999160558 */,
359*f30ccc91SDavid du Colombier +MAD_F(0x0fff964c) /* +0.999899195 */, +MAD_F(0x0ffff8d3) /* +0.999993155 */
360*f30ccc91SDavid du Colombier };
361*f30ccc91SDavid du Colombier
362*f30ccc91SDavid du Colombier static
363*f30ccc91SDavid du Colombier mad_fixed_t const ca[8] = {
364*f30ccc91SDavid du Colombier -MAD_F(0x083b5fe7) /* -0.514495755 */, -MAD_F(0x078c36d2) /* -0.471731969 */,
365*f30ccc91SDavid du Colombier -MAD_F(0x05039814) /* -0.313377454 */, -MAD_F(0x02e91dd1) /* -0.181913200 */,
366*f30ccc91SDavid du Colombier -MAD_F(0x0183603a) /* -0.094574193 */, -MAD_F(0x00a7cb87) /* -0.040965583 */,
367*f30ccc91SDavid du Colombier -MAD_F(0x003a2847) /* -0.014198569 */, -MAD_F(0x000f27b4) /* -0.003699975 */
368*f30ccc91SDavid du Colombier };
369*f30ccc91SDavid du Colombier
370*f30ccc91SDavid du Colombier /*
371*f30ccc91SDavid du Colombier * IMDCT coefficients for short blocks
372*f30ccc91SDavid du Colombier * derived from section 2.4.3.4.10.2 of ISO/IEC 11172-3
373*f30ccc91SDavid du Colombier *
374*f30ccc91SDavid du Colombier * imdct_s[i/even][k] = cos((PI / 24) * (2 * (i / 2) + 7) * (2 * k + 1))
375*f30ccc91SDavid du Colombier * imdct_s[i /odd][k] = cos((PI / 24) * (2 * (6 + (i-1)/2) + 7) * (2 * k + 1))
376*f30ccc91SDavid du Colombier */
377*f30ccc91SDavid du Colombier static
378*f30ccc91SDavid du Colombier mad_fixed_t const imdct_s[6][6] = {
379*f30ccc91SDavid du Colombier # include "imdct_s.dat"
380*f30ccc91SDavid du Colombier };
381*f30ccc91SDavid du Colombier
382*f30ccc91SDavid du Colombier # if !defined(ASO_IMDCT)
383*f30ccc91SDavid du Colombier /*
384*f30ccc91SDavid du Colombier * windowing coefficients for long blocks
385*f30ccc91SDavid du Colombier * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3
386*f30ccc91SDavid du Colombier *
387*f30ccc91SDavid du Colombier * window_l[i] = sin((PI / 36) * (i + 1/2))
388*f30ccc91SDavid du Colombier */
389*f30ccc91SDavid du Colombier static
390*f30ccc91SDavid du Colombier mad_fixed_t const window_l[36] = {
391*f30ccc91SDavid du Colombier MAD_F(0x00b2aa3e) /* 0.043619387 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
392*f30ccc91SDavid du Colombier MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x04cfb0e2) /* 0.300705800 */,
393*f30ccc91SDavid du Colombier MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x07635284) /* 0.461748613 */,
394*f30ccc91SDavid du Colombier MAD_F(0x0898c779) /* 0.537299608 */, MAD_F(0x09bd7ca0) /* 0.608761429 */,
395*f30ccc91SDavid du Colombier MAD_F(0x0acf37ad) /* 0.675590208 */, MAD_F(0x0bcbe352) /* 0.737277337 */,
396*f30ccc91SDavid du Colombier MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0d7e8807) /* 0.843391446 */,
397*f30ccc91SDavid du Colombier
398*f30ccc91SDavid du Colombier MAD_F(0x0e313245) /* 0.887010833 */, MAD_F(0x0ec835e8) /* 0.923879533 */,
399*f30ccc91SDavid du Colombier MAD_F(0x0f426cb5) /* 0.953716951 */, MAD_F(0x0f9ee890) /* 0.976296007 */,
400*f30ccc91SDavid du Colombier MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ffc19fd) /* 0.999048222 */,
401*f30ccc91SDavid du Colombier MAD_F(0x0ffc19fd) /* 0.999048222 */, MAD_F(0x0fdcf549) /* 0.991444861 */,
402*f30ccc91SDavid du Colombier MAD_F(0x0f9ee890) /* 0.976296007 */, MAD_F(0x0f426cb5) /* 0.953716951 */,
403*f30ccc91SDavid du Colombier MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0e313245) /* 0.887010833 */,
404*f30ccc91SDavid du Colombier
405*f30ccc91SDavid du Colombier MAD_F(0x0d7e8807) /* 0.843391446 */, MAD_F(0x0cb19346) /* 0.793353340 */,
406*f30ccc91SDavid du Colombier MAD_F(0x0bcbe352) /* 0.737277337 */, MAD_F(0x0acf37ad) /* 0.675590208 */,
407*f30ccc91SDavid du Colombier MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0898c779) /* 0.537299608 */,
408*f30ccc91SDavid du Colombier MAD_F(0x07635284) /* 0.461748613 */, MAD_F(0x061f78aa) /* 0.382683432 */,
409*f30ccc91SDavid du Colombier MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x03768962) /* 0.216439614 */,
410*f30ccc91SDavid du Colombier MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x00b2aa3e) /* 0.043619387 */,
411*f30ccc91SDavid du Colombier };
412*f30ccc91SDavid du Colombier # endif /* ASO_IMDCT */
413*f30ccc91SDavid du Colombier
414*f30ccc91SDavid du Colombier /*
415*f30ccc91SDavid du Colombier * windowing coefficients for short blocks
416*f30ccc91SDavid du Colombier * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3
417*f30ccc91SDavid du Colombier *
418*f30ccc91SDavid du Colombier * window_s[i] = sin((PI / 12) * (i + 1/2))
419*f30ccc91SDavid du Colombier */
420*f30ccc91SDavid du Colombier static
421*f30ccc91SDavid du Colombier mad_fixed_t const window_s[12] = {
422*f30ccc91SDavid du Colombier MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x061f78aa) /* 0.382683432 */,
423*f30ccc91SDavid du Colombier MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0cb19346) /* 0.793353340 */,
424*f30ccc91SDavid du Colombier MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0fdcf549) /* 0.991444861 */,
425*f30ccc91SDavid du Colombier MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ec835e8) /* 0.923879533 */,
426*f30ccc91SDavid du Colombier MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x09bd7ca0) /* 0.608761429 */,
427*f30ccc91SDavid du Colombier MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
428*f30ccc91SDavid du Colombier };
429*f30ccc91SDavid du Colombier
430*f30ccc91SDavid du Colombier /*
431*f30ccc91SDavid du Colombier * coefficients for intensity stereo processing
432*f30ccc91SDavid du Colombier * derived from section 2.4.3.4.9.3 of ISO/IEC 11172-3
433*f30ccc91SDavid du Colombier *
434*f30ccc91SDavid du Colombier * is_ratio[i] = tan(i * (PI / 12))
435*f30ccc91SDavid du Colombier * is_table[i] = is_ratio[i] / (1 + is_ratio[i])
436*f30ccc91SDavid du Colombier */
437*f30ccc91SDavid du Colombier static
438*f30ccc91SDavid du Colombier mad_fixed_t const is_table[7] = {
439*f30ccc91SDavid du Colombier MAD_F(0x00000000) /* 0.000000000 */,
440*f30ccc91SDavid du Colombier MAD_F(0x0361962f) /* 0.211324865 */,
441*f30ccc91SDavid du Colombier MAD_F(0x05db3d74) /* 0.366025404 */,
442*f30ccc91SDavid du Colombier MAD_F(0x08000000) /* 0.500000000 */,
443*f30ccc91SDavid du Colombier MAD_F(0x0a24c28c) /* 0.633974596 */,
444*f30ccc91SDavid du Colombier MAD_F(0x0c9e69d1) /* 0.788675135 */,
445*f30ccc91SDavid du Colombier MAD_F(0x10000000) /* 1.000000000 */
446*f30ccc91SDavid du Colombier };
447*f30ccc91SDavid du Colombier
448*f30ccc91SDavid du Colombier /*
449*f30ccc91SDavid du Colombier * coefficients for LSF intensity stereo processing
450*f30ccc91SDavid du Colombier * derived from section 2.4.3.2 of ISO/IEC 13818-3
451*f30ccc91SDavid du Colombier *
452*f30ccc91SDavid du Colombier * is_lsf_table[0][i] = (1 / sqrt(sqrt(2)))^(i + 1)
453*f30ccc91SDavid du Colombier * is_lsf_table[1][i] = (1 / sqrt(2)) ^(i + 1)
454*f30ccc91SDavid du Colombier */
455*f30ccc91SDavid du Colombier static
456*f30ccc91SDavid du Colombier mad_fixed_t const is_lsf_table[2][15] = {
4578f5875f3SDavid du Colombier {
458*f30ccc91SDavid du Colombier MAD_F(0x0d744fcd) /* 0.840896415 */,
459*f30ccc91SDavid du Colombier MAD_F(0x0b504f33) /* 0.707106781 */,
460*f30ccc91SDavid du Colombier MAD_F(0x09837f05) /* 0.594603558 */,
461*f30ccc91SDavid du Colombier MAD_F(0x08000000) /* 0.500000000 */,
462*f30ccc91SDavid du Colombier MAD_F(0x06ba27e6) /* 0.420448208 */,
463*f30ccc91SDavid du Colombier MAD_F(0x05a8279a) /* 0.353553391 */,
464*f30ccc91SDavid du Colombier MAD_F(0x04c1bf83) /* 0.297301779 */,
465*f30ccc91SDavid du Colombier MAD_F(0x04000000) /* 0.250000000 */,
466*f30ccc91SDavid du Colombier MAD_F(0x035d13f3) /* 0.210224104 */,
467*f30ccc91SDavid du Colombier MAD_F(0x02d413cd) /* 0.176776695 */,
468*f30ccc91SDavid du Colombier MAD_F(0x0260dfc1) /* 0.148650889 */,
469*f30ccc91SDavid du Colombier MAD_F(0x02000000) /* 0.125000000 */,
470*f30ccc91SDavid du Colombier MAD_F(0x01ae89fa) /* 0.105112052 */,
471*f30ccc91SDavid du Colombier MAD_F(0x016a09e6) /* 0.088388348 */,
472*f30ccc91SDavid du Colombier MAD_F(0x01306fe1) /* 0.074325445 */
473*f30ccc91SDavid du Colombier }, {
474*f30ccc91SDavid du Colombier MAD_F(0x0b504f33) /* 0.707106781 */,
475*f30ccc91SDavid du Colombier MAD_F(0x08000000) /* 0.500000000 */,
476*f30ccc91SDavid du Colombier MAD_F(0x05a8279a) /* 0.353553391 */,
477*f30ccc91SDavid du Colombier MAD_F(0x04000000) /* 0.250000000 */,
478*f30ccc91SDavid du Colombier MAD_F(0x02d413cd) /* 0.176776695 */,
479*f30ccc91SDavid du Colombier MAD_F(0x02000000) /* 0.125000000 */,
480*f30ccc91SDavid du Colombier MAD_F(0x016a09e6) /* 0.088388348 */,
481*f30ccc91SDavid du Colombier MAD_F(0x01000000) /* 0.062500000 */,
482*f30ccc91SDavid du Colombier MAD_F(0x00b504f3) /* 0.044194174 */,
483*f30ccc91SDavid du Colombier MAD_F(0x00800000) /* 0.031250000 */,
484*f30ccc91SDavid du Colombier MAD_F(0x005a827a) /* 0.022097087 */,
485*f30ccc91SDavid du Colombier MAD_F(0x00400000) /* 0.015625000 */,
486*f30ccc91SDavid du Colombier MAD_F(0x002d413d) /* 0.011048543 */,
487*f30ccc91SDavid du Colombier MAD_F(0x00200000) /* 0.007812500 */,
488*f30ccc91SDavid du Colombier MAD_F(0x0016a09e) /* 0.005524272 */
489*f30ccc91SDavid du Colombier }
490*f30ccc91SDavid du Colombier };
4918f5875f3SDavid du Colombier
492*f30ccc91SDavid du Colombier /*
493*f30ccc91SDavid du Colombier * NAME: III_sideinfo()
494*f30ccc91SDavid du Colombier * DESCRIPTION: decode frame side information from a bitstream
495*f30ccc91SDavid du Colombier */
496*f30ccc91SDavid du Colombier static
III_sideinfo(struct mad_bitptr * ptr,unsigned int nch,int lsf,struct sideinfo * si,unsigned int * data_bitlen,unsigned int * priv_bitlen)497*f30ccc91SDavid du Colombier enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch,
498*f30ccc91SDavid du Colombier int lsf, struct sideinfo *si,
499*f30ccc91SDavid du Colombier unsigned int *data_bitlen,
500*f30ccc91SDavid du Colombier unsigned int *priv_bitlen)
501*f30ccc91SDavid du Colombier {
502*f30ccc91SDavid du Colombier unsigned int ngr, gr, ch, i;
503*f30ccc91SDavid du Colombier enum mad_error result = MAD_ERROR_NONE;
5048f5875f3SDavid du Colombier
505*f30ccc91SDavid du Colombier *data_bitlen = 0;
506*f30ccc91SDavid du Colombier *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3);
5078f5875f3SDavid du Colombier
508*f30ccc91SDavid du Colombier si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9);
509*f30ccc91SDavid du Colombier si->private_bits = mad_bit_read(ptr, *priv_bitlen);
510*f30ccc91SDavid du Colombier
511*f30ccc91SDavid du Colombier ngr = 1;
5128f5875f3SDavid du Colombier if (!lsf) {
513*f30ccc91SDavid du Colombier ngr = 2;
514*f30ccc91SDavid du Colombier
515*f30ccc91SDavid du Colombier for (ch = 0; ch < nch; ++ch)
516*f30ccc91SDavid du Colombier si->scfsi[ch] = mad_bit_read(ptr, 4);
5178f5875f3SDavid du Colombier }
5188f5875f3SDavid du Colombier
519*f30ccc91SDavid du Colombier for (gr = 0; gr < ngr; ++gr) {
520*f30ccc91SDavid du Colombier struct granule *granule = &si->gr[gr];
5218f5875f3SDavid du Colombier
522*f30ccc91SDavid du Colombier for (ch = 0; ch < nch; ++ch) {
523*f30ccc91SDavid du Colombier struct channel *channel = &granule->ch[ch];
5248f5875f3SDavid du Colombier
525*f30ccc91SDavid du Colombier channel->part2_3_length = mad_bit_read(ptr, 12);
526*f30ccc91SDavid du Colombier channel->big_values = mad_bit_read(ptr, 9);
527*f30ccc91SDavid du Colombier channel->global_gain = mad_bit_read(ptr, 8);
528*f30ccc91SDavid du Colombier channel->scalefac_compress = mad_bit_read(ptr, lsf ? 9 : 4);
5298f5875f3SDavid du Colombier
530*f30ccc91SDavid du Colombier *data_bitlen += channel->part2_3_length;
5318f5875f3SDavid du Colombier
532*f30ccc91SDavid du Colombier if (channel->big_values > 288 && result == 0)
533*f30ccc91SDavid du Colombier result = MAD_ERROR_BADBIGVALUES;
5348f5875f3SDavid du Colombier
535*f30ccc91SDavid du Colombier channel->flags = 0;
5368f5875f3SDavid du Colombier
537*f30ccc91SDavid du Colombier /* window_switching_flag */
538*f30ccc91SDavid du Colombier if (mad_bit_read(ptr, 1)) {
539*f30ccc91SDavid du Colombier channel->block_type = mad_bit_read(ptr, 2);
5408f5875f3SDavid du Colombier
541*f30ccc91SDavid du Colombier if (channel->block_type == 0 && result == 0)
542*f30ccc91SDavid du Colombier result = MAD_ERROR_BADBLOCKTYPE;
5438f5875f3SDavid du Colombier
544*f30ccc91SDavid du Colombier if (!lsf && channel->block_type == 2 && si->scfsi[ch] && result == 0)
545*f30ccc91SDavid du Colombier result = MAD_ERROR_BADSCFSI;
5468f5875f3SDavid du Colombier
547*f30ccc91SDavid du Colombier channel->region0_count = 7;
548*f30ccc91SDavid du Colombier channel->region1_count = 36;
549*f30ccc91SDavid du Colombier
550*f30ccc91SDavid du Colombier if (mad_bit_read(ptr, 1))
551*f30ccc91SDavid du Colombier channel->flags |= mixed_block_flag;
552*f30ccc91SDavid du Colombier else if (channel->block_type == 2)
553*f30ccc91SDavid du Colombier channel->region0_count = 8;
554*f30ccc91SDavid du Colombier
555*f30ccc91SDavid du Colombier for (i = 0; i < 2; ++i)
556*f30ccc91SDavid du Colombier channel->table_select[i] = mad_bit_read(ptr, 5);
557*f30ccc91SDavid du Colombier
558*f30ccc91SDavid du Colombier # if defined(DEBUG)
559*f30ccc91SDavid du Colombier channel->table_select[2] = 4; /* not used */
5608f5875f3SDavid du Colombier # endif
5618f5875f3SDavid du Colombier
562*f30ccc91SDavid du Colombier for (i = 0; i < 3; ++i)
563*f30ccc91SDavid du Colombier channel->subblock_gain[i] = mad_bit_read(ptr, 3);
564*f30ccc91SDavid du Colombier }
565*f30ccc91SDavid du Colombier else {
566*f30ccc91SDavid du Colombier channel->block_type = 0;
567*f30ccc91SDavid du Colombier
568*f30ccc91SDavid du Colombier for (i = 0; i < 3; ++i)
569*f30ccc91SDavid du Colombier channel->table_select[i] = mad_bit_read(ptr, 5);
570*f30ccc91SDavid du Colombier
571*f30ccc91SDavid du Colombier channel->region0_count = mad_bit_read(ptr, 4);
572*f30ccc91SDavid du Colombier channel->region1_count = mad_bit_read(ptr, 3);
573*f30ccc91SDavid du Colombier }
574*f30ccc91SDavid du Colombier
575*f30ccc91SDavid du Colombier /* [preflag,] scalefac_scale, count1table_select */
576*f30ccc91SDavid du Colombier channel->flags |= mad_bit_read(ptr, lsf ? 2 : 3);
577*f30ccc91SDavid du Colombier }
578*f30ccc91SDavid du Colombier }
579*f30ccc91SDavid du Colombier
580*f30ccc91SDavid du Colombier return result;
581*f30ccc91SDavid du Colombier }
582*f30ccc91SDavid du Colombier
5838f5875f3SDavid du Colombier /*
584*f30ccc91SDavid du Colombier * NAME: III_scalefactors_lsf()
585*f30ccc91SDavid du Colombier * DESCRIPTION: decode channel scalefactors for LSF from a bitstream
5868f5875f3SDavid du Colombier */
587*f30ccc91SDavid du Colombier static
III_scalefactors_lsf(struct mad_bitptr * ptr,struct channel * channel,struct channel * gr1ch,int mode_extension)588*f30ccc91SDavid du Colombier unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr,
589*f30ccc91SDavid du Colombier struct channel *channel,
590*f30ccc91SDavid du Colombier struct channel *gr1ch, int mode_extension)
5918f5875f3SDavid du Colombier {
592*f30ccc91SDavid du Colombier struct mad_bitptr start;
593*f30ccc91SDavid du Colombier unsigned int scalefac_compress, index, slen[4], part, n, i;
594*f30ccc91SDavid du Colombier unsigned char const *nsfb;
5958f5875f3SDavid du Colombier
596*f30ccc91SDavid du Colombier start = *ptr;
5978f5875f3SDavid du Colombier
598*f30ccc91SDavid du Colombier scalefac_compress = channel->scalefac_compress;
599*f30ccc91SDavid du Colombier index = (channel->block_type == 2) ?
600*f30ccc91SDavid du Colombier ((channel->flags & mixed_block_flag) ? 2 : 1) : 0;
601*f30ccc91SDavid du Colombier
602*f30ccc91SDavid du Colombier if (!((mode_extension & I_STEREO) && gr1ch)) {
603*f30ccc91SDavid du Colombier if (scalefac_compress < 400) {
604*f30ccc91SDavid du Colombier slen[0] = (scalefac_compress >> 4) / 5;
605*f30ccc91SDavid du Colombier slen[1] = (scalefac_compress >> 4) % 5;
606*f30ccc91SDavid du Colombier slen[2] = (scalefac_compress % 16) >> 2;
607*f30ccc91SDavid du Colombier slen[3] = scalefac_compress % 4;
608*f30ccc91SDavid du Colombier
609*f30ccc91SDavid du Colombier nsfb = nsfb_table[0][index];
6108f5875f3SDavid du Colombier }
611*f30ccc91SDavid du Colombier else if (scalefac_compress < 500) {
612*f30ccc91SDavid du Colombier scalefac_compress -= 400;
6138f5875f3SDavid du Colombier
614*f30ccc91SDavid du Colombier slen[0] = (scalefac_compress >> 2) / 5;
615*f30ccc91SDavid du Colombier slen[1] = (scalefac_compress >> 2) % 5;
616*f30ccc91SDavid du Colombier slen[2] = scalefac_compress % 4;
617*f30ccc91SDavid du Colombier slen[3] = 0;
618*f30ccc91SDavid du Colombier
619*f30ccc91SDavid du Colombier nsfb = nsfb_table[1][index];
6208f5875f3SDavid du Colombier }
6218f5875f3SDavid du Colombier else {
622*f30ccc91SDavid du Colombier scalefac_compress -= 500;
6238f5875f3SDavid du Colombier
624*f30ccc91SDavid du Colombier slen[0] = scalefac_compress / 3;
625*f30ccc91SDavid du Colombier slen[1] = scalefac_compress % 3;
626*f30ccc91SDavid du Colombier slen[2] = 0;
627*f30ccc91SDavid du Colombier slen[3] = 0;
6288f5875f3SDavid du Colombier
629*f30ccc91SDavid du Colombier channel->flags |= preflag;
6308f5875f3SDavid du Colombier
631*f30ccc91SDavid du Colombier nsfb = nsfb_table[2][index];
6328f5875f3SDavid du Colombier }
6338f5875f3SDavid du Colombier
6348f5875f3SDavid du Colombier n = 0;
635*f30ccc91SDavid du Colombier for (part = 0; part < 4; ++part) {
636*f30ccc91SDavid du Colombier for (i = 0; i < nsfb[part]; ++i)
637*f30ccc91SDavid du Colombier channel->scalefac[n++] = mad_bit_read(ptr, slen[part]);
6388f5875f3SDavid du Colombier }
6398f5875f3SDavid du Colombier
640*f30ccc91SDavid du Colombier while (n < 39)
641*f30ccc91SDavid du Colombier channel->scalefac[n++] = 0;
642*f30ccc91SDavid du Colombier }
643*f30ccc91SDavid du Colombier else { /* (mode_extension & I_STEREO) && gr1ch (i.e. ch == 1) */
644*f30ccc91SDavid du Colombier scalefac_compress >>= 1;
6458f5875f3SDavid du Colombier
646*f30ccc91SDavid du Colombier if (scalefac_compress < 180) {
647*f30ccc91SDavid du Colombier slen[0] = scalefac_compress / 36;
648*f30ccc91SDavid du Colombier slen[1] = (scalefac_compress % 36) / 6;
649*f30ccc91SDavid du Colombier slen[2] = (scalefac_compress % 36) % 6;
650*f30ccc91SDavid du Colombier slen[3] = 0;
651*f30ccc91SDavid du Colombier
652*f30ccc91SDavid du Colombier nsfb = nsfb_table[3][index];
653*f30ccc91SDavid du Colombier }
654*f30ccc91SDavid du Colombier else if (scalefac_compress < 244) {
655*f30ccc91SDavid du Colombier scalefac_compress -= 180;
656*f30ccc91SDavid du Colombier
657*f30ccc91SDavid du Colombier slen[0] = (scalefac_compress % 64) >> 4;
658*f30ccc91SDavid du Colombier slen[1] = (scalefac_compress % 16) >> 2;
659*f30ccc91SDavid du Colombier slen[2] = scalefac_compress % 4;
660*f30ccc91SDavid du Colombier slen[3] = 0;
661*f30ccc91SDavid du Colombier
662*f30ccc91SDavid du Colombier nsfb = nsfb_table[4][index];
6638f5875f3SDavid du Colombier }
6648f5875f3SDavid du Colombier else {
665*f30ccc91SDavid du Colombier scalefac_compress -= 244;
666*f30ccc91SDavid du Colombier
667*f30ccc91SDavid du Colombier slen[0] = scalefac_compress / 3;
668*f30ccc91SDavid du Colombier slen[1] = scalefac_compress % 3;
669*f30ccc91SDavid du Colombier slen[2] = 0;
670*f30ccc91SDavid du Colombier slen[3] = 0;
671*f30ccc91SDavid du Colombier
672*f30ccc91SDavid du Colombier nsfb = nsfb_table[5][index];
673*f30ccc91SDavid du Colombier }
674*f30ccc91SDavid du Colombier
675*f30ccc91SDavid du Colombier n = 0;
676*f30ccc91SDavid du Colombier for (part = 0; part < 4; ++part) {
677*f30ccc91SDavid du Colombier unsigned int max, is_pos;
678*f30ccc91SDavid du Colombier
679*f30ccc91SDavid du Colombier max = (1 << slen[part]) - 1;
680*f30ccc91SDavid du Colombier
681*f30ccc91SDavid du Colombier for (i = 0; i < nsfb[part]; ++i) {
682*f30ccc91SDavid du Colombier is_pos = mad_bit_read(ptr, slen[part]);
683*f30ccc91SDavid du Colombier
684*f30ccc91SDavid du Colombier channel->scalefac[n] = is_pos;
685*f30ccc91SDavid du Colombier gr1ch->scalefac[n++] = (is_pos == max);
6868f5875f3SDavid du Colombier }
6878f5875f3SDavid du Colombier }
6888f5875f3SDavid du Colombier
689*f30ccc91SDavid du Colombier while (n < 39) {
690*f30ccc91SDavid du Colombier channel->scalefac[n] = 0;
691*f30ccc91SDavid du Colombier gr1ch->scalefac[n++] = 0; /* apparently not illegal */
692*f30ccc91SDavid du Colombier }
6938f5875f3SDavid du Colombier }
6948f5875f3SDavid du Colombier
695*f30ccc91SDavid du Colombier return mad_bit_length(&start, ptr);
696*f30ccc91SDavid du Colombier }
6978f5875f3SDavid du Colombier
6988f5875f3SDavid du Colombier /*
699*f30ccc91SDavid du Colombier * NAME: III_scalefactors()
700*f30ccc91SDavid du Colombier * DESCRIPTION: decode channel scalefactors of one granule from a bitstream
7018f5875f3SDavid du Colombier */
702*f30ccc91SDavid du Colombier static
III_scalefactors(struct mad_bitptr * ptr,struct channel * channel,struct channel const * gr0ch,unsigned int scfsi)703*f30ccc91SDavid du Colombier unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel,
704*f30ccc91SDavid du Colombier struct channel const *gr0ch, unsigned int scfsi)
7058f5875f3SDavid du Colombier {
706*f30ccc91SDavid du Colombier struct mad_bitptr start;
707*f30ccc91SDavid du Colombier unsigned int slen1, slen2, sfbi;
7088f5875f3SDavid du Colombier
709*f30ccc91SDavid du Colombier start = *ptr;
7108f5875f3SDavid du Colombier
711*f30ccc91SDavid du Colombier slen1 = sflen_table[channel->scalefac_compress].slen1;
712*f30ccc91SDavid du Colombier slen2 = sflen_table[channel->scalefac_compress].slen2;
7138f5875f3SDavid du Colombier
714*f30ccc91SDavid du Colombier if (channel->block_type == 2) {
715*f30ccc91SDavid du Colombier unsigned int nsfb;
716*f30ccc91SDavid du Colombier
717*f30ccc91SDavid du Colombier sfbi = 0;
718*f30ccc91SDavid du Colombier
719*f30ccc91SDavid du Colombier nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3;
720*f30ccc91SDavid du Colombier while (nsfb--)
721*f30ccc91SDavid du Colombier channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1);
722*f30ccc91SDavid du Colombier
723*f30ccc91SDavid du Colombier nsfb = 6 * 3;
724*f30ccc91SDavid du Colombier while (nsfb--)
725*f30ccc91SDavid du Colombier channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2);
726*f30ccc91SDavid du Colombier
727*f30ccc91SDavid du Colombier nsfb = 1 * 3;
728*f30ccc91SDavid du Colombier while (nsfb--)
729*f30ccc91SDavid du Colombier channel->scalefac[sfbi++] = 0;
730*f30ccc91SDavid du Colombier }
731*f30ccc91SDavid du Colombier else { /* channel->block_type != 2 */
732*f30ccc91SDavid du Colombier if (scfsi & 0x8) {
733*f30ccc91SDavid du Colombier for (sfbi = 0; sfbi < 6; ++sfbi)
734*f30ccc91SDavid du Colombier channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
735*f30ccc91SDavid du Colombier }
736*f30ccc91SDavid du Colombier else {
737*f30ccc91SDavid du Colombier for (sfbi = 0; sfbi < 6; ++sfbi)
738*f30ccc91SDavid du Colombier channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
739*f30ccc91SDavid du Colombier }
740*f30ccc91SDavid du Colombier
741*f30ccc91SDavid du Colombier if (scfsi & 0x4) {
742*f30ccc91SDavid du Colombier for (sfbi = 6; sfbi < 11; ++sfbi)
743*f30ccc91SDavid du Colombier channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
744*f30ccc91SDavid du Colombier }
745*f30ccc91SDavid du Colombier else {
746*f30ccc91SDavid du Colombier for (sfbi = 6; sfbi < 11; ++sfbi)
747*f30ccc91SDavid du Colombier channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
748*f30ccc91SDavid du Colombier }
749*f30ccc91SDavid du Colombier
750*f30ccc91SDavid du Colombier if (scfsi & 0x2) {
751*f30ccc91SDavid du Colombier for (sfbi = 11; sfbi < 16; ++sfbi)
752*f30ccc91SDavid du Colombier channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
753*f30ccc91SDavid du Colombier }
754*f30ccc91SDavid du Colombier else {
755*f30ccc91SDavid du Colombier for (sfbi = 11; sfbi < 16; ++sfbi)
756*f30ccc91SDavid du Colombier channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
757*f30ccc91SDavid du Colombier }
758*f30ccc91SDavid du Colombier
759*f30ccc91SDavid du Colombier if (scfsi & 0x1) {
760*f30ccc91SDavid du Colombier for (sfbi = 16; sfbi < 21; ++sfbi)
761*f30ccc91SDavid du Colombier channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
762*f30ccc91SDavid du Colombier }
763*f30ccc91SDavid du Colombier else {
764*f30ccc91SDavid du Colombier for (sfbi = 16; sfbi < 21; ++sfbi)
765*f30ccc91SDavid du Colombier channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
766*f30ccc91SDavid du Colombier }
767*f30ccc91SDavid du Colombier
768*f30ccc91SDavid du Colombier channel->scalefac[21] = 0;
769*f30ccc91SDavid du Colombier }
770*f30ccc91SDavid du Colombier
771*f30ccc91SDavid du Colombier return mad_bit_length(&start, ptr);
772*f30ccc91SDavid du Colombier }
773*f30ccc91SDavid du Colombier
7748f5875f3SDavid du Colombier /*
775*f30ccc91SDavid du Colombier * The Layer III formula for requantization and scaling is defined by
776*f30ccc91SDavid du Colombier * section 2.4.3.4.7.1 of ISO/IEC 11172-3, as follows:
777*f30ccc91SDavid du Colombier *
778*f30ccc91SDavid du Colombier * long blocks:
779*f30ccc91SDavid du Colombier * xr[i] = sign(is[i]) * abs(is[i])^(4/3) *
780*f30ccc91SDavid du Colombier * 2^((1/4) * (global_gain - 210)) *
781*f30ccc91SDavid du Colombier * 2^-(scalefac_multiplier *
782*f30ccc91SDavid du Colombier * (scalefac_l[sfb] + preflag * pretab[sfb]))
783*f30ccc91SDavid du Colombier *
784*f30ccc91SDavid du Colombier * short blocks:
785*f30ccc91SDavid du Colombier * xr[i] = sign(is[i]) * abs(is[i])^(4/3) *
786*f30ccc91SDavid du Colombier * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) *
787*f30ccc91SDavid du Colombier * 2^-(scalefac_multiplier * scalefac_s[sfb][w])
788*f30ccc91SDavid du Colombier *
789*f30ccc91SDavid du Colombier * where:
790*f30ccc91SDavid du Colombier * scalefac_multiplier = (scalefac_scale + 1) / 2
791*f30ccc91SDavid du Colombier *
792*f30ccc91SDavid du Colombier * The routines III_exponents() and III_requantize() facilitate this
793*f30ccc91SDavid du Colombier * calculation.
7948f5875f3SDavid du Colombier */
7958f5875f3SDavid du Colombier
7968f5875f3SDavid du Colombier /*
797*f30ccc91SDavid du Colombier * NAME: III_exponents()
798*f30ccc91SDavid du Colombier * DESCRIPTION: calculate scalefactor exponents
7998f5875f3SDavid du Colombier */
800*f30ccc91SDavid du Colombier static
III_exponents(struct channel const * channel,unsigned char const * sfbwidth,signed int exponents[39])801*f30ccc91SDavid du Colombier void III_exponents(struct channel const *channel,
802*f30ccc91SDavid du Colombier unsigned char const *sfbwidth, signed int exponents[39])
8038f5875f3SDavid du Colombier {
804*f30ccc91SDavid du Colombier signed int gain;
805*f30ccc91SDavid du Colombier unsigned int scalefac_multiplier, sfbi;
806*f30ccc91SDavid du Colombier
807*f30ccc91SDavid du Colombier gain = (signed int) channel->global_gain - 210;
808*f30ccc91SDavid du Colombier scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1;
809*f30ccc91SDavid du Colombier
810*f30ccc91SDavid du Colombier if (channel->block_type == 2) {
811*f30ccc91SDavid du Colombier unsigned int l;
812*f30ccc91SDavid du Colombier signed int gain0, gain1, gain2;
813*f30ccc91SDavid du Colombier
814*f30ccc91SDavid du Colombier sfbi = l = 0;
815*f30ccc91SDavid du Colombier
816*f30ccc91SDavid du Colombier if (channel->flags & mixed_block_flag) {
817*f30ccc91SDavid du Colombier unsigned int premask;
818*f30ccc91SDavid du Colombier
819*f30ccc91SDavid du Colombier premask = (channel->flags & preflag) ? ~0 : 0;
820*f30ccc91SDavid du Colombier
821*f30ccc91SDavid du Colombier /* long block subbands 0-1 */
822*f30ccc91SDavid du Colombier
823*f30ccc91SDavid du Colombier while (l < 36) {
824*f30ccc91SDavid du Colombier exponents[sfbi] = gain -
825*f30ccc91SDavid du Colombier (signed int) ((channel->scalefac[sfbi] + (pretab[sfbi] & premask)) <<
826*f30ccc91SDavid du Colombier scalefac_multiplier);
827*f30ccc91SDavid du Colombier
828*f30ccc91SDavid du Colombier l += sfbwidth[sfbi++];
8298f5875f3SDavid du Colombier }
8308f5875f3SDavid du Colombier }
8318f5875f3SDavid du Colombier
832*f30ccc91SDavid du Colombier /* this is probably wrong for 8000 Hz short/mixed blocks */
8338f5875f3SDavid du Colombier
834*f30ccc91SDavid du Colombier gain0 = gain - 8 * (signed int) channel->subblock_gain[0];
835*f30ccc91SDavid du Colombier gain1 = gain - 8 * (signed int) channel->subblock_gain[1];
836*f30ccc91SDavid du Colombier gain2 = gain - 8 * (signed int) channel->subblock_gain[2];
837*f30ccc91SDavid du Colombier
838*f30ccc91SDavid du Colombier while (l < 576) {
839*f30ccc91SDavid du Colombier exponents[sfbi + 0] = gain0 -
840*f30ccc91SDavid du Colombier (signed int) (channel->scalefac[sfbi + 0] << scalefac_multiplier);
841*f30ccc91SDavid du Colombier exponents[sfbi + 1] = gain1 -
842*f30ccc91SDavid du Colombier (signed int) (channel->scalefac[sfbi + 1] << scalefac_multiplier);
843*f30ccc91SDavid du Colombier exponents[sfbi + 2] = gain2 -
844*f30ccc91SDavid du Colombier (signed int) (channel->scalefac[sfbi + 2] << scalefac_multiplier);
845*f30ccc91SDavid du Colombier
846*f30ccc91SDavid du Colombier l += 3 * sfbwidth[sfbi];
847*f30ccc91SDavid du Colombier sfbi += 3;
8488f5875f3SDavid du Colombier }
849*f30ccc91SDavid du Colombier }
850*f30ccc91SDavid du Colombier else { /* channel->block_type != 2 */
851*f30ccc91SDavid du Colombier if (channel->flags & preflag) {
852*f30ccc91SDavid du Colombier for (sfbi = 0; sfbi < 22; ++sfbi) {
853*f30ccc91SDavid du Colombier exponents[sfbi] = gain -
854*f30ccc91SDavid du Colombier (signed int) ((channel->scalefac[sfbi] + pretab[sfbi]) <<
855*f30ccc91SDavid du Colombier scalefac_multiplier);
856*f30ccc91SDavid du Colombier }
857*f30ccc91SDavid du Colombier }
858*f30ccc91SDavid du Colombier else {
859*f30ccc91SDavid du Colombier for (sfbi = 0; sfbi < 22; ++sfbi) {
860*f30ccc91SDavid du Colombier exponents[sfbi] = gain -
861*f30ccc91SDavid du Colombier (signed int) (channel->scalefac[sfbi] << scalefac_multiplier);
862*f30ccc91SDavid du Colombier }
863*f30ccc91SDavid du Colombier }
864*f30ccc91SDavid du Colombier }
865*f30ccc91SDavid du Colombier }
866*f30ccc91SDavid du Colombier
867*f30ccc91SDavid du Colombier /*
868*f30ccc91SDavid du Colombier * NAME: III_requantize()
869*f30ccc91SDavid du Colombier * DESCRIPTION: requantize one (positive) value
870*f30ccc91SDavid du Colombier */
871*f30ccc91SDavid du Colombier static
III_requantize(unsigned int value,signed int exp)872*f30ccc91SDavid du Colombier mad_fixed_t III_requantize(unsigned int value, signed int exp)
873*f30ccc91SDavid du Colombier {
874*f30ccc91SDavid du Colombier mad_fixed_t requantized;
875*f30ccc91SDavid du Colombier signed int frac;
876*f30ccc91SDavid du Colombier struct fixedfloat const *power;
877*f30ccc91SDavid du Colombier
878*f30ccc91SDavid du Colombier frac = exp % 4; /* assumes sign(frac) == sign(exp) */
879*f30ccc91SDavid du Colombier exp /= 4;
880*f30ccc91SDavid du Colombier
881*f30ccc91SDavid du Colombier power = &rq_table[value];
882*f30ccc91SDavid du Colombier requantized = power->mantissa;
883*f30ccc91SDavid du Colombier exp += power->exponent;
884*f30ccc91SDavid du Colombier
885*f30ccc91SDavid du Colombier if (exp < 0) {
886*f30ccc91SDavid du Colombier if (-exp >= sizeof(mad_fixed_t) * CHAR_BIT) {
887*f30ccc91SDavid du Colombier /* underflow */
888*f30ccc91SDavid du Colombier requantized = 0;
889*f30ccc91SDavid du Colombier }
890*f30ccc91SDavid du Colombier else {
891*f30ccc91SDavid du Colombier requantized += 1L << (-exp - 1);
892*f30ccc91SDavid du Colombier requantized >>= -exp;
893*f30ccc91SDavid du Colombier }
894*f30ccc91SDavid du Colombier }
895*f30ccc91SDavid du Colombier else {
896*f30ccc91SDavid du Colombier if (exp >= 5) {
897*f30ccc91SDavid du Colombier /* overflow */
898*f30ccc91SDavid du Colombier # if defined(DEBUG)
899*f30ccc91SDavid du Colombier fprintf(stderr, "requantize overflow (%f * 2^%d)\n",
900*f30ccc91SDavid du Colombier mad_f_todouble(requantized), exp);
901*f30ccc91SDavid du Colombier # endif
902*f30ccc91SDavid du Colombier requantized = MAD_F_MAX;
903*f30ccc91SDavid du Colombier }
904*f30ccc91SDavid du Colombier else
905*f30ccc91SDavid du Colombier requantized <<= exp;
906*f30ccc91SDavid du Colombier }
907*f30ccc91SDavid du Colombier
908*f30ccc91SDavid du Colombier return frac ? mad_f_mul(requantized, root_table[3 + frac]) : requantized;
909*f30ccc91SDavid du Colombier }
910*f30ccc91SDavid du Colombier
911*f30ccc91SDavid du Colombier /* we must take care that sz >= bits and sz < sizeof(long) lest bits == 0 */
912*f30ccc91SDavid du Colombier # define MASK(cache, sz, bits) \
913*f30ccc91SDavid du Colombier (((cache) >> ((sz) - (bits))) & ((1 << (bits)) - 1))
914*f30ccc91SDavid du Colombier # define MASK1BIT(cache, sz) \
915*f30ccc91SDavid du Colombier ((cache) & (1 << ((sz) - 1)))
916*f30ccc91SDavid du Colombier
917*f30ccc91SDavid du Colombier /*
918*f30ccc91SDavid du Colombier * NAME: III_huffdecode()
919*f30ccc91SDavid du Colombier * DESCRIPTION: decode Huffman code words of one channel of one granule
920*f30ccc91SDavid du Colombier */
921*f30ccc91SDavid du Colombier static
III_huffdecode(struct mad_bitptr * ptr,mad_fixed_t xr[576],struct channel * channel,unsigned char const * sfbwidth,unsigned int part2_length)922*f30ccc91SDavid du Colombier enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576],
923*f30ccc91SDavid du Colombier struct channel *channel,
924*f30ccc91SDavid du Colombier unsigned char const *sfbwidth,
925*f30ccc91SDavid du Colombier unsigned int part2_length)
926*f30ccc91SDavid du Colombier {
927*f30ccc91SDavid du Colombier signed int exponents[39], exp;
928*f30ccc91SDavid du Colombier signed int const *expptr;
929*f30ccc91SDavid du Colombier struct mad_bitptr peek;
930*f30ccc91SDavid du Colombier signed int bits_left, cachesz;
931*f30ccc91SDavid du Colombier register mad_fixed_t *xrptr;
932*f30ccc91SDavid du Colombier mad_fixed_t const *sfbound;
933*f30ccc91SDavid du Colombier register unsigned long bitcache;
934*f30ccc91SDavid du Colombier
935*f30ccc91SDavid du Colombier bits_left = (signed) channel->part2_3_length - (signed) part2_length;
936*f30ccc91SDavid du Colombier if (bits_left < 0)
937*f30ccc91SDavid du Colombier return MAD_ERROR_BADPART3LEN;
938*f30ccc91SDavid du Colombier
939*f30ccc91SDavid du Colombier III_exponents(channel, sfbwidth, exponents);
940*f30ccc91SDavid du Colombier
941*f30ccc91SDavid du Colombier peek = *ptr;
942*f30ccc91SDavid du Colombier mad_bit_skip(ptr, bits_left);
943*f30ccc91SDavid du Colombier
944*f30ccc91SDavid du Colombier /* align bit reads to byte boundaries */
945*f30ccc91SDavid du Colombier cachesz = mad_bit_bitsleft(&peek);
946*f30ccc91SDavid du Colombier cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7;
947*f30ccc91SDavid du Colombier
948*f30ccc91SDavid du Colombier bitcache = mad_bit_read(&peek, cachesz);
949*f30ccc91SDavid du Colombier bits_left -= cachesz;
950*f30ccc91SDavid du Colombier
951*f30ccc91SDavid du Colombier xrptr = &xr[0];
952*f30ccc91SDavid du Colombier
953*f30ccc91SDavid du Colombier /* big_values */
954*f30ccc91SDavid du Colombier {
955*f30ccc91SDavid du Colombier unsigned int region, rcount;
956*f30ccc91SDavid du Colombier struct hufftable const *entry;
957*f30ccc91SDavid du Colombier struct huffpair const *table;
958*f30ccc91SDavid du Colombier unsigned int linbits, startbits, big_values, reqhits;
959*f30ccc91SDavid du Colombier mad_fixed_t reqcache[16];
960*f30ccc91SDavid du Colombier
961*f30ccc91SDavid du Colombier sfbound = xrptr + *sfbwidth++;
962*f30ccc91SDavid du Colombier rcount = channel->region0_count + 1;
963*f30ccc91SDavid du Colombier
964*f30ccc91SDavid du Colombier entry = &mad_huff_pair_table[channel->table_select[region = 0]];
965*f30ccc91SDavid du Colombier table = entry->table;
966*f30ccc91SDavid du Colombier linbits = entry->linbits;
967*f30ccc91SDavid du Colombier startbits = entry->startbits;
968*f30ccc91SDavid du Colombier
969*f30ccc91SDavid du Colombier if (table == 0)
970*f30ccc91SDavid du Colombier return MAD_ERROR_BADHUFFTABLE;
971*f30ccc91SDavid du Colombier
972*f30ccc91SDavid du Colombier expptr = &exponents[0];
973*f30ccc91SDavid du Colombier exp = *expptr++;
974*f30ccc91SDavid du Colombier reqhits = 0;
975*f30ccc91SDavid du Colombier
976*f30ccc91SDavid du Colombier big_values = channel->big_values;
977*f30ccc91SDavid du Colombier
978*f30ccc91SDavid du Colombier while (big_values-- && cachesz + bits_left > 0) {
979*f30ccc91SDavid du Colombier struct huffpair const *pair;
980*f30ccc91SDavid du Colombier unsigned int clumpsz, value;
981*f30ccc91SDavid du Colombier register mad_fixed_t requantized;
982*f30ccc91SDavid du Colombier
983*f30ccc91SDavid du Colombier if (xrptr == sfbound) {
984*f30ccc91SDavid du Colombier sfbound += *sfbwidth++;
985*f30ccc91SDavid du Colombier
986*f30ccc91SDavid du Colombier /* change table if region boundary */
987*f30ccc91SDavid du Colombier
988*f30ccc91SDavid du Colombier if (--rcount == 0) {
989*f30ccc91SDavid du Colombier if (region == 0)
990*f30ccc91SDavid du Colombier rcount = channel->region1_count + 1;
991*f30ccc91SDavid du Colombier else
992*f30ccc91SDavid du Colombier rcount = 0; /* all remaining */
993*f30ccc91SDavid du Colombier
994*f30ccc91SDavid du Colombier entry = &mad_huff_pair_table[channel->table_select[++region]];
995*f30ccc91SDavid du Colombier table = entry->table;
996*f30ccc91SDavid du Colombier linbits = entry->linbits;
997*f30ccc91SDavid du Colombier startbits = entry->startbits;
998*f30ccc91SDavid du Colombier
999*f30ccc91SDavid du Colombier if (table == 0)
1000*f30ccc91SDavid du Colombier return MAD_ERROR_BADHUFFTABLE;
1001*f30ccc91SDavid du Colombier }
1002*f30ccc91SDavid du Colombier
1003*f30ccc91SDavid du Colombier if (exp != *expptr) {
1004*f30ccc91SDavid du Colombier exp = *expptr;
1005*f30ccc91SDavid du Colombier reqhits = 0;
1006*f30ccc91SDavid du Colombier }
1007*f30ccc91SDavid du Colombier
1008*f30ccc91SDavid du Colombier ++expptr;
1009*f30ccc91SDavid du Colombier }
1010*f30ccc91SDavid du Colombier
1011*f30ccc91SDavid du Colombier if (cachesz < 21) {
1012*f30ccc91SDavid du Colombier unsigned int bits;
1013*f30ccc91SDavid du Colombier
1014*f30ccc91SDavid du Colombier bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7;
1015*f30ccc91SDavid du Colombier bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
1016*f30ccc91SDavid du Colombier cachesz += bits;
1017*f30ccc91SDavid du Colombier bits_left -= bits;
1018*f30ccc91SDavid du Colombier }
1019*f30ccc91SDavid du Colombier
1020*f30ccc91SDavid du Colombier /* hcod (0..19) */
1021*f30ccc91SDavid du Colombier
1022*f30ccc91SDavid du Colombier clumpsz = startbits;
1023*f30ccc91SDavid du Colombier pair = &table[MASK(bitcache, cachesz, clumpsz)];
1024*f30ccc91SDavid du Colombier
1025*f30ccc91SDavid du Colombier while (!pair->final) {
1026*f30ccc91SDavid du Colombier cachesz -= clumpsz;
1027*f30ccc91SDavid du Colombier
1028*f30ccc91SDavid du Colombier clumpsz = pair->ptr.bits;
1029*f30ccc91SDavid du Colombier pair = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)];
1030*f30ccc91SDavid du Colombier }
1031*f30ccc91SDavid du Colombier
1032*f30ccc91SDavid du Colombier cachesz -= pair->value.hlen;
1033*f30ccc91SDavid du Colombier
1034*f30ccc91SDavid du Colombier if (linbits) {
1035*f30ccc91SDavid du Colombier /* x (0..14) */
1036*f30ccc91SDavid du Colombier
1037*f30ccc91SDavid du Colombier value = pair->value.x;
1038*f30ccc91SDavid du Colombier
1039*f30ccc91SDavid du Colombier switch (value) {
1040*f30ccc91SDavid du Colombier case 0:
1041*f30ccc91SDavid du Colombier xrptr[0] = 0;
1042*f30ccc91SDavid du Colombier break;
1043*f30ccc91SDavid du Colombier
1044*f30ccc91SDavid du Colombier case 15:
1045*f30ccc91SDavid du Colombier if (cachesz < linbits + 2) {
1046*f30ccc91SDavid du Colombier bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
1047*f30ccc91SDavid du Colombier cachesz += 16;
1048*f30ccc91SDavid du Colombier bits_left -= 16;
1049*f30ccc91SDavid du Colombier }
1050*f30ccc91SDavid du Colombier
1051*f30ccc91SDavid du Colombier value += MASK(bitcache, cachesz, linbits);
1052*f30ccc91SDavid du Colombier cachesz -= linbits;
1053*f30ccc91SDavid du Colombier
1054*f30ccc91SDavid du Colombier requantized = III_requantize(value, exp);
1055*f30ccc91SDavid du Colombier goto x_final;
1056*f30ccc91SDavid du Colombier
1057*f30ccc91SDavid du Colombier default:
1058*f30ccc91SDavid du Colombier if (reqhits & (1 << value))
1059*f30ccc91SDavid du Colombier requantized = reqcache[value];
1060*f30ccc91SDavid du Colombier else {
1061*f30ccc91SDavid du Colombier reqhits |= (1 << value);
1062*f30ccc91SDavid du Colombier requantized = reqcache[value] = III_requantize(value, exp);
1063*f30ccc91SDavid du Colombier }
1064*f30ccc91SDavid du Colombier
1065*f30ccc91SDavid du Colombier x_final:
1066*f30ccc91SDavid du Colombier xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
1067*f30ccc91SDavid du Colombier -requantized : requantized;
1068*f30ccc91SDavid du Colombier }
1069*f30ccc91SDavid du Colombier
1070*f30ccc91SDavid du Colombier /* y (0..14) */
1071*f30ccc91SDavid du Colombier
1072*f30ccc91SDavid du Colombier value = pair->value.y;
1073*f30ccc91SDavid du Colombier
1074*f30ccc91SDavid du Colombier switch (value) {
1075*f30ccc91SDavid du Colombier case 0:
1076*f30ccc91SDavid du Colombier xrptr[1] = 0;
1077*f30ccc91SDavid du Colombier break;
1078*f30ccc91SDavid du Colombier
1079*f30ccc91SDavid du Colombier case 15:
1080*f30ccc91SDavid du Colombier if (cachesz < linbits + 1) {
1081*f30ccc91SDavid du Colombier bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
1082*f30ccc91SDavid du Colombier cachesz += 16;
1083*f30ccc91SDavid du Colombier bits_left -= 16;
1084*f30ccc91SDavid du Colombier }
1085*f30ccc91SDavid du Colombier
1086*f30ccc91SDavid du Colombier value += MASK(bitcache, cachesz, linbits);
1087*f30ccc91SDavid du Colombier cachesz -= linbits;
1088*f30ccc91SDavid du Colombier
1089*f30ccc91SDavid du Colombier requantized = III_requantize(value, exp);
1090*f30ccc91SDavid du Colombier goto y_final;
1091*f30ccc91SDavid du Colombier
1092*f30ccc91SDavid du Colombier default:
1093*f30ccc91SDavid du Colombier if (reqhits & (1 << value))
1094*f30ccc91SDavid du Colombier requantized = reqcache[value];
1095*f30ccc91SDavid du Colombier else {
1096*f30ccc91SDavid du Colombier reqhits |= (1 << value);
1097*f30ccc91SDavid du Colombier requantized = reqcache[value] = III_requantize(value, exp);
1098*f30ccc91SDavid du Colombier }
1099*f30ccc91SDavid du Colombier
1100*f30ccc91SDavid du Colombier y_final:
1101*f30ccc91SDavid du Colombier xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
1102*f30ccc91SDavid du Colombier -requantized : requantized;
1103*f30ccc91SDavid du Colombier }
1104*f30ccc91SDavid du Colombier }
1105*f30ccc91SDavid du Colombier else {
1106*f30ccc91SDavid du Colombier /* x (0..1) */
1107*f30ccc91SDavid du Colombier
1108*f30ccc91SDavid du Colombier value = pair->value.x;
1109*f30ccc91SDavid du Colombier
1110*f30ccc91SDavid du Colombier if (value == 0)
1111*f30ccc91SDavid du Colombier xrptr[0] = 0;
1112*f30ccc91SDavid du Colombier else {
1113*f30ccc91SDavid du Colombier if (reqhits & (1 << value))
1114*f30ccc91SDavid du Colombier requantized = reqcache[value];
1115*f30ccc91SDavid du Colombier else {
1116*f30ccc91SDavid du Colombier reqhits |= (1 << value);
1117*f30ccc91SDavid du Colombier requantized = reqcache[value] = III_requantize(value, exp);
1118*f30ccc91SDavid du Colombier }
1119*f30ccc91SDavid du Colombier
1120*f30ccc91SDavid du Colombier xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
1121*f30ccc91SDavid du Colombier -requantized : requantized;
1122*f30ccc91SDavid du Colombier }
1123*f30ccc91SDavid du Colombier
1124*f30ccc91SDavid du Colombier /* y (0..1) */
1125*f30ccc91SDavid du Colombier
1126*f30ccc91SDavid du Colombier value = pair->value.y;
1127*f30ccc91SDavid du Colombier
1128*f30ccc91SDavid du Colombier if (value == 0)
1129*f30ccc91SDavid du Colombier xrptr[1] = 0;
1130*f30ccc91SDavid du Colombier else {
1131*f30ccc91SDavid du Colombier if (reqhits & (1 << value))
1132*f30ccc91SDavid du Colombier requantized = reqcache[value];
1133*f30ccc91SDavid du Colombier else {
1134*f30ccc91SDavid du Colombier reqhits |= (1 << value);
1135*f30ccc91SDavid du Colombier requantized = reqcache[value] = III_requantize(value, exp);
1136*f30ccc91SDavid du Colombier }
1137*f30ccc91SDavid du Colombier
1138*f30ccc91SDavid du Colombier xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
1139*f30ccc91SDavid du Colombier -requantized : requantized;
1140*f30ccc91SDavid du Colombier }
1141*f30ccc91SDavid du Colombier }
1142*f30ccc91SDavid du Colombier
1143*f30ccc91SDavid du Colombier xrptr += 2;
1144*f30ccc91SDavid du Colombier }
1145*f30ccc91SDavid du Colombier }
1146*f30ccc91SDavid du Colombier
1147*f30ccc91SDavid du Colombier if (cachesz + bits_left < 0)
1148*f30ccc91SDavid du Colombier return MAD_ERROR_BADHUFFDATA; /* big_values overrun */
1149*f30ccc91SDavid du Colombier
1150*f30ccc91SDavid du Colombier /* count1 */
1151*f30ccc91SDavid du Colombier {
1152*f30ccc91SDavid du Colombier struct huffquad const *table;
1153*f30ccc91SDavid du Colombier register mad_fixed_t requantized;
1154*f30ccc91SDavid du Colombier
1155*f30ccc91SDavid du Colombier table = mad_huff_quad_table[channel->flags & count1table_select];
1156*f30ccc91SDavid du Colombier
1157*f30ccc91SDavid du Colombier requantized = III_requantize(1, exp);
1158*f30ccc91SDavid du Colombier
1159*f30ccc91SDavid du Colombier while (cachesz + bits_left > 0 && xrptr <= &xr[572]) {
1160*f30ccc91SDavid du Colombier struct huffquad const *quad;
1161*f30ccc91SDavid du Colombier
1162*f30ccc91SDavid du Colombier /* hcod (1..6) */
1163*f30ccc91SDavid du Colombier
1164*f30ccc91SDavid du Colombier if (cachesz < 10) {
1165*f30ccc91SDavid du Colombier bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
1166*f30ccc91SDavid du Colombier cachesz += 16;
1167*f30ccc91SDavid du Colombier bits_left -= 16;
1168*f30ccc91SDavid du Colombier }
1169*f30ccc91SDavid du Colombier
1170*f30ccc91SDavid du Colombier quad = &table[MASK(bitcache, cachesz, 4)];
1171*f30ccc91SDavid du Colombier
1172*f30ccc91SDavid du Colombier /* quad tables guaranteed to have at most one extra lookup */
1173*f30ccc91SDavid du Colombier if (!quad->final) {
1174*f30ccc91SDavid du Colombier cachesz -= 4;
1175*f30ccc91SDavid du Colombier
1176*f30ccc91SDavid du Colombier quad = &table[quad->ptr.offset +
1177*f30ccc91SDavid du Colombier MASK(bitcache, cachesz, quad->ptr.bits)];
1178*f30ccc91SDavid du Colombier }
1179*f30ccc91SDavid du Colombier
1180*f30ccc91SDavid du Colombier cachesz -= quad->value.hlen;
1181*f30ccc91SDavid du Colombier
1182*f30ccc91SDavid du Colombier if (xrptr == sfbound) {
1183*f30ccc91SDavid du Colombier sfbound += *sfbwidth++;
1184*f30ccc91SDavid du Colombier
1185*f30ccc91SDavid du Colombier if (exp != *expptr) {
1186*f30ccc91SDavid du Colombier exp = *expptr;
1187*f30ccc91SDavid du Colombier requantized = III_requantize(1, exp);
1188*f30ccc91SDavid du Colombier }
1189*f30ccc91SDavid du Colombier
1190*f30ccc91SDavid du Colombier ++expptr;
1191*f30ccc91SDavid du Colombier }
1192*f30ccc91SDavid du Colombier
1193*f30ccc91SDavid du Colombier /* v (0..1) */
1194*f30ccc91SDavid du Colombier
1195*f30ccc91SDavid du Colombier xrptr[0] = quad->value.v ?
1196*f30ccc91SDavid du Colombier (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
1197*f30ccc91SDavid du Colombier
1198*f30ccc91SDavid du Colombier /* w (0..1) */
1199*f30ccc91SDavid du Colombier
1200*f30ccc91SDavid du Colombier xrptr[1] = quad->value.w ?
1201*f30ccc91SDavid du Colombier (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
1202*f30ccc91SDavid du Colombier
1203*f30ccc91SDavid du Colombier xrptr += 2;
1204*f30ccc91SDavid du Colombier
1205*f30ccc91SDavid du Colombier if (xrptr == sfbound) {
1206*f30ccc91SDavid du Colombier sfbound += *sfbwidth++;
1207*f30ccc91SDavid du Colombier
1208*f30ccc91SDavid du Colombier if (exp != *expptr) {
1209*f30ccc91SDavid du Colombier exp = *expptr;
1210*f30ccc91SDavid du Colombier requantized = III_requantize(1, exp);
1211*f30ccc91SDavid du Colombier }
1212*f30ccc91SDavid du Colombier
1213*f30ccc91SDavid du Colombier ++expptr;
1214*f30ccc91SDavid du Colombier }
1215*f30ccc91SDavid du Colombier
1216*f30ccc91SDavid du Colombier /* x (0..1) */
1217*f30ccc91SDavid du Colombier
1218*f30ccc91SDavid du Colombier xrptr[0] = quad->value.x ?
1219*f30ccc91SDavid du Colombier (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
1220*f30ccc91SDavid du Colombier
1221*f30ccc91SDavid du Colombier /* y (0..1) */
1222*f30ccc91SDavid du Colombier
1223*f30ccc91SDavid du Colombier xrptr[1] = quad->value.y ?
1224*f30ccc91SDavid du Colombier (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
1225*f30ccc91SDavid du Colombier
1226*f30ccc91SDavid du Colombier xrptr += 2;
1227*f30ccc91SDavid du Colombier }
1228*f30ccc91SDavid du Colombier
1229*f30ccc91SDavid du Colombier if (cachesz + bits_left < 0) {
1230*f30ccc91SDavid du Colombier # if 0 && defined(DEBUG)
1231*f30ccc91SDavid du Colombier fprintf(stderr, "huffman count1 overrun (%d bits)\n",
1232*f30ccc91SDavid du Colombier -(cachesz + bits_left));
1233*f30ccc91SDavid du Colombier # endif
1234*f30ccc91SDavid du Colombier
1235*f30ccc91SDavid du Colombier /* technically the bitstream is misformatted, but apparently
1236*f30ccc91SDavid du Colombier some encoders are just a bit sloppy with stuffing bits */
1237*f30ccc91SDavid du Colombier
1238*f30ccc91SDavid du Colombier xrptr -= 4;
1239*f30ccc91SDavid du Colombier }
1240*f30ccc91SDavid du Colombier }
1241*f30ccc91SDavid du Colombier
1242*f30ccc91SDavid du Colombier assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT);
1243*f30ccc91SDavid du Colombier
1244*f30ccc91SDavid du Colombier # if 0 && defined(DEBUG)
1245*f30ccc91SDavid du Colombier if (bits_left < 0)
1246*f30ccc91SDavid du Colombier fprintf(stderr, "read %d bits too many\n", -bits_left);
1247*f30ccc91SDavid du Colombier else if (cachesz + bits_left > 0)
1248*f30ccc91SDavid du Colombier fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left);
1249*f30ccc91SDavid du Colombier # endif
1250*f30ccc91SDavid du Colombier
1251*f30ccc91SDavid du Colombier /* rzero */
1252*f30ccc91SDavid du Colombier while (xrptr < &xr[576]) {
1253*f30ccc91SDavid du Colombier xrptr[0] = 0;
1254*f30ccc91SDavid du Colombier xrptr[1] = 0;
1255*f30ccc91SDavid du Colombier
1256*f30ccc91SDavid du Colombier xrptr += 2;
1257*f30ccc91SDavid du Colombier }
1258*f30ccc91SDavid du Colombier
1259*f30ccc91SDavid du Colombier return MAD_ERROR_NONE;
1260*f30ccc91SDavid du Colombier }
1261*f30ccc91SDavid du Colombier
1262*f30ccc91SDavid du Colombier # undef MASK
1263*f30ccc91SDavid du Colombier # undef MASK1BIT
1264*f30ccc91SDavid du Colombier
1265*f30ccc91SDavid du Colombier /*
1266*f30ccc91SDavid du Colombier * NAME: III_reorder()
1267*f30ccc91SDavid du Colombier * DESCRIPTION: reorder frequency lines of a short block into subband order
1268*f30ccc91SDavid du Colombier */
1269*f30ccc91SDavid du Colombier static
III_reorder(mad_fixed_t xr[576],struct channel const * channel,unsigned char const sfbwidth[39])1270*f30ccc91SDavid du Colombier void III_reorder(mad_fixed_t xr[576], struct channel const *channel,
1271*f30ccc91SDavid du Colombier unsigned char const sfbwidth[39])
1272*f30ccc91SDavid du Colombier {
1273*f30ccc91SDavid du Colombier mad_fixed_t tmp[32][3][6];
1274*f30ccc91SDavid du Colombier unsigned int sb, l, f, w, sbw[3], sw[3];
1275*f30ccc91SDavid du Colombier
1276*f30ccc91SDavid du Colombier /* this is probably wrong for 8000 Hz mixed blocks */
1277*f30ccc91SDavid du Colombier
1278*f30ccc91SDavid du Colombier sb = 0;
1279*f30ccc91SDavid du Colombier if (channel->flags & mixed_block_flag) {
1280*f30ccc91SDavid du Colombier sb = 2;
1281*f30ccc91SDavid du Colombier
1282*f30ccc91SDavid du Colombier l = 0;
1283*f30ccc91SDavid du Colombier while (l < 36)
1284*f30ccc91SDavid du Colombier l += *sfbwidth++;
1285*f30ccc91SDavid du Colombier }
1286*f30ccc91SDavid du Colombier
1287*f30ccc91SDavid du Colombier for (w = 0; w < 3; ++w) {
1288*f30ccc91SDavid du Colombier sbw[w] = sb;
1289*f30ccc91SDavid du Colombier sw[w] = 0;
1290*f30ccc91SDavid du Colombier }
1291*f30ccc91SDavid du Colombier
1292*f30ccc91SDavid du Colombier f = *sfbwidth++;
1293*f30ccc91SDavid du Colombier w = 0;
1294*f30ccc91SDavid du Colombier
1295*f30ccc91SDavid du Colombier for (l = 18 * sb; l < 576; ++l) {
1296*f30ccc91SDavid du Colombier if (f-- == 0) {
1297*f30ccc91SDavid du Colombier f = *sfbwidth++ - 1;
1298*f30ccc91SDavid du Colombier w = (w + 1) % 3;
1299*f30ccc91SDavid du Colombier }
1300*f30ccc91SDavid du Colombier
1301*f30ccc91SDavid du Colombier tmp[sbw[w]][w][sw[w]++] = xr[l];
1302*f30ccc91SDavid du Colombier
1303*f30ccc91SDavid du Colombier if (sw[w] == 6) {
1304*f30ccc91SDavid du Colombier sw[w] = 0;
1305*f30ccc91SDavid du Colombier ++sbw[w];
1306*f30ccc91SDavid du Colombier }
1307*f30ccc91SDavid du Colombier }
1308*f30ccc91SDavid du Colombier
1309*f30ccc91SDavid du Colombier memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t));
1310*f30ccc91SDavid du Colombier }
1311*f30ccc91SDavid du Colombier
1312*f30ccc91SDavid du Colombier /*
1313*f30ccc91SDavid du Colombier * NAME: III_stereo()
1314*f30ccc91SDavid du Colombier * DESCRIPTION: perform joint stereo processing on a granule
1315*f30ccc91SDavid du Colombier */
1316*f30ccc91SDavid du Colombier static
III_stereo(mad_fixed_t xr[2][576],struct granule const * granule,struct mad_header * header,unsigned char const * sfbwidth)1317*f30ccc91SDavid du Colombier enum mad_error III_stereo(mad_fixed_t xr[2][576],
1318*f30ccc91SDavid du Colombier struct granule const *granule,
1319*f30ccc91SDavid du Colombier struct mad_header *header,
1320*f30ccc91SDavid du Colombier unsigned char const *sfbwidth)
1321*f30ccc91SDavid du Colombier {
1322*f30ccc91SDavid du Colombier short modes[39];
1323*f30ccc91SDavid du Colombier unsigned int sfbi, l, n, i;
1324*f30ccc91SDavid du Colombier
1325*f30ccc91SDavid du Colombier if (granule->ch[0].block_type !=
1326*f30ccc91SDavid du Colombier granule->ch[1].block_type ||
1327*f30ccc91SDavid du Colombier (granule->ch[0].flags & mixed_block_flag) !=
1328*f30ccc91SDavid du Colombier (granule->ch[1].flags & mixed_block_flag))
1329*f30ccc91SDavid du Colombier return MAD_ERROR_BADSTEREO;
1330*f30ccc91SDavid du Colombier
1331*f30ccc91SDavid du Colombier for (i = 0; i < 39; ++i)
1332*f30ccc91SDavid du Colombier modes[i] = header->mode_extension;
1333*f30ccc91SDavid du Colombier
1334*f30ccc91SDavid du Colombier /* intensity stereo */
1335*f30ccc91SDavid du Colombier
1336*f30ccc91SDavid du Colombier if (header->mode_extension & I_STEREO) {
1337*f30ccc91SDavid du Colombier struct channel const *right_ch = &granule->ch[1];
1338*f30ccc91SDavid du Colombier mad_fixed_t const *right_xr = xr[1];
1339*f30ccc91SDavid du Colombier unsigned int is_pos;
1340*f30ccc91SDavid du Colombier
1341*f30ccc91SDavid du Colombier header->flags |= MAD_FLAG_I_STEREO;
1342*f30ccc91SDavid du Colombier
1343*f30ccc91SDavid du Colombier /* first determine which scalefactor bands are to be processed */
1344*f30ccc91SDavid du Colombier
1345*f30ccc91SDavid du Colombier if (right_ch->block_type == 2) {
1346*f30ccc91SDavid du Colombier unsigned int lower, start, max, bound[3], w;
1347*f30ccc91SDavid du Colombier
1348*f30ccc91SDavid du Colombier lower = start = max = bound[0] = bound[1] = bound[2] = 0;
1349*f30ccc91SDavid du Colombier
1350*f30ccc91SDavid du Colombier sfbi = l = 0;
1351*f30ccc91SDavid du Colombier
1352*f30ccc91SDavid du Colombier if (right_ch->flags & mixed_block_flag) {
1353*f30ccc91SDavid du Colombier while (l < 36) {
1354*f30ccc91SDavid du Colombier n = sfbwidth[sfbi++];
1355*f30ccc91SDavid du Colombier
1356*f30ccc91SDavid du Colombier for (i = 0; i < n; ++i) {
1357*f30ccc91SDavid du Colombier if (right_xr[i]) {
1358*f30ccc91SDavid du Colombier lower = sfbi;
13598f5875f3SDavid du Colombier break;
13608f5875f3SDavid du Colombier }
13618f5875f3SDavid du Colombier }
1362*f30ccc91SDavid du Colombier
1363*f30ccc91SDavid du Colombier right_xr += n;
1364*f30ccc91SDavid du Colombier l += n;
1365*f30ccc91SDavid du Colombier }
1366*f30ccc91SDavid du Colombier
1367*f30ccc91SDavid du Colombier start = sfbi;
1368*f30ccc91SDavid du Colombier }
1369*f30ccc91SDavid du Colombier
1370*f30ccc91SDavid du Colombier w = 0;
1371*f30ccc91SDavid du Colombier while (l < 576) {
1372*f30ccc91SDavid du Colombier n = sfbwidth[sfbi++];
1373*f30ccc91SDavid du Colombier
1374*f30ccc91SDavid du Colombier for (i = 0; i < n; ++i) {
1375*f30ccc91SDavid du Colombier if (right_xr[i]) {
1376*f30ccc91SDavid du Colombier max = bound[w] = sfbi;
1377*f30ccc91SDavid du Colombier break;
1378*f30ccc91SDavid du Colombier }
1379*f30ccc91SDavid du Colombier }
1380*f30ccc91SDavid du Colombier
1381*f30ccc91SDavid du Colombier right_xr += n;
1382*f30ccc91SDavid du Colombier l += n;
1383*f30ccc91SDavid du Colombier w = (w + 1) % 3;
1384*f30ccc91SDavid du Colombier }
1385*f30ccc91SDavid du Colombier
1386*f30ccc91SDavid du Colombier if (max)
1387*f30ccc91SDavid du Colombier lower = start;
1388*f30ccc91SDavid du Colombier
1389*f30ccc91SDavid du Colombier /* long blocks */
1390*f30ccc91SDavid du Colombier
1391*f30ccc91SDavid du Colombier for (i = 0; i < lower; ++i)
1392*f30ccc91SDavid du Colombier modes[i] = header->mode_extension & ~I_STEREO;
1393*f30ccc91SDavid du Colombier
1394*f30ccc91SDavid du Colombier /* short blocks */
1395*f30ccc91SDavid du Colombier
1396*f30ccc91SDavid du Colombier w = 0;
1397*f30ccc91SDavid du Colombier for (i = start; i < max; ++i) {
1398*f30ccc91SDavid du Colombier if (i < bound[w])
1399*f30ccc91SDavid du Colombier modes[i] = header->mode_extension & ~I_STEREO;
1400*f30ccc91SDavid du Colombier
1401*f30ccc91SDavid du Colombier w = (w + 1) % 3;
1402*f30ccc91SDavid du Colombier }
1403*f30ccc91SDavid du Colombier }
1404*f30ccc91SDavid du Colombier else { /* right_ch->block_type != 2 */
1405*f30ccc91SDavid du Colombier unsigned int bound;
1406*f30ccc91SDavid du Colombier
1407*f30ccc91SDavid du Colombier bound = 0;
1408*f30ccc91SDavid du Colombier for (sfbi = l = 0; l < 576; l += n) {
1409*f30ccc91SDavid du Colombier n = sfbwidth[sfbi++];
1410*f30ccc91SDavid du Colombier
1411*f30ccc91SDavid du Colombier for (i = 0; i < n; ++i) {
1412*f30ccc91SDavid du Colombier if (right_xr[i]) {
1413*f30ccc91SDavid du Colombier bound = sfbi;
1414*f30ccc91SDavid du Colombier break;
1415*f30ccc91SDavid du Colombier }
1416*f30ccc91SDavid du Colombier }
1417*f30ccc91SDavid du Colombier
1418*f30ccc91SDavid du Colombier right_xr += n;
1419*f30ccc91SDavid du Colombier }
1420*f30ccc91SDavid du Colombier
1421*f30ccc91SDavid du Colombier for (i = 0; i < bound; ++i)
1422*f30ccc91SDavid du Colombier modes[i] = header->mode_extension & ~I_STEREO;
1423*f30ccc91SDavid du Colombier }
1424*f30ccc91SDavid du Colombier
1425*f30ccc91SDavid du Colombier /* now do the actual processing */
1426*f30ccc91SDavid du Colombier
1427*f30ccc91SDavid du Colombier if (header->flags & MAD_FLAG_LSF_EXT) {
1428*f30ccc91SDavid du Colombier unsigned char const *illegal_pos = granule[1].ch[1].scalefac;
1429*f30ccc91SDavid du Colombier mad_fixed_t const *lsf_scale;
1430*f30ccc91SDavid du Colombier
1431*f30ccc91SDavid du Colombier /* intensity_scale */
1432*f30ccc91SDavid du Colombier lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1];
1433*f30ccc91SDavid du Colombier
1434*f30ccc91SDavid du Colombier for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
1435*f30ccc91SDavid du Colombier n = sfbwidth[sfbi];
1436*f30ccc91SDavid du Colombier
1437*f30ccc91SDavid du Colombier if (!(modes[sfbi] & I_STEREO))
1438*f30ccc91SDavid du Colombier continue;
1439*f30ccc91SDavid du Colombier
1440*f30ccc91SDavid du Colombier if (illegal_pos[sfbi]) {
1441*f30ccc91SDavid du Colombier modes[sfbi] &= ~I_STEREO;
1442*f30ccc91SDavid du Colombier continue;
1443*f30ccc91SDavid du Colombier }
1444*f30ccc91SDavid du Colombier
1445*f30ccc91SDavid du Colombier is_pos = right_ch->scalefac[sfbi];
1446*f30ccc91SDavid du Colombier
1447*f30ccc91SDavid du Colombier for (i = 0; i < n; ++i) {
1448*f30ccc91SDavid du Colombier register mad_fixed_t left;
1449*f30ccc91SDavid du Colombier
1450*f30ccc91SDavid du Colombier left = xr[0][l + i];
1451*f30ccc91SDavid du Colombier
1452*f30ccc91SDavid du Colombier if (is_pos == 0)
1453*f30ccc91SDavid du Colombier xr[1][l + i] = left;
14548f5875f3SDavid du Colombier else {
1455*f30ccc91SDavid du Colombier register mad_fixed_t opposite;
1456*f30ccc91SDavid du Colombier
1457*f30ccc91SDavid du Colombier opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]);
1458*f30ccc91SDavid du Colombier
1459*f30ccc91SDavid du Colombier if (is_pos & 1) {
1460*f30ccc91SDavid du Colombier xr[0][l + i] = opposite;
1461*f30ccc91SDavid du Colombier xr[1][l + i] = left;
14628f5875f3SDavid du Colombier }
14638f5875f3SDavid du Colombier else
1464*f30ccc91SDavid du Colombier xr[1][l + i] = opposite;
1465*f30ccc91SDavid du Colombier }
1466*f30ccc91SDavid du Colombier }
1467*f30ccc91SDavid du Colombier }
1468*f30ccc91SDavid du Colombier }
1469*f30ccc91SDavid du Colombier else { /* !(header->flags & MAD_FLAG_LSF_EXT) */
1470*f30ccc91SDavid du Colombier for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
1471*f30ccc91SDavid du Colombier n = sfbwidth[sfbi];
1472*f30ccc91SDavid du Colombier
1473*f30ccc91SDavid du Colombier if (!(modes[sfbi] & I_STEREO))
1474*f30ccc91SDavid du Colombier continue;
1475*f30ccc91SDavid du Colombier
1476*f30ccc91SDavid du Colombier is_pos = right_ch->scalefac[sfbi];
1477*f30ccc91SDavid du Colombier
1478*f30ccc91SDavid du Colombier if (is_pos >= 7) { /* illegal intensity position */
1479*f30ccc91SDavid du Colombier modes[sfbi] &= ~I_STEREO;
1480*f30ccc91SDavid du Colombier continue;
1481*f30ccc91SDavid du Colombier }
1482*f30ccc91SDavid du Colombier
1483*f30ccc91SDavid du Colombier for (i = 0; i < n; ++i) {
1484*f30ccc91SDavid du Colombier register mad_fixed_t left;
1485*f30ccc91SDavid du Colombier
1486*f30ccc91SDavid du Colombier left = xr[0][l + i];
1487*f30ccc91SDavid du Colombier
1488*f30ccc91SDavid du Colombier xr[0][l + i] = mad_f_mul(left, is_table[ is_pos]);
1489*f30ccc91SDavid du Colombier xr[1][l + i] = mad_f_mul(left, is_table[6 - is_pos]);
1490*f30ccc91SDavid du Colombier }
1491*f30ccc91SDavid du Colombier }
14928f5875f3SDavid du Colombier }
14938f5875f3SDavid du Colombier }
14948f5875f3SDavid du Colombier
1495*f30ccc91SDavid du Colombier /* middle/side stereo */
1496*f30ccc91SDavid du Colombier
1497*f30ccc91SDavid du Colombier if (header->mode_extension & MS_STEREO) {
1498*f30ccc91SDavid du Colombier register mad_fixed_t invsqrt2;
1499*f30ccc91SDavid du Colombier
1500*f30ccc91SDavid du Colombier header->flags |= MAD_FLAG_MS_STEREO;
1501*f30ccc91SDavid du Colombier
1502*f30ccc91SDavid du Colombier invsqrt2 = root_table[3 + -2];
1503*f30ccc91SDavid du Colombier
1504*f30ccc91SDavid du Colombier for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
1505*f30ccc91SDavid du Colombier n = sfbwidth[sfbi];
1506*f30ccc91SDavid du Colombier
1507*f30ccc91SDavid du Colombier if (modes[sfbi] != MS_STEREO)
1508*f30ccc91SDavid du Colombier continue;
1509*f30ccc91SDavid du Colombier
1510*f30ccc91SDavid du Colombier for (i = 0; i < n; ++i) {
1511*f30ccc91SDavid du Colombier register mad_fixed_t m, s;
1512*f30ccc91SDavid du Colombier
1513*f30ccc91SDavid du Colombier m = xr[0][l + i];
1514*f30ccc91SDavid du Colombier s = xr[1][l + i];
1515*f30ccc91SDavid du Colombier
1516*f30ccc91SDavid du Colombier xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */
1517*f30ccc91SDavid du Colombier xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */
15188f5875f3SDavid du Colombier }
15198f5875f3SDavid du Colombier }
15208f5875f3SDavid du Colombier }
15218f5875f3SDavid du Colombier
1522*f30ccc91SDavid du Colombier return MAD_ERROR_NONE;
1523*f30ccc91SDavid du Colombier }
15248f5875f3SDavid du Colombier
1525*f30ccc91SDavid du Colombier /*
1526*f30ccc91SDavid du Colombier * NAME: III_aliasreduce()
1527*f30ccc91SDavid du Colombier * DESCRIPTION: perform frequency line alias reduction
1528*f30ccc91SDavid du Colombier */
1529*f30ccc91SDavid du Colombier static
III_aliasreduce(mad_fixed_t xr[576],int lines)1530*f30ccc91SDavid du Colombier void III_aliasreduce(mad_fixed_t xr[576], int lines)
15318f5875f3SDavid du Colombier {
1532*f30ccc91SDavid du Colombier mad_fixed_t const *bound;
1533*f30ccc91SDavid du Colombier int i;
15348f5875f3SDavid du Colombier
1535*f30ccc91SDavid du Colombier bound = &xr[lines];
1536*f30ccc91SDavid du Colombier for (xr += 18; xr < bound; xr += 18) {
1537*f30ccc91SDavid du Colombier for (i = 0; i < 8; ++i) {
1538*f30ccc91SDavid du Colombier register mad_fixed_t a, b;
1539*f30ccc91SDavid du Colombier register mad_fixed64hi_t hi;
1540*f30ccc91SDavid du Colombier register mad_fixed64lo_t lo;
15418f5875f3SDavid du Colombier
1542*f30ccc91SDavid du Colombier a = xr[-1 - i];
1543*f30ccc91SDavid du Colombier b = xr[ i];
15448f5875f3SDavid du Colombier
1545*f30ccc91SDavid du Colombier # if defined(ASO_ZEROCHECK)
1546*f30ccc91SDavid du Colombier if (a | b) {
1547*f30ccc91SDavid du Colombier # endif
1548*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, a, cs[i]);
1549*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, -b, ca[i]);
15508f5875f3SDavid du Colombier
1551*f30ccc91SDavid du Colombier xr[-1 - i] = MAD_F_MLZ(hi, lo);
15528f5875f3SDavid du Colombier
1553*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, b, cs[i]);
1554*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, a, ca[i]);
15558f5875f3SDavid du Colombier
1556*f30ccc91SDavid du Colombier xr[ i] = MAD_F_MLZ(hi, lo);
1557*f30ccc91SDavid du Colombier # if defined(ASO_ZEROCHECK)
15588f5875f3SDavid du Colombier }
1559*f30ccc91SDavid du Colombier # endif
15608f5875f3SDavid du Colombier }
15618f5875f3SDavid du Colombier }
15628f5875f3SDavid du Colombier }
15638f5875f3SDavid du Colombier
1564*f30ccc91SDavid du Colombier # if defined(ASO_IMDCT)
1565*f30ccc91SDavid du Colombier void III_imdct_l(mad_fixed_t const [18], mad_fixed_t [36], unsigned int);
1566*f30ccc91SDavid du Colombier # else
15678f5875f3SDavid du Colombier # if 1
1568*f30ccc91SDavid du Colombier static
fastsdct(mad_fixed_t const x[9],mad_fixed_t y[18])1569*f30ccc91SDavid du Colombier void fastsdct(mad_fixed_t const x[9], mad_fixed_t y[18])
1570*f30ccc91SDavid du Colombier {
1571*f30ccc91SDavid du Colombier mad_fixed_t a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12;
1572*f30ccc91SDavid du Colombier mad_fixed_t a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25;
1573*f30ccc91SDavid du Colombier mad_fixed_t m0, m1, m2, m3, m4, m5, m6, m7;
1574*f30ccc91SDavid du Colombier
1575*f30ccc91SDavid du Colombier enum {
1576*f30ccc91SDavid du Colombier c0 = MAD_F(0x1f838b8d), /* 2 * cos( 1 * PI / 18) */
1577*f30ccc91SDavid du Colombier c1 = MAD_F(0x1bb67ae8), /* 2 * cos( 3 * PI / 18) */
1578*f30ccc91SDavid du Colombier c2 = MAD_F(0x18836fa3), /* 2 * cos( 4 * PI / 18) */
1579*f30ccc91SDavid du Colombier c3 = MAD_F(0x1491b752), /* 2 * cos( 5 * PI / 18) */
1580*f30ccc91SDavid du Colombier c4 = MAD_F(0x0af1d43a), /* 2 * cos( 7 * PI / 18) */
1581*f30ccc91SDavid du Colombier c5 = MAD_F(0x058e86a0), /* 2 * cos( 8 * PI / 18) */
1582*f30ccc91SDavid du Colombier c6 = -MAD_F(0x1e11f642) /* 2 * cos(16 * PI / 18) */
15838f5875f3SDavid du Colombier };
15848f5875f3SDavid du Colombier
1585*f30ccc91SDavid du Colombier a0 = x[3] + x[5];
1586*f30ccc91SDavid du Colombier a1 = x[3] - x[5];
1587*f30ccc91SDavid du Colombier a2 = x[6] + x[2];
1588*f30ccc91SDavid du Colombier a3 = x[6] - x[2];
1589*f30ccc91SDavid du Colombier a4 = x[1] + x[7];
1590*f30ccc91SDavid du Colombier a5 = x[1] - x[7];
1591*f30ccc91SDavid du Colombier a6 = x[8] + x[0];
1592*f30ccc91SDavid du Colombier a7 = x[8] - x[0];
15938f5875f3SDavid du Colombier
1594*f30ccc91SDavid du Colombier a8 = a0 + a2;
1595*f30ccc91SDavid du Colombier a9 = a0 - a2;
1596*f30ccc91SDavid du Colombier a10 = a0 - a6;
1597*f30ccc91SDavid du Colombier a11 = a2 - a6;
1598*f30ccc91SDavid du Colombier a12 = a8 + a6;
1599*f30ccc91SDavid du Colombier a13 = a1 - a3;
1600*f30ccc91SDavid du Colombier a14 = a13 + a7;
1601*f30ccc91SDavid du Colombier a15 = a3 + a7;
1602*f30ccc91SDavid du Colombier a16 = a1 - a7;
1603*f30ccc91SDavid du Colombier a17 = a1 + a3;
16048f5875f3SDavid du Colombier
1605*f30ccc91SDavid du Colombier m0 = mad_f_mul(a17, -c3);
1606*f30ccc91SDavid du Colombier m1 = mad_f_mul(a16, -c0);
1607*f30ccc91SDavid du Colombier m2 = mad_f_mul(a15, -c4);
1608*f30ccc91SDavid du Colombier m3 = mad_f_mul(a14, -c1);
1609*f30ccc91SDavid du Colombier m4 = mad_f_mul(a5, -c1);
1610*f30ccc91SDavid du Colombier m5 = mad_f_mul(a11, -c6);
1611*f30ccc91SDavid du Colombier m6 = mad_f_mul(a10, -c5);
1612*f30ccc91SDavid du Colombier m7 = mad_f_mul(a9, -c2);
16138f5875f3SDavid du Colombier
1614*f30ccc91SDavid du Colombier a18 = x[4] + a4;
1615*f30ccc91SDavid du Colombier a19 = 2 * x[4] - a4;
1616*f30ccc91SDavid du Colombier a20 = a19 + m5;
1617*f30ccc91SDavid du Colombier a21 = a19 - m5;
1618*f30ccc91SDavid du Colombier a22 = a19 + m6;
1619*f30ccc91SDavid du Colombier a23 = m4 + m2;
1620*f30ccc91SDavid du Colombier a24 = m4 - m2;
1621*f30ccc91SDavid du Colombier a25 = m4 + m1;
1622*f30ccc91SDavid du Colombier
1623*f30ccc91SDavid du Colombier /* output to every other slot for convenience */
1624*f30ccc91SDavid du Colombier
1625*f30ccc91SDavid du Colombier y[ 0] = a18 + a12;
1626*f30ccc91SDavid du Colombier y[ 2] = m0 - a25;
1627*f30ccc91SDavid du Colombier y[ 4] = m7 - a20;
1628*f30ccc91SDavid du Colombier y[ 6] = m3;
1629*f30ccc91SDavid du Colombier y[ 8] = a21 - m6;
1630*f30ccc91SDavid du Colombier y[10] = a24 - m1;
1631*f30ccc91SDavid du Colombier y[12] = a12 - 2 * a18;
1632*f30ccc91SDavid du Colombier y[14] = a23 + m0;
1633*f30ccc91SDavid du Colombier y[16] = a22 + m7;
16348f5875f3SDavid du Colombier }
16358f5875f3SDavid du Colombier
1636*f30ccc91SDavid du Colombier static inline
sdctII(mad_fixed_t const x[18],mad_fixed_t X[18])1637*f30ccc91SDavid du Colombier void sdctII(mad_fixed_t const x[18], mad_fixed_t X[18])
16388f5875f3SDavid du Colombier {
1639*f30ccc91SDavid du Colombier mad_fixed_t tmp[9];
16408f5875f3SDavid du Colombier int i;
1641*f30ccc91SDavid du Colombier
1642*f30ccc91SDavid du Colombier /* scale[i] = 2 * cos(PI * (2 * i + 1) / (2 * 18)) */
1643*f30ccc91SDavid du Colombier static mad_fixed_t const scale[9] = {
1644*f30ccc91SDavid du Colombier MAD_F(0x1fe0d3b4), MAD_F(0x1ee8dd47), MAD_F(0x1d007930),
1645*f30ccc91SDavid du Colombier MAD_F(0x1a367e59), MAD_F(0x16a09e66), MAD_F(0x125abcf8),
1646*f30ccc91SDavid du Colombier MAD_F(0x0d8616bc), MAD_F(0x08483ee1), MAD_F(0x02c9fad7)
1647*f30ccc91SDavid du Colombier };
1648*f30ccc91SDavid du Colombier
1649*f30ccc91SDavid du Colombier /* divide the 18-point SDCT-II into two 9-point SDCT-IIs */
1650*f30ccc91SDavid du Colombier
1651*f30ccc91SDavid du Colombier /* even input butterfly */
1652*f30ccc91SDavid du Colombier
1653*f30ccc91SDavid du Colombier for (i = 0; i < 9; i += 3) {
1654*f30ccc91SDavid du Colombier tmp[i + 0] = x[i + 0] + x[18 - (i + 0) - 1];
1655*f30ccc91SDavid du Colombier tmp[i + 1] = x[i + 1] + x[18 - (i + 1) - 1];
1656*f30ccc91SDavid du Colombier tmp[i + 2] = x[i + 2] + x[18 - (i + 2) - 1];
1657*f30ccc91SDavid du Colombier }
1658*f30ccc91SDavid du Colombier
1659*f30ccc91SDavid du Colombier fastsdct(tmp, &X[0]);
1660*f30ccc91SDavid du Colombier
1661*f30ccc91SDavid du Colombier /* odd input butterfly and scaling */
1662*f30ccc91SDavid du Colombier
1663*f30ccc91SDavid du Colombier for (i = 0; i < 9; i += 3) {
1664*f30ccc91SDavid du Colombier tmp[i + 0] = mad_f_mul(x[i + 0] - x[18 - (i + 0) - 1], scale[i + 0]);
1665*f30ccc91SDavid du Colombier tmp[i + 1] = mad_f_mul(x[i + 1] - x[18 - (i + 1) - 1], scale[i + 1]);
1666*f30ccc91SDavid du Colombier tmp[i + 2] = mad_f_mul(x[i + 2] - x[18 - (i + 2) - 1], scale[i + 2]);
1667*f30ccc91SDavid du Colombier }
1668*f30ccc91SDavid du Colombier
1669*f30ccc91SDavid du Colombier fastsdct(tmp, &X[1]);
1670*f30ccc91SDavid du Colombier
1671*f30ccc91SDavid du Colombier /* output accumulation */
1672*f30ccc91SDavid du Colombier
1673*f30ccc91SDavid du Colombier for (i = 3; i < 18; i += 8) {
1674*f30ccc91SDavid du Colombier X[i + 0] -= X[(i + 0) - 2];
1675*f30ccc91SDavid du Colombier X[i + 2] -= X[(i + 2) - 2];
1676*f30ccc91SDavid du Colombier X[i + 4] -= X[(i + 4) - 2];
1677*f30ccc91SDavid du Colombier X[i + 6] -= X[(i + 6) - 2];
16788f5875f3SDavid du Colombier }
16798f5875f3SDavid du Colombier }
1680*f30ccc91SDavid du Colombier
1681*f30ccc91SDavid du Colombier static inline
dctIV(mad_fixed_t const y[18],mad_fixed_t X[18])1682*f30ccc91SDavid du Colombier void dctIV(mad_fixed_t const y[18], mad_fixed_t X[18])
1683*f30ccc91SDavid du Colombier {
1684*f30ccc91SDavid du Colombier mad_fixed_t tmp[18];
1685*f30ccc91SDavid du Colombier int i;
1686*f30ccc91SDavid du Colombier
1687*f30ccc91SDavid du Colombier /* scale[i] = 2 * cos(PI * (2 * i + 1) / (4 * 18)) */
1688*f30ccc91SDavid du Colombier static mad_fixed_t const scale[18] = {
1689*f30ccc91SDavid du Colombier MAD_F(0x1ff833fa), MAD_F(0x1fb9ea93), MAD_F(0x1f3dd120),
1690*f30ccc91SDavid du Colombier MAD_F(0x1e84d969), MAD_F(0x1d906bcf), MAD_F(0x1c62648b),
1691*f30ccc91SDavid du Colombier MAD_F(0x1afd100f), MAD_F(0x1963268b), MAD_F(0x1797c6a4),
1692*f30ccc91SDavid du Colombier MAD_F(0x159e6f5b), MAD_F(0x137af940), MAD_F(0x11318ef3),
1693*f30ccc91SDavid du Colombier MAD_F(0x0ec6a507), MAD_F(0x0c3ef153), MAD_F(0x099f61c5),
1694*f30ccc91SDavid du Colombier MAD_F(0x06ed12c5), MAD_F(0x042d4544), MAD_F(0x0165547c)
1695*f30ccc91SDavid du Colombier };
1696*f30ccc91SDavid du Colombier
1697*f30ccc91SDavid du Colombier /* scaling */
1698*f30ccc91SDavid du Colombier
1699*f30ccc91SDavid du Colombier for (i = 0; i < 18; i += 3) {
1700*f30ccc91SDavid du Colombier tmp[i + 0] = mad_f_mul(y[i + 0], scale[i + 0]);
1701*f30ccc91SDavid du Colombier tmp[i + 1] = mad_f_mul(y[i + 1], scale[i + 1]);
1702*f30ccc91SDavid du Colombier tmp[i + 2] = mad_f_mul(y[i + 2], scale[i + 2]);
1703*f30ccc91SDavid du Colombier }
1704*f30ccc91SDavid du Colombier
1705*f30ccc91SDavid du Colombier /* SDCT-II */
1706*f30ccc91SDavid du Colombier
1707*f30ccc91SDavid du Colombier sdctII(tmp, X);
1708*f30ccc91SDavid du Colombier
1709*f30ccc91SDavid du Colombier /* scale reduction and output accumulation */
1710*f30ccc91SDavid du Colombier
1711*f30ccc91SDavid du Colombier X[0] /= 2;
1712*f30ccc91SDavid du Colombier for (i = 1; i < 17; i += 4) {
1713*f30ccc91SDavid du Colombier X[i + 0] = X[i + 0] / 2 - X[(i + 0) - 1];
1714*f30ccc91SDavid du Colombier X[i + 1] = X[i + 1] / 2 - X[(i + 1) - 1];
1715*f30ccc91SDavid du Colombier X[i + 2] = X[i + 2] / 2 - X[(i + 2) - 1];
1716*f30ccc91SDavid du Colombier X[i + 3] = X[i + 3] / 2 - X[(i + 3) - 1];
1717*f30ccc91SDavid du Colombier }
1718*f30ccc91SDavid du Colombier X[17] = X[17] / 2 - X[16];
17198f5875f3SDavid du Colombier }
17208f5875f3SDavid du Colombier
17218f5875f3SDavid du Colombier /*
1722*f30ccc91SDavid du Colombier * NAME: imdct36
1723*f30ccc91SDavid du Colombier * DESCRIPTION: perform X[18]->x[36] IMDCT using Szu-Wei Lee's fast algorithm
17248f5875f3SDavid du Colombier */
1725*f30ccc91SDavid du Colombier static inline
imdct36(mad_fixed_t const x[18],mad_fixed_t y[36])1726*f30ccc91SDavid du Colombier void imdct36(mad_fixed_t const x[18], mad_fixed_t y[36])
17278f5875f3SDavid du Colombier {
1728*f30ccc91SDavid du Colombier mad_fixed_t tmp[18];
17298f5875f3SDavid du Colombier int i;
1730*f30ccc91SDavid du Colombier
1731*f30ccc91SDavid du Colombier /* DCT-IV */
1732*f30ccc91SDavid du Colombier
1733*f30ccc91SDavid du Colombier dctIV(x, tmp);
1734*f30ccc91SDavid du Colombier
1735*f30ccc91SDavid du Colombier /* convert 18-point DCT-IV to 36-point IMDCT */
1736*f30ccc91SDavid du Colombier
1737*f30ccc91SDavid du Colombier for (i = 0; i < 9; i += 3) {
1738*f30ccc91SDavid du Colombier y[i + 0] = tmp[9 + (i + 0)];
1739*f30ccc91SDavid du Colombier y[i + 1] = tmp[9 + (i + 1)];
1740*f30ccc91SDavid du Colombier y[i + 2] = tmp[9 + (i + 2)];
1741*f30ccc91SDavid du Colombier }
1742*f30ccc91SDavid du Colombier for (i = 9; i < 27; i += 3) {
1743*f30ccc91SDavid du Colombier y[i + 0] = -tmp[36 - (9 + (i + 0)) - 1];
1744*f30ccc91SDavid du Colombier y[i + 1] = -tmp[36 - (9 + (i + 1)) - 1];
1745*f30ccc91SDavid du Colombier y[i + 2] = -tmp[36 - (9 + (i + 2)) - 1];
1746*f30ccc91SDavid du Colombier }
1747*f30ccc91SDavid du Colombier for (i = 27; i < 36; i += 3) {
1748*f30ccc91SDavid du Colombier y[i + 0] = -tmp[(i + 0) - 27];
1749*f30ccc91SDavid du Colombier y[i + 1] = -tmp[(i + 1) - 27];
1750*f30ccc91SDavid du Colombier y[i + 2] = -tmp[(i + 2) - 27];
17518f5875f3SDavid du Colombier }
17528f5875f3SDavid du Colombier }
1753*f30ccc91SDavid du Colombier # else
1754*f30ccc91SDavid du Colombier /*
1755*f30ccc91SDavid du Colombier * NAME: imdct36
1756*f30ccc91SDavid du Colombier * DESCRIPTION: perform X[18]->x[36] IMDCT
1757*f30ccc91SDavid du Colombier */
1758*f30ccc91SDavid du Colombier static inline
imdct36(mad_fixed_t const X[18],mad_fixed_t x[36])1759*f30ccc91SDavid du Colombier void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36])
17608f5875f3SDavid du Colombier {
1761*f30ccc91SDavid du Colombier mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7;
1762*f30ccc91SDavid du Colombier mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15;
1763*f30ccc91SDavid du Colombier register mad_fixed64hi_t hi;
1764*f30ccc91SDavid du Colombier register mad_fixed64lo_t lo;
1765*f30ccc91SDavid du Colombier
1766*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[4], MAD_F(0x0ec835e8));
1767*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[13], MAD_F(0x061f78aa));
1768*f30ccc91SDavid du Colombier
1769*f30ccc91SDavid du Colombier t6 = MAD_F_MLZ(hi, lo);
1770*f30ccc91SDavid du Colombier
1771*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, (t14 = X[1] - X[10]), -MAD_F(0x061f78aa));
1772*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, (t15 = X[7] + X[16]), -MAD_F(0x0ec835e8));
1773*f30ccc91SDavid du Colombier
1774*f30ccc91SDavid du Colombier t0 = MAD_F_MLZ(hi, lo);
1775*f30ccc91SDavid du Colombier
1776*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, (t8 = X[0] - X[11] - X[12]), MAD_F(0x0216a2a2));
1777*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, (t9 = X[2] - X[9] - X[14]), MAD_F(0x09bd7ca0));
1778*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, (t10 = X[3] - X[8] - X[15]), -MAD_F(0x0cb19346));
1779*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, (t11 = X[5] - X[6] - X[17]), -MAD_F(0x0fdcf549));
1780*f30ccc91SDavid du Colombier
1781*f30ccc91SDavid du Colombier x[7] = MAD_F_MLZ(hi, lo);
1782*f30ccc91SDavid du Colombier x[10] = -x[7];
1783*f30ccc91SDavid du Colombier
1784*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, t8, -MAD_F(0x0cb19346));
1785*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t9, MAD_F(0x0fdcf549));
1786*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t10, MAD_F(0x0216a2a2));
1787*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t11, -MAD_F(0x09bd7ca0));
1788*f30ccc91SDavid du Colombier
1789*f30ccc91SDavid du Colombier x[19] = x[34] = MAD_F_MLZ(hi, lo) - t0;
1790*f30ccc91SDavid du Colombier
1791*f30ccc91SDavid du Colombier t12 = X[0] - X[3] + X[8] - X[11] - X[12] + X[15];
1792*f30ccc91SDavid du Colombier t13 = X[2] + X[5] - X[6] - X[9] - X[14] - X[17];
1793*f30ccc91SDavid du Colombier
1794*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, t12, -MAD_F(0x0ec835e8));
1795*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t13, MAD_F(0x061f78aa));
1796*f30ccc91SDavid du Colombier
1797*f30ccc91SDavid du Colombier x[22] = x[31] = MAD_F_MLZ(hi, lo) + t0;
1798*f30ccc91SDavid du Colombier
1799*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[1], -MAD_F(0x09bd7ca0));
1800*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[7], MAD_F(0x0216a2a2));
1801*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[10], -MAD_F(0x0fdcf549));
1802*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[16], MAD_F(0x0cb19346));
1803*f30ccc91SDavid du Colombier
1804*f30ccc91SDavid du Colombier t1 = MAD_F_MLZ(hi, lo) + t6;
1805*f30ccc91SDavid du Colombier
1806*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], MAD_F(0x03768962));
1807*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], MAD_F(0x0e313245));
1808*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0ffc19fd));
1809*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0acf37ad));
1810*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], MAD_F(0x04cfb0e2));
1811*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0898c779));
1812*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], MAD_F(0x0d7e8807));
1813*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f426cb5));
1814*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0bcbe352));
1815*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], MAD_F(0x00b2aa3e));
1816*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], -MAD_F(0x07635284));
1817*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0f9ee890));
1818*f30ccc91SDavid du Colombier
1819*f30ccc91SDavid du Colombier x[6] = MAD_F_MLZ(hi, lo) + t1;
1820*f30ccc91SDavid du Colombier x[11] = -x[6];
1821*f30ccc91SDavid du Colombier
1822*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f426cb5));
1823*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], -MAD_F(0x00b2aa3e));
1824*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], MAD_F(0x0898c779));
1825*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], MAD_F(0x0f9ee890));
1826*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], MAD_F(0x0acf37ad));
1827*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], -MAD_F(0x07635284));
1828*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0e313245));
1829*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0bcbe352));
1830*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], -MAD_F(0x03768962));
1831*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], MAD_F(0x0d7e8807));
1832*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], MAD_F(0x0ffc19fd));
1833*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], MAD_F(0x04cfb0e2));
1834*f30ccc91SDavid du Colombier
1835*f30ccc91SDavid du Colombier x[23] = x[30] = MAD_F_MLZ(hi, lo) + t1;
1836*f30ccc91SDavid du Colombier
1837*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0bcbe352));
1838*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], MAD_F(0x0d7e8807));
1839*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], -MAD_F(0x07635284));
1840*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], MAD_F(0x04cfb0e2));
1841*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f9ee890));
1842*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0ffc19fd));
1843*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], -MAD_F(0x00b2aa3e));
1844*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], MAD_F(0x03768962));
1845*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0f426cb5));
1846*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], MAD_F(0x0e313245));
1847*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], MAD_F(0x0898c779));
1848*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0acf37ad));
1849*f30ccc91SDavid du Colombier
1850*f30ccc91SDavid du Colombier x[18] = x[35] = MAD_F_MLZ(hi, lo) - t1;
1851*f30ccc91SDavid du Colombier
1852*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[4], MAD_F(0x061f78aa));
1853*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[13], -MAD_F(0x0ec835e8));
1854*f30ccc91SDavid du Colombier
1855*f30ccc91SDavid du Colombier t7 = MAD_F_MLZ(hi, lo);
1856*f30ccc91SDavid du Colombier
1857*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[1], -MAD_F(0x0cb19346));
1858*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[7], MAD_F(0x0fdcf549));
1859*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[10], MAD_F(0x0216a2a2));
1860*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[16], -MAD_F(0x09bd7ca0));
1861*f30ccc91SDavid du Colombier
1862*f30ccc91SDavid du Colombier t2 = MAD_F_MLZ(hi, lo);
1863*f30ccc91SDavid du Colombier
1864*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[0], MAD_F(0x04cfb0e2));
1865*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], MAD_F(0x0ffc19fd));
1866*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0d7e8807));
1867*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], MAD_F(0x03768962));
1868*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0bcbe352));
1869*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0e313245));
1870*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], MAD_F(0x07635284));
1871*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0acf37ad));
1872*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], MAD_F(0x0f9ee890));
1873*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], MAD_F(0x0898c779));
1874*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], MAD_F(0x00b2aa3e));
1875*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], MAD_F(0x0f426cb5));
1876*f30ccc91SDavid du Colombier
1877*f30ccc91SDavid du Colombier x[5] = MAD_F_MLZ(hi, lo);
1878*f30ccc91SDavid du Colombier x[12] = -x[5];
1879*f30ccc91SDavid du Colombier
1880*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], MAD_F(0x0acf37ad));
1881*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0898c779));
1882*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], MAD_F(0x0e313245));
1883*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0f426cb5));
1884*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], -MAD_F(0x03768962));
1885*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], MAD_F(0x00b2aa3e));
1886*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0ffc19fd));
1887*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f9ee890));
1888*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], -MAD_F(0x04cfb0e2));
1889*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], MAD_F(0x07635284));
1890*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], MAD_F(0x0d7e8807));
1891*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0bcbe352));
1892*f30ccc91SDavid du Colombier
1893*f30ccc91SDavid du Colombier x[0] = MAD_F_MLZ(hi, lo) + t2;
1894*f30ccc91SDavid du Colombier x[17] = -x[0];
1895*f30ccc91SDavid du Colombier
1896*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f9ee890));
1897*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], -MAD_F(0x07635284));
1898*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], -MAD_F(0x00b2aa3e));
1899*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], MAD_F(0x0bcbe352));
1900*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f426cb5));
1901*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], MAD_F(0x0d7e8807));
1902*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], MAD_F(0x0898c779));
1903*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], -MAD_F(0x04cfb0e2));
1904*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0acf37ad));
1905*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0ffc19fd));
1906*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0e313245));
1907*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], -MAD_F(0x03768962));
1908*f30ccc91SDavid du Colombier
1909*f30ccc91SDavid du Colombier x[24] = x[29] = MAD_F_MLZ(hi, lo) + t2;
1910*f30ccc91SDavid du Colombier
1911*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0216a2a2));
1912*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[7], -MAD_F(0x09bd7ca0));
1913*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[10], MAD_F(0x0cb19346));
1914*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[16], MAD_F(0x0fdcf549));
1915*f30ccc91SDavid du Colombier
1916*f30ccc91SDavid du Colombier t3 = MAD_F_MLZ(hi, lo) + t7;
1917*f30ccc91SDavid du Colombier
1918*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], MAD_F(0x00b2aa3e));
1919*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], MAD_F(0x03768962));
1920*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], -MAD_F(0x04cfb0e2));
1921*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], -MAD_F(0x07635284));
1922*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], MAD_F(0x0898c779));
1923*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], MAD_F(0x0acf37ad));
1924*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0bcbe352));
1925*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0d7e8807));
1926*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], MAD_F(0x0e313245));
1927*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f426cb5));
1928*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0f9ee890));
1929*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0ffc19fd));
1930*f30ccc91SDavid du Colombier
1931*f30ccc91SDavid du Colombier x[8] = MAD_F_MLZ(hi, lo) + t3;
1932*f30ccc91SDavid du Colombier x[9] = -x[8];
1933*f30ccc91SDavid du Colombier
1934*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0e313245));
1935*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], MAD_F(0x0bcbe352));
1936*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], MAD_F(0x0f9ee890));
1937*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0898c779));
1938*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0ffc19fd));
1939*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], MAD_F(0x04cfb0e2));
1940*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f426cb5));
1941*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], -MAD_F(0x00b2aa3e));
1942*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0d7e8807));
1943*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], -MAD_F(0x03768962));
1944*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], MAD_F(0x0acf37ad));
1945*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], MAD_F(0x07635284));
1946*f30ccc91SDavid du Colombier
1947*f30ccc91SDavid du Colombier x[21] = x[32] = MAD_F_MLZ(hi, lo) + t3;
1948*f30ccc91SDavid du Colombier
1949*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0d7e8807));
1950*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], MAD_F(0x0f426cb5));
1951*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], MAD_F(0x0acf37ad));
1952*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0ffc19fd));
1953*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], -MAD_F(0x07635284));
1954*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f9ee890));
1955*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], MAD_F(0x03768962));
1956*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0e313245));
1957*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], MAD_F(0x00b2aa3e));
1958*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], MAD_F(0x0bcbe352));
1959*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], -MAD_F(0x04cfb0e2));
1960*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0898c779));
1961*f30ccc91SDavid du Colombier
1962*f30ccc91SDavid du Colombier x[20] = x[33] = MAD_F_MLZ(hi, lo) - t3;
1963*f30ccc91SDavid du Colombier
1964*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, t14, -MAD_F(0x0ec835e8));
1965*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t15, MAD_F(0x061f78aa));
1966*f30ccc91SDavid du Colombier
1967*f30ccc91SDavid du Colombier t4 = MAD_F_MLZ(hi, lo) - t7;
1968*f30ccc91SDavid du Colombier
1969*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, t12, MAD_F(0x061f78aa));
1970*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t13, MAD_F(0x0ec835e8));
1971*f30ccc91SDavid du Colombier
1972*f30ccc91SDavid du Colombier x[4] = MAD_F_MLZ(hi, lo) + t4;
1973*f30ccc91SDavid du Colombier x[13] = -x[4];
1974*f30ccc91SDavid du Colombier
1975*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, t8, MAD_F(0x09bd7ca0));
1976*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t9, -MAD_F(0x0216a2a2));
1977*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t10, MAD_F(0x0fdcf549));
1978*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t11, -MAD_F(0x0cb19346));
1979*f30ccc91SDavid du Colombier
1980*f30ccc91SDavid du Colombier x[1] = MAD_F_MLZ(hi, lo) + t4;
1981*f30ccc91SDavid du Colombier x[16] = -x[1];
1982*f30ccc91SDavid du Colombier
1983*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, t8, -MAD_F(0x0fdcf549));
1984*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t9, -MAD_F(0x0cb19346));
1985*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t10, -MAD_F(0x09bd7ca0));
1986*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, t11, -MAD_F(0x0216a2a2));
1987*f30ccc91SDavid du Colombier
1988*f30ccc91SDavid du Colombier x[25] = x[28] = MAD_F_MLZ(hi, lo) + t4;
1989*f30ccc91SDavid du Colombier
1990*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0fdcf549));
1991*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[7], -MAD_F(0x0cb19346));
1992*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[10], -MAD_F(0x09bd7ca0));
1993*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[16], -MAD_F(0x0216a2a2));
1994*f30ccc91SDavid du Colombier
1995*f30ccc91SDavid du Colombier t5 = MAD_F_MLZ(hi, lo) - t6;
1996*f30ccc91SDavid du Colombier
1997*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], MAD_F(0x0898c779));
1998*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], MAD_F(0x04cfb0e2));
1999*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], MAD_F(0x0bcbe352));
2000*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], MAD_F(0x00b2aa3e));
2001*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], MAD_F(0x0e313245));
2002*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], -MAD_F(0x03768962));
2003*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f9ee890));
2004*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], -MAD_F(0x07635284));
2005*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], MAD_F(0x0ffc19fd));
2006*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0acf37ad));
2007*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], MAD_F(0x0f426cb5));
2008*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0d7e8807));
2009*f30ccc91SDavid du Colombier
2010*f30ccc91SDavid du Colombier x[2] = MAD_F_MLZ(hi, lo) + t5;
2011*f30ccc91SDavid du Colombier x[15] = -x[2];
2012*f30ccc91SDavid du Colombier
2013*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], MAD_F(0x07635284));
2014*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], MAD_F(0x0acf37ad));
2015*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], MAD_F(0x03768962));
2016*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], MAD_F(0x0d7e8807));
2017*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], -MAD_F(0x00b2aa3e));
2018*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f426cb5));
2019*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], -MAD_F(0x04cfb0e2));
2020*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], MAD_F(0x0ffc19fd));
2021*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0898c779));
2022*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f9ee890));
2023*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0bcbe352));
2024*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], MAD_F(0x0e313245));
2025*f30ccc91SDavid du Colombier
2026*f30ccc91SDavid du Colombier x[3] = MAD_F_MLZ(hi, lo) + t5;
2027*f30ccc91SDavid du Colombier x[14] = -x[3];
2028*f30ccc91SDavid du Colombier
2029*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0ffc19fd));
2030*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0f9ee890));
2031*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0f426cb5));
2032*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0e313245));
2033*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0d7e8807));
2034*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0bcbe352));
2035*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0acf37ad));
2036*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0898c779));
2037*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[12], -MAD_F(0x07635284));
2038*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[14], -MAD_F(0x04cfb0e2));
2039*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[15], -MAD_F(0x03768962));
2040*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[17], -MAD_F(0x00b2aa3e));
2041*f30ccc91SDavid du Colombier
2042*f30ccc91SDavid du Colombier x[26] = x[27] = MAD_F_MLZ(hi, lo) + t5;
20438f5875f3SDavid du Colombier }
2044*f30ccc91SDavid du Colombier # endif
2045*f30ccc91SDavid du Colombier
2046*f30ccc91SDavid du Colombier /*
2047*f30ccc91SDavid du Colombier * NAME: III_imdct_l()
2048*f30ccc91SDavid du Colombier * DESCRIPTION: perform IMDCT and windowing for long blocks
2049*f30ccc91SDavid du Colombier */
2050*f30ccc91SDavid du Colombier static
III_imdct_l(mad_fixed_t const X[18],mad_fixed_t z[36],unsigned int block_type)2051*f30ccc91SDavid du Colombier void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36],
2052*f30ccc91SDavid du Colombier unsigned int block_type)
2053*f30ccc91SDavid du Colombier {
2054*f30ccc91SDavid du Colombier unsigned int i;
2055*f30ccc91SDavid du Colombier
2056*f30ccc91SDavid du Colombier /* IMDCT */
2057*f30ccc91SDavid du Colombier
2058*f30ccc91SDavid du Colombier imdct36(X, z);
2059*f30ccc91SDavid du Colombier
2060*f30ccc91SDavid du Colombier /* windowing */
2061*f30ccc91SDavid du Colombier
2062*f30ccc91SDavid du Colombier switch (block_type) {
2063*f30ccc91SDavid du Colombier case 0: /* normal window */
2064*f30ccc91SDavid du Colombier # if defined(ASO_INTERLEAVE1)
2065*f30ccc91SDavid du Colombier {
2066*f30ccc91SDavid du Colombier register mad_fixed_t tmp1, tmp2;
2067*f30ccc91SDavid du Colombier
2068*f30ccc91SDavid du Colombier tmp1 = window_l[0];
2069*f30ccc91SDavid du Colombier tmp2 = window_l[1];
2070*f30ccc91SDavid du Colombier
2071*f30ccc91SDavid du Colombier for (i = 0; i < 34; i += 2) {
2072*f30ccc91SDavid du Colombier z[i + 0] = mad_f_mul(z[i + 0], tmp1);
2073*f30ccc91SDavid du Colombier tmp1 = window_l[i + 2];
2074*f30ccc91SDavid du Colombier z[i + 1] = mad_f_mul(z[i + 1], tmp2);
2075*f30ccc91SDavid du Colombier tmp2 = window_l[i + 3];
2076*f30ccc91SDavid du Colombier }
2077*f30ccc91SDavid du Colombier
2078*f30ccc91SDavid du Colombier z[34] = mad_f_mul(z[34], tmp1);
2079*f30ccc91SDavid du Colombier z[35] = mad_f_mul(z[35], tmp2);
2080*f30ccc91SDavid du Colombier }
2081*f30ccc91SDavid du Colombier # elif defined(ASO_INTERLEAVE2)
2082*f30ccc91SDavid du Colombier {
2083*f30ccc91SDavid du Colombier register mad_fixed_t tmp1, tmp2;
2084*f30ccc91SDavid du Colombier
2085*f30ccc91SDavid du Colombier tmp1 = z[0];
2086*f30ccc91SDavid du Colombier tmp2 = window_l[0];
2087*f30ccc91SDavid du Colombier
2088*f30ccc91SDavid du Colombier for (i = 0; i < 35; ++i) {
2089*f30ccc91SDavid du Colombier z[i] = mad_f_mul(tmp1, tmp2);
2090*f30ccc91SDavid du Colombier tmp1 = z[i + 1];
2091*f30ccc91SDavid du Colombier tmp2 = window_l[i + 1];
2092*f30ccc91SDavid du Colombier }
2093*f30ccc91SDavid du Colombier
2094*f30ccc91SDavid du Colombier z[35] = mad_f_mul(tmp1, tmp2);
2095*f30ccc91SDavid du Colombier }
2096*f30ccc91SDavid du Colombier # elif 1
2097*f30ccc91SDavid du Colombier for (i = 0; i < 36; i += 4) {
2098*f30ccc91SDavid du Colombier z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
2099*f30ccc91SDavid du Colombier z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
2100*f30ccc91SDavid du Colombier z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
2101*f30ccc91SDavid du Colombier z[i + 3] = mad_f_mul(z[i + 3], window_l[i + 3]);
2102*f30ccc91SDavid du Colombier }
2103*f30ccc91SDavid du Colombier # else
2104*f30ccc91SDavid du Colombier for (i = 0; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
2105*f30ccc91SDavid du Colombier # endif
21068f5875f3SDavid du Colombier break;
2107*f30ccc91SDavid du Colombier
2108*f30ccc91SDavid du Colombier case 1: /* start block */
2109*f30ccc91SDavid du Colombier for (i = 0; i < 18; i += 3) {
2110*f30ccc91SDavid du Colombier z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
2111*f30ccc91SDavid du Colombier z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
2112*f30ccc91SDavid du Colombier z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
2113*f30ccc91SDavid du Colombier }
2114*f30ccc91SDavid du Colombier /* (i = 18; i < 24; ++i) z[i] unchanged */
2115*f30ccc91SDavid du Colombier for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s[i - 18]);
2116*f30ccc91SDavid du Colombier for (i = 30; i < 36; ++i) z[i] = 0;
2117*f30ccc91SDavid du Colombier break;
2118*f30ccc91SDavid du Colombier
2119*f30ccc91SDavid du Colombier case 3: /* stop block */
2120*f30ccc91SDavid du Colombier for (i = 0; i < 6; ++i) z[i] = 0;
2121*f30ccc91SDavid du Colombier for (i = 6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s[i - 6]);
2122*f30ccc91SDavid du Colombier /* (i = 12; i < 18; ++i) z[i] unchanged */
2123*f30ccc91SDavid du Colombier for (i = 18; i < 36; i += 3) {
2124*f30ccc91SDavid du Colombier z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
2125*f30ccc91SDavid du Colombier z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
2126*f30ccc91SDavid du Colombier z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
21278f5875f3SDavid du Colombier }
21288f5875f3SDavid du Colombier break;
21298f5875f3SDavid du Colombier }
21308f5875f3SDavid du Colombier }
2131*f30ccc91SDavid du Colombier # endif /* ASO_IMDCT */
21328f5875f3SDavid du Colombier
2133*f30ccc91SDavid du Colombier /*
2134*f30ccc91SDavid du Colombier * NAME: III_imdct_s()
2135*f30ccc91SDavid du Colombier * DESCRIPTION: perform IMDCT and windowing for short blocks
2136*f30ccc91SDavid du Colombier */
2137*f30ccc91SDavid du Colombier static
III_imdct_s(mad_fixed_t const X[18],mad_fixed_t z[36])2138*f30ccc91SDavid du Colombier void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])
2139*f30ccc91SDavid du Colombier {
2140*f30ccc91SDavid du Colombier mad_fixed_t y[36], *yptr;
2141*f30ccc91SDavid du Colombier mad_fixed_t const *wptr;
2142*f30ccc91SDavid du Colombier int w, i;
2143*f30ccc91SDavid du Colombier register mad_fixed64hi_t hi;
2144*f30ccc91SDavid du Colombier register mad_fixed64lo_t lo;
2145*f30ccc91SDavid du Colombier
2146*f30ccc91SDavid du Colombier /* IMDCT */
2147*f30ccc91SDavid du Colombier
2148*f30ccc91SDavid du Colombier yptr = &y[0];
2149*f30ccc91SDavid du Colombier
2150*f30ccc91SDavid du Colombier for (w = 0; w < 3; ++w) {
2151*f30ccc91SDavid du Colombier register mad_fixed_t const (*s)[6];
2152*f30ccc91SDavid du Colombier
2153*f30ccc91SDavid du Colombier s = imdct_s;
2154*f30ccc91SDavid du Colombier
2155*f30ccc91SDavid du Colombier for (i = 0; i < 3; ++i) {
2156*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], (*s)[0]);
2157*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[1], (*s)[1]);
2158*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], (*s)[2]);
2159*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], (*s)[3]);
2160*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[4], (*s)[4]);
2161*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], (*s)[5]);
2162*f30ccc91SDavid du Colombier
2163*f30ccc91SDavid du Colombier yptr[i + 0] = MAD_F_MLZ(hi, lo);
2164*f30ccc91SDavid du Colombier yptr[5 - i] = -yptr[i + 0];
2165*f30ccc91SDavid du Colombier
2166*f30ccc91SDavid du Colombier ++s;
2167*f30ccc91SDavid du Colombier
2168*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, X[0], (*s)[0]);
2169*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[1], (*s)[1]);
2170*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[2], (*s)[2]);
2171*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[3], (*s)[3]);
2172*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[4], (*s)[4]);
2173*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, X[5], (*s)[5]);
2174*f30ccc91SDavid du Colombier
2175*f30ccc91SDavid du Colombier yptr[ i + 6] = MAD_F_MLZ(hi, lo);
2176*f30ccc91SDavid du Colombier yptr[11 - i] = yptr[i + 6];
2177*f30ccc91SDavid du Colombier
2178*f30ccc91SDavid du Colombier ++s;
21798f5875f3SDavid du Colombier }
21808f5875f3SDavid du Colombier
2181*f30ccc91SDavid du Colombier yptr += 12;
2182*f30ccc91SDavid du Colombier X += 6;
2183*f30ccc91SDavid du Colombier }
2184*f30ccc91SDavid du Colombier
2185*f30ccc91SDavid du Colombier /* windowing, overlapping and concatenation */
2186*f30ccc91SDavid du Colombier
2187*f30ccc91SDavid du Colombier yptr = &y[0];
2188*f30ccc91SDavid du Colombier wptr = &window_s[0];
2189*f30ccc91SDavid du Colombier
2190*f30ccc91SDavid du Colombier for (i = 0; i < 6; ++i) {
2191*f30ccc91SDavid du Colombier z[i + 0] = 0;
2192*f30ccc91SDavid du Colombier z[i + 6] = mad_f_mul(yptr[ 0 + 0], wptr[0]);
2193*f30ccc91SDavid du Colombier
2194*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, yptr[ 0 + 6], wptr[6]);
2195*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, yptr[12 + 0], wptr[0]);
2196*f30ccc91SDavid du Colombier
2197*f30ccc91SDavid du Colombier z[i + 12] = MAD_F_MLZ(hi, lo);
2198*f30ccc91SDavid du Colombier
2199*f30ccc91SDavid du Colombier MAD_F_ML0(hi, lo, yptr[12 + 6], wptr[6]);
2200*f30ccc91SDavid du Colombier MAD_F_MLA(hi, lo, yptr[24 + 0], wptr[0]);
2201*f30ccc91SDavid du Colombier
2202*f30ccc91SDavid du Colombier z[i + 18] = MAD_F_MLZ(hi, lo);
2203*f30ccc91SDavid du Colombier
2204*f30ccc91SDavid du Colombier z[i + 24] = mad_f_mul(yptr[24 + 6], wptr[6]);
2205*f30ccc91SDavid du Colombier z[i + 30] = 0;
2206*f30ccc91SDavid du Colombier
2207*f30ccc91SDavid du Colombier ++yptr;
2208*f30ccc91SDavid du Colombier ++wptr;
2209*f30ccc91SDavid du Colombier }
2210*f30ccc91SDavid du Colombier }
2211*f30ccc91SDavid du Colombier
2212*f30ccc91SDavid du Colombier /*
2213*f30ccc91SDavid du Colombier * NAME: III_overlap()
2214*f30ccc91SDavid du Colombier * DESCRIPTION: perform overlap-add of windowed IMDCT outputs
2215*f30ccc91SDavid du Colombier */
2216*f30ccc91SDavid du Colombier static
III_overlap(mad_fixed_t const output[36],mad_fixed_t overlap[18],mad_fixed_t sample[18][32],unsigned int sb)2217*f30ccc91SDavid du Colombier void III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18],
2218*f30ccc91SDavid du Colombier mad_fixed_t sample[18][32], unsigned int sb)
2219*f30ccc91SDavid du Colombier {
2220*f30ccc91SDavid du Colombier unsigned int i;
2221*f30ccc91SDavid du Colombier
2222*f30ccc91SDavid du Colombier # if defined(ASO_INTERLEAVE2)
2223*f30ccc91SDavid du Colombier {
2224*f30ccc91SDavid du Colombier register mad_fixed_t tmp1, tmp2;
2225*f30ccc91SDavid du Colombier
2226*f30ccc91SDavid du Colombier tmp1 = overlap[0];
2227*f30ccc91SDavid du Colombier tmp2 = overlap[1];
2228*f30ccc91SDavid du Colombier
2229*f30ccc91SDavid du Colombier for (i = 0; i < 16; i += 2) {
2230*f30ccc91SDavid du Colombier sample[i + 0][sb] = output[i + 0 + 0] + tmp1;
2231*f30ccc91SDavid du Colombier overlap[i + 0] = output[i + 0 + 18];
2232*f30ccc91SDavid du Colombier tmp1 = overlap[i + 2];
2233*f30ccc91SDavid du Colombier
2234*f30ccc91SDavid du Colombier sample[i + 1][sb] = output[i + 1 + 0] + tmp2;
2235*f30ccc91SDavid du Colombier overlap[i + 1] = output[i + 1 + 18];
2236*f30ccc91SDavid du Colombier tmp2 = overlap[i + 3];
2237*f30ccc91SDavid du Colombier }
2238*f30ccc91SDavid du Colombier
2239*f30ccc91SDavid du Colombier sample[16][sb] = output[16 + 0] + tmp1;
2240*f30ccc91SDavid du Colombier overlap[16] = output[16 + 18];
2241*f30ccc91SDavid du Colombier sample[17][sb] = output[17 + 0] + tmp2;
2242*f30ccc91SDavid du Colombier overlap[17] = output[17 + 18];
2243*f30ccc91SDavid du Colombier }
2244*f30ccc91SDavid du Colombier # elif 0
2245*f30ccc91SDavid du Colombier for (i = 0; i < 18; i += 2) {
2246*f30ccc91SDavid du Colombier sample[i + 0][sb] = output[i + 0 + 0] + overlap[i + 0];
2247*f30ccc91SDavid du Colombier overlap[i + 0] = output[i + 0 + 18];
2248*f30ccc91SDavid du Colombier
2249*f30ccc91SDavid du Colombier sample[i + 1][sb] = output[i + 1 + 0] + overlap[i + 1];
2250*f30ccc91SDavid du Colombier overlap[i + 1] = output[i + 1 + 18];
2251*f30ccc91SDavid du Colombier }
2252*f30ccc91SDavid du Colombier # else
2253*f30ccc91SDavid du Colombier for (i = 0; i < 18; ++i) {
2254*f30ccc91SDavid du Colombier sample[i][sb] = output[i + 0] + overlap[i];
2255*f30ccc91SDavid du Colombier overlap[i] = output[i + 18];
2256*f30ccc91SDavid du Colombier }
22578f5875f3SDavid du Colombier # endif
2258*f30ccc91SDavid du Colombier }
2259*f30ccc91SDavid du Colombier
2260*f30ccc91SDavid du Colombier /*
2261*f30ccc91SDavid du Colombier * NAME: III_overlap_z()
2262*f30ccc91SDavid du Colombier * DESCRIPTION: perform "overlap-add" of zero IMDCT outputs
2263*f30ccc91SDavid du Colombier */
2264*f30ccc91SDavid du Colombier static inline
III_overlap_z(mad_fixed_t overlap[18],mad_fixed_t sample[18][32],unsigned int sb)2265*f30ccc91SDavid du Colombier void III_overlap_z(mad_fixed_t overlap[18],
2266*f30ccc91SDavid du Colombier mad_fixed_t sample[18][32], unsigned int sb)
2267*f30ccc91SDavid du Colombier {
2268*f30ccc91SDavid du Colombier unsigned int i;
2269*f30ccc91SDavid du Colombier
2270*f30ccc91SDavid du Colombier # if defined(ASO_INTERLEAVE2)
2271*f30ccc91SDavid du Colombier {
2272*f30ccc91SDavid du Colombier register mad_fixed_t tmp1, tmp2;
2273*f30ccc91SDavid du Colombier
2274*f30ccc91SDavid du Colombier tmp1 = overlap[0];
2275*f30ccc91SDavid du Colombier tmp2 = overlap[1];
2276*f30ccc91SDavid du Colombier
2277*f30ccc91SDavid du Colombier for (i = 0; i < 16; i += 2) {
2278*f30ccc91SDavid du Colombier sample[i + 0][sb] = tmp1;
2279*f30ccc91SDavid du Colombier overlap[i + 0] = 0;
2280*f30ccc91SDavid du Colombier tmp1 = overlap[i + 2];
2281*f30ccc91SDavid du Colombier
2282*f30ccc91SDavid du Colombier sample[i + 1][sb] = tmp2;
2283*f30ccc91SDavid du Colombier overlap[i + 1] = 0;
2284*f30ccc91SDavid du Colombier tmp2 = overlap[i + 3];
2285*f30ccc91SDavid du Colombier }
2286*f30ccc91SDavid du Colombier
2287*f30ccc91SDavid du Colombier sample[16][sb] = tmp1;
2288*f30ccc91SDavid du Colombier overlap[16] = 0;
2289*f30ccc91SDavid du Colombier sample[17][sb] = tmp2;
2290*f30ccc91SDavid du Colombier overlap[17] = 0;
2291*f30ccc91SDavid du Colombier }
2292*f30ccc91SDavid du Colombier # else
2293*f30ccc91SDavid du Colombier for (i = 0; i < 18; ++i) {
2294*f30ccc91SDavid du Colombier sample[i][sb] = overlap[i];
2295*f30ccc91SDavid du Colombier overlap[i] = 0;
2296*f30ccc91SDavid du Colombier }
2297*f30ccc91SDavid du Colombier # endif
2298*f30ccc91SDavid du Colombier }
2299*f30ccc91SDavid du Colombier
2300*f30ccc91SDavid du Colombier /*
2301*f30ccc91SDavid du Colombier * NAME: III_freqinver()
2302*f30ccc91SDavid du Colombier * DESCRIPTION: perform subband frequency inversion for odd sample lines
2303*f30ccc91SDavid du Colombier */
2304*f30ccc91SDavid du Colombier static
III_freqinver(mad_fixed_t sample[18][32],unsigned int sb)2305*f30ccc91SDavid du Colombier void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb)
2306*f30ccc91SDavid du Colombier {
2307*f30ccc91SDavid du Colombier unsigned int i;
2308*f30ccc91SDavid du Colombier
2309*f30ccc91SDavid du Colombier # if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2)
2310*f30ccc91SDavid du Colombier {
2311*f30ccc91SDavid du Colombier register mad_fixed_t tmp1, tmp2;
2312*f30ccc91SDavid du Colombier
2313*f30ccc91SDavid du Colombier tmp1 = sample[1][sb];
2314*f30ccc91SDavid du Colombier tmp2 = sample[3][sb];
2315*f30ccc91SDavid du Colombier
2316*f30ccc91SDavid du Colombier for (i = 1; i < 13; i += 4) {
2317*f30ccc91SDavid du Colombier sample[i + 0][sb] = -tmp1;
2318*f30ccc91SDavid du Colombier tmp1 = sample[i + 4][sb];
2319*f30ccc91SDavid du Colombier sample[i + 2][sb] = -tmp2;
2320*f30ccc91SDavid du Colombier tmp2 = sample[i + 6][sb];
2321*f30ccc91SDavid du Colombier }
2322*f30ccc91SDavid du Colombier
2323*f30ccc91SDavid du Colombier sample[13][sb] = -tmp1;
2324*f30ccc91SDavid du Colombier tmp1 = sample[17][sb];
2325*f30ccc91SDavid du Colombier sample[15][sb] = -tmp2;
2326*f30ccc91SDavid du Colombier sample[17][sb] = -tmp1;
2327*f30ccc91SDavid du Colombier }
2328*f30ccc91SDavid du Colombier # else
2329*f30ccc91SDavid du Colombier for (i = 1; i < 18; i += 2)
2330*f30ccc91SDavid du Colombier sample[i][sb] = -sample[i][sb];
2331*f30ccc91SDavid du Colombier # endif
2332*f30ccc91SDavid du Colombier }
2333*f30ccc91SDavid du Colombier
2334*f30ccc91SDavid du Colombier /*
2335*f30ccc91SDavid du Colombier * NAME: III_decode()
2336*f30ccc91SDavid du Colombier * DESCRIPTION: decode frame main_data
2337*f30ccc91SDavid du Colombier */
2338*f30ccc91SDavid du Colombier static
III_decode(struct mad_bitptr * ptr,struct mad_frame * frame,struct sideinfo * si,unsigned int nch)2339*f30ccc91SDavid du Colombier enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame,
2340*f30ccc91SDavid du Colombier struct sideinfo *si, unsigned int nch)
2341*f30ccc91SDavid du Colombier {
2342*f30ccc91SDavid du Colombier struct mad_header *header = &frame->header;
2343*f30ccc91SDavid du Colombier unsigned int sfreqi, ngr, gr;
2344*f30ccc91SDavid du Colombier
2345*f30ccc91SDavid du Colombier {
2346*f30ccc91SDavid du Colombier unsigned int sfreq;
2347*f30ccc91SDavid du Colombier
2348*f30ccc91SDavid du Colombier sfreq = header->samplerate;
2349*f30ccc91SDavid du Colombier if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
2350*f30ccc91SDavid du Colombier sfreq *= 2;
2351*f30ccc91SDavid du Colombier
2352*f30ccc91SDavid du Colombier /* 48000 => 0, 44100 => 1, 32000 => 2,
2353*f30ccc91SDavid du Colombier 24000 => 3, 22050 => 4, 16000 => 5 */
2354*f30ccc91SDavid du Colombier sfreqi = ((sfreq >> 7) & 0x000f) +
2355*f30ccc91SDavid du Colombier ((sfreq >> 15) & 0x0001) - 8;
2356*f30ccc91SDavid du Colombier
2357*f30ccc91SDavid du Colombier if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
2358*f30ccc91SDavid du Colombier sfreqi += 3;
2359*f30ccc91SDavid du Colombier }
2360*f30ccc91SDavid du Colombier
2361*f30ccc91SDavid du Colombier /* scalefactors, Huffman decoding, requantization */
2362*f30ccc91SDavid du Colombier
2363*f30ccc91SDavid du Colombier ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2;
2364*f30ccc91SDavid du Colombier
2365*f30ccc91SDavid du Colombier for (gr = 0; gr < ngr; ++gr) {
2366*f30ccc91SDavid du Colombier struct granule *granule = &si->gr[gr];
2367*f30ccc91SDavid du Colombier unsigned char const *sfbwidth[2];
2368*f30ccc91SDavid du Colombier mad_fixed_t xr[2][576];
2369*f30ccc91SDavid du Colombier unsigned int ch;
2370*f30ccc91SDavid du Colombier enum mad_error error;
2371*f30ccc91SDavid du Colombier
2372*f30ccc91SDavid du Colombier for (ch = 0; ch < nch; ++ch) {
2373*f30ccc91SDavid du Colombier struct channel *channel = &granule->ch[ch];
2374*f30ccc91SDavid du Colombier unsigned int part2_length;
2375*f30ccc91SDavid du Colombier
2376*f30ccc91SDavid du Colombier sfbwidth[ch] = sfbwidth_table[sfreqi].l;
2377*f30ccc91SDavid du Colombier if (channel->block_type == 2) {
2378*f30ccc91SDavid du Colombier sfbwidth[ch] = (channel->flags & mixed_block_flag) ?
2379*f30ccc91SDavid du Colombier sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s;
2380*f30ccc91SDavid du Colombier }
2381*f30ccc91SDavid du Colombier
2382*f30ccc91SDavid du Colombier if (header->flags & MAD_FLAG_LSF_EXT) {
2383*f30ccc91SDavid du Colombier part2_length = III_scalefactors_lsf(ptr, channel,
2384*f30ccc91SDavid du Colombier ch == 0 ? 0 : &si->gr[1].ch[1],
2385*f30ccc91SDavid du Colombier header->mode_extension);
23868f5875f3SDavid du Colombier }
23878f5875f3SDavid du Colombier else {
2388*f30ccc91SDavid du Colombier part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch],
2389*f30ccc91SDavid du Colombier gr == 0 ? 0 : si->scfsi[ch]);
23908f5875f3SDavid du Colombier }
23918f5875f3SDavid du Colombier
2392*f30ccc91SDavid du Colombier error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length);
2393*f30ccc91SDavid du Colombier if (error)
2394*f30ccc91SDavid du Colombier return error;
2395*f30ccc91SDavid du Colombier }
2396*f30ccc91SDavid du Colombier
2397*f30ccc91SDavid du Colombier /* joint stereo processing */
2398*f30ccc91SDavid du Colombier
2399*f30ccc91SDavid du Colombier if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) {
2400*f30ccc91SDavid du Colombier error = III_stereo(xr, granule, header, sfbwidth[0]);
2401*f30ccc91SDavid du Colombier if (error)
2402*f30ccc91SDavid du Colombier return error;
2403*f30ccc91SDavid du Colombier }
2404*f30ccc91SDavid du Colombier
2405*f30ccc91SDavid du Colombier /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */
2406*f30ccc91SDavid du Colombier
2407*f30ccc91SDavid du Colombier for (ch = 0; ch < nch; ++ch) {
2408*f30ccc91SDavid du Colombier struct channel const *channel = &granule->ch[ch];
2409*f30ccc91SDavid du Colombier mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr];
2410*f30ccc91SDavid du Colombier unsigned int sb, l, i, sblimit;
2411*f30ccc91SDavid du Colombier mad_fixed_t output[36];
2412*f30ccc91SDavid du Colombier
2413*f30ccc91SDavid du Colombier if (channel->block_type == 2) {
2414*f30ccc91SDavid du Colombier III_reorder(xr[ch], channel, sfbwidth[ch]);
2415*f30ccc91SDavid du Colombier
2416*f30ccc91SDavid du Colombier # if !defined(OPT_STRICT)
2417*f30ccc91SDavid du Colombier /*
2418*f30ccc91SDavid du Colombier * According to ISO/IEC 11172-3, "Alias reduction is not applied for
2419*f30ccc91SDavid du Colombier * granules with block_type == 2 (short block)." However, other
2420*f30ccc91SDavid du Colombier * sources suggest alias reduction should indeed be performed on the
2421*f30ccc91SDavid du Colombier * lower two subbands of mixed blocks. Most other implementations do
2422*f30ccc91SDavid du Colombier * this, so by default we will too.
2423*f30ccc91SDavid du Colombier */
2424*f30ccc91SDavid du Colombier if (channel->flags & mixed_block_flag)
2425*f30ccc91SDavid du Colombier III_aliasreduce(xr[ch], 36);
2426*f30ccc91SDavid du Colombier # endif
24278f5875f3SDavid du Colombier }
24288f5875f3SDavid du Colombier else
2429*f30ccc91SDavid du Colombier III_aliasreduce(xr[ch], 576);
2430*f30ccc91SDavid du Colombier
2431*f30ccc91SDavid du Colombier l = 0;
2432*f30ccc91SDavid du Colombier
2433*f30ccc91SDavid du Colombier /* subbands 0-1 */
2434*f30ccc91SDavid du Colombier
2435*f30ccc91SDavid du Colombier if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) {
2436*f30ccc91SDavid du Colombier unsigned int block_type;
2437*f30ccc91SDavid du Colombier
2438*f30ccc91SDavid du Colombier block_type = channel->block_type;
2439*f30ccc91SDavid du Colombier if (channel->flags & mixed_block_flag)
2440*f30ccc91SDavid du Colombier block_type = 0;
2441*f30ccc91SDavid du Colombier
2442*f30ccc91SDavid du Colombier /* long blocks */
2443*f30ccc91SDavid du Colombier for (sb = 0; sb < 2; ++sb, l += 18) {
2444*f30ccc91SDavid du Colombier III_imdct_l(&xr[ch][l], output, block_type);
2445*f30ccc91SDavid du Colombier III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
2446*f30ccc91SDavid du Colombier }
2447*f30ccc91SDavid du Colombier }
2448*f30ccc91SDavid du Colombier else {
2449*f30ccc91SDavid du Colombier /* short blocks */
2450*f30ccc91SDavid du Colombier for (sb = 0; sb < 2; ++sb, l += 18) {
2451*f30ccc91SDavid du Colombier III_imdct_s(&xr[ch][l], output);
2452*f30ccc91SDavid du Colombier III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
2453*f30ccc91SDavid du Colombier }
2454*f30ccc91SDavid du Colombier }
2455*f30ccc91SDavid du Colombier
2456*f30ccc91SDavid du Colombier III_freqinver(sample, 1);
2457*f30ccc91SDavid du Colombier
2458*f30ccc91SDavid du Colombier /* (nonzero) subbands 2-31 */
2459*f30ccc91SDavid du Colombier
2460*f30ccc91SDavid du Colombier i = 576;
2461*f30ccc91SDavid du Colombier while (i > 36 && xr[ch][i - 1] == 0)
2462*f30ccc91SDavid du Colombier --i;
2463*f30ccc91SDavid du Colombier
2464*f30ccc91SDavid du Colombier sblimit = 32 - (576 - i) / 18;
2465*f30ccc91SDavid du Colombier
2466*f30ccc91SDavid du Colombier if (channel->block_type != 2) {
2467*f30ccc91SDavid du Colombier /* long blocks */
2468*f30ccc91SDavid du Colombier for (sb = 2; sb < sblimit; ++sb, l += 18) {
2469*f30ccc91SDavid du Colombier III_imdct_l(&xr[ch][l], output, channel->block_type);
2470*f30ccc91SDavid du Colombier III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
2471*f30ccc91SDavid du Colombier
2472*f30ccc91SDavid du Colombier if (sb & 1)
2473*f30ccc91SDavid du Colombier III_freqinver(sample, sb);
2474*f30ccc91SDavid du Colombier }
2475*f30ccc91SDavid du Colombier }
2476*f30ccc91SDavid du Colombier else {
2477*f30ccc91SDavid du Colombier /* short blocks */
2478*f30ccc91SDavid du Colombier for (sb = 2; sb < sblimit; ++sb, l += 18) {
2479*f30ccc91SDavid du Colombier III_imdct_s(&xr[ch][l], output);
2480*f30ccc91SDavid du Colombier III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
2481*f30ccc91SDavid du Colombier
2482*f30ccc91SDavid du Colombier if (sb & 1)
2483*f30ccc91SDavid du Colombier III_freqinver(sample, sb);
2484*f30ccc91SDavid du Colombier }
2485*f30ccc91SDavid du Colombier }
2486*f30ccc91SDavid du Colombier
2487*f30ccc91SDavid du Colombier /* remaining (zero) subbands */
2488*f30ccc91SDavid du Colombier
2489*f30ccc91SDavid du Colombier for (sb = sblimit; sb < 32; ++sb) {
2490*f30ccc91SDavid du Colombier III_overlap_z((*frame->overlap)[ch][sb], sample, sb);
2491*f30ccc91SDavid du Colombier
2492*f30ccc91SDavid du Colombier if (sb & 1)
2493*f30ccc91SDavid du Colombier III_freqinver(sample, sb);
2494*f30ccc91SDavid du Colombier }
2495*f30ccc91SDavid du Colombier }
2496*f30ccc91SDavid du Colombier }
2497*f30ccc91SDavid du Colombier
2498*f30ccc91SDavid du Colombier return MAD_ERROR_NONE;
2499*f30ccc91SDavid du Colombier }
2500*f30ccc91SDavid du Colombier
2501*f30ccc91SDavid du Colombier /*
2502*f30ccc91SDavid du Colombier * NAME: layer->III()
2503*f30ccc91SDavid du Colombier * DESCRIPTION: decode a single Layer III frame
2504*f30ccc91SDavid du Colombier */
mad_layer_III(struct mad_stream * stream,struct mad_frame * frame)2505*f30ccc91SDavid du Colombier int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame)
2506*f30ccc91SDavid du Colombier {
2507*f30ccc91SDavid du Colombier struct mad_header *header = &frame->header;
2508*f30ccc91SDavid du Colombier unsigned int nch, priv_bitlen, next_md_begin = 0;
2509*f30ccc91SDavid du Colombier unsigned int si_len, data_bitlen, md_len;
2510*f30ccc91SDavid du Colombier unsigned int frame_space, frame_used, frame_free;
2511*f30ccc91SDavid du Colombier struct mad_bitptr ptr;
2512*f30ccc91SDavid du Colombier struct sideinfo si;
2513*f30ccc91SDavid du Colombier enum mad_error error;
2514*f30ccc91SDavid du Colombier int result = 0;
2515*f30ccc91SDavid du Colombier
2516*f30ccc91SDavid du Colombier /* allocate Layer III dynamic structures */
2517*f30ccc91SDavid du Colombier
2518*f30ccc91SDavid du Colombier if (stream->main_data == 0) {
2519*f30ccc91SDavid du Colombier stream->main_data = malloc(MAD_BUFFER_MDLEN);
2520*f30ccc91SDavid du Colombier if (stream->main_data == 0) {
2521*f30ccc91SDavid du Colombier stream->error = MAD_ERROR_NOMEM;
2522*f30ccc91SDavid du Colombier return -1;
2523*f30ccc91SDavid du Colombier }
2524*f30ccc91SDavid du Colombier }
2525*f30ccc91SDavid du Colombier
2526*f30ccc91SDavid du Colombier if (frame->overlap == 0) {
2527*f30ccc91SDavid du Colombier frame->overlap = calloc(2 * 32 * 18, sizeof(mad_fixed_t));
2528*f30ccc91SDavid du Colombier if (frame->overlap == 0) {
2529*f30ccc91SDavid du Colombier stream->error = MAD_ERROR_NOMEM;
2530*f30ccc91SDavid du Colombier return -1;
2531*f30ccc91SDavid du Colombier }
2532*f30ccc91SDavid du Colombier }
2533*f30ccc91SDavid du Colombier
2534*f30ccc91SDavid du Colombier nch = MAD_NCHANNELS(header);
2535*f30ccc91SDavid du Colombier si_len = (header->flags & MAD_FLAG_LSF_EXT) ?
2536*f30ccc91SDavid du Colombier (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32);
2537*f30ccc91SDavid du Colombier
2538*f30ccc91SDavid du Colombier /* check frame sanity */
2539*f30ccc91SDavid du Colombier
2540*f30ccc91SDavid du Colombier if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) <
2541*f30ccc91SDavid du Colombier (signed int) si_len) {
2542*f30ccc91SDavid du Colombier stream->error = MAD_ERROR_BADFRAMELEN;
2543*f30ccc91SDavid du Colombier stream->md_len = 0;
2544*f30ccc91SDavid du Colombier return -1;
2545*f30ccc91SDavid du Colombier }
2546*f30ccc91SDavid du Colombier
2547*f30ccc91SDavid du Colombier /* check CRC word */
2548*f30ccc91SDavid du Colombier
2549*f30ccc91SDavid du Colombier if (header->flags & MAD_FLAG_PROTECTION) {
2550*f30ccc91SDavid du Colombier header->crc_check =
2551*f30ccc91SDavid du Colombier mad_bit_crc(stream->ptr, si_len * CHAR_BIT, header->crc_check);
2552*f30ccc91SDavid du Colombier
2553*f30ccc91SDavid du Colombier if (header->crc_check != header->crc_target &&
2554*f30ccc91SDavid du Colombier !(frame->options & MAD_OPTION_IGNORECRC)) {
2555*f30ccc91SDavid du Colombier stream->error = MAD_ERROR_BADCRC;
2556*f30ccc91SDavid du Colombier result = -1;
2557*f30ccc91SDavid du Colombier }
2558*f30ccc91SDavid du Colombier }
2559*f30ccc91SDavid du Colombier
2560*f30ccc91SDavid du Colombier /* decode frame side information */
2561*f30ccc91SDavid du Colombier
2562*f30ccc91SDavid du Colombier error = III_sideinfo(&stream->ptr, nch, header->flags & MAD_FLAG_LSF_EXT,
2563*f30ccc91SDavid du Colombier &si, &data_bitlen, &priv_bitlen);
2564*f30ccc91SDavid du Colombier if (error && result == 0) {
2565*f30ccc91SDavid du Colombier stream->error = error;
2566*f30ccc91SDavid du Colombier result = -1;
2567*f30ccc91SDavid du Colombier }
2568*f30ccc91SDavid du Colombier
2569*f30ccc91SDavid du Colombier header->flags |= priv_bitlen;
2570*f30ccc91SDavid du Colombier header->private_bits |= si.private_bits;
2571*f30ccc91SDavid du Colombier
2572*f30ccc91SDavid du Colombier /* find main_data of next frame */
2573*f30ccc91SDavid du Colombier
2574*f30ccc91SDavid du Colombier {
2575*f30ccc91SDavid du Colombier struct mad_bitptr peek;
2576*f30ccc91SDavid du Colombier unsigned long header;
2577*f30ccc91SDavid du Colombier
2578*f30ccc91SDavid du Colombier mad_bit_init(&peek, stream->next_frame);
2579*f30ccc91SDavid du Colombier
2580*f30ccc91SDavid du Colombier header = mad_bit_read(&peek, 32);
2581*f30ccc91SDavid du Colombier if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) {
2582*f30ccc91SDavid du Colombier if (!(header & 0x00010000L)) /* protection_bit */
2583*f30ccc91SDavid du Colombier mad_bit_skip(&peek, 16); /* crc_check */
2584*f30ccc91SDavid du Colombier
2585*f30ccc91SDavid du Colombier next_md_begin =
2586*f30ccc91SDavid du Colombier mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8);
2587*f30ccc91SDavid du Colombier }
2588*f30ccc91SDavid du Colombier
2589*f30ccc91SDavid du Colombier mad_bit_finish(&peek);
2590*f30ccc91SDavid du Colombier }
2591*f30ccc91SDavid du Colombier
2592*f30ccc91SDavid du Colombier /* find main_data of this frame */
2593*f30ccc91SDavid du Colombier
2594*f30ccc91SDavid du Colombier frame_space = stream->next_frame - mad_bit_nextbyte(&stream->ptr);
2595*f30ccc91SDavid du Colombier
2596*f30ccc91SDavid du Colombier if (next_md_begin > si.main_data_begin + frame_space)
2597*f30ccc91SDavid du Colombier next_md_begin = 0;
2598*f30ccc91SDavid du Colombier
2599*f30ccc91SDavid du Colombier md_len = si.main_data_begin + frame_space - next_md_begin;
2600*f30ccc91SDavid du Colombier
2601*f30ccc91SDavid du Colombier frame_used = 0;
2602*f30ccc91SDavid du Colombier
2603*f30ccc91SDavid du Colombier if (si.main_data_begin == 0) {
2604*f30ccc91SDavid du Colombier ptr = stream->ptr;
2605*f30ccc91SDavid du Colombier stream->md_len = 0;
2606*f30ccc91SDavid du Colombier
2607*f30ccc91SDavid du Colombier frame_used = md_len;
2608*f30ccc91SDavid du Colombier }
2609*f30ccc91SDavid du Colombier else {
2610*f30ccc91SDavid du Colombier if (si.main_data_begin > stream->md_len) {
2611*f30ccc91SDavid du Colombier if (result == 0) {
2612*f30ccc91SDavid du Colombier stream->error = MAD_ERROR_BADDATAPTR;
2613*f30ccc91SDavid du Colombier result = -1;
2614*f30ccc91SDavid du Colombier }
2615*f30ccc91SDavid du Colombier }
2616*f30ccc91SDavid du Colombier else {
2617*f30ccc91SDavid du Colombier mad_bit_init(&ptr,
2618*f30ccc91SDavid du Colombier *stream->main_data + stream->md_len - si.main_data_begin);
2619*f30ccc91SDavid du Colombier
2620*f30ccc91SDavid du Colombier if (md_len > si.main_data_begin) {
2621*f30ccc91SDavid du Colombier assert(stream->md_len + md_len -
2622*f30ccc91SDavid du Colombier si.main_data_begin <= MAD_BUFFER_MDLEN);
2623*f30ccc91SDavid du Colombier
2624*f30ccc91SDavid du Colombier memcpy(*stream->main_data + stream->md_len,
2625*f30ccc91SDavid du Colombier mad_bit_nextbyte(&stream->ptr),
2626*f30ccc91SDavid du Colombier frame_used = md_len - si.main_data_begin);
2627*f30ccc91SDavid du Colombier stream->md_len += frame_used;
2628*f30ccc91SDavid du Colombier }
2629*f30ccc91SDavid du Colombier }
2630*f30ccc91SDavid du Colombier }
2631*f30ccc91SDavid du Colombier
2632*f30ccc91SDavid du Colombier frame_free = frame_space - frame_used;
2633*f30ccc91SDavid du Colombier
2634*f30ccc91SDavid du Colombier /* decode main_data */
2635*f30ccc91SDavid du Colombier
2636*f30ccc91SDavid du Colombier if (result == 0) {
2637*f30ccc91SDavid du Colombier error = III_decode(&ptr, frame, &si, nch);
2638*f30ccc91SDavid du Colombier if (error) {
2639*f30ccc91SDavid du Colombier stream->error = error;
2640*f30ccc91SDavid du Colombier result = -1;
2641*f30ccc91SDavid du Colombier }
2642*f30ccc91SDavid du Colombier
2643*f30ccc91SDavid du Colombier /* designate ancillary bits */
2644*f30ccc91SDavid du Colombier
2645*f30ccc91SDavid du Colombier stream->anc_ptr = ptr;
2646*f30ccc91SDavid du Colombier stream->anc_bitlen = md_len * CHAR_BIT - data_bitlen;
2647*f30ccc91SDavid du Colombier }
2648*f30ccc91SDavid du Colombier
2649*f30ccc91SDavid du Colombier # if 0 && defined(DEBUG)
2650*f30ccc91SDavid du Colombier fprintf(stderr,
2651*f30ccc91SDavid du Colombier "main_data_begin:%u, md_len:%u, frame_free:%u, "
2652*f30ccc91SDavid du Colombier "data_bitlen:%u, anc_bitlen: %u\n",
2653*f30ccc91SDavid du Colombier si.main_data_begin, md_len, frame_free,
2654*f30ccc91SDavid du Colombier data_bitlen, stream->anc_bitlen);
26558f5875f3SDavid du Colombier # endif
26568f5875f3SDavid du Colombier
2657*f30ccc91SDavid du Colombier /* preload main_data buffer with up to 511 bytes for next frame(s) */
2658*f30ccc91SDavid du Colombier
2659*f30ccc91SDavid du Colombier if (frame_free >= next_md_begin) {
2660*f30ccc91SDavid du Colombier memcpy(*stream->main_data,
2661*f30ccc91SDavid du Colombier stream->next_frame - next_md_begin, next_md_begin);
2662*f30ccc91SDavid du Colombier stream->md_len = next_md_begin;
26638f5875f3SDavid du Colombier }
2664*f30ccc91SDavid du Colombier else {
2665*f30ccc91SDavid du Colombier if (md_len < si.main_data_begin) {
2666*f30ccc91SDavid du Colombier unsigned int extra;
26678f5875f3SDavid du Colombier
2668*f30ccc91SDavid du Colombier extra = si.main_data_begin - md_len;
2669*f30ccc91SDavid du Colombier if (extra + frame_free > next_md_begin)
2670*f30ccc91SDavid du Colombier extra = next_md_begin - frame_free;
26718f5875f3SDavid du Colombier
2672*f30ccc91SDavid du Colombier if (extra < stream->md_len) {
2673*f30ccc91SDavid du Colombier memmove(*stream->main_data,
2674*f30ccc91SDavid du Colombier *stream->main_data + stream->md_len - extra, extra);
2675*f30ccc91SDavid du Colombier stream->md_len = extra;
26768f5875f3SDavid du Colombier }
26778f5875f3SDavid du Colombier }
2678*f30ccc91SDavid du Colombier else
2679*f30ccc91SDavid du Colombier stream->md_len = 0;
2680*f30ccc91SDavid du Colombier
2681*f30ccc91SDavid du Colombier memcpy(*stream->main_data + stream->md_len,
2682*f30ccc91SDavid du Colombier stream->next_frame - frame_free, frame_free);
2683*f30ccc91SDavid du Colombier stream->md_len += frame_free;
26848f5875f3SDavid du Colombier }
26858f5875f3SDavid du Colombier
2686*f30ccc91SDavid du Colombier return result;
26878f5875f3SDavid du Colombier }
2688