Home | History | Annotate | Download | only in src
      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:		ms_stereo.c
     18 
     19 	Content:	MS stereo processing function
     20 
     21 *******************************************************************************/
     22 
     23 #include "basic_op.h"
     24 #include "oper_32b.h"
     25 #include "psy_const.h"
     26 #include "ms_stereo.h"
     27 
     28 
     29 /********************************************************************************
     30 *
     31 * function name: MsStereoProcessing
     32 * description:  detect use ms stereo or not
     33 *				if ((min(thrLn, thrRn)*min(thrLn, thrRn))/(enMn*enSn))
     34 *				>= ((thrLn *thrRn)/(enLn*enRn)) then ms stereo
     35 *
     36 **********************************************************************************/
     37 void MsStereoProcessing(Word32       *sfbEnergyLeft,
     38                         Word32       *sfbEnergyRight,
     39                         const Word32 *sfbEnergyMid,
     40                         const Word32 *sfbEnergySide,
     41                         Word32       *mdctSpectrumLeft,
     42                         Word32       *mdctSpectrumRight,
     43                         Word32       *sfbThresholdLeft,
     44                         Word32       *sfbThresholdRight,
     45                         Word32       *sfbSpreadedEnLeft,
     46                         Word32       *sfbSpreadedEnRight,
     47                         Word16       *msDigest,
     48                         Word16       *msMask,
     49                         const Word16  sfbCnt,
     50                         const Word16  sfbPerGroup,
     51                         const Word16  maxSfbPerGroup,
     52                         const Word16 *sfbOffset) {
     53   Word32 sfb,sfboffs, j;
     54   Word32 msMaskTrueSomewhere = 0;
     55   Word32 msMaskFalseSomewhere = 0;
     56 
     57   for (sfb=0; sfb<sfbCnt; sfb+=sfbPerGroup) {
     58     for (sfboffs=0;sfboffs<maxSfbPerGroup;sfboffs++) {
     59 
     60       Word32 temp;
     61       Word32 pnlr,pnms;
     62       Word32 minThreshold;
     63       Word32 thrL, thrR, nrgL, nrgR;
     64       Word32 idx, shift;
     65 
     66       idx = sfb + sfboffs;
     67 
     68       thrL = sfbThresholdLeft[idx];
     69       thrR = sfbThresholdRight[idx];
     70       nrgL = sfbEnergyLeft[idx];
     71       nrgR = sfbEnergyRight[idx];
     72 
     73       minThreshold = min(thrL, thrR);
     74 
     75       nrgL = max(nrgL,thrL) + 1;
     76       shift = norm_l(nrgL);
     77 	  nrgL = Div_32(thrL << shift, nrgL << shift);
     78       nrgR = max(nrgR,thrR) + 1;
     79       shift = norm_l(nrgR);
     80 	  nrgR = Div_32(thrR << shift, nrgR << shift);
     81 
     82 	  pnlr = fixmul(nrgL, nrgR);
     83 
     84       nrgL = sfbEnergyMid[idx];
     85       nrgR = sfbEnergySide[idx];
     86 
     87       nrgL = max(nrgL,minThreshold) + 1;
     88       shift = norm_l(nrgL);
     89 	  nrgL = Div_32(minThreshold << shift, nrgL << shift);
     90 
     91       nrgR = max(nrgR,minThreshold) + 1;
     92       shift = norm_l(nrgR);
     93 	  nrgR = Div_32(minThreshold << shift, nrgR << shift);
     94 
     95       pnms = fixmul(nrgL, nrgR);
     96 
     97       temp = (pnlr + 1) / ((pnms >> 8) + 1);
     98 
     99       temp = pnms - pnlr;
    100       if( temp > 0 ){
    101 
    102         msMask[idx] = 1;
    103         msMaskTrueSomewhere = 1;
    104 
    105         for (j=sfbOffset[idx]; j<sfbOffset[idx+1]; j++) {
    106           Word32 left, right;
    107           left  = (mdctSpectrumLeft[j] >>  1);
    108           right = (mdctSpectrumRight[j] >> 1);
    109           mdctSpectrumLeft[j] =  left + right;
    110           mdctSpectrumRight[j] =  left - right;
    111         }
    112 
    113         sfbThresholdLeft[idx] = minThreshold;
    114         sfbThresholdRight[idx] = minThreshold;
    115         sfbEnergyLeft[idx] = sfbEnergyMid[idx];
    116         sfbEnergyRight[idx] = sfbEnergySide[idx];
    117 
    118         sfbSpreadedEnRight[idx] = min(sfbSpreadedEnLeft[idx],sfbSpreadedEnRight[idx]) >> 1;
    119         sfbSpreadedEnLeft[idx] = sfbSpreadedEnRight[idx];
    120 
    121       }
    122       else {
    123         msMask[idx]  = 0;
    124         msMaskFalseSomewhere = 1;
    125       }
    126     }
    127     if ( msMaskTrueSomewhere ) {
    128       if(msMaskFalseSomewhere ) {
    129         *msDigest = SI_MS_MASK_SOME;
    130       } else {
    131         *msDigest = SI_MS_MASK_ALL;
    132       }
    133     } else {
    134       *msDigest = SI_MS_MASK_NONE;
    135     }
    136   }
    137 
    138 }
    139