diff options
Diffstat (limited to 'media/libstagefright/codecs/aacenc/src/tns.c')
-rw-r--r-- | media/libstagefright/codecs/aacenc/src/tns.c | 932 |
1 files changed, 0 insertions, 932 deletions
diff --git a/media/libstagefright/codecs/aacenc/src/tns.c b/media/libstagefright/codecs/aacenc/src/tns.c deleted file mode 100644 index 455a864..0000000 --- a/media/libstagefright/codecs/aacenc/src/tns.c +++ /dev/null @@ -1,932 +0,0 @@ -/* - ** Copyright 2003-2010, VisualOn, Inc. - ** - ** Licensed under the Apache License, Version 2.0 (the "License"); - ** you may not use this file except in compliance with the License. - ** You may obtain a copy of the License at - ** - ** http://www.apache.org/licenses/LICENSE-2.0 - ** - ** Unless required by applicable law or agreed to in writing, software - ** distributed under the License is distributed on an "AS IS" BASIS, - ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ** See the License for the specific language governing permissions and - ** limitations under the License. - */ -/******************************************************************************* - File: tns.c - - Content: Definition TNS tools functions - -*******************************************************************************/ - -#include "basic_op.h" -#include "oper_32b.h" -#include "assert.h" -#include "aac_rom.h" -#include "psy_const.h" -#include "tns.h" -#include "tns_param.h" -#include "psy_configuration.h" -#include "tns_func.h" - -#define TNS_MODIFY_BEGIN 2600 /* Hz */ -#define RATIO_PATCH_LOWER_BORDER 380 /* Hz */ -#define TNS_GAIN_THRESH 141 /* 1.41*100 */ -#define NORM_COEF 0x028f5c28 - -static const Word32 TNS_PARCOR_THRESH = 0x0ccccccd; /* 0.1*(1 << 31) */ -/* Limit bands to > 2.0 kHz */ -static unsigned short tnsMinBandNumberLong[12] = -{ 11, 12, 15, 16, 17, 20, 25, 26, 24, 28, 30, 31 }; -static unsigned short tnsMinBandNumberShort[12] = -{ 2, 2, 2, 3, 3, 4, 6, 6, 8, 10, 10, 12 }; - -/**************************************/ -/* Main/Low Profile TNS Parameters */ -/**************************************/ -static unsigned short tnsMaxBandsLongMainLow[12] = -{ 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39 }; - -static unsigned short tnsMaxBandsShortMainLow[12] = -{ 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14 }; - - -static void CalcWeightedSpectrum(const Word32 spectrum[], - Word16 weightedSpectrum[], - Word32* sfbEnergy, - const Word16* sfbOffset, Word16 lpcStartLine, - Word16 lpcStopLine, Word16 lpcStartBand,Word16 lpcStopBand, - Word32 *pWork32); - - - -void AutoCorrelation(const Word16 input[], Word32 corr[], - Word16 samples, Word16 corrCoeff); -static Word16 AutoToParcor(Word32 workBuffer[], Word32 reflCoeff[], Word16 numOfCoeff); - -static Word16 CalcTnsFilter(const Word16* signal, const Word32 window[], Word16 numOfLines, - Word16 tnsOrder, Word32 parcor[]); - - -static void Parcor2Index(const Word32 parcor[], Word16 index[], Word16 order, - Word16 bitsPerCoeff); - -static void Index2Parcor(const Word16 index[], Word32 parcor[], Word16 order, - Word16 bitsPerCoeff); - - - -static void AnalysisFilterLattice(const Word32 signal[], Word16 numOfLines, - const Word32 parCoeff[], Word16 order, - Word32 output[]); - - -/** -* -* function name: FreqToBandWithRounding -* description: Retrieve index of nearest band border -* returnt: index -* -*/ -static Word16 FreqToBandWithRounding(Word32 freq, /*!< frequency in Hertz */ - Word32 fs, /*!< Sampling frequency in Hertz */ - Word16 numOfBands, /*!< total number of bands */ - const Word16 *bandStartOffset) /*!< table of band borders */ -{ - Word32 lineNumber, band; - Word32 temp, shift; - - /* assert(freq >= 0); */ - shift = norm_l(fs); - lineNumber = (extract_l(fixmul((bandStartOffset[numOfBands] << 2),Div_32(freq << shift,fs << shift))) + 1) >> 1; - - /* freq > fs/2 */ - temp = lineNumber - bandStartOffset[numOfBands] ; - if (temp >= 0) - return numOfBands; - - /* find band the line number lies in */ - for (band=0; band<numOfBands; band++) { - temp = bandStartOffset[band + 1] - lineNumber; - if (temp > 0) break; - } - - temp = (lineNumber - bandStartOffset[band]); - temp = (temp - (bandStartOffset[band + 1] - lineNumber)); - if ( temp > 0 ) - { - band = band + 1; - } - - return extract_l(band); -} - - -/** -* -* function name: InitTnsConfigurationLong -* description: Fill TNS_CONFIG structure with sensible content for long blocks -* returns: 0 if success -* -*/ -Word16 InitTnsConfigurationLong(Word32 bitRate, /*!< bitrate */ - Word32 sampleRate, /*!< Sampling frequency */ - Word16 channels, /*!< number of channels */ - TNS_CONFIG *tC, /*!< TNS Config struct (modified) */ - PSY_CONFIGURATION_LONG *pC, /*!< psy config struct */ - Word16 active) /*!< tns active flag */ -{ - - Word32 bitratePerChannel; - tC->maxOrder = TNS_MAX_ORDER; - tC->tnsStartFreq = 1275; - tC->coefRes = 4; - - /* to avoid integer division */ - if ( sub(channels,2) == 0 ) { - bitratePerChannel = bitRate >> 1; - } - else { - bitratePerChannel = bitRate; - } - - tC->tnsMaxSfb = tnsMaxBandsLongMainLow[pC->sampRateIdx]; - - tC->tnsActive = active; - - /* now calc band and line borders */ - tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb); - tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand]; - - tC->tnsStartBand = FreqToBandWithRounding(tC->tnsStartFreq, sampleRate, - pC->sfbCnt, (const Word16*)pC->sfbOffset); - - tC->tnsModifyBeginCb = FreqToBandWithRounding(TNS_MODIFY_BEGIN, - sampleRate, - pC->sfbCnt, - (const Word16*)pC->sfbOffset); - - tC->tnsRatioPatchLowestCb = FreqToBandWithRounding(RATIO_PATCH_LOWER_BORDER, - sampleRate, - pC->sfbCnt, - (const Word16*)pC->sfbOffset); - - - tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand]; - - tC->lpcStopBand = tnsMaxBandsLongMainLow[pC->sampRateIdx]; - tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive); - - tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand]; - - tC->lpcStartBand = tnsMinBandNumberLong[pC->sampRateIdx]; - - tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand]; - - tC->threshold = TNS_GAIN_THRESH; - - - return(0); -} - -/** -* -* function name: InitTnsConfigurationShort -* description: Fill TNS_CONFIG structure with sensible content for short blocks -* returns: 0 if success -* -*/ -Word16 InitTnsConfigurationShort(Word32 bitRate, /*!< bitrate */ - Word32 sampleRate, /*!< Sampling frequency */ - Word16 channels, /*!< number of channels */ - TNS_CONFIG *tC, /*!< TNS Config struct (modified) */ - PSY_CONFIGURATION_SHORT *pC, /*!< psy config struct */ - Word16 active) /*!< tns active flag */ -{ - Word32 bitratePerChannel; - tC->maxOrder = TNS_MAX_ORDER_SHORT; - tC->tnsStartFreq = 2750; - tC->coefRes = 3; - - /* to avoid integer division */ - if ( sub(channels,2) == 0 ) { - bitratePerChannel = L_shr(bitRate,1); - } - else { - bitratePerChannel = bitRate; - } - - tC->tnsMaxSfb = tnsMaxBandsShortMainLow[pC->sampRateIdx]; - - tC->tnsActive = active; - - /* now calc band and line borders */ - tC->tnsStopBand = min(pC->sfbCnt, tC->tnsMaxSfb); - tC->tnsStopLine = pC->sfbOffset[tC->tnsStopBand]; - - tC->tnsStartBand=FreqToBandWithRounding(tC->tnsStartFreq, sampleRate, - pC->sfbCnt, (const Word16*)pC->sfbOffset); - - tC->tnsModifyBeginCb = FreqToBandWithRounding(TNS_MODIFY_BEGIN, - sampleRate, - pC->sfbCnt, - (const Word16*)pC->sfbOffset); - - tC->tnsRatioPatchLowestCb = FreqToBandWithRounding(RATIO_PATCH_LOWER_BORDER, - sampleRate, - pC->sfbCnt, - (const Word16*)pC->sfbOffset); - - - tC->tnsStartLine = pC->sfbOffset[tC->tnsStartBand]; - - tC->lpcStopBand = tnsMaxBandsShortMainLow[pC->sampRateIdx]; - - tC->lpcStopBand = min(tC->lpcStopBand, pC->sfbActive); - - tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand]; - - tC->lpcStartBand = tnsMinBandNumberShort[pC->sampRateIdx]; - - tC->lpcStartLine = pC->sfbOffset[tC->lpcStartBand]; - - tC->threshold = TNS_GAIN_THRESH; - - return(0); -} - -/** -* -* function name: TnsDetect -* description: Calculate TNS filter and decide on TNS usage -* returns: 0 if success -* -*/ -Word32 TnsDetect(TNS_DATA* tnsData, /*!< tns data structure (modified) */ - TNS_CONFIG tC, /*!< tns config structure */ - Word32* pScratchTns, /*!< pointer to scratch space */ - const Word16 sfbOffset[], /*!< scalefactor size and table */ - Word32* spectrum, /*!< spectral data */ - Word16 subBlockNumber, /*!< subblock num */ - Word16 blockType, /*!< blocktype (long or short) */ - Word32 * sfbEnergy) /*!< sfb-wise energy */ -{ - - Word32 predictionGain; - Word32 temp; - Word32* pWork32 = &pScratchTns[subBlockNumber >> 8]; - Word16* pWeightedSpectrum = (Word16 *)&pScratchTns[subBlockNumber >> 8]; - - - if (tC.tnsActive) { - CalcWeightedSpectrum(spectrum, - pWeightedSpectrum, - sfbEnergy, - sfbOffset, - tC.lpcStartLine, - tC.lpcStopLine, - tC.lpcStartBand, - tC.lpcStopBand, - pWork32); - - temp = blockType - SHORT_WINDOW; - if ( temp != 0 ) { - predictionGain = CalcTnsFilter( &pWeightedSpectrum[tC.lpcStartLine], - tC.acfWindow, - tC.lpcStopLine - tC.lpcStartLine, - tC.maxOrder, - tnsData->dataRaw.tnsLong.subBlockInfo.parcor); - - - temp = predictionGain - tC.threshold; - if ( temp > 0 ) { - tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 1; - } - else { - tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0; - } - - tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = predictionGain; - } - else{ - - predictionGain = CalcTnsFilter( &pWeightedSpectrum[tC.lpcStartLine], - tC.acfWindow, - tC.lpcStopLine - tC.lpcStartLine, - tC.maxOrder, - tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].parcor); - - temp = predictionGain - tC.threshold; - if ( temp > 0 ) { - tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 1; - } - else { - tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0; - } - - tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = predictionGain; - } - - } - else{ - - temp = blockType - SHORT_WINDOW; - if ( temp != 0 ) { - tnsData->dataRaw.tnsLong.subBlockInfo.tnsActive = 0; - tnsData->dataRaw.tnsLong.subBlockInfo.predictionGain = 0; - } - else { - tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].tnsActive = 0; - tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber].predictionGain = 0; - } - } - - return(0); -} - - -/***************************************************************************** -* -* function name: TnsSync -* description: update tns parameter -* -*****************************************************************************/ -void TnsSync(TNS_DATA *tnsDataDest, - const TNS_DATA *tnsDataSrc, - const TNS_CONFIG tC, - const Word16 subBlockNumber, - const Word16 blockType) -{ - TNS_SUBBLOCK_INFO *sbInfoDest; - const TNS_SUBBLOCK_INFO *sbInfoSrc; - Word32 i, temp; - - temp = blockType - SHORT_WINDOW; - if ( temp != 0 ) { - sbInfoDest = &tnsDataDest->dataRaw.tnsLong.subBlockInfo; - sbInfoSrc = &tnsDataSrc->dataRaw.tnsLong.subBlockInfo; - } - else { - sbInfoDest = &tnsDataDest->dataRaw.tnsShort.subBlockInfo[subBlockNumber]; - sbInfoSrc = &tnsDataSrc->dataRaw.tnsShort.subBlockInfo[subBlockNumber]; - } - - if (100*abs_s(sbInfoDest->predictionGain - sbInfoSrc->predictionGain) < - (3 * sbInfoDest->predictionGain)) { - sbInfoDest->tnsActive = sbInfoSrc->tnsActive; - for ( i=0; i< tC.maxOrder; i++) { - sbInfoDest->parcor[i] = sbInfoSrc->parcor[i]; - } - } -} - -/***************************************************************************** -* -* function name: TnsEncode -* description: do TNS filtering -* returns: 0 if success -* -*****************************************************************************/ -Word16 TnsEncode(TNS_INFO* tnsInfo, /*!< tns info structure (modified) */ - TNS_DATA* tnsData, /*!< tns data structure (modified) */ - Word16 numOfSfb, /*!< number of scale factor bands */ - TNS_CONFIG tC, /*!< tns config structure */ - Word16 lowPassLine, /*!< lowpass line */ - Word32* spectrum, /*!< spectral data (modified) */ - Word16 subBlockNumber, /*!< subblock num */ - Word16 blockType) /*!< blocktype (long or short) */ -{ - Word32 i; - Word32 temp_s; - Word32 temp; - TNS_SUBBLOCK_INFO *psubBlockInfo; - - temp_s = blockType - SHORT_WINDOW; - if ( temp_s != 0) { - psubBlockInfo = &tnsData->dataRaw.tnsLong.subBlockInfo; - if (psubBlockInfo->tnsActive == 0) { - tnsInfo->tnsActive[subBlockNumber] = 0; - return(0); - } - else { - - Parcor2Index(psubBlockInfo->parcor, - tnsInfo->coef, - tC.maxOrder, - tC.coefRes); - - Index2Parcor(tnsInfo->coef, - psubBlockInfo->parcor, - tC.maxOrder, - tC.coefRes); - - for (i=tC.maxOrder - 1; i>=0; i--) { - temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH; - if ( temp > 0 ) - break; - temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH; - if ( temp < 0 ) - break; - } - tnsInfo->order[subBlockNumber] = i + 1; - - - tnsInfo->tnsActive[subBlockNumber] = 1; - for (i=subBlockNumber+1; i<TRANS_FAC; i++) { - tnsInfo->tnsActive[i] = 0; - } - tnsInfo->coefRes[subBlockNumber] = tC.coefRes; - tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand; - - - AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]), - (min(tC.tnsStopLine,lowPassLine) - tC.tnsStartLine), - psubBlockInfo->parcor, - tnsInfo->order[subBlockNumber], - &(spectrum[tC.tnsStartLine])); - - } - } /* if (blockType!=SHORT_WINDOW) */ - else /*short block*/ { - psubBlockInfo = &tnsData->dataRaw.tnsShort.subBlockInfo[subBlockNumber]; - if (psubBlockInfo->tnsActive == 0) { - tnsInfo->tnsActive[subBlockNumber] = 0; - return(0); - } - else { - - Parcor2Index(psubBlockInfo->parcor, - &tnsInfo->coef[subBlockNumber*TNS_MAX_ORDER_SHORT], - tC.maxOrder, - tC.coefRes); - - Index2Parcor(&tnsInfo->coef[subBlockNumber*TNS_MAX_ORDER_SHORT], - psubBlockInfo->parcor, - tC.maxOrder, - tC.coefRes); - for (i=(tC.maxOrder - 1); i>=0; i--) { - temp = psubBlockInfo->parcor[i] - TNS_PARCOR_THRESH; - if ( temp > 0 ) - break; - - temp = psubBlockInfo->parcor[i] + TNS_PARCOR_THRESH; - if ( temp < 0 ) - break; - } - tnsInfo->order[subBlockNumber] = i + 1; - - tnsInfo->tnsActive[subBlockNumber] = 1; - tnsInfo->coefRes[subBlockNumber] = tC.coefRes; - tnsInfo->length[subBlockNumber] = numOfSfb - tC.tnsStartBand; - - - AnalysisFilterLattice(&(spectrum[tC.tnsStartLine]), (tC.tnsStopLine - tC.tnsStartLine), - psubBlockInfo->parcor, - tnsInfo->order[subBlockNumber], - &(spectrum[tC.tnsStartLine])); - - } - } - - return(0); -} - - -/***************************************************************************** -* -* function name: m_pow2_cordic -* description: Iterative power function -* -* Calculates pow(2.0,x-1.0*(scale+1)) with INT_BITS bit precision -* using modified cordic algorithm -* returns: the result of pow2 -* -*****************************************************************************/ -static Word32 m_pow2_cordic(Word32 x, Word16 scale) -{ - Word32 k; - - Word32 accu_y = 0x40000000; - accu_y = L_shr(accu_y,scale); - - for(k=1; k<INT_BITS; k++) { - const Word32 z = m_log2_table[k]; - - while(L_sub(x,z) >= 0) { - - x = L_sub(x, z); - accu_y = L_add(accu_y, (accu_y >> k)); - } - } - return(accu_y); -} - - -/***************************************************************************** -* -* function name: CalcWeightedSpectrum -* description: Calculate weighted spectrum for LPC calculation -* -*****************************************************************************/ -static void CalcWeightedSpectrum(const Word32 spectrum[], /*!< input spectrum */ - Word16 weightedSpectrum[], - Word32 *sfbEnergy, /*!< sfb energies */ - const Word16 *sfbOffset, - Word16 lpcStartLine, - Word16 lpcStopLine, - Word16 lpcStartBand, - Word16 lpcStopBand, - Word32 *pWork32) -{ - #define INT_BITS_SCAL 1<<(INT_BITS/2) - - Word32 i, sfb, shift; - Word32 maxShift; - Word32 tmp_s, tmp2_s; - Word32 tmp, tmp2; - Word32 maxWS; - Word32 tnsSfbMean[MAX_SFB]; /* length [lpcStopBand-lpcStartBand] should be sufficient here */ - - maxWS = 0; - - /* calc 1.0*2^-INT_BITS/2/sqrt(en) */ - for( sfb = lpcStartBand; sfb < lpcStopBand; sfb++) { - - tmp2 = sfbEnergy[sfb] - 2; - if( tmp2 > 0) { - tmp = rsqrt(sfbEnergy[sfb], INT_BITS); - if(tmp > INT_BITS_SCAL) - { - shift = norm_l(tmp); - tmp = Div_32( INT_BITS_SCAL << shift, tmp << shift ); - } - else - { - tmp = 0x7fffffff; - } - } - else { - tmp = 0x7fffffff; - } - tnsSfbMean[sfb] = tmp; - } - - /* spread normalized values from sfbs to lines */ - sfb = lpcStartBand; - tmp = tnsSfbMean[sfb]; - for ( i=lpcStartLine; i<lpcStopLine; i++){ - tmp_s = sfbOffset[sfb + 1] - i; - if ( tmp_s == 0 ) { - sfb = sfb + 1; - tmp2_s = sfb + 1 - lpcStopBand; - if (tmp2_s <= 0) { - tmp = tnsSfbMean[sfb]; - } - } - pWork32[i] = tmp; - } - /*filter down*/ - for (i=(lpcStopLine - 2); i>=lpcStartLine; i--){ - pWork32[i] = (pWork32[i] + pWork32[i + 1]) >> 1; - } - /* filter up */ - for (i=(lpcStartLine + 1); i<lpcStopLine; i++){ - pWork32[i] = (pWork32[i] + pWork32[i - 1]) >> 1; - } - - /* weight and normalize */ - for (i=lpcStartLine; i<lpcStopLine; i++){ - pWork32[i] = MULHIGH(pWork32[i], spectrum[i]); - maxWS |= L_abs(pWork32[i]); - } - maxShift = norm_l(maxWS); - - maxShift = 16 - maxShift; - if(maxShift >= 0) - { - for (i=lpcStartLine; i<lpcStopLine; i++){ - weightedSpectrum[i] = pWork32[i] >> maxShift; - } - } - else - { - maxShift = -maxShift; - for (i=lpcStartLine; i<lpcStopLine; i++){ - weightedSpectrum[i] = saturate(pWork32[i] << maxShift); - } - } -} - - - - -/***************************************************************************** -* -* function name: CalcTnsFilter -* description: LPC calculation for one TNS filter -* returns: prediction gain -* input: signal spectrum, acf window, no. of spectral lines, -* max. TNS order, ptr. to reflection ocefficients -* output: reflection coefficients -*(half) window size must be larger than tnsOrder !!* -******************************************************************************/ - -static Word16 CalcTnsFilter(const Word16 *signal, - const Word32 window[], - Word16 numOfLines, - Word16 tnsOrder, - Word32 parcor[]) -{ - Word32 parcorWorkBuffer[2*TNS_MAX_ORDER+1]; - Word32 predictionGain; - Word32 i; - Word32 tnsOrderPlus1 = tnsOrder + 1; - - assert(tnsOrder <= TNS_MAX_ORDER); /* remove asserts later? (btg) */ - - for(i=0;i<tnsOrder;i++) { - parcor[i] = 0; - } - - AutoCorrelation(signal, parcorWorkBuffer, numOfLines, tnsOrderPlus1); - - /* early return if signal is very low: signal prediction off, with zero parcor coeffs */ - if (parcorWorkBuffer[0] == 0) - return 0; - - predictionGain = AutoToParcor(parcorWorkBuffer, parcor, tnsOrder); - - return(predictionGain); -} - -/***************************************************************************** -* -* function name: AutoCorrelation -* description: calc. autocorrelation (acf) -* returns: - -* input: input values, no. of input values, no. of acf values -* output: acf values -* -*****************************************************************************/ -#ifndef ARMV5E -void AutoCorrelation(const Word16 input[], - Word32 corr[], - Word16 samples, - Word16 corrCoeff) { - Word32 i, j, isamples; - Word32 accu; - Word32 scf; - - scf = 10 - 1; - - isamples = samples; - /* calc first corrCoef: R[0] = sum { t[i] * t[i] } ; i = 0..N-1 */ - accu = 0; - for(j=0; j<isamples; j++) { - accu = L_add(accu, ((input[j] * input[j]) >> scf)); - } - corr[0] = accu; - - /* early termination if all corr coeffs are likely going to be zero */ - if(corr[0] == 0) return ; - - /* calc all other corrCoef: R[j] = sum { t[i] * t[i+j] } ; i = 0..(N-j-1), j=1..p */ - for(i=1; i<corrCoeff; i++) { - isamples = isamples - 1; - accu = 0; - for(j=0; j<isamples; j++) { - accu = L_add(accu, ((input[j] * input[j+i]) >> scf)); - } - corr[i] = accu; - } -} -#endif - -/***************************************************************************** -* -* function name: AutoToParcor -* description: conversion autocorrelation to reflection coefficients -* returns: prediction gain -* input: <order+1> input values, no. of output values (=order), -* ptr. to workbuffer (required size: 2*order) -* output: <order> reflection coefficients -* -*****************************************************************************/ -static Word16 AutoToParcor(Word32 workBuffer[], Word32 reflCoeff[], Word16 numOfCoeff) { - - Word32 i, j, shift; - Word32 *pWorkBuffer; /* temp pointer */ - Word32 predictionGain = 0; - Word32 num, denom; - Word32 temp, workBuffer0; - - - num = workBuffer[0]; - temp = workBuffer[numOfCoeff]; - - for(i=0; i<numOfCoeff-1; i++) { - workBuffer[i + numOfCoeff] = workBuffer[i + 1]; - } - workBuffer[i + numOfCoeff] = temp; - - for(i=0; i<numOfCoeff; i++) { - Word32 refc; - - - if (workBuffer[0] < L_abs(workBuffer[i + numOfCoeff])) { - return 0 ; - } - shift = norm_l(workBuffer[0]); - workBuffer0 = Div_32(1 << shift, workBuffer[0] << shift); - /* calculate refc = -workBuffer[numOfCoeff+i] / workBuffer[0]; -1 <= refc < 1 */ - refc = L_negate(fixmul(workBuffer[numOfCoeff + i], workBuffer0)); - - reflCoeff[i] = refc; - - pWorkBuffer = &(workBuffer[numOfCoeff]); - - for(j=i; j<numOfCoeff; j++) { - Word32 accu1, accu2; - accu1 = L_add(pWorkBuffer[j], fixmul(refc, workBuffer[j - i])); - accu2 = L_add(workBuffer[j - i], fixmul(refc, pWorkBuffer[j])); - pWorkBuffer[j] = accu1; - workBuffer[j - i] = accu2; - } - } - - denom = MULHIGH(workBuffer[0], NORM_COEF); - - if (denom != 0) { - Word32 temp; - shift = norm_l(denom); - temp = Div_32(1 << shift, denom << shift); - predictionGain = fixmul(num, temp); - } - - return extract_l(predictionGain); -} - - - -static Word16 Search3(Word32 parcor) -{ - Word32 index = 0; - Word32 i; - Word32 temp; - - for (i=0;i<8;i++) { - temp = L_sub( parcor, tnsCoeff3Borders[i]); - if (temp > 0) - index=i; - } - return extract_l(index - 4); -} - -static Word16 Search4(Word32 parcor) -{ - Word32 index = 0; - Word32 i; - Word32 temp; - - - for (i=0;i<16;i++) { - temp = L_sub(parcor, tnsCoeff4Borders[i]); - if (temp > 0) - index=i; - } - return extract_l(index - 8); -} - - - -/***************************************************************************** -* -* functionname: Parcor2Index -* description: quantization index for reflection coefficients -* -*****************************************************************************/ -static void Parcor2Index(const Word32 parcor[], /*!< parcor coefficients */ - Word16 index[], /*!< quantized coeff indices */ - Word16 order, /*!< filter order */ - Word16 bitsPerCoeff) { /*!< quantizer resolution */ - Word32 i; - Word32 temp; - - for(i=0; i<order; i++) { - temp = bitsPerCoeff - 3; - if (temp == 0) { - index[i] = Search3(parcor[i]); - } - else { - index[i] = Search4(parcor[i]); - } - } -} - -/***************************************************************************** -* -* functionname: Index2Parcor -* description: Inverse quantization for reflection coefficients -* -*****************************************************************************/ -static void Index2Parcor(const Word16 index[], /*!< quantized values */ - Word32 parcor[], /*!< ptr. to reflection coefficients (output) */ - Word16 order, /*!< no. of coefficients */ - Word16 bitsPerCoeff) /*!< quantizer resolution */ -{ - Word32 i; - Word32 temp; - - for (i=0; i<order; i++) { - temp = bitsPerCoeff - 4; - if ( temp == 0 ) { - parcor[i] = tnsCoeff4[index[i] + 8]; - } - else { - parcor[i] = tnsCoeff3[index[i] + 4]; - } - } -} - -/***************************************************************************** -* -* functionname: FIRLattice -* description: in place lattice filtering of spectral data -* returns: pointer to modified data -* -*****************************************************************************/ -static Word32 FIRLattice(Word16 order, /*!< filter order */ - Word32 x, /*!< spectral data */ - Word32 *state_par, /*!< filter states */ - const Word32 *coef_par) /*!< filter coefficients */ -{ - Word32 i; - Word32 accu,tmp,tmpSave; - - x = x >> 1; - tmpSave = x; - - for (i=0; i<(order - 1); i++) { - - tmp = L_add(fixmul(coef_par[i], x), state_par[i]); - x = L_add(fixmul(coef_par[i], state_par[i]), x); - - state_par[i] = tmpSave; - tmpSave = tmp; - } - - /* last stage: only need half operations */ - accu = fixmul(state_par[order - 1], coef_par[(order - 1)]); - state_par[(order - 1)] = tmpSave; - - x = L_add(accu, x); - x = L_add(x, x); - - return x; -} - -/***************************************************************************** -* -* functionname: AnalysisFilterLattice -* description: filters spectral lines with TNS filter -* -*****************************************************************************/ -static void AnalysisFilterLattice(const Word32 signal[], /*!< input spectrum */ - Word16 numOfLines, /*!< no. of lines */ - const Word32 parCoeff[],/*!< PARC coefficients */ - Word16 order, /*!< filter order */ - Word32 output[]) /*!< filtered signal values */ -{ - - Word32 state_par[TNS_MAX_ORDER]; - Word32 j; - - for ( j=0; j<TNS_MAX_ORDER; j++ ) { - state_par[j] = 0; - } - - for(j=0; j<numOfLines; j++) { - output[j] = FIRLattice(order,signal[j],state_par,parCoeff); - } -} - -/***************************************************************************** -* -* functionname: ApplyTnsMultTableToRatios -* description: Change thresholds according to tns -* -*****************************************************************************/ -void ApplyTnsMultTableToRatios(Word16 startCb, - Word16 stopCb, - TNS_SUBBLOCK_INFO subInfo, /*!< TNS subblock info */ - Word32 *thresholds) /*!< thresholds (modified) */ -{ - Word32 i; - if (subInfo.tnsActive) { - for(i=startCb; i<stopCb; i++) { - /* thresholds[i] * 0.25 */ - thresholds[i] = (thresholds[i] >> 2); - } - } -} |