block_switch.c revision 9538ab83ed3917e643fc88f63ed83736d5a22d19
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:		block_switch.c
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Content:	Block switching functions
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*******************************************************************************/
22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h"
24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "oper_32b.h"
26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "psy_const.h"
27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "block_switch.h"
28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#define ENERGY_SHIFT (8 - 1)
31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/**************** internal function prototypes ***********/
33956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16
34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongIIRFilter(const Word16 in, const Word32 coeff[], Word32 states[]);
35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32
37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongSrchMaxWithIndex(const Word32 *in, Word16 *index, Word16 n);
38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord32
41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongCalcWindowEnergy(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 Word16 *timeSignal,
43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 Word16 chIncrement,
44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 Word16 windowLen);
45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/****************** Constants *****************************/
49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*
52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  IIR high pass coeffs
53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*/
549538ab83ed3917e643fc88f63ed83736d5a22d19Martin Storsjoconst Word32 hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = {
55b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  0xbec8b439, 0x609d4952  /* -0.5095f, 0.7548f */
56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong};
57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32 accWindowNrgFac = 0x26666666;                   /* factor for accumulating filtered window energies 0.3 */
59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32 oneMinusAccWindowNrgFac = 0x5999999a;			/* 0.7 */
60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32 invAttackRatioHighBr = 0x0ccccccd;              /* inverted lower ratio limit for attacks 0.1*/
61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32 invAttackRatioLowBr =  0x072b020c;              /* 0.056 */
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32 minAttackNrg = 0x00001e84;                      /* minimum energy for attacks 1e+6 */
63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/****************** Routines ****************************/
66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: InitBlockSwitching
71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  init Block Switching parameter.
72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      TRUE if success
73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 InitBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          const Word32 bitRate, const Word16 nChannels)
77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* select attackRatio */
79b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
80b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  if ((sub(nChannels,1)==0 && L_sub(bitRate, 24000) > 0) ||
81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      (sub(nChannels,1)>0 && bitRate > (nChannels * 16000))) {
82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    blockSwitchingControl->invAttackRatio = invAttackRatioHighBr;
83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else  {
85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    blockSwitchingControl->invAttackRatio = invAttackRatioLowBr;
86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(TRUE);
89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 suggestedGroupingTable[TRANS_FAC][MAX_NO_OF_GROUPS] = {
92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Attack in Window 0 */ {1,  3,  3,  1},
93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Attack in Window 1 */ {1,  1,  3,  3},
94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Attack in Window 2 */ {2,  1,  3,  2},
95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Attack in Window 3 */ {3,  1,  3,  1},
96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Attack in Window 4 */ {3,  1,  1,  3},
97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Attack in Window 5 */ {3,  2,  1,  2},
98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Attack in Window 6 */ {3,  3,  1,  1},
99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Attack in Window 7 */ {3,  3,  1,  1}
100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong};
101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
104956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: BlockSwitching
105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  detect this frame whether there is an attack
106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      TRUE if success
107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                      Word16 *timeSignal,
111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong					  Word32 sampleRate,
112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                      Word16 chIncrement)
113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 i, w;
115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 enM1, enMax;
116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Reset grouping info */
118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (i=0; i<TRANS_FAC; i++) {
119b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    blockSwitchingControl->groupLen[i] = 0;
120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Search for position and amplitude of attack in last frame (1 windows delay) */
124956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  blockSwitchingControl->maxWindowNrg = SrchMaxWithIndex( &blockSwitchingControl->windowNrg[0][BLOCK_SWITCH_WINDOWS-1],
125956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                                          &blockSwitchingControl->attackIndex,
126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                                          BLOCK_SWITCH_WINDOWS);
127956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
128b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  blockSwitchingControl->attackIndex = blockSwitchingControl->lastAttackIndex;
129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Set grouping info */
131b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS;
132956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
133956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (i=0; i<MAX_NO_OF_GROUPS; i++) {
134b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    blockSwitchingControl->groupLen[i] = suggestedGroupingTable[blockSwitchingControl->attackIndex][i];
135e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  }
136b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
137956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* if the samplerate is less than 16000, it should be all the short block, avoid pre&post echo */
138956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if(sampleRate >= 16000) {
139956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  /* Save current window energy as last window energy */
140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) {
141b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		  blockSwitchingControl->windowNrg[0][w] = blockSwitchingControl->windowNrg[1][w];
142b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		  blockSwitchingControl->windowNrgF[0][w] = blockSwitchingControl->windowNrgF[1][w];
143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  }
144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  /* Calculate unfiltered and filtered energies in subwindows and combine to segments */
147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  CalcWindowEnergy(blockSwitchingControl, timeSignal, chIncrement, BLOCK_SWITCH_WINDOW_LEN);
148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
149956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  /* reset attack */
150b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	  blockSwitchingControl->attack = FALSE;
151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
152b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	  enMax = 0;
153b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	  enM1 = blockSwitchingControl->windowNrgF[0][BLOCK_SWITCH_WINDOWS-1];
154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) {
156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  Word32 enM1_Tmp, accWindowNrg_Tmp, windowNrgF_Tmp;
157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  Word16 enM1_Shf, accWindowNrg_Shf, windowNrgF_Shf;
158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  accWindowNrg_Shf = norm_l(blockSwitchingControl->accWindowNrg);
160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  enM1_Shf = norm_l(enM1);
161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  windowNrgF_Shf = norm_l(blockSwitchingControl->windowNrgF[1][w]);
162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  accWindowNrg_Tmp = blockSwitchingControl->accWindowNrg << accWindowNrg_Shf;
164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  enM1_Tmp = enM1 << enM1_Shf;
165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  windowNrgF_Tmp = blockSwitchingControl->windowNrgF[1][w] << windowNrgF_Shf;
166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  /* a sliding average of the previous energies */
168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  blockSwitchingControl->accWindowNrg = (fixmul(oneMinusAccWindowNrgFac, accWindowNrg_Tmp) >> accWindowNrg_Shf) +
169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			  (fixmul(accWindowNrgFac, enM1_Tmp) >> enM1_Shf);
170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  /* if the energy with the ratio is bigger than the average, and the attack and short block  */
173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  if ((fixmul(windowNrgF_Tmp, blockSwitchingControl->invAttackRatio) >> windowNrgF_Shf) >
174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong			  blockSwitchingControl->accWindowNrg ) {
175b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				  blockSwitchingControl->attack = TRUE;
176b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				  blockSwitchingControl->lastAttackIndex = w;
177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  }
178b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		  enM1 = blockSwitchingControl->windowNrgF[1][w];
179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong		  enMax = max(enMax, enM1);
180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  }
181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  if (enMax < minAttackNrg) {
183b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		  blockSwitchingControl->attack = FALSE;
184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  }
185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else
187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  {
188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  blockSwitchingControl->attack = TRUE;
189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
191b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  /* Check if attack spreads over frame border */
192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if ((!blockSwitchingControl->attack) && (blockSwitchingControl->lastattack)) {
193b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (blockSwitchingControl->attackIndex == TRANS_FAC-1) {
195b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControl->attack = TRUE;
196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
198b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    blockSwitchingControl->lastattack = FALSE;
199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else {
201b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    blockSwitchingControl->lastattack = blockSwitchingControl->attack;
202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
204b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  blockSwitchingControl->windowSequence =  blockSwitchingControl->nextwindowSequence;
205b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (blockSwitchingControl->attack) {
208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    blockSwitchingControl->nextwindowSequence = SHORT_WINDOW;
209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else {
211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    blockSwitchingControl->nextwindowSequence = LONG_WINDOW;
212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
214b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  /* update short block group */
215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (blockSwitchingControl->nextwindowSequence == SHORT_WINDOW) {
216b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (blockSwitchingControl->windowSequence== LONG_WINDOW) {
218b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControl->windowSequence = START_WINDOW;
219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
220b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (blockSwitchingControl->windowSequence == STOP_WINDOW) {
222b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControl->windowSequence = SHORT_WINDOW;
223b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControl->noOfGroups = 3;
224b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControl->groupLen[0] = 3;
225b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControl->groupLen[1] = 3;
226b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControl->groupLen[2] = 2;
227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
228956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
230b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  /* update block type */
231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (blockSwitchingControl->nextwindowSequence == LONG_WINDOW) {
232b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (blockSwitchingControl->windowSequence == SHORT_WINDOW) {
234b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControl->nextwindowSequence = STOP_WINDOW;
235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(TRUE);
239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: SrchMaxWithIndex
245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  search for the biggest value in an array
246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      the max value
247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32 SrchMaxWithIndex(const Word32 in[], Word16 *index, Word16 n)
250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 max;
252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 i, idx;
253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* Search maximum value in array and return index and value */
255b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  max = 0;
256b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  idx = 0;
257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (i = 0; i < n; i++) {
259b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (in[i+1]  > max) {
261b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      max = in[i+1];
262b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      idx = i;
263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
265b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  *index = idx;
266956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
267956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(max);
268956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: CalcWindowEnergy
273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  calculate the energy before iir-filter and after irr-filter
274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      TRUE if success
275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
277e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifndef ARMV5E
278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord32 CalcWindowEnergy(BLOCK_SWITCHING_CONTROL *blockSwitchingControl,
279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word16 *timeSignal,
280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word16 chIncrement,
281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                        Word16 windowLen)
282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 w, i, wOffset, tidx, ch;
284956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 accuUE, accuFE;
285956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 tempUnfiltered;
286e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word32 tempFiltered;
287e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word32 states0, states1;
288e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Word32 Coeff0, Coeff1;
289e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
290e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
291e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  states0 = blockSwitchingControl->iirStates[0];
292e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  states1 = blockSwitchingControl->iirStates[1];
293e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  Coeff0 = hiPassCoeff[0];
294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Coeff1 = hiPassCoeff[1];
295b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  tidx = 0;
296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  for (w=0; w < BLOCK_SWITCH_WINDOWS; w++) {
297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
298b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    accuUE = 0;
299b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    accuFE = 0;
300956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for(i=0; i<windowLen; i++) {
302e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  Word32 accu1, accu2, accu3;
303e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  Word32 out;
304956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  tempUnfiltered = timeSignal[tidx];
305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      tidx = tidx + chIncrement;
306e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
307e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  accu1 = L_mpy_ls(Coeff1, tempUnfiltered);
308e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  accu2 = fixmul( Coeff0, states1 );
309e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  accu3 = accu1 - states0;
310e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	  out = accu3 - accu2;
311e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
312b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	  states0 = accu1;
313b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	  states1 = out;
314e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
315b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      tempFiltered = extract_h(out);
316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      accuUE += (tempUnfiltered * tempUnfiltered) >> ENERGY_SHIFT;
317956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      accuFE += (tempFiltered * tempFiltered) >> ENERGY_SHIFT;
318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
320b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    blockSwitchingControl->windowNrg[1][w] = accuUE;
321b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    blockSwitchingControl->windowNrgF[1][w] = accuFE;
322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
323e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  }
324e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
325e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  blockSwitchingControl->iirStates[0] = states0;
326956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  blockSwitchingControl->iirStates[1] = states1;
327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(TRUE);
329956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#endif
331956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
333956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: IIRFilter
335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  calculate the iir-filter for an array
336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      the result after iir-filter
337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
338956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
339956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 IIRFilter(const Word16 in, const Word32 coeff[], Word32 states[])
340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
341956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 accu1, accu2, accu3;
342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word32 out;
343956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
344956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  accu1 = L_mpy_ls(coeff[1], in);
345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  accu3 = accu1 - states[0];
346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  accu2 = fixmul( coeff[0], states[1] );
347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  out = accu3 - accu2;
348956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
349b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  states[0] = accu1;
350b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  states[1] = out;
351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return round16(out);
353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
355956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
356956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 synchronizedBlockTypeTable[4][4] = {
357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /*                 LONG_WINDOW   START_WINDOW  SHORT_WINDOW  STOP_WINDOW */
358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* LONG_WINDOW  */{LONG_WINDOW,  START_WINDOW, SHORT_WINDOW, STOP_WINDOW},
359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* START_WINDOW */{START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW},
360956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* SHORT_WINDOW */{SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW},
361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  /* STOP_WINDOW  */{STOP_WINDOW,  SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW}
362956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong};
363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
364956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
366956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: SyncBlockSwitching
368956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  update block type and group value
369956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns:      TRUE if success
370956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/
372956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 SyncBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft,
373956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight,
374956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                          const Word16 nChannels)
375956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
376956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 i;
377b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  Word16 patchType = LONG_WINDOW;
378b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
379956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
380956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if (nChannels == 1) { /* Mono */
381956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (blockSwitchingControlLeft->windowSequence != SHORT_WINDOW) {
382b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControlLeft->noOfGroups = 1;
383b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControlLeft->groupLen[0] = 1;
384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      for (i=1; i<TRANS_FAC; i++) {
386b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        blockSwitchingControlLeft->groupLen[i] = 0;
387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  else { /* Stereo common Window */
391b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft->windowSequence];
392b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight->windowSequence];
393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    /* Set synchronized Blocktype */
395b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    blockSwitchingControlLeft->windowSequence = patchType;
396b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    blockSwitchingControlRight->windowSequence = patchType;
397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
398b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    /* Synchronize grouping info */
399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if(patchType != SHORT_WINDOW) { /* Long Blocks */
400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      /* Set grouping info */
401b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControlLeft->noOfGroups = 1;
402b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControlRight->noOfGroups = 1;
403b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControlLeft->groupLen[0] = 1;
404b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard      blockSwitchingControlRight->groupLen[0] = 1;
405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      for (i=1; i<TRANS_FAC; i++) {
407b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        blockSwitchingControlLeft->groupLen[i] = 0;
408b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        blockSwitchingControlRight->groupLen[i] = 0;
409956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
411956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    else {
412b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      if (blockSwitchingControlLeft->maxWindowNrg > blockSwitchingControlRight->maxWindowNrg) {
414956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        /* Left Channel wins */
415b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        blockSwitchingControlRight->noOfGroups = blockSwitchingControlLeft->noOfGroups;
416956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        for (i=0; i<TRANS_FAC; i++) {
417b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          blockSwitchingControlRight->groupLen[i] = blockSwitchingControlLeft->groupLen[i];
418956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
419956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
420956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      else {
421956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        /* Right Channel wins */
422b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard        blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups;
423956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        for (i=0; i<TRANS_FAC; i++) {
424b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard          blockSwitchingControlLeft->groupLen[i] = blockSwitchingControlRight->groupLen[i];
425956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
426956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      }
427956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
428956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  } /*endif Mono or Stereo */
429956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
430956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return(TRUE);
431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
432