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 Word32 34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongSrchMaxWithIndex(const Word32 *in, Word16 *index, Word16 n); 35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord32 38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongCalcWindowEnergy(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, 39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 *timeSignal, 40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 chIncrement, 41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 windowLen); 42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/****************** Constants *****************************/ 46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/* 49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong IIR high pass coeffs 50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*/ 519538ab83ed3917e643fc88f63ed83736d5a22d19Martin Storsjoconst Word32 hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = { 52b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 0xbec8b439, 0x609d4952 /* -0.5095f, 0.7548f */ 53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}; 54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32 accWindowNrgFac = 0x26666666; /* factor for accumulating filtered window energies 0.3 */ 56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32 oneMinusAccWindowNrgFac = 0x5999999a; /* 0.7 */ 57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32 invAttackRatioHighBr = 0x0ccccccd; /* inverted lower ratio limit for attacks 0.1*/ 58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32 invAttackRatioLowBr = 0x072b020c; /* 0.056 */ 59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32 minAttackNrg = 0x00001e84; /* minimum energy for attacks 1e+6 */ 60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/****************** Routines ****************************/ 63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: InitBlockSwitching 68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: init Block Switching parameter. 69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: TRUE if success 70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 InitBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, 73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word32 bitRate, const Word16 nChannels) 74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* select attackRatio */ 76b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 77b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard if ((sub(nChannels,1)==0 && L_sub(bitRate, 24000) > 0) || 78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (sub(nChannels,1)>0 && bitRate > (nChannels * 16000))) { 79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong blockSwitchingControl->invAttackRatio = invAttackRatioHighBr; 80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong blockSwitchingControl->invAttackRatio = invAttackRatioLowBr; 83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(TRUE); 86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 suggestedGroupingTable[TRANS_FAC][MAX_NO_OF_GROUPS] = { 89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Attack in Window 0 */ {1, 3, 3, 1}, 90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Attack in Window 1 */ {1, 1, 3, 3}, 91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Attack in Window 2 */ {2, 1, 3, 2}, 92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Attack in Window 3 */ {3, 1, 3, 1}, 93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Attack in Window 4 */ {3, 1, 1, 3}, 94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Attack in Window 5 */ {3, 2, 1, 2}, 95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Attack in Window 6 */ {3, 3, 1, 1}, 96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Attack in Window 7 */ {3, 3, 1, 1} 97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}; 98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: BlockSwitching 102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: detect this frame whether there is an attack 103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: TRUE if success 104956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, 107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 *timeSignal, 108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate, 109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 chIncrement) 110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i, w; 112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 enM1, enMax; 113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Reset grouping info */ 115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<TRANS_FAC; i++) { 116b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->groupLen[i] = 0; 117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Search for position and amplitude of attack in last frame (1 windows delay) */ 121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong blockSwitchingControl->maxWindowNrg = SrchMaxWithIndex( &blockSwitchingControl->windowNrg[0][BLOCK_SWITCH_WINDOWS-1], 122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &blockSwitchingControl->attackIndex, 123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong BLOCK_SWITCH_WINDOWS); 124956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 125b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->attackIndex = blockSwitchingControl->lastAttackIndex; 126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 127956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Set grouping info */ 128b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS; 129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<MAX_NO_OF_GROUPS; i++) { 131b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->groupLen[i] = suggestedGroupingTable[blockSwitchingControl->attackIndex][i]; 132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 133b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* if the samplerate is less than 16000, it should be all the short block, avoid pre&post echo */ 135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(sampleRate >= 16000) { 136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Save current window energy as last window energy */ 137956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) { 138b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->windowNrg[0][w] = blockSwitchingControl->windowNrg[1][w]; 139b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->windowNrgF[0][w] = blockSwitchingControl->windowNrgF[1][w]; 140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 141956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Calculate unfiltered and filtered energies in subwindows and combine to segments */ 144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcWindowEnergy(blockSwitchingControl, timeSignal, chIncrement, BLOCK_SWITCH_WINDOW_LEN); 145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* reset attack */ 147b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->attack = FALSE; 148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 149b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard enMax = 0; 150b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard enM1 = blockSwitchingControl->windowNrgF[0][BLOCK_SWITCH_WINDOWS-1]; 151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (w=0; w<BLOCK_SWITCH_WINDOWS; w++) { 153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 enM1_Tmp, accWindowNrg_Tmp, windowNrgF_Tmp; 154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 enM1_Shf, accWindowNrg_Shf, windowNrgF_Shf; 155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accWindowNrg_Shf = norm_l(blockSwitchingControl->accWindowNrg); 157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong enM1_Shf = norm_l(enM1); 158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong windowNrgF_Shf = norm_l(blockSwitchingControl->windowNrgF[1][w]); 159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accWindowNrg_Tmp = blockSwitchingControl->accWindowNrg << accWindowNrg_Shf; 161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong enM1_Tmp = enM1 << enM1_Shf; 162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong windowNrgF_Tmp = blockSwitchingControl->windowNrgF[1][w] << windowNrgF_Shf; 163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* a sliding average of the previous energies */ 165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong blockSwitchingControl->accWindowNrg = (fixmul(oneMinusAccWindowNrgFac, accWindowNrg_Tmp) >> accWindowNrg_Shf) + 166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (fixmul(accWindowNrgFac, enM1_Tmp) >> enM1_Shf); 167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* if the energy with the ratio is bigger than the average, and the attack and short block */ 170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ((fixmul(windowNrgF_Tmp, blockSwitchingControl->invAttackRatio) >> windowNrgF_Shf) > 171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong blockSwitchingControl->accWindowNrg ) { 172b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->attack = TRUE; 173b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->lastAttackIndex = w; 174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 175b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard enM1 = blockSwitchingControl->windowNrgF[1][w]; 176956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong enMax = max(enMax, enM1); 177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 178956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (enMax < minAttackNrg) { 180b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->attack = FALSE; 181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else 184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong { 185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong blockSwitchingControl->attack = TRUE; 186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 188b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* Check if attack spreads over frame border */ 189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ((!blockSwitchingControl->attack) && (blockSwitchingControl->lastattack)) { 190b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (blockSwitchingControl->attackIndex == TRANS_FAC-1) { 192b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->attack = TRUE; 193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 195b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->lastattack = FALSE; 196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 198b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->lastattack = blockSwitchingControl->attack; 199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 201b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->windowSequence = blockSwitchingControl->nextwindowSequence; 202b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (blockSwitchingControl->attack) { 205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong blockSwitchingControl->nextwindowSequence = SHORT_WINDOW; 206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong blockSwitchingControl->nextwindowSequence = LONG_WINDOW; 209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 211b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* update short block group */ 212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (blockSwitchingControl->nextwindowSequence == SHORT_WINDOW) { 213b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (blockSwitchingControl->windowSequence== LONG_WINDOW) { 215b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->windowSequence = START_WINDOW; 216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 217b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (blockSwitchingControl->windowSequence == STOP_WINDOW) { 219b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->windowSequence = SHORT_WINDOW; 220b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->noOfGroups = 3; 221b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->groupLen[0] = 3; 222b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->groupLen[1] = 3; 223b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->groupLen[2] = 2; 224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 225956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 227b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* update block type */ 228956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (blockSwitchingControl->nextwindowSequence == LONG_WINDOW) { 229b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 230956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (blockSwitchingControl->windowSequence == SHORT_WINDOW) { 231b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->nextwindowSequence = STOP_WINDOW; 232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(TRUE); 236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: SrchMaxWithIndex 242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: search for the biggest value in an array 243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: the max value 244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32 SrchMaxWithIndex(const Word32 in[], Word16 *index, Word16 n) 247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 max; 249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i, idx; 250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Search maximum value in array and return index and value */ 252b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard max = 0; 253b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard idx = 0; 254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i = 0; i < n; i++) { 256b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (in[i+1] > max) { 258b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard max = in[i+1]; 259b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard idx = i; 260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 262b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *index = idx; 263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(max); 265956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 266956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 267956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 268956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: CalcWindowEnergy 270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: calculate the energy before iir-filter and after irr-filter 271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: TRUE if success 272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 274e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifndef ARMV5E 275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord32 CalcWindowEnergy(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, 276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 *timeSignal, 277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 chIncrement, 278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 windowLen) 279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 28054e96f62859d933a5c8d4716cc5ab7bb00bd8711Andreas Gampe Word32 w, i, tidx; 281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 accuUE, accuFE; 282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 tempUnfiltered; 283e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 tempFiltered; 284e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 states0, states1; 285e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 Coeff0, Coeff1; 286e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 287e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 288e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard states0 = blockSwitchingControl->iirStates[0]; 289e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard states1 = blockSwitchingControl->iirStates[1]; 290e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Coeff0 = hiPassCoeff[0]; 291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Coeff1 = hiPassCoeff[1]; 292b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tidx = 0; 293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (w=0; w < BLOCK_SWITCH_WINDOWS; w++) { 294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 295b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard accuUE = 0; 296b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard accuFE = 0; 297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=0; i<windowLen; i++) { 299e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 accu1, accu2, accu3; 300e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 out; 301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tempUnfiltered = timeSignal[tidx]; 302956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tidx = tidx + chIncrement; 303e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 304e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard accu1 = L_mpy_ls(Coeff1, tempUnfiltered); 305e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard accu2 = fixmul( Coeff0, states1 ); 306e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard accu3 = accu1 - states0; 307e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard out = accu3 - accu2; 308e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 309b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard states0 = accu1; 310b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard states1 = out; 311e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 312b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tempFiltered = extract_h(out); 313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accuUE += (tempUnfiltered * tempUnfiltered) >> ENERGY_SHIFT; 314956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accuFE += (tempFiltered * tempFiltered) >> ENERGY_SHIFT; 315956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 317b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->windowNrg[1][w] = accuUE; 318b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControl->windowNrgF[1][w] = accuFE; 319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 320e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 321e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 322e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard blockSwitchingControl->iirStates[0] = states0; 323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong blockSwitchingControl->iirStates[1] = states1; 324956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(TRUE); 326956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#endif 328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 329956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 synchronizedBlockTypeTable[4][4] = { 330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* LONG_WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW */ 331956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* LONG_WINDOW */{LONG_WINDOW, START_WINDOW, SHORT_WINDOW, STOP_WINDOW}, 332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* START_WINDOW */{START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW}, 333956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* SHORT_WINDOW */{SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW}, 334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* STOP_WINDOW */{STOP_WINDOW, SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW} 335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}; 336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 338956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 339956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: SyncBlockSwitching 341956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: update block type and group value 342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: TRUE if success 343956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 344956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong**********************************************************************************/ 345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 SyncBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft, 346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, 347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 nChannels) 348956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 349956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 i; 350b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 patchType = LONG_WINDOW; 351b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (nChannels == 1) { /* Mono */ 354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (blockSwitchingControlLeft->windowSequence != SHORT_WINDOW) { 355b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlLeft->noOfGroups = 1; 356b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlLeft->groupLen[0] = 1; 357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=1; i<TRANS_FAC; i++) { 359b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlLeft->groupLen[i] = 0; 360956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 362956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { /* Stereo common Window */ 364b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft->windowSequence]; 365b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight->windowSequence]; 366956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Set synchronized Blocktype */ 368b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlLeft->windowSequence = patchType; 369b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlRight->windowSequence = patchType; 370956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 371b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard /* Synchronize grouping info */ 372956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(patchType != SHORT_WINDOW) { /* Long Blocks */ 373956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Set grouping info */ 374b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlLeft->noOfGroups = 1; 375b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlRight->noOfGroups = 1; 376b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlLeft->groupLen[0] = 1; 377b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlRight->groupLen[0] = 1; 378956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 379956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=1; i<TRANS_FAC; i++) { 380b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlLeft->groupLen[i] = 0; 381b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlRight->groupLen[i] = 0; 382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 385b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (blockSwitchingControlLeft->maxWindowNrg > blockSwitchingControlRight->maxWindowNrg) { 387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Left Channel wins */ 388b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlRight->noOfGroups = blockSwitchingControlLeft->noOfGroups; 389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<TRANS_FAC; i++) { 390b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlRight->groupLen[i] = blockSwitchingControlLeft->groupLen[i]; 391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* Right Channel wins */ 395b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups; 396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<TRANS_FAC; i++) { 397b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard blockSwitchingControlLeft->groupLen[i] = blockSwitchingControlRight->groupLen[i]; 398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 401956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } /*endif Mono or Stereo */ 402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 403956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(TRUE); 404956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 405