diff options
Diffstat (limited to 'lib/rbcodec/codecs/libfaad/pns.c')
-rw-r--r-- | lib/rbcodec/codecs/libfaad/pns.c | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libfaad/pns.c b/lib/rbcodec/codecs/libfaad/pns.c new file mode 100644 index 0000000000..b75cf9f1ed --- /dev/null +++ b/lib/rbcodec/codecs/libfaad/pns.c | |||
@@ -0,0 +1,263 @@ | |||
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 step(shift) \ | ||
42 | if ((0x40000000l >> shift) + root <= value) \ | ||
43 | { \ | ||
44 | value -= (0x40000000l >> shift) + root; \ | ||
45 | root = (root >> 1) | (0x40000000l >> shift); \ | ||
46 | } else { \ | ||
47 | root = root >> 1; \ | ||
48 | } | ||
49 | |||
50 | /* fixed point square root approximation */ | ||
51 | /* !!!! ONLY WORKS FOR EVEN %REAL_BITS% !!!! */ | ||
52 | static real_t fp_sqrt(real_t value) | ||
53 | { | ||
54 | real_t root = 0; | ||
55 | |||
56 | step( 0); step( 2); step( 4); step( 6); | ||
57 | step( 8); step(10); step(12); step(14); | ||
58 | step(16); step(18); step(20); step(22); | ||
59 | step(24); step(26); step(28); step(30); | ||
60 | |||
61 | if (root < value) | ||
62 | ++root; | ||
63 | |||
64 | root <<= (REAL_BITS/2); | ||
65 | |||
66 | return root; | ||
67 | } | ||
68 | |||
69 | static real_t pow2_table[] = | ||
70 | { | ||
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_R(REAL_CONST(1), energy); | ||
128 | |||
129 | exp = scale_factor >> 2; | ||
130 | frac = scale_factor & 3; | ||
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]); | ||
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 | #ifdef LTP_DEC | ||
186 | /* Simultaneous use of LTP and PNS is not prevented in the | ||
187 | syntax. If both LTP, and PNS are enabled on the same | ||
188 | scalefactor band, PNS takes precedence, and no prediction | ||
189 | is applied to this band. | ||
190 | */ | ||
191 | ics_left->ltp.long_used[sfb] = 0; | ||
192 | ics_left->ltp2.long_used[sfb] = 0; | ||
193 | #endif | ||
194 | |||
195 | #ifdef MAIN_DEC | ||
196 | /* For scalefactor bands coded using PNS the corresponding | ||
197 | predictors are switched to "off". | ||
198 | */ | ||
199 | ics_left->pred.prediction_used[sfb] = 0; | ||
200 | #endif | ||
201 | |||
202 | offs = ics_left->swb_offset[sfb]; | ||
203 | size = ics_left->swb_offset[sfb+1] - offs; | ||
204 | |||
205 | /* Generate random vector */ | ||
206 | gen_rand_vector(&spec_left[(group*nshort)+offs], | ||
207 | ics_left->scale_factors[g][sfb], size, sub); | ||
208 | } | ||
209 | |||
210 | /* From the spec: | ||
211 | If the same scalefactor band and group is coded by perceptual noise | ||
212 | substitution in both channels of a channel pair, the correlation of | ||
213 | the noise signal can be controlled by means of the ms_used field: While | ||
214 | the default noise generation process works independently for each channel | ||
215 | (separate generation of random vectors), the same random vector is used | ||
216 | for both channels if ms_used[] is set for a particular scalefactor band | ||
217 | and group. In this case, no M/S stereo coding is carried out (because M/S | ||
218 | stereo coding and noise substitution coding are mutually exclusive). | ||
219 | If the same scalefactor band and group is coded by perceptual noise | ||
220 | substitution in only one channel of a channel pair the setting of ms_used[] | ||
221 | is not evaluated. | ||
222 | */ | ||
223 | if (channel_pair) | ||
224 | { | ||
225 | if (is_noise(ics_right, g, sfb)) | ||
226 | { | ||
227 | if (((ics_left->ms_mask_present == 1) && | ||
228 | (ics_left->ms_used[g][sfb])) || | ||
229 | (ics_left->ms_mask_present == 2)) | ||
230 | { | ||
231 | uint16_t c; | ||
232 | |||
233 | offs = ics_right->swb_offset[sfb]; | ||
234 | size = ics_right->swb_offset[sfb+1] - offs; | ||
235 | |||
236 | for (c = 0; c < size; c++) | ||
237 | { | ||
238 | spec_right[(group*nshort) + offs + c] = | ||
239 | spec_left[(group*nshort) + offs + c]; | ||
240 | } | ||
241 | } else /*if (ics_left->ms_mask_present == 0)*/ { | ||
242 | #ifdef LTP_DEC | ||
243 | ics_right->ltp.long_used[sfb] = 0; | ||
244 | ics_right->ltp2.long_used[sfb] = 0; | ||
245 | #endif | ||
246 | #ifdef MAIN_DEC | ||
247 | ics_right->pred.prediction_used[sfb] = 0; | ||
248 | #endif | ||
249 | |||
250 | offs = ics_right->swb_offset[sfb]; | ||
251 | size = ics_right->swb_offset[sfb+1] - offs; | ||
252 | |||
253 | /* Generate random vector */ | ||
254 | gen_rand_vector(&spec_right[(group*nshort)+offs], | ||
255 | ics_right->scale_factors[g][sfb], size, sub); | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | } /* sfb */ | ||
260 | group++; | ||
261 | } /* b */ | ||
262 | } /* g */ | ||
263 | } | ||