pns.c

00001 /*
00002 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
00003 ** Copyright (C) 2003-2005 M. Bakker, Ahead Software AG, http://www.nero.com
00004 **  
00005 ** This program is free software; you can redistribute it and/or modify
00006 ** it under the terms of the GNU General Public License as published by
00007 ** the Free Software Foundation; either version 2 of the License, or
00008 ** (at your option) any later version.
00009 ** 
00010 ** This program is distributed in the hope that it will be useful,
00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 ** GNU General Public License for more details.
00014 ** 
00015 ** You should have received a copy of the GNU General Public License
00016 ** along with this program; if not, write to the Free Software 
00017 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 **
00019 ** Any non-GPL usage of this software or parts of this software is strictly
00020 ** forbidden.
00021 **
00022 ** Software using this code must display the following message visibly in the
00023 ** software:
00024 ** "FAAD2 AAC/HE-AAC/HE-AACv2/DRM decoder (c) Ahead Software, www.nero.com"
00025 ** in, for example, the about-box or help/startup screen.
00026 **
00027 ** Commercial non-GPL licensing of this software is possible.
00028 ** For more info contact Ahead Software through [email protected].
00029 **
00030 ** $Id: pns.c,v 1.3 2005/11/01 21:41:43 gabest Exp $
00031 **/
00032 
00033 #include "common.h"
00034 #include "structs.h"
00035 
00036 #include "pns.h"
00037 
00038 
00039 /* static function declarations */
00040 static void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size,
00041                             uint8_t sub);
00042 
00043 
00044 #ifdef FIXED_POINT
00045 
00046 #define DIV(A, B) (((int64_t)A << REAL_BITS)/B)
00047 
00048 #define step(shift) \
00049     if ((0x40000000l >> shift) + root <= value)       \
00050     {                                                 \
00051         value -= (0x40000000l >> shift) + root;       \
00052         root = (root >> 1) | (0x40000000l >> shift);  \
00053     } else {                                          \
00054         root = root >> 1;                             \
00055     }
00056 
00057 /* fixed point square root approximation */
00058 /* !!!! ONLY WORKS FOR EVEN %REAL_BITS% !!!! */
00059 real_t fp_sqrt(real_t value)
00060 {
00061     real_t root = 0;
00062 
00063     step( 0); step( 2); step( 4); step( 6);
00064     step( 8); step(10); step(12); step(14);
00065     step(16); step(18); step(20); step(22);
00066     step(24); step(26); step(28); step(30);
00067 
00068     if (root < value)
00069         ++root;
00070 
00071     root <<= (REAL_BITS/2);
00072 
00073     return root;
00074 }
00075 
00076 static real_t pow2_table[] =
00077 {
00078     COEF_CONST(1.0),
00079     COEF_CONST(1.18920711500272),
00080     COEF_CONST(1.41421356237310),
00081     COEF_CONST(1.68179283050743)
00082 };
00083 #endif
00084 
00085 /* The function gen_rand_vector(addr, size) generates a vector of length
00086    <size> with signed random values of average energy MEAN_NRG per random
00087    value. A suitable random number generator can be realized using one
00088    multiplication/accumulation per random value.
00089 */
00090 static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size,
00091                                    uint8_t sub)
00092 {
00093 #ifndef FIXED_POINT
00094     uint16_t i;
00095     real_t energy = 0.0;
00096 
00097     real_t scale = (real_t)1.0/(real_t)size;
00098 
00099     for (i = 0; i < size; i++)
00100     {
00101         real_t tmp = scale*(real_t)(int32_t)random_int();
00102         spec[i] = tmp;
00103         energy += tmp*tmp;
00104     }
00105 
00106     scale = (real_t)1.0/(real_t)sqrt(energy);
00107     scale *= (real_t)pow(2.0, 0.25 * scale_factor);
00108     for (i = 0; i < size; i++)
00109     {
00110         spec[i] *= scale;
00111     }
00112 #else
00113     uint16_t i;
00114     real_t energy = 0, scale;
00115     int32_t exp, frac;
00116 
00117     for (i = 0; i < size; i++)
00118     {
00119         /* this can be replaced by a 16 bit random generator!!!! */
00120         real_t tmp = (int32_t)random_int();
00121         if (tmp < 0)
00122             tmp = -(tmp & ((1<<(REAL_BITS-1))-1));
00123         else
00124             tmp = (tmp & ((1<<(REAL_BITS-1))-1));
00125 
00126         energy += MUL_R(tmp,tmp);
00127 
00128         spec[i] = tmp;
00129     }
00130 
00131     energy = fp_sqrt(energy);
00132     if (energy > 0)
00133     {
00134         scale = DIV(REAL_CONST(1),energy);
00135 
00136         exp = scale_factor >> 2;
00137         frac = scale_factor & 3;
00138 
00139         /* IMDCT pre-scaling */
00140         exp -= sub;
00141 
00142         if (exp < 0)
00143             scale >>= -exp;
00144         else
00145             scale <<= exp;
00146 
00147         if (frac)
00148             scale = MUL_C(scale, pow2_table[frac]);
00149 
00150         for (i = 0; i < size; i++)
00151         {
00152             spec[i] = MUL_R(spec[i], scale);
00153         }
00154     }
00155 #endif
00156 }
00157 
00158 void pns_decode(ic_stream *ics_left, ic_stream *ics_right,
00159                 real_t *spec_left, real_t *spec_right, uint16_t frame_len,
00160                 uint8_t channel_pair, uint8_t object_type)
00161 {
00162     uint8_t g, sfb, b;
00163     uint16_t size, offs;
00164 
00165     uint8_t group = 0;
00166     uint16_t nshort = frame_len >> 3;
00167 
00168     uint8_t sub = 0;
00169 
00170 #ifdef FIXED_POINT
00171     /* IMDCT scaling */
00172     if (object_type == LD)
00173     {
00174         sub = 9 /*9*/;
00175     } else {
00176         if (ics_left->window_sequence == EIGHT_SHORT_SEQUENCE)
00177             sub = 7 /*7*/;
00178         else
00179             sub = 10 /*10*/;
00180     }
00181 #endif
00182 
00183     for (g = 0; g < ics_left->num_window_groups; g++)
00184     {
00185         /* Do perceptual noise substitution decoding */
00186         for (b = 0; b < ics_left->window_group_length[g]; b++)
00187         {
00188             for (sfb = 0; sfb < ics_left->max_sfb; sfb++)
00189             {
00190                 if (is_noise(ics_left, g, sfb))
00191                 {
00192 #ifdef LTP_DEC
00193                     /* Simultaneous use of LTP and PNS is not prevented in the
00194                        syntax. If both LTP, and PNS are enabled on the same
00195                        scalefactor band, PNS takes precedence, and no prediction
00196                        is applied to this band.
00197                     */
00198                     ics_left->ltp.long_used[sfb] = 0;
00199                     ics_left->ltp2.long_used[sfb] = 0;
00200 #endif
00201 
00202 #ifdef MAIN_DEC
00203                     /* For scalefactor bands coded using PNS the corresponding
00204                        predictors are switched to "off".
00205                     */
00206                     ics_left->pred.prediction_used[sfb] = 0;
00207 #endif
00208 
00209                     offs = ics_left->swb_offset[sfb];
00210                     size = ics_left->swb_offset[sfb+1] - offs;
00211 
00212                     /* Generate random vector */
00213                     gen_rand_vector(&spec_left[(group*nshort)+offs],
00214                         ics_left->scale_factors[g][sfb], size, sub);
00215                 }
00216 
00217 /* From the spec:
00218    If the same scalefactor band and group is coded by perceptual noise
00219    substitution in both channels of a channel pair, the correlation of
00220    the noise signal can be controlled by means of the ms_used field: While
00221    the default noise generation process works independently for each channel
00222    (separate generation of random vectors), the same random vector is used
00223    for both channels if ms_used[] is set for a particular scalefactor band
00224    and group. In this case, no M/S stereo coding is carried out (because M/S
00225    stereo coding and noise substitution coding are mutually exclusive).
00226    If the same scalefactor band and group is coded by perceptual noise
00227    substitution in only one channel of a channel pair the setting of ms_used[]
00228    is not evaluated.
00229 */
00230                 if (channel_pair)
00231                 {
00232                     if (is_noise(ics_right, g, sfb))
00233                     {
00234                         if (((ics_left->ms_mask_present == 1) &&
00235                             (ics_left->ms_used[g][sfb])) ||
00236                             (ics_left->ms_mask_present == 2))
00237                         {
00238                             uint16_t c;
00239 
00240                             offs = ics_right->swb_offset[sfb];
00241                             size = ics_right->swb_offset[sfb+1] - offs;
00242 
00243                             for (c = 0; c < size; c++)
00244                             {
00245                                 spec_right[(group*nshort) + offs + c] =
00246                                     spec_left[(group*nshort) + offs + c];
00247                             }
00248                         } else /*if (ics_left->ms_mask_present == 0)*/ {
00249 #ifdef LTP_DEC
00250                             ics_right->ltp.long_used[sfb] = 0;
00251                             ics_right->ltp2.long_used[sfb] = 0;
00252 #endif
00253 #ifdef MAIN_DEC
00254                             ics_right->pred.prediction_used[sfb] = 0;
00255 #endif
00256 
00257                             offs = ics_right->swb_offset[sfb];
00258                             size = ics_right->swb_offset[sfb+1] - offs;
00259 
00260                             /* Generate random vector */
00261                             gen_rand_vector(&spec_right[(group*nshort)+offs],
00262                                 ics_right->scale_factors[g][sfb], size, sub);
00263                         }
00264                     }
00265                 }
00266             } /* sfb */
00267             group++;
00268         } /* b */
00269     } /* g */
00270 }

Generated on Tue Dec 13 14:47:42 2005 for guliverkli by  doxygen 1.4.5