- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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 Mpeg4AAClicense@nero.com.
    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 }