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: tns.c 18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Content: Definition TNS tools functions 20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*******************************************************************************/ 22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h" 24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "oper_32b.h" 25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "assert.h" 26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "aac_rom.h" 27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "psy_const.h" 28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "tns.h" 29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "tns_param.h" 30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "psy_configuration.h" 31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "tns_func.h" 32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 3384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED(x) (void)(x) 3484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#define TNS_MODIFY_BEGIN 2600 /* Hz */ 36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#define RATIO_PATCH_LOWER_BORDER 380 /* Hz */ 37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define TNS_GAIN_THRESH 141 /* 1.41*100 */ 38e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define NORM_COEF 0x028f5c28 39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic const Word32 TNS_PARCOR_THRESH = 0x0ccccccd; /* 0.1*(1 << 31) */ 41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* Limit bands to > 2.0 kHz */ 42e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic unsigned short tnsMinBandNumberLong[12] = 43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 11, 12, 15, 16, 17, 20, 25, 26, 24, 28, 30, 31 }; 44e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic unsigned short tnsMinBandNumberShort[12] = 45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 2, 2, 2, 3, 3, 4, 6, 6, 8, 10, 10, 12 }; 46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 47e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/**************************************/ 48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* Main/Low Profile TNS Parameters */ 49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/**************************************/ 50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic unsigned short tnsMaxBandsLongMainLow[12] = 51e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39 }; 52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic unsigned short tnsMaxBandsShortMainLow[12] = 54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14 }; 55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void CalcWeightedSpectrum(const Word32 spectrum[], 58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 weightedSpectrum[], 59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32* sfbEnergy, 60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16* sfbOffset, Word16 lpcStartLine, 61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 lpcStopLine, Word16 lpcStartBand,Word16 lpcStopBand, 62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pWork32); 63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid AutoCorrelation(const Word16 input[], Word32 corr[], 67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 samples, Word16 corrCoeff); 68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 AutoToParcor(Word32 workBuffer[], Word32 reflCoeff[], Word16 numOfCoeff); 69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 CalcTnsFilter(const Word16* signal, const Word32 window[], Word16 numOfLines, 71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 tnsOrder, Word32 parcor[]); 72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void Parcor2Index(const Word32 parcor[], Word16 index[], Word16 order, 75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitsPerCoeff); 76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void Index2Parcor(const Word16 index[], Word32 parcor[], Word16 order, 78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitsPerCoeff); 79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void AnalysisFilterLattice(const Word32 signal[], Word16 numOfLines, 83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word32 parCoeff[], Word16 order, 84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 output[]); 85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/** 88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: FreqToBandWithRounding 90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Retrieve index of nearest band border 91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returnt: index 92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*/ 94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 FreqToBandWithRounding(Word32 freq, /*!< frequency in Hertz */ 95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 fs, /*!< Sampling frequency in Hertz */ 96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 numOfBands, /*!< total number of bands */ 97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 *bandStartOffset) /*!< table of band borders */ 98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 lineNumber, band; 100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp, shift; 101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* assert(freq >= 0); */ 103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong shift = norm_l(fs); 104956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong lineNumber = (extract_l(fixmul((bandStartOffset[numOfBands] << 2),Div_32(freq << shift,fs << shift))) + 1) >> 1; 105b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* freq > fs/2 */ 107b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = lineNumber - bandStartOffset[numOfBands] ; 108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (temp >= 0) 109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return numOfBands; 110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* find band the line number lies in */ 112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (band=0; band<numOfBands; band++) { 113b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = bandStartOffset[band + 1] - lineNumber; 114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (temp > 0) break; 115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong temp = (lineNumber - bandStartOffset[band]); 118b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = (temp - (bandStartOffset[band + 1] - lineNumber)); 119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp > 0 ) 120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong { 121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong band = band + 1; 122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 124956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return extract_l(band); 125956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 127956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 128956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/** 129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: InitTnsConfigurationLong 131956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Fill TNS_CONFIG structure with sensible content for long blocks 132956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 133956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*/ 135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 InitTnsConfigurationLong(Word32 bitRate, /*!< bitrate */ 136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate, /*!< Sampling frequency */ 137956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 channels, /*!< number of channels */ 138956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_CONFIG *tC, /*!< TNS Config struct (modified) */ 139956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_CONFIGURATION_LONG *pC, /*!< psy config struct */ 140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 active) /*!< tns active flag */ 141956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 bitratePerChannel; 144b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->maxOrder = TNS_MAX_ORDER; 145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsStartFreq = 1275; 146b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->coefRes = 4; 147b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* to avoid integer division */ 149b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard if ( sub(channels,2) == 0 ) { 150b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard bitratePerChannel = bitRate >> 1; 151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 153b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard bitratePerChannel = bitRate; 154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsMaxSfb = tnsMaxBandsLongMainLow[pC->sampRateIdx]; 157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 158b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->tnsActive = active; 159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* now calc band and line borders */ 161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb); 162b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand]; 163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsStartBand = FreqToBandWithRounding(tC->tnsStartFreq, sampleRate, 165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pC->sfbCnt, (const Word16*)pC->sfbOffset); 166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsModifyBeginCb = FreqToBandWithRounding(TNS_MODIFY_BEGIN, 168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pC->sfbCnt, 170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)pC->sfbOffset); 171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsRatioPatchLowestCb = FreqToBandWithRounding(RATIO_PATCH_LOWER_BORDER, 173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pC->sfbCnt, 175956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)pC->sfbOffset); 176956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 178b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand]; 179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->lpcStopBand = tnsMaxBandsLongMainLow[pC->sampRateIdx]; 181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive); 182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 183b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand]; 184b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->lpcStartBand = tnsMinBandNumberLong[pC->sampRateIdx]; 186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 187b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand]; 188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 189b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->threshold = TNS_GAIN_THRESH; 190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(0); 193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/** 196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: InitTnsConfigurationShort 198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Fill TNS_CONFIG structure with sensible content for short blocks 199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*/ 202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 InitTnsConfigurationShort(Word32 bitRate, /*!< bitrate */ 203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sampleRate, /*!< Sampling frequency */ 204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 channels, /*!< number of channels */ 205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_CONFIG *tC, /*!< TNS Config struct (modified) */ 206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong PSY_CONFIGURATION_SHORT *pC, /*!< psy config struct */ 207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 active) /*!< tns active flag */ 208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 bitratePerChannel; 210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->maxOrder = TNS_MAX_ORDER_SHORT; 211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsStartFreq = 2750; 212b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->coefRes = 3; 213b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* to avoid integer division */ 215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( sub(channels,2) == 0 ) { 216b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard bitratePerChannel = L_shr(bitRate,1); 217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 219b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard bitratePerChannel = bitRate; 220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsMaxSfb = tnsMaxBandsShortMainLow[pC->sampRateIdx]; 223956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 224b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->tnsActive = active; 225956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* now calc band and line borders */ 227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb); 228b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand]; 229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 230956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsStartBand=FreqToBandWithRounding(tC->tnsStartFreq, sampleRate, 231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pC->sfbCnt, (const Word16*)pC->sfbOffset); 232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsModifyBeginCb = FreqToBandWithRounding(TNS_MODIFY_BEGIN, 234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pC->sfbCnt, 236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)pC->sfbOffset); 237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->tnsRatioPatchLowestCb = FreqToBandWithRounding(RATIO_PATCH_LOWER_BORDER, 239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sampleRate, 240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pC->sfbCnt, 241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (const Word16*)pC->sfbOffset); 242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 244b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand]; 245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 246e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tC->lpcStopBand = tnsMaxBandsShortMainLow[pC->sampRateIdx]; 247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive); 249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 250b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand]; 251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 252e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tC->lpcStartBand = tnsMinBandNumberShort[pC->sampRateIdx]; 253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 254b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand]; 255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 256b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tC->threshold = TNS_GAIN_THRESH; 257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(0); 259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/** 262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: TnsDetect 264b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* description: Calculate TNS filter and decide on TNS usage 265956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 266956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 267956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*/ 268956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord32 TnsDetect(TNS_DATA* tnsData, /*!< tns data structure (modified) */ 269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_CONFIG tC, /*!< tns config structure */ 270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32* pScratchTns, /*!< pointer to scratch space */ 271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 sfbOffset[], /*!< scalefactor size and table */ 272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32* spectrum, /*!< spectral data */ 273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 subBlockNumber, /*!< subblock num */ 274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 blockType, /*!< blocktype (long or short) */ 275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 * sfbEnergy) /*!< sfb-wise energy */ 276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 predictionGain; 279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp; 280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32* pWork32 = &pScratchTns[subBlockNumber >> 8]; 281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16* pWeightedSpectrum = (Word16 *)&pScratchTns[subBlockNumber >> 8]; 282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 283b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 284956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (tC.tnsActive) { 285956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CalcWeightedSpectrum(spectrum, 286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pWeightedSpectrum, 287956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sfbEnergy, 288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sfbOffset, 289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.lpcStartLine, 290956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.lpcStopLine, 291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.lpcStartBand, 292956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.lpcStopBand, 293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pWork32); 294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 295b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = blockType - SHORT_WINDOW; 296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp != 0 ) { 297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong predictionGain = CalcTnsFilter( &pWeightedSpectrum[tC.lpcStartLine], 298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.acfWindow, 299956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.lpcStopLine - tC.lpcStartLine, 300956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.maxOrder, 301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData->dataRaw.tnsLong.subBlockInfo.parcor); 302956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 303956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 304b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = predictionGain - tC.threshold; 305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp > 0 ) { 306b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 1; 307956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 309b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0; 310956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 311956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 312b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = predictionGain; 313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 314956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else{ 315956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong predictionGain = CalcTnsFilter( &pWeightedSpectrum[tC.lpcStartLine], 317956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.acfWindow, 318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.lpcStopLine - tC.lpcStartLine, 319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.maxOrder, 320956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].parcor); 321956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 322b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = predictionGain - tC.threshold; 323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp > 0 ) { 324b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 1; 325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 326956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 327b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0; 328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 329956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 330b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = predictionGain; 331956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 333956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else{ 335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 336b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = blockType - SHORT_WINDOW; 337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp != 0 ) { 338b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0; 339b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = 0; 340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 341956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 342b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0; 343b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = 0; 344956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(0); 348956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 349956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 350956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: TnsSync 354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: update tns parameter 355956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 356956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid TnsSync(TNS_DATA *tnsDataDest, 358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const TNS_DATA *tnsDataSrc, 359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const TNS_CONFIG tC, 360956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 subBlockNumber, 361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 blockType) 362956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_SUBBLOCK_INFO *sbInfoDest; 364956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const TNS_SUBBLOCK_INFO *sbInfoSrc; 365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i, temp; 366956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 367b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = blockType - SHORT_WINDOW; 368956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp != 0 ) { 369b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard sbInfoDest = &tnsDataDest->dataRaw.tnsLong.subBlockInfo; 370b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard sbInfoSrc = &tnsDataSrc->dataRaw.tnsLong.subBlockInfo; 371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 372956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 373b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard sbInfoDest = &tnsDataDest->dataRaw.tnsShort.subBlockInfo[subBlockNumber]; 374b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard sbInfoSrc = &tnsDataSrc->dataRaw.tnsShort.subBlockInfo[subBlockNumber]; 375956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 376956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 377956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (100*abs_s(sbInfoDest->predictionGain - sbInfoSrc->predictionGain) < 378956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (3 * sbInfoDest->predictionGain)) { 379b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard sbInfoDest->tnsActive = sbInfoSrc->tnsActive; 380956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for ( i=0; i< tC.maxOrder; i++) { 381b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard sbInfoDest->parcor[i] = sbInfoSrc->parcor[i]; 382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: TnsEncode 389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: do TNS filtering 390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 0 if success 391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 TnsEncode(TNS_INFO* tnsInfo, /*!< tns info structure (modified) */ 394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_DATA* tnsData, /*!< tns data structure (modified) */ 395956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 numOfSfb, /*!< number of scale factor bands */ 396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_CONFIG tC, /*!< tns config structure */ 397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 lowPassLine, /*!< lowpass line */ 398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32* spectrum, /*!< spectral data (modified) */ 399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 subBlockNumber, /*!< subblock num */ 400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 blockType) /*!< blocktype (long or short) */ 401956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 403956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp_s; 404e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 temp; 405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_SUBBLOCK_INFO *psubBlockInfo; 406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 407b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp_s = blockType - SHORT_WINDOW; 408b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard if ( temp_s != 0) { 409e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard psubBlockInfo = &tnsData->dataRaw.tnsLong.subBlockInfo; 410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psubBlockInfo->tnsActive == 0) { 411b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsInfo->tnsActive[subBlockNumber] = 0; 412956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(0); 413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 414956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 415956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 416956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Parcor2Index(psubBlockInfo->parcor, 417956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsInfo->coef, 418956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.maxOrder, 419956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.coefRes); 420956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 421956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Index2Parcor(tnsInfo->coef, 422956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psubBlockInfo->parcor, 423956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.maxOrder, 424956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.coefRes); 425956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 426956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=tC.maxOrder - 1; i>=0; i--) { 427b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH; 428956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp > 0 ) 429956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong break; 430b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH; 431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp < 0 ) 432956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong break; 433956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 434b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsInfo->order[subBlockNumber] = i + 1; 435956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 436956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 437b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsInfo->tnsActive[subBlockNumber] = 1; 438956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=subBlockNumber+1; i<TRANS_FAC; i++) { 439b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsInfo->tnsActive[i] = 0; 440956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 441b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsInfo->coefRes[subBlockNumber] = tC.coefRes; 442b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand; 443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 444956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 445956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]), 446956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong (min(tC.tnsStopLine,lowPassLine) - tC.tnsStartLine), 447956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psubBlockInfo->parcor, 448956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsInfo->order[subBlockNumber], 449956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &(spectrum[tC.tnsStartLine])); 450956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 451956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 452956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } /* if (blockType!=SHORT_WINDOW) */ 453b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard else /*short block*/ { 454e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard psubBlockInfo = &tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber]; 455956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (psubBlockInfo->tnsActive == 0) { 456b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsInfo->tnsActive[subBlockNumber] = 0; 457956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(0); 458956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 459956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 460956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 461956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Parcor2Index(psubBlockInfo->parcor, 462956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &tnsInfo->coef[subBlockNumber*TNS_MAX_ORDER_SHORT], 463956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.maxOrder, 464956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.coefRes); 465956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 466956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Index2Parcor(&tnsInfo->coef[subBlockNumber*TNS_MAX_ORDER_SHORT], 467956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psubBlockInfo->parcor, 468956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.maxOrder, 469956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tC.coefRes); 470956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=(tC.maxOrder - 1); i>=0; i--) { 471b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH; 472956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp > 0 ) 473956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong break; 474956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 475b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH; 476956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp < 0 ) 477956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong break; 478956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 479b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsInfo->order[subBlockNumber] = i + 1; 480956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 481b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsInfo->tnsActive[subBlockNumber] = 1; 482b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsInfo->coefRes[subBlockNumber] = tC.coefRes; 483b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand; 484956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 485956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 486956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]), (tC.tnsStopLine - tC.tnsStartLine), 487956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong psubBlockInfo->parcor, 488956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tnsInfo->order[subBlockNumber], 489956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong &(spectrum[tC.tnsStartLine])); 490956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 491956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 492956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 493956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 494956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(0); 495956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 496956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 497956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 498956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 499956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 500956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: m_pow2_cordic 501956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Iterative power function 502956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 503956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* Calculates pow(2.0,x-1.0*(scale+1)) with INT_BITS bit precision 504956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* using modified cordic algorithm 505956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: the result of pow2 506956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 507956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 508956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32 m_pow2_cordic(Word32 x, Word16 scale) 509956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 510956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 k; 511956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 512b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word32 accu_y = 0x40000000; 513956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accu_y = L_shr(accu_y,scale); 514956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 515956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(k=1; k<INT_BITS; k++) { 516b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard const Word32 z = m_log2_table[k]; 517956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 518956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong while(L_sub(x,z) >= 0) { 519b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 520956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x = L_sub(x, z); 521956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accu_y = L_add(accu_y, (accu_y >> k)); 522956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 523956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 524956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(accu_y); 525956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 526956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 527956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 528956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 529956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 530956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: CalcWeightedSpectrum 531956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Calculate weighted spectrum for LPC calculation 532956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 533956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 534956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void CalcWeightedSpectrum(const Word32 spectrum[], /*!< input spectrum */ 535956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 weightedSpectrum[], 536956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *sfbEnergy, /*!< sfb energies */ 537956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 *sfbOffset, 538956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 lpcStartLine, 539956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 lpcStopLine, 540956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 lpcStartBand, 541956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 lpcStopBand, 542956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pWork32) 543956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 544956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong #define INT_BITS_SCAL 1<<(INT_BITS/2) 545956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 546956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i, sfb, shift; 547956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 maxShift; 548956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 tmp_s, tmp2_s; 549956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 tmp, tmp2; 550956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 maxWS; 551956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 tnsSfbMean[MAX_SFB]; /* length [lpcStopBand-lpcStartBand] should be sufficient here */ 552956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 553b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxWS = 0; 554b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 555956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* calc 1.0*2^-INT_BITS/2/sqrt(en) */ 556956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for( sfb = lpcStartBand; sfb < lpcStopBand; sfb++) { 557956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 558b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp2 = sfbEnergy[sfb] - 2; 559956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if( tmp2 > 0) { 560956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tmp = rsqrt(sfbEnergy[sfb], INT_BITS); 561b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard if(tmp > INT_BITS_SCAL) 562e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 563e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard shift = norm_l(tmp); 564b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = Div_32( INT_BITS_SCAL << shift, tmp << shift ); 565956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 566956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else 567956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong { 568b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = 0x7fffffff; 569956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 570956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 571956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 572b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = 0x7fffffff; 573b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard } 574b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsSfbMean[sfb] = tmp; 575956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 576956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 577956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spread normalized values from sfbs to lines */ 578b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard sfb = lpcStartBand; 579b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = tnsSfbMean[sfb]; 580956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for ( i=lpcStartLine; i<lpcStopLine; i++){ 581b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp_s = sfbOffset[sfb + 1] - i; 582956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( tmp_s == 0 ) { 583956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sfb = sfb + 1; 584b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp2_s = sfb + 1 - lpcStopBand; 585956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (tmp2_s <= 0) { 586b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = tnsSfbMean[sfb]; 587956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 588956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 589b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard pWork32[i] = tmp; 590956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 591956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /*filter down*/ 592956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=(lpcStopLine - 2); i>=lpcStartLine; i--){ 593956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pWork32[i] = (pWork32[i] + pWork32[i + 1]) >> 1; 594956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 595956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* filter up */ 596956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=(lpcStartLine + 1); i<lpcStopLine; i++){ 597956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pWork32[i] = (pWork32[i] + pWork32[i - 1]) >> 1; 598956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 599956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 600956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* weight and normalize */ 601956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=lpcStartLine; i<lpcStopLine; i++){ 602b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard pWork32[i] = MULHIGH(pWork32[i], spectrum[i]); 603b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxWS |= L_abs(pWork32[i]); 604956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 605956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxShift = norm_l(maxWS); 606e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 607e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard maxShift = 16 - maxShift; 608e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(maxShift >= 0) 609e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 610e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i=lpcStartLine; i<lpcStopLine; i++){ 611e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard weightedSpectrum[i] = pWork32[i] >> maxShift; 612e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 613e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 614e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else 615e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 616e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard maxShift = -maxShift; 617e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i=lpcStartLine; i<lpcStopLine; i++){ 618e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard weightedSpectrum[i] = saturate(pWork32[i] << maxShift); 619e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 620956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 621956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 622956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 623956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 624956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 625956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 626956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 627956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 628956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: CalcTnsFilter 629956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: LPC calculation for one TNS filter 630956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: prediction gain 631956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: signal spectrum, acf window, no. of spectral lines, 632956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* max. TNS order, ptr. to reflection ocefficients 633956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* output: reflection coefficients 634956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*(half) window size must be larger than tnsOrder !!* 635956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong******************************************************************************/ 636956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 637956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 CalcTnsFilter(const Word16 *signal, 638956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word32 window[], 639956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 numOfLines, 640956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 tnsOrder, 641956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 parcor[]) 642956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 643956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 parcorWorkBuffer[2*TNS_MAX_ORDER+1]; 644956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 predictionGain; 645956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 646956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 tnsOrderPlus1 = tnsOrder + 1; 647956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 64884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED(window); 64984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 650956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong assert(tnsOrder <= TNS_MAX_ORDER); /* remove asserts later? (btg) */ 651956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 652956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=0;i<tnsOrder;i++) { 653b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard parcor[i] = 0; 654956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 655956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 656956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong AutoCorrelation(signal, parcorWorkBuffer, numOfLines, tnsOrderPlus1); 657956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 658956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* early return if signal is very low: signal prediction off, with zero parcor coeffs */ 659956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (parcorWorkBuffer[0] == 0) 660956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 661956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 662956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong predictionGain = AutoToParcor(parcorWorkBuffer, parcor, tnsOrder); 663956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 664956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(predictionGain); 665956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 666956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 667956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 668956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 669956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: AutoCorrelation 670956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: calc. autocorrelation (acf) 671956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: - 672956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: input values, no. of input values, no. of acf values 673956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* output: acf values 674956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 675956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 676e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifndef ARMV5E 677956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid AutoCorrelation(const Word16 input[], 678956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 corr[], 679956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 samples, 680956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 corrCoeff) { 681956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i, j, isamples; 682956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 accu; 683956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 scf; 684956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 685b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard scf = 10 - 1; 686e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 687956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong isamples = samples; 688956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* calc first corrCoef: R[0] = sum { t[i] * t[i] } ; i = 0..N-1 */ 689b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard accu = 0; 690956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(j=0; j<isamples; j++) { 691e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard accu = L_add(accu, ((input[j] * input[j]) >> scf)); 692956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 693b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard corr[0] = accu; 694956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 695956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* early termination if all corr coeffs are likely going to be zero */ 696956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(corr[0] == 0) return ; 697956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 698956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* calc all other corrCoef: R[j] = sum { t[i] * t[i+j] } ; i = 0..(N-j-1), j=1..p */ 699956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=1; i<corrCoeff; i++) { 700956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong isamples = isamples - 1; 701b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard accu = 0; 702956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(j=0; j<isamples; j++) { 703e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard accu = L_add(accu, ((input[j] * input[j+i]) >> scf)); 704956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 705b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard corr[i] = accu; 706956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 707b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard} 708956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#endif 709956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 710956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 711956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 712956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: AutoToParcor 713956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: conversion autocorrelation to reflection coefficients 714956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: prediction gain 715956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: <order+1> input values, no. of output values (=order), 716956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* ptr. to workbuffer (required size: 2*order) 717956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* output: <order> reflection coefficients 718956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 719956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 720956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 AutoToParcor(Word32 workBuffer[], Word32 reflCoeff[], Word16 numOfCoeff) { 721956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 722956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i, j, shift; 723956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pWorkBuffer; /* temp pointer */ 724956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 predictionGain = 0; 725956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 num, denom; 726956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp, workBuffer0; 727956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 728b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 729b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard num = workBuffer[0]; 730b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = workBuffer[numOfCoeff]; 731956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 732956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=0; i<numOfCoeff-1; i++) { 733b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard workBuffer[i + numOfCoeff] = workBuffer[i + 1]; 734956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 735b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard workBuffer[i + numOfCoeff] = temp; 736b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 737956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=0; i<numOfCoeff; i++) { 738956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 refc; 739956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 740b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 741956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (workBuffer[0] < L_abs(workBuffer[i + numOfCoeff])) { 742956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0 ; 743956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 744e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard shift = norm_l(workBuffer[0]); 745956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong workBuffer0 = Div_32(1 << shift, workBuffer[0] << shift); 746956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* calculate refc = -workBuffer[numOfCoeff+i] / workBuffer[0]; -1 <= refc < 1 */ 747956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong refc = L_negate(fixmul(workBuffer[numOfCoeff + i], workBuffer0)); 748956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 749b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard reflCoeff[i] = refc; 750956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 751b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard pWorkBuffer = &(workBuffer[numOfCoeff]); 752956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 753956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(j=i; j<numOfCoeff; j++) { 754956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 accu1, accu2; 755956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accu1 = L_add(pWorkBuffer[j], fixmul(refc, workBuffer[j - i])); 756956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accu2 = L_add(workBuffer[j - i], fixmul(refc, pWorkBuffer[j])); 757b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard pWorkBuffer[j] = accu1; 758b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard workBuffer[j - i] = accu2; 759956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 760956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 761956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 762956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong denom = MULHIGH(workBuffer[0], NORM_COEF); 763b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 764956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (denom != 0) { 765e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 temp; 766e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard shift = norm_l(denom); 767956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong temp = Div_32(1 << shift, denom << shift); 768956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong predictionGain = fixmul(num, temp); 769956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 770956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 771956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return extract_l(predictionGain); 772956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 773956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 774956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 775956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 776956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 Search3(Word32 parcor) 777956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 778956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 index = 0; 779956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 780956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp; 781b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 782956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0;i<8;i++) { 783b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = L_sub( parcor, tnsCoeff3Borders[i]); 784956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (temp > 0) 785b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard index=i; 786956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 787956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return extract_l(index - 4); 788956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 789956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 790956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 Search4(Word32 parcor) 791956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 792956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 index = 0; 793956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 794956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp; 795b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 796956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 797956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0;i<16;i++) { 798b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = L_sub(parcor, tnsCoeff4Borders[i]); 799956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (temp > 0) 800b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard index=i; 801956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 802956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return extract_l(index - 8); 803956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 804956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 805956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 806956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 807956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 808956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 809956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* functionname: Parcor2Index 810956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: quantization index for reflection coefficients 811956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 812956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 813956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void Parcor2Index(const Word32 parcor[], /*!< parcor coefficients */ 814956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 index[], /*!< quantized coeff indices */ 815956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 order, /*!< filter order */ 816956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitsPerCoeff) { /*!< quantizer resolution */ 817956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 818956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp; 819956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 820956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=0; i<order; i++) { 821b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = bitsPerCoeff - 3; 822956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (temp == 0) { 823b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard index[i] = Search3(parcor[i]); 824b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard } 825956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 826b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard index[i] = Search4(parcor[i]); 827956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 828956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 829956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 830956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 831956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 832956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 833956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* functionname: Index2Parcor 834956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Inverse quantization for reflection coefficients 835956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 836956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 837956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void Index2Parcor(const Word16 index[], /*!< quantized values */ 838956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 parcor[], /*!< ptr. to reflection coefficients (output) */ 839956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 order, /*!< no. of coefficients */ 840956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitsPerCoeff) /*!< quantizer resolution */ 841956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 842956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 843956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp; 844956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 845956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<order; i++) { 846b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = bitsPerCoeff - 4; 847956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp == 0 ) { 848b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard parcor[i] = tnsCoeff4[index[i] + 8]; 849956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 850956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 851b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard parcor[i] = tnsCoeff3[index[i] + 4]; 852956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 853956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 854956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 855956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 856956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 857956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 858956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* functionname: FIRLattice 859956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: in place lattice filtering of spectral data 860956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: pointer to modified data 861956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 862956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 863956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32 FIRLattice(Word16 order, /*!< filter order */ 864956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 x, /*!< spectral data */ 865956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *state_par, /*!< filter states */ 866956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word32 *coef_par) /*!< filter coefficients */ 867956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 868956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 869956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 accu,tmp,tmpSave; 870956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 871956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x = x >> 1; 872b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmpSave = x; 873956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 874956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<(order - 1); i++) { 875956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 876956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tmp = L_add(fixmul(coef_par[i], x), state_par[i]); 877956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x = L_add(fixmul(coef_par[i], state_par[i]), x); 878956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 879b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard state_par[i] = tmpSave; 880b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmpSave = tmp; 881956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 882956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 883956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* last stage: only need half operations */ 884956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accu = fixmul(state_par[order - 1], coef_par[(order - 1)]); 885b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard state_par[(order - 1)] = tmpSave; 886956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 887956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x = L_add(accu, x); 888956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x = L_add(x, x); 889956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 890956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return x; 891956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 892956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 893956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 894956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 895956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* functionname: AnalysisFilterLattice 896956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: filters spectral lines with TNS filter 897956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 898956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 899956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void AnalysisFilterLattice(const Word32 signal[], /*!< input spectrum */ 900956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 numOfLines, /*!< no. of lines */ 901956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word32 parCoeff[],/*!< PARC coefficients */ 902956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 order, /*!< filter order */ 903956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 output[]) /*!< filtered signal values */ 904956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 905956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 906956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 state_par[TNS_MAX_ORDER]; 907956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 j; 908956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 909956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for ( j=0; j<TNS_MAX_ORDER; j++ ) { 910b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard state_par[j] = 0; 911956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 912956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 913956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(j=0; j<numOfLines; j++) { 914b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard output[j] = FIRLattice(order,signal[j],state_par,parCoeff); 915956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 916956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 917956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 918956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 919956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 920956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* functionname: ApplyTnsMultTableToRatios 921956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Change thresholds according to tns 922956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 923956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 924956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid ApplyTnsMultTableToRatios(Word16 startCb, 925956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 stopCb, 926956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_SUBBLOCK_INFO subInfo, /*!< TNS subblock info */ 927956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *thresholds) /*!< thresholds (modified) */ 928956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 929b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word32 i; 930956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (subInfo.tnsActive) { 931956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=startCb; i<stopCb; i++) { 932956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* thresholds[i] * 0.25 */ 933b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard thresholds[i] = (thresholds[i] >> 2); 934956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 935956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 936956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 937