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:		line_pe.c
     18 
     19 	Content:	Perceptual entropie module functions
     20 
     21 *******************************************************************************/
     22 
     23 #include "basic_op.h"
     24 #include "oper_32b.h"
     25 #include "typedef.h"
     26 #include "line_pe.h"
     27 
     28 
     29 static const Word16  C1_I = 12;    /* log(8.0)/log(2) *4         */
     30 static const Word32  C2_I = 10830; /* log(2.5)/log(2) * 1024 * 4 * 2 */
     31 static const Word16  C3_I = 573;   /* (1-C2/C1) *1024            */
     32 
     33 
     34 /*****************************************************************************
     35 *
     36 * function name: prepareSfbPe
     37 * description:  constants that do not change during successive pe calculations
     38 *
     39 **********************************************************************************/
     40 void prepareSfbPe(PE_DATA *peData,
     41                   PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
     42                   Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
     43                   Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
     44                   const Word16 nChannels,
     45                   const Word16 peOffset)
     46 {
     47   Word32 sfbGrp, sfb;
     48   Word32 ch;
     49 
     50   for(ch=0; ch<nChannels; ch++) {
     51     PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
     52     PE_CHANNEL_DATA *peChanData=&peData->peChannelData[ch];
     53     for(sfbGrp=0;sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup){
     54       for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
     55 	    peChanData->sfbNLines4[sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb];
     56         sfbNRelevantLines[ch][sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb] >> 2;
     57 	    peChanData->sfbLdEnergy[sfbGrp+sfb] = logSfbEnergy[ch][sfbGrp+sfb];
     58       }
     59     }
     60   }
     61   peData->offset = peOffset;
     62 }
     63 
     64 
     65 /*****************************************************************************
     66 *
     67 * function name: calcSfbPe
     68 * description:  constPart is sfbPe without the threshold part n*ld(thr) or n*C3*ld(thr)
     69 *
     70 **********************************************************************************/
     71 void calcSfbPe(PE_DATA *peData,
     72                PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
     73                const Word16 nChannels)
     74 {
     75   Word32 ch;
     76   Word32 sfbGrp, sfb;
     77   Word32 nLines4;
     78   Word32 ldThr, ldRatio;
     79   Word32 pe, constPart, nActiveLines;
     80 
     81   peData->pe = peData->offset;
     82   peData->constPart = 0;
     83   peData->nActiveLines = 0;
     84   for(ch=0; ch<nChannels; ch++) {
     85     PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
     86     PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
     87     const Word32 *sfbEnergy = psyOutChan->sfbEnergy;
     88     const Word32 *sfbThreshold = psyOutChan->sfbThreshold;
     89 
     90     pe = 0;
     91     constPart = 0;
     92     nActiveLines = 0;
     93 
     94     for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {
     95       for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
     96         Word32 nrg = sfbEnergy[sfbGrp+sfb];
     97         Word32 thres = sfbThreshold[sfbGrp+sfb];
     98         Word32 sfbLDEn = peChanData->sfbLdEnergy[sfbGrp+sfb];
     99 
    100         if (nrg > thres) {
    101           ldThr = iLog4(thres);
    102 
    103           ldRatio = sfbLDEn - ldThr;
    104 
    105           nLines4 = peChanData->sfbNLines4[sfbGrp+sfb];
    106 
    107           /* sfbPe = nl*log2(en/thr)*/
    108 		  if (ldRatio >= C1_I) {
    109             peChanData->sfbPe[sfbGrp+sfb] = (nLines4*ldRatio + 8) >> 4;
    110             peChanData->sfbConstPart[sfbGrp+sfb] = ((nLines4*sfbLDEn)) >> 4;
    111           }
    112           else {
    113 		  /* sfbPe = nl*(c2 + c3*log2(en/thr))*/
    114             peChanData->sfbPe[sfbGrp+sfb] = extract_l((L_mpy_wx(
    115                     (C2_I + C3_I * ldRatio * 2) << 4, nLines4) + 4) >> 3);
    116             peChanData->sfbConstPart[sfbGrp+sfb] = extract_l(( L_mpy_wx(
    117                     (C2_I + C3_I * sfbLDEn * 2) << 4, nLines4) + 4) >> 3);
    118             nLines4 = (nLines4 * C3_I + (1024<<1)) >> 10;
    119           }
    120           peChanData->sfbNActiveLines[sfbGrp+sfb] = nLines4 >> 2;
    121         }
    122         else {
    123           peChanData->sfbPe[sfbGrp+sfb] = 0;
    124           peChanData->sfbConstPart[sfbGrp+sfb] = 0;
    125           peChanData->sfbNActiveLines[sfbGrp+sfb] = 0;
    126         }
    127         pe = pe + peChanData->sfbPe[sfbGrp+sfb];
    128         constPart = constPart + peChanData->sfbConstPart[sfbGrp+sfb];
    129         nActiveLines = nActiveLines + peChanData->sfbNActiveLines[sfbGrp+sfb];
    130       }
    131     }
    132 
    133 	peChanData->pe = saturate(pe);
    134     peChanData->constPart = saturate(constPart);
    135     peChanData->nActiveLines = saturate(nActiveLines);
    136 
    137 
    138 	pe += peData->pe;
    139 	peData->pe = saturate(pe);
    140     constPart += peData->constPart;
    141 	peData->constPart = saturate(constPart);
    142     nActiveLines += peData->nActiveLines;
    143 	peData->nActiveLines = saturate(nActiveLines);
    144   }
    145 }
    146