1219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard/*
2219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard **
4219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** you may not use this file except in compliance with the License.
6219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** You may obtain a copy of the License at
7219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard **
8219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard **
10219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** See the License for the specific language governing permissions and
14219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard ** limitations under the License.
15219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard */
16219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard/*******************************************************************************
17219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	File:		line_pe.c
18219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
19219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	Content:	Perceptual entropie module functions
20219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
21219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard*******************************************************************************/
22219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
23219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard#include "basic_op.h"
2417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "oper_32b.h"
2517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "typedef.h"
2617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong#include "line_pe.h"
2717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
2817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
2917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongstatic const Word16  C1_I = 12;    /* log(8.0)/log(2) *4         */
3017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongstatic const Word32  C2_I = 10830; /* log(2.5)/log(2) * 1024 * 4 * 2 */
3117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongstatic const Word16  C3_I = 573;   /* (1-C2/C1) *1024            */
3217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
3317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
3417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*****************************************************************************
3517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*
3617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* function name: prepareSfbPe
3717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* description:  constants that do not change during successive pe calculations
3817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*
3917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong**********************************************************************************/
4017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid prepareSfbPe(PE_DATA *peData,
4117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong                  PSY_OUT_CHANNEL  psyOutChannel[MAX_CHANNELS],
4217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong                  Word16 logSfbEnergy[MAX_CHANNELS][MAX_GROUPED_SFB],
4317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong                  Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
4417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong                  const Word16 nChannels,
4517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong                  const Word16 peOffset)
4617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
4717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  Word32 sfbGrp, sfb;
4817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  Word32 ch;
4917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
5017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  for(ch=0; ch<nChannels; ch++) {
5117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
5217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    PE_CHANNEL_DATA *peChanData=&peData->peChannelData[ch];
5317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    for(sfbGrp=0;sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup){
5417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
5517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	    peChanData->sfbNLines4[sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb];
5617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong        sfbNRelevantLines[ch][sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb] >> 2;
5717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	    peChanData->sfbLdEnergy[sfbGrp+sfb] = logSfbEnergy[ch][sfbGrp+sfb];
5817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong      }
5917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    }
6017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  }
6117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  peData->offset = peOffset;
6217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
6317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
6417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
6517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong/*****************************************************************************
6617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*
6717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* function name: calcSfbPe
6817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong* description:  constPart is sfbPe without the threshold part n*ld(thr) or n*C3*ld(thr)
6917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong*
7017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong**********************************************************************************/
7117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dongvoid calcSfbPe(PE_DATA *peData,
7217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong               PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
7317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong               const Word16 nChannels)
7417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong{
7517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  Word32 ch;
7617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  Word32 sfbGrp, sfb;
7717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  Word32 nLines4;
78219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard  Word32 ldThr, ldRatio;
7917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  Word32 pe, constPart, nActiveLines;
8017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
8117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  peData->pe = peData->offset;
8217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  peData->constPart = 0;
8317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  peData->nActiveLines = 0;
8417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  for(ch=0; ch<nChannels; ch++) {
8517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
8617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
8717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    const Word32 *sfbEnergy = psyOutChan->sfbEnergy;
8817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    const Word32 *sfbThreshold = psyOutChan->sfbThreshold;
8917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
9017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    pe = 0;
9117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    constPart = 0;
9217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    nActiveLines = 0;
9317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
9417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {
9517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong      for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
9617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong        Word32 nrg = sfbEnergy[sfbGrp+sfb];
9717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong        Word32 thres = sfbThreshold[sfbGrp+sfb];
98219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard        Word32 sfbLDEn = peChanData->sfbLdEnergy[sfbGrp+sfb];
9917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
10017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong        if (nrg > thres) {
10117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong          ldThr = iLog4(thres);
10217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
10317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong          ldRatio = sfbLDEn - ldThr;
10417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
10517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong          nLines4 = peChanData->sfbNLines4[sfbGrp+sfb];
10617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
10717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong          /* sfbPe = nl*log2(en/thr)*/
10817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		  if (ldRatio >= C1_I) {
10917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong            peChanData->sfbPe[sfbGrp+sfb] = (nLines4*ldRatio + 8) >> 4;
11017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong            peChanData->sfbConstPart[sfbGrp+sfb] = ((nLines4*sfbLDEn)) >> 4;
11117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong          }
11217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong          else {
11317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong		  /* sfbPe = nl*(c2 + c3*log2(en/thr))*/
114219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard            peChanData->sfbPe[sfbGrp+sfb] = extract_l((L_mpy_wx(
115219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard                    (C2_I + C3_I * ldRatio * 2) << 4, nLines4) + 4) >> 3);
116219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard            peChanData->sfbConstPart[sfbGrp+sfb] = extract_l(( L_mpy_wx(
117219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard                    (C2_I + C3_I * sfbLDEn * 2) << 4, nLines4) + 4) >> 3);
11817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong            nLines4 = (nLines4 * C3_I + (1024<<1)) >> 10;
11917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong          }
12017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong          peChanData->sfbNActiveLines[sfbGrp+sfb] = nLines4 >> 2;
12117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong        }
12217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong        else {
12317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong          peChanData->sfbPe[sfbGrp+sfb] = 0;
12417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong          peChanData->sfbConstPart[sfbGrp+sfb] = 0;
12517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong          peChanData->sfbNActiveLines[sfbGrp+sfb] = 0;
12617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong        }
12717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong        pe = pe + peChanData->sfbPe[sfbGrp+sfb];
12817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong        constPart = constPart + peChanData->sfbConstPart[sfbGrp+sfb];
12917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong        nActiveLines = nActiveLines + peChanData->sfbNActiveLines[sfbGrp+sfb];
13017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong      }
13117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    }
132219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard
133219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard	peChanData->pe = saturate(pe);
134219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    peChanData->constPart = saturate(constPart);
135219e2627f1e062c10645664b0d2470d4dfaf5083Mans Rullgard    peChanData->nActiveLines = saturate(nActiveLines);
13617299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
13717299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong
13817299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	pe += peData->pe;
13917299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	peData->pe = saturate(pe);
14017299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    constPart += peData->constPart;
14117299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	peData->constPart = saturate(constPart);
14217299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong    nActiveLines += peData->nActiveLines;
14317299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong	peData->nActiveLines = saturate(nActiveLines);
14417299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong  }
14517299ab50ceb70d904e610e3b2d7fb2361a11e03James Dong}
146