1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*******************************************************************************
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	File:		line_pe.c
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Content:	Perceptual entropie module functions
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/
22e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
24956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "oper_32b.h"
25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "typedef.h"
26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "line_pe.h"
27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word16  C1_I = 12;    /* log(8.0)/log(2) *4         */
30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32  C2_I = 10830; /* log(2.5)/log(2) * 1024 * 4 * 2 */
31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word16  C3_I = 573;   /* (1-C2/C1) *1024            */
32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
33956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: prepareSfbPe
37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  constants that do not change during successive pe calculations
38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid prepareSfbPe(PE_DATA *peData,
41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  const Word16 nChannels,
45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                  const Word16 peOffset)
46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 sfbGrp, sfb;
48b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  Word32 ch;
49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for(ch=0; ch<nChannels; ch++) {
51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    PE_CHANNEL_DATA *peChanData=&peData->peChannelData[ch];
53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for(sfbGrp=0;sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup){
54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
55b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	    peChanData->sfbNLines4[sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb];
56b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        sfbNRelevantLines[ch][sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb] >> 2;
57b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	    peChanData->sfbLdEnergy[sfbGrp+sfb] = logSfbEnergy[ch][sfbGrp+sfb];
58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
61b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  peData->offset = peOffset;
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: calcSfbPe
68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  constPart is sfbPe without the threshold part n*ld(thr) or n*C3*ld(thr)
69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid calcSfbPe(PE_DATA *peData,
72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong               const Word16 nChannels)
74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 ch;
76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 sfbGrp, sfb;
77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 nLines4;
78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word32 ldThr, ldRatio;
79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 pe, constPart, nActiveLines;
80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
81b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  peData->pe = peData->offset;
82b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  peData->constPart = 0;
83b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  peData->nActiveLines = 0;
84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for(ch=0; ch<nChannels; ch++) {
85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    const Word32 *sfbEnergy = psyOutChan->sfbEnergy;
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    const Word32 *sfbThreshold = psyOutChan->sfbThreshold;
89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
90b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    pe = 0;
91b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    constPart = 0;
92b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    nActiveLines = 0;
93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {
95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
96b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        Word32 nrg = sfbEnergy[sfbGrp+sfb];
97b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        Word32 thres = sfbThreshold[sfbGrp+sfb];
98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard        Word32 sfbLDEn = peChanData->sfbLdEnergy[sfbGrp+sfb];
99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (nrg > thres) {
101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          ldThr = iLog4(thres);
102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          ldRatio = sfbLDEn - ldThr;
104956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
105b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          nLines4 = peChanData->sfbNLines4[sfbGrp+sfb];
106b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          /* sfbPe = nl*log2(en/thr)*/
108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  if (ldRatio >= C1_I) {
109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            peChanData->sfbPe[sfbGrp+sfb] = (nLines4*ldRatio + 8) >> 4;
110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            peChanData->sfbConstPart[sfbGrp+sfb] = ((nLines4*sfbLDEn)) >> 4;
111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          else {
113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  /* sfbPe = nl*(c2 + c3*log2(en/thr))*/
114e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard            peChanData->sfbPe[sfbGrp+sfb] = extract_l((L_mpy_wx(
115e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard                    (C2_I + C3_I * ldRatio * 2) << 4, nLines4) + 4) >> 3);
116e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard            peChanData->sfbConstPart[sfbGrp+sfb] = extract_l(( L_mpy_wx(
117e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard                    (C2_I + C3_I * sfbLDEn * 2) << 4, nLines4) + 4) >> 3);
118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            nLines4 = (nLines4 * C3_I + (1024<<1)) >> 10;
119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          }
120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          peChanData->sfbNActiveLines[sfbGrp+sfb] = nLines4 >> 2;
121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        else {
123b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          peChanData->sfbPe[sfbGrp+sfb] = 0;
124b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          peChanData->sfbConstPart[sfbGrp+sfb] = 0;
125b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          peChanData->sfbNActiveLines[sfbGrp+sfb] = 0;
126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
127956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        pe = pe + peChanData->sfbPe[sfbGrp+sfb];
128956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        constPart = constPart + peChanData->sfbConstPart[sfbGrp+sfb];
129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        nActiveLines = nActiveLines + peChanData->sfbNActiveLines[sfbGrp+sfb];
130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
131956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
132956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
133b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	peChanData->pe = saturate(pe);
134b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    peChanData->constPart = saturate(constPart);
135b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    peChanData->nActiveLines = saturate(nActiveLines);
136b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
137b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
138956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	pe += peData->pe;
139b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	peData->pe = saturate(pe);
140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    constPart += peData->constPart;
141b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	peData->constPart = saturate(constPart);
142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    nActiveLines += peData->nActiveLines;
143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	peData->nActiveLines = saturate(nActiveLines);
144b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  }
145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
146