Mercurial > audlegacy
comparison Plugins/Input/aac/libfaad2/pns.c @ 61:fa848bd484d8 trunk
[svn] Move plugins to Plugins/
author | nenolod |
---|---|
date | Fri, 28 Oct 2005 22:58:11 -0700 |
parents | |
children | 0a2ad94e8607 |
comparison
equal
deleted
inserted
replaced
60:1771f253e1b2 | 61:fa848bd484d8 |
---|---|
1 /* | |
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | |
3 ** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com | |
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 ** | |
25 ** $Id: pns.c,v 1.27 2003/11/12 20:47:58 menno Exp $ | |
26 **/ | |
27 | |
28 #include "common.h" | |
29 #include "structs.h" | |
30 | |
31 #include "pns.h" | |
32 | |
33 | |
34 #ifdef FIXED_POINT | |
35 | |
36 #define DIV(A, B) (((int64_t)A << REAL_BITS)/B) | |
37 | |
38 #define step(shift) \ | |
39 if ((0x40000000l >> shift) + root <= value) \ | |
40 { \ | |
41 value -= (0x40000000l >> shift) + root; \ | |
42 root = (root >> 1) | (0x40000000l >> shift); \ | |
43 } else { \ | |
44 root = root >> 1; \ | |
45 } | |
46 | |
47 /* fixed point square root approximation */ | |
48 /* !!!! ONLY WORKS FOR EVEN %REAL_BITS% !!!! */ | |
49 real_t fp_sqrt(real_t value) | |
50 { | |
51 real_t root = 0; | |
52 | |
53 step( 0); step( 2); step( 4); step( 6); | |
54 step( 8); step(10); step(12); step(14); | |
55 step(16); step(18); step(20); step(22); | |
56 step(24); step(26); step(28); step(30); | |
57 | |
58 if (root < value) | |
59 ++root; | |
60 | |
61 root <<= (REAL_BITS/2); | |
62 | |
63 return root; | |
64 } | |
65 | |
66 static real_t pow2_table[] = | |
67 { | |
68 COEF_CONST(0.59460355750136), | |
69 COEF_CONST(0.70710678118655), | |
70 COEF_CONST(0.84089641525371), | |
71 COEF_CONST(1.0), | |
72 COEF_CONST(1.18920711500272), | |
73 COEF_CONST(1.41421356237310), | |
74 COEF_CONST(1.68179283050743) | |
75 }; | |
76 #endif | |
77 | |
78 /* The function gen_rand_vector(addr, size) generates a vector of length | |
79 <size> with signed random values of average energy MEAN_NRG per random | |
80 value. A suitable random number generator can be realized using one | |
81 multiplication/accumulation per random value. | |
82 */ | |
83 static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size, | |
84 uint8_t sub) | |
85 { | |
86 #ifndef FIXED_POINT | |
87 uint16_t i; | |
88 real_t energy = 0.0; | |
89 | |
90 real_t scale = (real_t)1.0/(real_t)size; | |
91 | |
92 for (i = 0; i < size; i++) | |
93 { | |
94 real_t tmp = scale*(real_t)(int32_t)random_int(); | |
95 spec[i] = tmp; | |
96 energy += tmp*tmp; | |
97 } | |
98 | |
99 scale = (real_t)1.0/(real_t)sqrt(energy); | |
100 scale *= (real_t)pow(2.0, 0.25 * scale_factor); | |
101 for (i = 0; i < size; i++) | |
102 { | |
103 spec[i] *= scale; | |
104 } | |
105 #else | |
106 uint16_t i; | |
107 real_t energy = 0, scale; | |
108 int32_t exp, frac; | |
109 | |
110 for (i = 0; i < size; i++) | |
111 { | |
112 /* this can be replaced by a 16 bit random generator!!!! */ | |
113 real_t tmp = (int32_t)random_int(); | |
114 if (tmp < 0) | |
115 tmp = -(tmp & ((1<<(REAL_BITS-1))-1)); | |
116 else | |
117 tmp = (tmp & ((1<<(REAL_BITS-1))-1)); | |
118 | |
119 energy += MUL_R(tmp,tmp); | |
120 | |
121 spec[i] = tmp; | |
122 } | |
123 | |
124 energy = fp_sqrt(energy); | |
125 if (energy > 0) | |
126 { | |
127 scale = DIV(REAL_CONST(1),energy); | |
128 | |
129 exp = scale_factor / 4; | |
130 frac = scale_factor % 4; | |
131 | |
132 /* IMDCT pre-scaling */ | |
133 exp -= sub; | |
134 | |
135 if (exp < 0) | |
136 scale >>= -exp; | |
137 else | |
138 scale <<= exp; | |
139 | |
140 if (frac) | |
141 scale = MUL_C(scale, pow2_table[frac + 3]); | |
142 | |
143 for (i = 0; i < size; i++) | |
144 { | |
145 spec[i] = MUL_R(spec[i], scale); | |
146 } | |
147 } | |
148 #endif | |
149 } | |
150 | |
151 void pns_decode(ic_stream *ics_left, ic_stream *ics_right, | |
152 real_t *spec_left, real_t *spec_right, uint16_t frame_len, | |
153 uint8_t channel_pair, uint8_t object_type) | |
154 { | |
155 uint8_t g, sfb, b; | |
156 uint16_t size, offs; | |
157 | |
158 uint8_t group = 0; | |
159 uint16_t nshort = frame_len >> 3; | |
160 | |
161 uint8_t sub = 0; | |
162 | |
163 #ifdef FIXED_POINT | |
164 /* IMDCT scaling */ | |
165 if (object_type == LD) | |
166 { | |
167 sub = 9 /*9*/; | |
168 } else { | |
169 if (ics_left->window_sequence == EIGHT_SHORT_SEQUENCE) | |
170 sub = 7 /*7*/; | |
171 else | |
172 sub = 10 /*10*/; | |
173 } | |
174 #endif | |
175 | |
176 for (g = 0; g < ics_left->num_window_groups; g++) | |
177 { | |
178 /* Do perceptual noise substitution decoding */ | |
179 for (b = 0; b < ics_left->window_group_length[g]; b++) | |
180 { | |
181 for (sfb = 0; sfb < ics_left->max_sfb; sfb++) | |
182 { | |
183 if (is_noise(ics_left, g, sfb)) | |
184 { | |
185 /* Simultaneous use of LTP and PNS is not prevented in the | |
186 syntax. If both LTP, and PNS are enabled on the same | |
187 scalefactor band, PNS takes precedence, and no prediction | |
188 is applied to this band. | |
189 */ | |
190 ics_left->ltp.long_used[sfb] = 0; | |
191 ics_left->ltp2.long_used[sfb] = 0; | |
192 | |
193 /* For scalefactor bands coded using PNS the corresponding | |
194 predictors are switched to "off". | |
195 */ | |
196 ics_left->pred.prediction_used[sfb] = 0; | |
197 | |
198 offs = ics_left->swb_offset[sfb]; | |
199 size = ics_left->swb_offset[sfb+1] - offs; | |
200 | |
201 /* Generate random vector */ | |
202 gen_rand_vector(&spec_left[(group*nshort)+offs], | |
203 ics_left->scale_factors[g][sfb], size, sub); | |
204 } | |
205 | |
206 /* From the spec: | |
207 If the same scalefactor band and group is coded by perceptual noise | |
208 substitution in both channels of a channel pair, the correlation of | |
209 the noise signal can be controlled by means of the ms_used field: While | |
210 the default noise generation process works independently for each channel | |
211 (separate generation of random vectors), the same random vector is used | |
212 for both channels if ms_used[] is set for a particular scalefactor band | |
213 and group. In this case, no M/S stereo coding is carried out (because M/S | |
214 stereo coding and noise substitution coding are mutually exclusive). | |
215 If the same scalefactor band and group is coded by perceptual noise | |
216 substitution in only one channel of a channel pair the setting of ms_used[] | |
217 is not evaluated. | |
218 */ | |
219 if (channel_pair) | |
220 { | |
221 if (is_noise(ics_right, g, sfb)) | |
222 { | |
223 if (((ics_left->ms_mask_present == 1) && | |
224 (ics_left->ms_used[g][sfb])) || | |
225 (ics_left->ms_mask_present == 2)) | |
226 { | |
227 uint16_t c; | |
228 | |
229 offs = ics_right->swb_offset[sfb]; | |
230 size = ics_right->swb_offset[sfb+1] - offs; | |
231 | |
232 for (c = 0; c < size; c++) | |
233 { | |
234 spec_right[(group*nshort) + offs + c] = | |
235 spec_left[(group*nshort) + offs + c]; | |
236 } | |
237 } else /*if (ics_left->ms_mask_present == 0)*/ { | |
238 ics_right->ltp.long_used[sfb] = 0; | |
239 ics_right->ltp2.long_used[sfb] = 0; | |
240 ics_right->pred.prediction_used[sfb] = 0; | |
241 | |
242 offs = ics_right->swb_offset[sfb]; | |
243 size = ics_right->swb_offset[sfb+1] - offs; | |
244 | |
245 /* Generate random vector */ | |
246 gen_rand_vector(&spec_right[(group*nshort)+offs], | |
247 ics_right->scale_factors[g][sfb], size, sub); | |
248 } | |
249 } | |
250 } | |
251 } /* sfb */ | |
252 group++; | |
253 } /* b */ | |
254 } /* g */ | |
255 } |