line_pe.c revision 956c553ab0ce72f8074ad0fda2ffd66a0305700c
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
29static const Word16  C1_I = 12;    /* log(8.0)/log(2) *4         */
30static const Word32  C2_I = 10830; /* log(2.5)/log(2) * 1024 * 4 * 2 */
31static 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**********************************************************************************/
40void 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**********************************************************************************/
71void 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