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 143b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe Word32 bitratePerChannel __unused; 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{ 209b3f9759c8c9437c45b9a34519ce2ea38a8314d4eAndreas Gampe Word32 bitratePerChannel __unused; 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: CalcWeightedSpectrum 501956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Calculate weighted spectrum for LPC calculation 502956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 503956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 504956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void CalcWeightedSpectrum(const Word32 spectrum[], /*!< input spectrum */ 505956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 weightedSpectrum[], 506956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *sfbEnergy, /*!< sfb energies */ 507956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 *sfbOffset, 508956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 lpcStartLine, 509956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 lpcStopLine, 510956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 lpcStartBand, 511956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 lpcStopBand, 512956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pWork32) 513956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 514956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong #define INT_BITS_SCAL 1<<(INT_BITS/2) 515956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 516956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i, sfb, shift; 517956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 maxShift; 518956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 tmp_s, tmp2_s; 519956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 tmp, tmp2; 520956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 maxWS; 521956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 tnsSfbMean[MAX_SFB]; /* length [lpcStopBand-lpcStartBand] should be sufficient here */ 522956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 523b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxWS = 0; 524b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 525956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* calc 1.0*2^-INT_BITS/2/sqrt(en) */ 526956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for( sfb = lpcStartBand; sfb < lpcStopBand; sfb++) { 527956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 528b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp2 = sfbEnergy[sfb] - 2; 529956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if( tmp2 > 0) { 530956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tmp = rsqrt(sfbEnergy[sfb], INT_BITS); 531b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard if(tmp > INT_BITS_SCAL) 532e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 533e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard shift = norm_l(tmp); 534b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = Div_32( INT_BITS_SCAL << shift, tmp << shift ); 535956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 536956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else 537956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong { 538b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = 0x7fffffff; 539956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 540956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 541956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 542b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = 0x7fffffff; 543b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard } 544b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tnsSfbMean[sfb] = tmp; 545956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 546956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 547956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* spread normalized values from sfbs to lines */ 548b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard sfb = lpcStartBand; 549b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = tnsSfbMean[sfb]; 550956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for ( i=lpcStartLine; i<lpcStopLine; i++){ 551b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp_s = sfbOffset[sfb + 1] - i; 552956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( tmp_s == 0 ) { 553956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sfb = sfb + 1; 554b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp2_s = sfb + 1 - lpcStopBand; 555956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (tmp2_s <= 0) { 556b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp = tnsSfbMean[sfb]; 557956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 558956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 559b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard pWork32[i] = tmp; 560956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 561956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /*filter down*/ 562956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=(lpcStopLine - 2); i>=lpcStartLine; i--){ 563956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pWork32[i] = (pWork32[i] + pWork32[i + 1]) >> 1; 564956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 565956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* filter up */ 566956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=(lpcStartLine + 1); i<lpcStopLine; i++){ 567956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pWork32[i] = (pWork32[i] + pWork32[i - 1]) >> 1; 568956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 569956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 570956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* weight and normalize */ 571956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=lpcStartLine; i<lpcStopLine; i++){ 572b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard pWork32[i] = MULHIGH(pWork32[i], spectrum[i]); 573b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard maxWS |= L_abs(pWork32[i]); 574956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 575956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong maxShift = norm_l(maxWS); 576e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 577e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard maxShift = 16 - maxShift; 578e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(maxShift >= 0) 579e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 580e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i=lpcStartLine; i<lpcStopLine; i++){ 581e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard weightedSpectrum[i] = pWork32[i] >> maxShift; 582e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 583e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 584e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else 585e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 586e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard maxShift = -maxShift; 587e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i=lpcStartLine; i<lpcStopLine; i++){ 588e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard weightedSpectrum[i] = saturate(pWork32[i] << maxShift); 589e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 590956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 591956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 592956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 593956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 594956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 595956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 596956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 597956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 598956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: CalcTnsFilter 599956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: LPC calculation for one TNS filter 600956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: prediction gain 601956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: signal spectrum, acf window, no. of spectral lines, 602956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* max. TNS order, ptr. to reflection ocefficients 603956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* output: reflection coefficients 604956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*(half) window size must be larger than tnsOrder !!* 605956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong******************************************************************************/ 606956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 607956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 CalcTnsFilter(const Word16 *signal, 608956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word32 window[], 609956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 numOfLines, 610956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 tnsOrder, 611956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 parcor[]) 612956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 613956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 parcorWorkBuffer[2*TNS_MAX_ORDER+1]; 614956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 predictionGain; 615956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 616956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 tnsOrderPlus1 = tnsOrder + 1; 617956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 61884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED(window); 61984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 620956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong assert(tnsOrder <= TNS_MAX_ORDER); /* remove asserts later? (btg) */ 621956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 622956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=0;i<tnsOrder;i++) { 623b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard parcor[i] = 0; 624956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 625956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 626956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong AutoCorrelation(signal, parcorWorkBuffer, numOfLines, tnsOrderPlus1); 627956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 628956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* early return if signal is very low: signal prediction off, with zero parcor coeffs */ 629956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (parcorWorkBuffer[0] == 0) 630956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0; 631956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 632956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong predictionGain = AutoToParcor(parcorWorkBuffer, parcor, tnsOrder); 633956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 634956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return(predictionGain); 635956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 636956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 637956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 638956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 639956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: AutoCorrelation 640956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: calc. autocorrelation (acf) 641956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: - 642956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: input values, no. of input values, no. of acf values 643956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* output: acf values 644956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 645956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 646e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifndef ARMV5E 647956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid AutoCorrelation(const Word16 input[], 648956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 corr[], 649956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 samples, 650956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 corrCoeff) { 651956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i, j, isamples; 652956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 accu; 653956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 scf; 654956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 655b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard scf = 10 - 1; 656e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 657956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong isamples = samples; 658956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* calc first corrCoef: R[0] = sum { t[i] * t[i] } ; i = 0..N-1 */ 659b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard accu = 0; 660956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(j=0; j<isamples; j++) { 661e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard accu = L_add(accu, ((input[j] * input[j]) >> scf)); 662956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 663b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard corr[0] = accu; 664956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 665956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* early termination if all corr coeffs are likely going to be zero */ 666956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(corr[0] == 0) return ; 667956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 668956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* calc all other corrCoef: R[j] = sum { t[i] * t[i+j] } ; i = 0..(N-j-1), j=1..p */ 669956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=1; i<corrCoeff; i++) { 670956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong isamples = isamples - 1; 671b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard accu = 0; 672956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(j=0; j<isamples; j++) { 673e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard accu = L_add(accu, ((input[j] * input[j+i]) >> scf)); 674956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 675b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard corr[i] = accu; 676956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 677b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard} 678956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#endif 679956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 680956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 681956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 682956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: AutoToParcor 683956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: conversion autocorrelation to reflection coefficients 684956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: prediction gain 685956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: <order+1> input values, no. of output values (=order), 686956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* ptr. to workbuffer (required size: 2*order) 687956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* output: <order> reflection coefficients 688956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 689956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 690956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 AutoToParcor(Word32 workBuffer[], Word32 reflCoeff[], Word16 numOfCoeff) { 691956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 692956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i, j, shift; 693956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *pWorkBuffer; /* temp pointer */ 694956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 predictionGain = 0; 695956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 num, denom; 696956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp, workBuffer0; 697956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 698b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 699b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard num = workBuffer[0]; 700b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = workBuffer[numOfCoeff]; 701956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 702956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=0; i<numOfCoeff-1; i++) { 703b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard workBuffer[i + numOfCoeff] = workBuffer[i + 1]; 704956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 705b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard workBuffer[i + numOfCoeff] = temp; 706b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 707956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=0; i<numOfCoeff; i++) { 708956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 refc; 709956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 710b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 711956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (workBuffer[0] < L_abs(workBuffer[i + numOfCoeff])) { 712956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return 0 ; 713956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 714e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard shift = norm_l(workBuffer[0]); 715956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong workBuffer0 = Div_32(1 << shift, workBuffer[0] << shift); 716956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* calculate refc = -workBuffer[numOfCoeff+i] / workBuffer[0]; -1 <= refc < 1 */ 717956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong refc = L_negate(fixmul(workBuffer[numOfCoeff + i], workBuffer0)); 718956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 719b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard reflCoeff[i] = refc; 720956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 721b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard pWorkBuffer = &(workBuffer[numOfCoeff]); 722956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 723956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(j=i; j<numOfCoeff; j++) { 724956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 accu1, accu2; 725956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accu1 = L_add(pWorkBuffer[j], fixmul(refc, workBuffer[j - i])); 726956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accu2 = L_add(workBuffer[j - i], fixmul(refc, pWorkBuffer[j])); 727b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard pWorkBuffer[j] = accu1; 728b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard workBuffer[j - i] = accu2; 729956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 730956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 731956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 732956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong denom = MULHIGH(workBuffer[0], NORM_COEF); 733b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 734956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (denom != 0) { 735e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 temp; 736e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard shift = norm_l(denom); 737956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong temp = Div_32(1 << shift, denom << shift); 738956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong predictionGain = fixmul(num, temp); 739956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 740956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 741956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return extract_l(predictionGain); 742956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 743956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 744956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 745956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 746956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 Search3(Word32 parcor) 747956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 748956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 index = 0; 749956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 750956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp; 751b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 752956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0;i<8;i++) { 753b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = L_sub( parcor, tnsCoeff3Borders[i]); 754956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (temp > 0) 755b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard index=i; 756956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 757956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return extract_l(index - 4); 758956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 759956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 760956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 Search4(Word32 parcor) 761956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 762956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 index = 0; 763956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 764956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp; 765b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 766956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 767956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0;i<16;i++) { 768b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = L_sub(parcor, tnsCoeff4Borders[i]); 769956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (temp > 0) 770b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard index=i; 771956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 772956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return extract_l(index - 8); 773956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 774956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 775956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 776956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 777956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 778956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 779956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* functionname: Parcor2Index 780956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: quantization index for reflection coefficients 781956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 782956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 783956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void Parcor2Index(const Word32 parcor[], /*!< parcor coefficients */ 784956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 index[], /*!< quantized coeff indices */ 785956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 order, /*!< filter order */ 786956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitsPerCoeff) { /*!< quantizer resolution */ 787956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 788956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp; 789956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 790956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=0; i<order; i++) { 791b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = bitsPerCoeff - 3; 792956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (temp == 0) { 793b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard index[i] = Search3(parcor[i]); 794b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard } 795956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 796b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard index[i] = Search4(parcor[i]); 797956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 798956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 799956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 800956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 801956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 802956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 803956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* functionname: Index2Parcor 804956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Inverse quantization for reflection coefficients 805956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 806956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 807956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void Index2Parcor(const Word16 index[], /*!< quantized values */ 808956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 parcor[], /*!< ptr. to reflection coefficients (output) */ 809956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 order, /*!< no. of coefficients */ 810956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 bitsPerCoeff) /*!< quantizer resolution */ 811956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 812956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 813956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 temp; 814956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 815956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<order; i++) { 816b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp = bitsPerCoeff - 4; 817956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if ( temp == 0 ) { 818b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard parcor[i] = tnsCoeff4[index[i] + 8]; 819956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 820956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 821b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard parcor[i] = tnsCoeff3[index[i] + 4]; 822956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 823956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 824956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 825956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 826956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 827956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 828956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* functionname: FIRLattice 829956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: in place lattice filtering of spectral data 830956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: pointer to modified data 831956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 832956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 833956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word32 FIRLattice(Word16 order, /*!< filter order */ 834956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 x, /*!< spectral data */ 835956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *state_par, /*!< filter states */ 836956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word32 *coef_par) /*!< filter coefficients */ 837956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 838956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 i; 839956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 accu,tmp,tmpSave; 840956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 841956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x = x >> 1; 842b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmpSave = x; 843956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 844956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (i=0; i<(order - 1); i++) { 845956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 846956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tmp = L_add(fixmul(coef_par[i], x), state_par[i]); 847956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x = L_add(fixmul(coef_par[i], state_par[i]), x); 848956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 849b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard state_par[i] = tmpSave; 850b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmpSave = tmp; 851956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 852956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 853956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* last stage: only need half operations */ 854956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accu = fixmul(state_par[order - 1], coef_par[(order - 1)]); 855b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard state_par[(order - 1)] = tmpSave; 856956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 857956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x = L_add(accu, x); 858956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x = L_add(x, x); 859956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 860956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return x; 861956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 862956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 863956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 864956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 865956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* functionname: AnalysisFilterLattice 866956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: filters spectral lines with TNS filter 867956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 868956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 869956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void AnalysisFilterLattice(const Word32 signal[], /*!< input spectrum */ 870956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 numOfLines, /*!< no. of lines */ 871956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word32 parCoeff[],/*!< PARC coefficients */ 872956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 order, /*!< filter order */ 873956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 output[]) /*!< filtered signal values */ 874956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 875956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 876956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 state_par[TNS_MAX_ORDER]; 877956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 j; 878956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 879956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for ( j=0; j<TNS_MAX_ORDER; j++ ) { 880b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard state_par[j] = 0; 881956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 882956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 883956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(j=0; j<numOfLines; j++) { 884b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard output[j] = FIRLattice(order,signal[j],state_par,parCoeff); 885956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 886956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 887956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 888956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 889956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 890956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* functionname: ApplyTnsMultTableToRatios 891956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: Change thresholds according to tns 892956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 893956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 894956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid ApplyTnsMultTableToRatios(Word16 startCb, 895956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 stopCb, 896956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong TNS_SUBBLOCK_INFO subInfo, /*!< TNS subblock info */ 897956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *thresholds) /*!< thresholds (modified) */ 898956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 899b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word32 i; 900956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (subInfo.tnsActive) { 901956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(i=startCb; i<stopCb; i++) { 902956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* thresholds[i] * 0.25 */ 903b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard thresholds[i] = (thresholds[i] >> 2); 904956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 905956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 906956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 907