Mercurial > mplayer.hg
annotate libfaad2/pns.c @ 12670:aebedab0ecac
top/bottom mb row skipping
author | michael |
---|---|
date | Sat, 26 Jun 2004 02:23:51 +0000 |
parents | d81145997036 |
children | 6d50ef45a058 |
rev | line source |
---|---|
10725 | 1 /* |
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | |
12527 | 3 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com |
10725 | 4 ** |
5 ** This program is free software; you can redistribute it and/or modify | |
6 ** it under the terms of the GNU General Public License as published by | |
7 ** the Free Software Foundation; either version 2 of the License, or | |
8 ** (at your option) any later version. | |
9 ** | |
10 ** This program is distributed in the hope that it will be useful, | |
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 ** GNU General Public License for more details. | |
14 ** | |
15 ** You should have received a copy of the GNU General Public License | |
16 ** along with this program; if not, write to the Free Software | |
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
18 ** | |
19 ** Any non-GPL usage of this software or parts of this software is strictly | |
20 ** forbidden. | |
21 ** | |
22 ** Commercial non-GPL licensing of this software is possible. | |
23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. | |
24 ** | |
12625
d81145997036
More information about modifications to comply more closely with GPL 2a.
diego
parents:
12527
diff
changeset
|
25 ** Initially modified for use with MPlayer by Arpad Gereöffy on 2003/08/30 |
d81145997036
More information about modifications to comply more closely with GPL 2a.
diego
parents:
12527
diff
changeset
|
26 ** $Id: pns.c,v 1.3 2004/06/02 22:59:03 diego Exp $ |
d81145997036
More information about modifications to comply more closely with GPL 2a.
diego
parents:
12527
diff
changeset
|
27 ** detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ |
10725 | 28 **/ |
29 | |
30 #include "common.h" | |
31 #include "structs.h" | |
32 | |
33 #include "pns.h" | |
34 | |
35 | |
12527 | 36 /* static function declarations */ |
37 static void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size, | |
38 uint8_t sub); | |
39 | |
40 | |
10725 | 41 #ifdef FIXED_POINT |
42 | |
10989 | 43 #define DIV(A, B) (((int64_t)A << REAL_BITS)/B) |
10725 | 44 |
45 #define step(shift) \ | |
46 if ((0x40000000l >> shift) + root <= value) \ | |
47 { \ | |
48 value -= (0x40000000l >> shift) + root; \ | |
49 root = (root >> 1) | (0x40000000l >> shift); \ | |
50 } else { \ | |
51 root = root >> 1; \ | |
52 } | |
53 | |
54 /* fixed point square root approximation */ | |
10989 | 55 /* !!!! ONLY WORKS FOR EVEN %REAL_BITS% !!!! */ |
10725 | 56 real_t fp_sqrt(real_t value) |
57 { | |
58 real_t root = 0; | |
59 | |
60 step( 0); step( 2); step( 4); step( 6); | |
61 step( 8); step(10); step(12); step(14); | |
62 step(16); step(18); step(20); step(22); | |
63 step(24); step(26); step(28); step(30); | |
64 | |
65 if (root < value) | |
66 ++root; | |
67 | |
10989 | 68 root <<= (REAL_BITS/2); |
10725 | 69 |
70 return root; | |
71 } | |
72 | |
73 static real_t pow2_table[] = | |
74 { | |
75 COEF_CONST(0.59460355750136), | |
76 COEF_CONST(0.70710678118655), | |
77 COEF_CONST(0.84089641525371), | |
78 COEF_CONST(1.0), | |
79 COEF_CONST(1.18920711500272), | |
80 COEF_CONST(1.41421356237310), | |
81 COEF_CONST(1.68179283050743) | |
82 }; | |
83 #endif | |
84 | |
85 /* The function gen_rand_vector(addr, size) generates a vector of length | |
86 <size> with signed random values of average energy MEAN_NRG per random | |
87 value. A suitable random number generator can be realized using one | |
88 multiplication/accumulation per random value. | |
89 */ | |
10989 | 90 static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size, |
91 uint8_t sub) | |
10725 | 92 { |
93 #ifndef FIXED_POINT | |
94 uint16_t i; | |
95 real_t energy = 0.0; | |
96 | |
10989 | 97 real_t scale = (real_t)1.0/(real_t)size; |
10725 | 98 |
99 for (i = 0; i < size; i++) | |
100 { | |
101 real_t tmp = scale*(real_t)(int32_t)random_int(); | |
102 spec[i] = tmp; | |
103 energy += tmp*tmp; | |
104 } | |
105 | |
10989 | 106 scale = (real_t)1.0/(real_t)sqrt(energy); |
10725 | 107 scale *= (real_t)pow(2.0, 0.25 * scale_factor); |
108 for (i = 0; i < size; i++) | |
109 { | |
110 spec[i] *= scale; | |
111 } | |
112 #else | |
113 uint16_t i; | |
114 real_t energy = 0, scale; | |
115 int32_t exp, frac; | |
116 | |
117 for (i = 0; i < size; i++) | |
118 { | |
10989 | 119 /* this can be replaced by a 16 bit random generator!!!! */ |
120 real_t tmp = (int32_t)random_int(); | |
121 if (tmp < 0) | |
122 tmp = -(tmp & ((1<<(REAL_BITS-1))-1)); | |
123 else | |
124 tmp = (tmp & ((1<<(REAL_BITS-1))-1)); | |
10725 | 125 |
12527 | 126 energy += MUL_R(tmp,tmp); |
10725 | 127 |
10989 | 128 spec[i] = tmp; |
10725 | 129 } |
130 | |
131 energy = fp_sqrt(energy); | |
132 if (energy > 0) | |
133 { | |
10989 | 134 scale = DIV(REAL_CONST(1),energy); |
10725 | 135 |
136 exp = scale_factor / 4; | |
137 frac = scale_factor % 4; | |
138 | |
10989 | 139 /* IMDCT pre-scaling */ |
140 exp -= sub; | |
141 | |
10725 | 142 if (exp < 0) |
143 scale >>= -exp; | |
144 else | |
145 scale <<= exp; | |
146 | |
147 if (frac) | |
12527 | 148 scale = MUL_C(scale, pow2_table[frac + 3]); |
10725 | 149 |
150 for (i = 0; i < size; i++) | |
151 { | |
12527 | 152 spec[i] = MUL_R(spec[i], scale); |
10725 | 153 } |
154 } | |
155 #endif | |
156 } | |
157 | |
158 void pns_decode(ic_stream *ics_left, ic_stream *ics_right, | |
159 real_t *spec_left, real_t *spec_right, uint16_t frame_len, | |
10989 | 160 uint8_t channel_pair, uint8_t object_type) |
10725 | 161 { |
162 uint8_t g, sfb, b; | |
163 uint16_t size, offs; | |
164 | |
165 uint8_t group = 0; | |
166 uint16_t nshort = frame_len >> 3; | |
167 | |
10989 | 168 uint8_t sub = 0; |
169 | |
170 #ifdef FIXED_POINT | |
171 /* IMDCT scaling */ | |
172 if (object_type == LD) | |
173 { | |
174 sub = 9 /*9*/; | |
175 } else { | |
176 if (ics_left->window_sequence == EIGHT_SHORT_SEQUENCE) | |
177 sub = 7 /*7*/; | |
178 else | |
179 sub = 10 /*10*/; | |
180 } | |
181 #endif | |
182 | |
10725 | 183 for (g = 0; g < ics_left->num_window_groups; g++) |
184 { | |
185 /* Do perceptual noise substitution decoding */ | |
186 for (b = 0; b < ics_left->window_group_length[g]; b++) | |
187 { | |
188 for (sfb = 0; sfb < ics_left->max_sfb; sfb++) | |
189 { | |
190 if (is_noise(ics_left, g, sfb)) | |
191 { | |
192 /* Simultaneous use of LTP and PNS is not prevented in the | |
193 syntax. If both LTP, and PNS are enabled on the same | |
194 scalefactor band, PNS takes precedence, and no prediction | |
195 is applied to this band. | |
196 */ | |
197 ics_left->ltp.long_used[sfb] = 0; | |
198 ics_left->ltp2.long_used[sfb] = 0; | |
199 | |
200 /* For scalefactor bands coded using PNS the corresponding | |
201 predictors are switched to "off". | |
202 */ | |
203 ics_left->pred.prediction_used[sfb] = 0; | |
204 | |
205 offs = ics_left->swb_offset[sfb]; | |
206 size = ics_left->swb_offset[sfb+1] - offs; | |
207 | |
208 /* Generate random vector */ | |
209 gen_rand_vector(&spec_left[(group*nshort)+offs], | |
10989 | 210 ics_left->scale_factors[g][sfb], size, sub); |
10725 | 211 } |
212 | |
213 /* From the spec: | |
214 If the same scalefactor band and group is coded by perceptual noise | |
215 substitution in both channels of a channel pair, the correlation of | |
216 the noise signal can be controlled by means of the ms_used field: While | |
217 the default noise generation process works independently for each channel | |
218 (separate generation of random vectors), the same random vector is used | |
219 for both channels if ms_used[] is set for a particular scalefactor band | |
220 and group. In this case, no M/S stereo coding is carried out (because M/S | |
221 stereo coding and noise substitution coding are mutually exclusive). | |
222 If the same scalefactor band and group is coded by perceptual noise | |
223 substitution in only one channel of a channel pair the setting of ms_used[] | |
224 is not evaluated. | |
225 */ | |
226 if (channel_pair) | |
227 { | |
228 if (is_noise(ics_right, g, sfb)) | |
229 { | |
230 if (((ics_left->ms_mask_present == 1) && | |
231 (ics_left->ms_used[g][sfb])) || | |
232 (ics_left->ms_mask_present == 2)) | |
233 { | |
234 uint16_t c; | |
235 | |
236 offs = ics_right->swb_offset[sfb]; | |
237 size = ics_right->swb_offset[sfb+1] - offs; | |
238 | |
239 for (c = 0; c < size; c++) | |
240 { | |
241 spec_right[(group*nshort) + offs + c] = | |
242 spec_left[(group*nshort) + offs + c]; | |
243 } | |
244 } else /*if (ics_left->ms_mask_present == 0)*/ { | |
245 ics_right->ltp.long_used[sfb] = 0; | |
246 ics_right->ltp2.long_used[sfb] = 0; | |
247 ics_right->pred.prediction_used[sfb] = 0; | |
248 | |
249 offs = ics_right->swb_offset[sfb]; | |
250 size = ics_right->swb_offset[sfb+1] - offs; | |
251 | |
252 /* Generate random vector */ | |
253 gen_rand_vector(&spec_right[(group*nshort)+offs], | |
10989 | 254 ics_right->scale_factors[g][sfb], size, sub); |
10725 | 255 } |
256 } | |
257 } | |
258 } /* sfb */ | |
259 group++; | |
260 } /* b */ | |
261 } /* g */ | |
262 } |