1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*******************************************************************************
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	File:		ms_stereo.c
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Content:	MS stereo processing function
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*******************************************************************************/
22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
24956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "oper_32b.h"
25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "psy_const.h"
26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "ms_stereo.h"
27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/********************************************************************************
30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: MsStereoProcessing
32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  detect use ms stereo or not
33b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard*				if ((min(thrLn, thrRn)*min(thrLn, thrRn))/(enMn*enSn))
34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*				>= ((thrLn *thrRn)/(enLn*enRn)) then ms stereo
35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid MsStereoProcessing(Word32       *sfbEnergyLeft,
38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word32       *sfbEnergyRight,
39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        const Word32 *sfbEnergyMid,
40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        const Word32 *sfbEnergySide,
41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word32       *mdctSpectrumLeft,
42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word32       *mdctSpectrumRight,
43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word32       *sfbThresholdLeft,
44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word32       *sfbThresholdRight,
45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word32       *sfbSpreadedEnLeft,
46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word32       *sfbSpreadedEnRight,
47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word16       *msDigest,
48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word16       *msMask,
49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        const Word16  sfbCnt,
50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        const Word16  sfbPerGroup,
51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        const Word16  maxSfbPerGroup,
52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        const Word16 *sfbOffset) {
53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 temp;
54b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  Word32 sfb,sfboffs, j;
55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 msMaskTrueSomewhere = 0;
56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 msMaskFalseSomewhere = 0;
57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (sfb=0; sfb<sfbCnt; sfb+=sfbPerGroup) {
59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for (sfboffs=0;sfboffs<maxSfbPerGroup;sfboffs++) {
60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      Word32 temp;
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      Word32 pnlr,pnms;
63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      Word32 minThreshold;
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      Word32 thrL, thrR, nrgL, nrgR;
65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      Word32 idx, shift;
66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
67b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      idx = sfb + sfboffs;
68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
69b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      thrL = sfbThresholdLeft[idx];
70b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      thrR = sfbThresholdRight[idx];
71b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      nrgL = sfbEnergyLeft[idx];
72b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      nrgR = sfbEnergyRight[idx];
73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      minThreshold = min(thrL, thrR);
75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      nrgL = max(nrgL,thrL) + 1;
77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard      shift = norm_l(nrgL);
78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  nrgL = Div_32(thrL << shift, nrgL << shift);
79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      nrgR = max(nrgR,thrR) + 1;
80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard      shift = norm_l(nrgR);
81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  nrgR = Div_32(thrR << shift, nrgR << shift);
82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  pnlr = fixmul(nrgL, nrgR);
84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
85b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      nrgL = sfbEnergyMid[idx];
86b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      nrgR = sfbEnergySide[idx];
87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      nrgL = max(nrgL,minThreshold) + 1;
89e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard      shift = norm_l(nrgL);
90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  nrgL = Div_32(minThreshold << shift, nrgL << shift);
91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      nrgR = max(nrgR,minThreshold) + 1;
93e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard      shift = norm_l(nrgR);
94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  nrgR = Div_32(minThreshold << shift, nrgR << shift);
95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      pnms = fixmul(nrgL, nrgR);
97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      temp = (pnlr + 1) / ((pnms >> 8) + 1);
99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
100b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      temp = pnms - pnlr;
101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if( temp > 0 ){
102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
103b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        msMask[idx] = 1;
104b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        msMaskTrueSomewhere = 1;
105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        for (j=sfbOffset[idx]; j<sfbOffset[idx+1]; j++) {
107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          Word32 left, right;
108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          left  = (mdctSpectrumLeft[j] >>  1);
109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong          right = (mdctSpectrumRight[j] >> 1);
110b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          mdctSpectrumLeft[j] =  left + right;
111b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          mdctSpectrumRight[j] =  left - right;
112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
113b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
114b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        sfbThresholdLeft[idx] = minThreshold;
115b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        sfbThresholdRight[idx] = minThreshold;
116b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        sfbEnergyLeft[idx] = sfbEnergyMid[idx];
117b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        sfbEnergyRight[idx] = sfbEnergySide[idx];
118b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
119b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        sfbSpreadedEnRight[idx] = min(sfbSpreadedEnLeft[idx],sfbSpreadedEnRight[idx]) >> 1;
120b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        sfbSpreadedEnLeft[idx] = sfbSpreadedEnRight[idx];
121b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      else {
124b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        msMask[idx]  = 0;
125b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        msMaskFalseSomewhere = 1;
126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
127b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    }
128b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    if ( msMaskTrueSomewhere ) {
129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if(msMaskFalseSomewhere ) {
130b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        *msDigest = SI_MS_MASK_SOME;
131956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      } else {
132b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        *msDigest = SI_MS_MASK_ALL;
133956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    } else {
135b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      *msDigest = SI_MS_MASK_NONE;
136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
137956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
138956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
139956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
140