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 temp;
     54   Word32 sfb,sfboffs, j;
     55   Word32 msMaskTrueSomewhere = 0;
     56   Word32 msMaskFalseSomewhere = 0;
     57 
     58   for (sfb=0; sfb<sfbCnt; sfb+=sfbPerGroup) {
     59     for (sfboffs=0;sfboffs<maxSfbPerGroup;sfboffs++) {
     60 
     61       Word32 temp;
     62       Word32 pnlr,pnms;
     63       Word32 minThreshold;
     64       Word32 thrL, thrR, nrgL, nrgR;
     65       Word32 idx, shift;
     66 
     67       idx = sfb + sfboffs;
     68 
     69       thrL = sfbThresholdLeft[idx];
     70       thrR = sfbThresholdRight[idx];
     71       nrgL = sfbEnergyLeft[idx];
     72       nrgR = sfbEnergyRight[idx];
     73 
     74       minThreshold = min(thrL, thrR);
     75 
     76       nrgL = max(nrgL,thrL) + 1;
     77       shift = norm_l(nrgL);
     78 	  nrgL = Div_32(thrL << shift, nrgL << shift);
     79       nrgR = max(nrgR,thrR) + 1;
     80       shift = norm_l(nrgR);
     81 	  nrgR = Div_32(thrR << shift, nrgR << shift);
     82 
     83 	  pnlr = fixmul(nrgL, nrgR);
     84 
     85       nrgL = sfbEnergyMid[idx];
     86       nrgR = sfbEnergySide[idx];
     87 
     88       nrgL = max(nrgL,minThreshold) + 1;
     89       shift = norm_l(nrgL);
     90 	  nrgL = Div_32(minThreshold << shift, nrgL << shift);
     91 
     92       nrgR = max(nrgR,minThreshold) + 1;
     93       shift = norm_l(nrgR);
     94 	  nrgR = Div_32(minThreshold << shift, nrgR << shift);
     95 
     96       pnms = fixmul(nrgL, nrgR);
     97 
     98       temp = (pnlr + 1) / ((pnms >> 8) + 1);
     99 
    100       temp = pnms - pnlr;
    101       if( temp > 0 ){
    102 
    103         msMask[idx] = 1;
    104         msMaskTrueSomewhere = 1;
    105 
    106         for (j=sfbOffset[idx]; j<sfbOffset[idx+1]; j++) {
    107           Word32 left, right;
    108           left  = (mdctSpectrumLeft[j] >>  1);
    109           right = (mdctSpectrumRight[j] >> 1);
    110           mdctSpectrumLeft[j] =  left + right;
    111           mdctSpectrumRight[j] =  left - right;
    112         }
    113 
    114         sfbThresholdLeft[idx] = minThreshold;
    115         sfbThresholdRight[idx] = minThreshold;
    116         sfbEnergyLeft[idx] = sfbEnergyMid[idx];
    117         sfbEnergyRight[idx] = sfbEnergySide[idx];
    118 
    119         sfbSpreadedEnRight[idx] = min(sfbSpreadedEnLeft[idx],sfbSpreadedEnRight[idx]) >> 1;
    120         sfbSpreadedEnLeft[idx] = sfbSpreadedEnRight[idx];
    121 
    122       }
    123       else {
    124         msMask[idx]  = 0;
    125         msMaskFalseSomewhere = 1;
    126       }
    127     }
    128     if ( msMaskTrueSomewhere ) {
    129       if(msMaskFalseSomewhere ) {
    130         *msDigest = SI_MS_MASK_SOME;
    131       } else {
    132         *msDigest = SI_MS_MASK_ALL;
    133       }
    134     } else {
    135       *msDigest = SI_MS_MASK_NONE;
    136     }
    137   }
    138 
    139 }
    140