146 lines
5.1 KiB
C
146 lines
5.1 KiB
C
/*
|
|
** Copyright 2003-2010, VisualOn, Inc.
|
|
**
|
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
|
** you may not use this file except in compliance with the License.
|
|
** You may obtain a copy of the License at
|
|
**
|
|
** http://www.apache.org/licenses/LICENSE-2.0
|
|
**
|
|
** Unless required by applicable law or agreed to in writing, software
|
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
** See the License for the specific language governing permissions and
|
|
** limitations under the License.
|
|
*/
|
|
/*******************************************************************************
|
|
File: line_pe.c
|
|
|
|
Content: Perceptual entropie module functions
|
|
|
|
*******************************************************************************/
|
|
|
|
#include "basic_op.h"
|
|
#include "oper_32b.h"
|
|
#include "typedef.h"
|
|
#include "line_pe.h"
|
|
|
|
|
|
static const Word16 C1_I = 12; /* log(8.0)/log(2) *4 */
|
|
static const Word32 C2_I = 10830; /* log(2.5)/log(2) * 1024 * 4 * 2 */
|
|
static const Word16 C3_I = 573; /* (1-C2/C1) *1024 */
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* function name: prepareSfbPe
|
|
* description: constants that do not change during successive pe calculations
|
|
*
|
|
**********************************************************************************/
|
|
void 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)
|
|
{
|
|
Word32 sfbGrp, sfb;
|
|
Word32 ch;
|
|
|
|
for(ch=0; ch<nChannels; ch++) {
|
|
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
|
|
PE_CHANNEL_DATA *peChanData=&peData->peChannelData[ch];
|
|
for(sfbGrp=0;sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup){
|
|
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
|
|
peChanData->sfbNLines4[sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb];
|
|
sfbNRelevantLines[ch][sfbGrp+sfb] = sfbNRelevantLines[ch][sfbGrp+sfb] >> 2;
|
|
peChanData->sfbLdEnergy[sfbGrp+sfb] = logSfbEnergy[ch][sfbGrp+sfb];
|
|
}
|
|
}
|
|
}
|
|
peData->offset = peOffset;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* function name: calcSfbPe
|
|
* description: constPart is sfbPe without the threshold part n*ld(thr) or n*C3*ld(thr)
|
|
*
|
|
**********************************************************************************/
|
|
void calcSfbPe(PE_DATA *peData,
|
|
PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
|
|
const Word16 nChannels)
|
|
{
|
|
Word32 ch;
|
|
Word32 sfbGrp, sfb;
|
|
Word32 nLines4;
|
|
Word32 ldThr, ldRatio;
|
|
Word32 pe, constPart, nActiveLines;
|
|
|
|
peData->pe = peData->offset;
|
|
peData->constPart = 0;
|
|
peData->nActiveLines = 0;
|
|
for(ch=0; ch<nChannels; ch++) {
|
|
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
|
|
PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch];
|
|
const Word32 *sfbEnergy = psyOutChan->sfbEnergy;
|
|
const Word32 *sfbThreshold = psyOutChan->sfbThreshold;
|
|
|
|
pe = 0;
|
|
constPart = 0;
|
|
nActiveLines = 0;
|
|
|
|
for(sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) {
|
|
for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) {
|
|
Word32 nrg = sfbEnergy[sfbGrp+sfb];
|
|
Word32 thres = sfbThreshold[sfbGrp+sfb];
|
|
Word32 sfbLDEn = peChanData->sfbLdEnergy[sfbGrp+sfb];
|
|
|
|
if (nrg > thres) {
|
|
ldThr = iLog4(thres);
|
|
|
|
ldRatio = sfbLDEn - ldThr;
|
|
|
|
nLines4 = peChanData->sfbNLines4[sfbGrp+sfb];
|
|
|
|
/* sfbPe = nl*log2(en/thr)*/
|
|
if (ldRatio >= C1_I) {
|
|
peChanData->sfbPe[sfbGrp+sfb] = (nLines4*ldRatio + 8) >> 4;
|
|
peChanData->sfbConstPart[sfbGrp+sfb] = ((nLines4*sfbLDEn)) >> 4;
|
|
}
|
|
else {
|
|
/* sfbPe = nl*(c2 + c3*log2(en/thr))*/
|
|
peChanData->sfbPe[sfbGrp+sfb] = extract_l((L_mpy_wx(
|
|
(C2_I + C3_I * ldRatio * 2) << 4, nLines4) + 4) >> 3);
|
|
peChanData->sfbConstPart[sfbGrp+sfb] = extract_l(( L_mpy_wx(
|
|
(C2_I + C3_I * sfbLDEn * 2) << 4, nLines4) + 4) >> 3);
|
|
nLines4 = (nLines4 * C3_I + (1024<<1)) >> 10;
|
|
}
|
|
peChanData->sfbNActiveLines[sfbGrp+sfb] = nLines4 >> 2;
|
|
}
|
|
else {
|
|
peChanData->sfbPe[sfbGrp+sfb] = 0;
|
|
peChanData->sfbConstPart[sfbGrp+sfb] = 0;
|
|
peChanData->sfbNActiveLines[sfbGrp+sfb] = 0;
|
|
}
|
|
pe = pe + peChanData->sfbPe[sfbGrp+sfb];
|
|
constPart = constPart + peChanData->sfbConstPart[sfbGrp+sfb];
|
|
nActiveLines = nActiveLines + peChanData->sfbNActiveLines[sfbGrp+sfb];
|
|
}
|
|
}
|
|
|
|
peChanData->pe = saturate(pe);
|
|
peChanData->constPart = saturate(constPart);
|
|
peChanData->nActiveLines = saturate(nActiveLines);
|
|
|
|
|
|
pe += peData->pe;
|
|
peData->pe = saturate(pe);
|
|
constPart += peData->constPart;
|
|
peData->constPart = saturate(constPart);
|
|
nActiveLines += peData->nActiveLines;
|
|
peData->nActiveLines = saturate(nActiveLines);
|
|
}
|
|
}
|