• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 **********************************************************************************/
prepareSfbPe(PE_DATA * peData,PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],const Word16 nChannels,const Word16 peOffset)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 **********************************************************************************/
calcSfbPe(PE_DATA * peData,PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],const Word16 nChannels)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