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