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