Home | History | Annotate | Download | only in src
      1 /*
      2  ** Copyright 2003-2010, VisualOn, Inc.
      3  **
      4  ** Licensed under the Apache License, Version 2.0 (the "License");
      5  ** you may not use this file except in compliance with the License.
      6  ** You may obtain a copy of the License at
      7  **
      8  **     http://www.apache.org/licenses/LICENSE-2.0
      9  **
     10  ** Unless required by applicable law or agreed to in writing, software
     11  ** distributed under the License is distributed on an "AS IS" BASIS,
     12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  ** See the License for the specific language governing permissions and
     14  ** limitations under the License.
     15  */
     16 /*******************************************************************************
     17 	File:		psy_configuration.c
     18 
     19 	Content:	Psychoaccoustic configuration functions
     20 
     21 *******************************************************************************/
     22 
     23 #include "basic_op.h"
     24 #include "oper_32b.h"
     25 #include "psy_configuration.h"
     26 #include "adj_thr.h"
     27 #include "aac_rom.h"
     28 
     29 
     30 
     31 #define BARC_SCALE	100 /* integer barc values are scaled with 100 */
     32 #define LOG2_1000	301 /* log2*1000 */
     33 #define PI2_1000	1571 /* pi/2*1000*/
     34 #define ATAN_COEF1	3560 /* 1000/0.280872f*/
     35 #define ATAN_COEF2	281 /* 1000*0.280872f*/
     36 
     37 
     38 typedef struct{
     39   Word32 sampleRate;
     40   const UWord8 *paramLong;
     41   const UWord8 *paramShort;
     42 }SFB_INFO_TAB;
     43 
     44 static const Word16 ABS_LEV = 20;
     45 static const Word16 BARC_THR_QUIET[] = {15, 10,  7,  2,  0,  0,  0,  0,  0,  0,
     46                                          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     47                                          3,  5, 10, 20, 30};
     48 
     49 
     50 
     51 static const Word16 max_bark = 24; /* maximum bark-value */
     52 static const Word16 maskLow  = 30; /* in 1dB/bark */
     53 static const Word16 maskHigh = 15; /* in 1*dB/bark */
     54 static const Word16 c_ratio  = 0x0029; /* pow(10.0f, -(29.0f/10.0f)) */
     55 
     56 static const Word16 maskLowSprEnLong = 30;       /* in 1dB/bark */
     57 static const Word16 maskHighSprEnLong = 20;      /* in 1dB/bark */
     58 static const Word16 maskHighSprEnLongLowBr = 15; /* in 1dB/bark */
     59 static const Word16 maskLowSprEnShort = 20;      /* in 1dB/bark */
     60 static const Word16 maskHighSprEnShort = 15;     /* in 1dB/bark */
     61 static const Word16 c_minRemainingThresholdFactor = 0x0148;    /* 0.01 *(1 << 15)*/
     62 static const Word32 c_maxsnr = 0x66666666;		 /* upper limit is -1 dB */
     63 static const Word32 c_minsnr = 0x00624dd3;		 /* lower limit is -25 dB */
     64 
     65 static const Word32 c_maxClipEnergyLong = 0x77359400;  /* 2.0e9f*/
     66 static const Word32 c_maxClipEnergyShort = 0x01dcd650; /* 2.0e9f/(AACENC_TRANS_FAC*AACENC_TRANS_FAC)*/
     67 
     68 
     69 Word32 GetSRIndex(Word32 sampleRate)
     70 {
     71     if (92017 <= sampleRate) return 0;
     72     if (75132 <= sampleRate) return 1;
     73     if (55426 <= sampleRate) return 2;
     74     if (46009 <= sampleRate) return 3;
     75     if (37566 <= sampleRate) return 4;
     76     if (27713 <= sampleRate) return 5;
     77     if (23004 <= sampleRate) return 6;
     78     if (18783 <= sampleRate) return 7;
     79     if (13856 <= sampleRate) return 8;
     80     if (11502 <= sampleRate) return 9;
     81     if (9391 <= sampleRate) return 10;
     82 
     83     return 11;
     84 }
     85 
     86 
     87 /*********************************************************************************
     88 *
     89 * function name: atan_1000
     90 * description:  calculates 1000*atan(x/1000)
     91 *               based on atan approx for x > 0
     92 *				atan(x) = x/((float)1.0f+(float)0.280872f*x*x)  if x < 1
     93 *						= pi/2 - x/((float)0.280872f +x*x)	    if x >= 1
     94 * return:       1000*atan(x/1000)
     95 *
     96 **********************************************************************************/
     97 static Word16 atan_1000(Word32 val)
     98 {
     99   Word32 y;
    100 
    101 
    102   if(L_sub(val, 1000) < 0) {
    103     y = extract_l(((1000 * val) / (1000 + ((val * val) / ATAN_COEF1))));
    104   }
    105   else {
    106     y = PI2_1000 - ((1000 * val) / (ATAN_COEF2 + ((val * val) / 1000)));
    107   }
    108 
    109   return extract_l(y);
    110 }
    111 
    112 
    113 /*****************************************************************************
    114 *
    115 * function name: BarcLineValue
    116 * description:  Calculates barc value for one frequency line
    117 * returns:      barc value of line * BARC_SCALE
    118 * input:        number of lines in transform, index of line to check, Fs
    119 * output:
    120 *
    121 *****************************************************************************/
    122 static Word16 BarcLineValue(Word16 noOfLines, Word16 fftLine, Word32 samplingFreq)
    123 {
    124   Word32 center_freq, temp, bvalFFTLine;
    125 
    126   /* center frequency of fft line */
    127   center_freq = (fftLine * samplingFreq) / (noOfLines << 1);
    128   temp =  atan_1000((center_freq << 2) / (3*10));
    129   bvalFFTLine =
    130     (26600 * atan_1000((center_freq*76) / 100) + 7*temp*temp) / (2*1000*1000 / BARC_SCALE);
    131 
    132   return saturate(bvalFFTLine);
    133 }
    134 
    135 /*****************************************************************************
    136 *
    137 * function name: initThrQuiet
    138 * description:  init thredhold in quiet
    139 *
    140 *****************************************************************************/
    141 static void initThrQuiet(Word16  numPb,
    142                          const Word16 *pbOffset,
    143                          Word16 *pbBarcVal,
    144                          Word32 *pbThresholdQuiet) {
    145   Word16 i;
    146   Word16 barcThrQuiet;
    147 
    148   for(i=0; i<numPb; i++) {
    149     Word16 bv1, bv2;
    150 
    151 
    152     if (i>0)
    153       bv1 = (pbBarcVal[i] + pbBarcVal[i-1]) >> 1;
    154     else
    155       bv1 = pbBarcVal[i] >> 1;
    156 
    157 
    158     if (i < (numPb - 1))
    159       bv2 = (pbBarcVal[i] + pbBarcVal[i+1]) >> 1;
    160     else {
    161       bv2 = pbBarcVal[i];
    162     }
    163 
    164     bv1 = min((bv1 / BARC_SCALE), max_bark);
    165     bv2 = min((bv2 / BARC_SCALE), max_bark);
    166 
    167     barcThrQuiet = min(BARC_THR_QUIET[bv1], BARC_THR_QUIET[bv2]);
    168 
    169 
    170     /*
    171       we calculate
    172       pow(10.0f,(float)(barcThrQuiet - ABS_LEV)*0.1)*(float)ABS_LOW*(pbOffset[i+1] - pbOffset[i]);
    173     */
    174 
    175     pbThresholdQuiet[i] = pow2_xy((((barcThrQuiet - ABS_LEV) * 100) +
    176                           LOG2_1000*(14+2*LOG_NORM_PCM)), LOG2_1000) * (pbOffset[i+1] - pbOffset[i]);
    177   }
    178 }
    179 
    180 
    181 /*****************************************************************************
    182 *
    183 * function name: initSpreading
    184 * description:  init energy spreading parameter
    185 *
    186 *****************************************************************************/
    187 static void initSpreading(Word16  numPb,
    188                           Word16 *pbBarcValue,
    189                           Word16 *pbMaskLoFactor,
    190                           Word16 *pbMaskHiFactor,
    191                           Word16 *pbMaskLoFactorSprEn,
    192                           Word16 *pbMaskHiFactorSprEn,
    193                           const Word32 bitrate,
    194                           const Word16 blockType)
    195 {
    196   Word16 i;
    197   Word16 maskLowSprEn, maskHighSprEn;
    198 
    199 
    200   if (sub(blockType, SHORT_WINDOW) != 0) {
    201     maskLowSprEn = maskLowSprEnLong;
    202 
    203     if (bitrate > 22000)
    204       maskHighSprEn = maskHighSprEnLong;
    205     else
    206       maskHighSprEn = maskHighSprEnLongLowBr;
    207   }
    208   else {
    209     maskLowSprEn = maskLowSprEnShort;
    210     maskHighSprEn = maskHighSprEnShort;
    211   }
    212 
    213   for(i=0; i<numPb; i++) {
    214 
    215     if (i > 0) {
    216       Word32 dbVal;
    217       Word16 dbark = pbBarcValue[i] - pbBarcValue[i-1];
    218 
    219       /*
    220         we calulate pow(10.0f, -0.1*dbVal/BARC_SCALE)
    221       */
    222       dbVal = (maskHigh * dbark);
    223       pbMaskHiFactor[i] = round16(pow2_xy(L_negate(dbVal), (Word32)LOG2_1000));             /* 0.301 log10(2) */
    224 
    225       dbVal = (maskLow * dbark);
    226       pbMaskLoFactor[i-1] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
    227 
    228 
    229       dbVal = (maskHighSprEn * dbark);
    230       pbMaskHiFactorSprEn[i] =  round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
    231       dbVal = (maskLowSprEn * dbark);
    232       pbMaskLoFactorSprEn[i-1] = round16(pow2_xy(L_negate(dbVal),(Word32)LOG2_1000));
    233     }
    234     else {
    235       pbMaskHiFactor[i] = 0;
    236       pbMaskLoFactor[numPb-1] = 0;
    237 
    238       pbMaskHiFactorSprEn[i] = 0;
    239       pbMaskLoFactorSprEn[numPb-1] = 0;
    240     }
    241   }
    242 
    243 }
    244 
    245 
    246 /*****************************************************************************
    247 *
    248 * function name: initBarcValues
    249 * description:  init bark value
    250 *
    251 *****************************************************************************/
    252 static void initBarcValues(Word16  numPb,
    253                            const Word16 *pbOffset,
    254                            Word16  numLines,
    255                            Word32  samplingFrequency,
    256                            Word16 *pbBval)
    257 {
    258   Word16 i;
    259   Word16 pbBval0, pbBval1;
    260 
    261   pbBval0 = 0;
    262 
    263   for(i=0; i<numPb; i++){
    264     pbBval1 = BarcLineValue(numLines, pbOffset[i+1], samplingFrequency);
    265     pbBval[i] = (pbBval0 + pbBval1) >> 1;
    266     pbBval0 = pbBval1;
    267   }
    268 }
    269 
    270 
    271 /*****************************************************************************
    272 *
    273 * function name: initMinSnr
    274 * description:  calculate min snr parameter
    275 *				minSnr(n) = 1/(2^sfbPemin(n)/w(n) - 1.5)
    276 *
    277 *****************************************************************************/
    278 static void initMinSnr(const Word32  bitrate,
    279                        const Word32  samplerate,
    280                        const Word16  numLines,
    281                        const Word16 *sfbOffset,
    282                        const Word16 *pbBarcVal,
    283                        const Word16  sfbActive,
    284                        Word16       *sfbMinSnr)
    285 {
    286   Word16 sfb;
    287   Word16 barcWidth;
    288   Word16 pePerWindow;
    289   Word32 pePart;
    290   Word32 snr;
    291   Word16 pbVal0, pbVal1, shift;
    292 
    293   /* relative number of active barks */
    294 
    295 
    296   pePerWindow = bits2pe(extract_l((bitrate * numLines) / samplerate));
    297 
    298   pbVal0 = 0;
    299 
    300   for (sfb=0; sfb<sfbActive; sfb++) {
    301 
    302     pbVal1 = (pbBarcVal[sfb] << 1) - pbVal0;
    303     barcWidth = pbVal1 - pbVal0;
    304     pbVal0 = pbVal1;
    305 
    306     /* allow at least 2.4% of pe for each active barc */
    307 	pePart = ((pePerWindow * 24) * (max_bark * barcWidth)) /
    308         (pbBarcVal[sfbActive-1] * (sfbOffset[sfb+1] - sfbOffset[sfb]));
    309 
    310 
    311     pePart = min(pePart, 8400);
    312     pePart = max(pePart, 1400);
    313 
    314     /* minSnr(n) = 1/(2^sfbPemin(n)/w(n) - 1.5)*/
    315 	/* we add an offset of 2^16 to the pow functions */
    316 	/* 0xc000 = 1.5*(1 << 15)*/
    317 
    318     snr = pow2_xy((pePart - 16*1000),1000) - 0x0000c000;
    319 
    320     if(snr > 0x00008000)
    321 	{
    322 		shift = norm_l(snr);
    323 		snr = Div_32(0x00008000 << shift, snr << shift);
    324 	}
    325 	else
    326 	{
    327 		snr = 0x7fffffff;
    328 	}
    329 
    330     /* upper limit is -1 dB */
    331     snr = min(snr, c_maxsnr);
    332     /* lower limit is -25 dB */
    333     snr = max(snr, c_minsnr);
    334     sfbMinSnr[sfb] = round16(snr);
    335   }
    336 
    337 }
    338 
    339 /*****************************************************************************
    340 *
    341 * function name: InitPsyConfigurationLong
    342 * description:  init long block psychoacoustic configuration
    343 *
    344 *****************************************************************************/
    345 Word16 InitPsyConfigurationLong(Word32 bitrate,
    346                                 Word32 samplerate,
    347                                 Word16 bandwidth,
    348                                 PSY_CONFIGURATION_LONG *psyConf)
    349 {
    350   Word32 samplerateindex;
    351   Word16 sfbBarcVal[MAX_SFB_LONG];
    352   Word16 sfb;
    353 
    354   /*
    355     init sfb table
    356   */
    357   samplerateindex = GetSRIndex(samplerate);
    358   psyConf->sfbCnt = sfBandTotalLong[samplerateindex];
    359   psyConf->sfbOffset = sfBandTabLong + sfBandTabLongOffset[samplerateindex];
    360   psyConf->sampRateIdx = samplerateindex;
    361 
    362   /*
    363     calculate barc values for each pb
    364   */
    365   initBarcValues(psyConf->sfbCnt,
    366                  psyConf->sfbOffset,
    367                  psyConf->sfbOffset[psyConf->sfbCnt],
    368                  samplerate,
    369                  sfbBarcVal);
    370 
    371   /*
    372     init thresholds in quiet
    373   */
    374   initThrQuiet(psyConf->sfbCnt,
    375                psyConf->sfbOffset,
    376                sfbBarcVal,
    377                psyConf->sfbThresholdQuiet);
    378 
    379   /*
    380     calculate spreading function
    381   */
    382   initSpreading(psyConf->sfbCnt,
    383                 sfbBarcVal,
    384                 psyConf->sfbMaskLowFactor,
    385                 psyConf->sfbMaskHighFactor,
    386                 psyConf->sfbMaskLowFactorSprEn,
    387                 psyConf->sfbMaskHighFactorSprEn,
    388                 bitrate,
    389                 LONG_WINDOW);
    390 
    391   /*
    392     init ratio
    393   */
    394   psyConf->ratio = c_ratio;
    395 
    396   psyConf->maxAllowedIncreaseFactor = 2;
    397   psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor;    /* 0.01 *(1 << 15)*/
    398 
    399   psyConf->clipEnergy = c_maxClipEnergyLong;
    400   psyConf->lowpassLine = extract_l((bandwidth<<1) * FRAME_LEN_LONG / samplerate);
    401 
    402   for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
    403     if (sub(psyConf->sfbOffset[sfb], psyConf->lowpassLine) >= 0)
    404       break;
    405   }
    406   psyConf->sfbActive = sfb;
    407 
    408   /*
    409     calculate minSnr
    410   */
    411   initMinSnr(bitrate,
    412              samplerate,
    413              psyConf->sfbOffset[psyConf->sfbCnt],
    414              psyConf->sfbOffset,
    415              sfbBarcVal,
    416              psyConf->sfbActive,
    417              psyConf->sfbMinSnr);
    418 
    419 
    420   return(0);
    421 }
    422 
    423 /*****************************************************************************
    424 *
    425 * function name: InitPsyConfigurationShort
    426 * description:  init short block psychoacoustic configuration
    427 *
    428 *****************************************************************************/
    429 Word16 InitPsyConfigurationShort(Word32 bitrate,
    430                                  Word32 samplerate,
    431                                  Word16 bandwidth,
    432                                  PSY_CONFIGURATION_SHORT *psyConf)
    433 {
    434   Word32 samplerateindex;
    435   Word16 sfbBarcVal[MAX_SFB_SHORT];
    436   Word16 sfb;
    437   /*
    438     init sfb table
    439   */
    440   samplerateindex = GetSRIndex(samplerate);
    441   psyConf->sfbCnt = sfBandTotalShort[samplerateindex];
    442   psyConf->sfbOffset = sfBandTabShort + sfBandTabShortOffset[samplerateindex];
    443   psyConf->sampRateIdx = samplerateindex;
    444   /*
    445     calculate barc values for each pb
    446   */
    447   initBarcValues(psyConf->sfbCnt,
    448                  psyConf->sfbOffset,
    449                  psyConf->sfbOffset[psyConf->sfbCnt],
    450                  samplerate,
    451                  sfbBarcVal);
    452 
    453   /*
    454     init thresholds in quiet
    455   */
    456   initThrQuiet(psyConf->sfbCnt,
    457                psyConf->sfbOffset,
    458                sfbBarcVal,
    459                psyConf->sfbThresholdQuiet);
    460 
    461   /*
    462     calculate spreading function
    463   */
    464   initSpreading(psyConf->sfbCnt,
    465                 sfbBarcVal,
    466                 psyConf->sfbMaskLowFactor,
    467                 psyConf->sfbMaskHighFactor,
    468                 psyConf->sfbMaskLowFactorSprEn,
    469                 psyConf->sfbMaskHighFactorSprEn,
    470                 bitrate,
    471                 SHORT_WINDOW);
    472 
    473   /*
    474     init ratio
    475   */
    476   psyConf->ratio = c_ratio;
    477 
    478   psyConf->maxAllowedIncreaseFactor = 2;
    479   psyConf->minRemainingThresholdFactor = c_minRemainingThresholdFactor;
    480 
    481   psyConf->clipEnergy = c_maxClipEnergyShort;
    482 
    483   psyConf->lowpassLine = extract_l(((bandwidth << 1) * FRAME_LEN_SHORT) / samplerate);
    484 
    485   for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) {
    486 
    487     if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine)
    488       break;
    489   }
    490   psyConf->sfbActive = sfb;
    491 
    492   /*
    493     calculate minSnr
    494   */
    495   initMinSnr(bitrate,
    496              samplerate,
    497              psyConf->sfbOffset[psyConf->sfbCnt],
    498              psyConf->sfbOffset,
    499              sfbBarcVal,
    500              psyConf->sfbActive,
    501              psyConf->sfbMinSnr);
    502 
    503   return(0);
    504 }
    505 
    506