/* ** 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; chpeChannelData[ch]; for(sfbGrp=0;sfbGrpsfbCnt; sfbGrp+=psyOutChan->sfbPerGroup){ for (sfb=0; sfbmaxSfbPerGroup; 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; chpeChannelData[ch]; const Word32 *sfbEnergy = psyOutChan->sfbEnergy; const Word32 *sfbThreshold = psyOutChan->sfbThreshold; pe = 0; constPart = 0; nActiveLines = 0; for(sfbGrp=0; sfbGrpsfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) { for (sfb=0; sfbmaxSfbPerGroup; 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); } }