📄 tns3.c
字号:
/********************************************************************** This software module was originally developed by Texas Instrumentsand edited by in the course of development of the MPEG-2 NBC/MPEG-4 Audio standardISO/IEC 13818-7, 14496-1,2 and 3. This software module is animplementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio toolsas specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC givesusers of the MPEG-2 NBC/MPEG-4 Audio standards free license to thissoftware module or modifications thereof for use in hardware orsoftware products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audiostandards. Those intending to use this software module in hardware orsoftware products are advised that this use may infringe existingpatents. The original developer of this software module and his/hercompany, the subsequent editors and their companies, and ISO/IEC haveno liability for use of this software module or modifications thereofin an implementation. Copyright is not released for non MPEG-2NBC/MPEG-4 Audio conforming products. The original developer retainsfull right to use the code for his/her own purpose, assign or donatethe code to a third party and to inhibit third party from using thecode for non MPEG-2 NBC/MPEG-4 Audio conforming products. Thiscopyright notice must be included in all copies or derivative works. Copyright (c) 1997.**********************************************************************//********************************************************************* * * tns.h - AAC temporal noise shaping * * Authors: * CL Chuck Lueck, TI <lueck@ti.com> * * Changes: * 20-oct-97 CL Initial revision. ***********************************************************************/#include <math.h>#include <stdlib.h>#include "interface.h" /* handler, defines, enums */#include "tf_mainHandle.h" /* handler, defines, enums */#include "common_m4a.h"#include "tns3.h"#define mymax(a,b) ((a)>(b)?(a):(b))#define mymin(a,b) ((a)<(b)?(a):(b))/***********************************************//* TNS Profile/Frequency Dependent Parameters *//***********************************************/static long tnsSupportedSamplingRates[13] = {8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,0};/* Limit bands to > 1.5 kHz *//*static unsigned short tnsMinBandNumberLong[12] = { 26, 25, 24, 20, 23, 22, 17, 14, 13, 12, 9, 8 };static unsigned short tnsMinBandNumberShort[12] = { 10, 9, 8, 8, 5, 4, 3, 3, 2, 2, 1, 1 }; */ /* Limit bands to > 2.0 kHz */static unsigned short tnsMinBandNumberLong[12] = { 31, 30, 28, 24, 26, 25, 20, 17, 16, 15, 12, 11 };static unsigned short tnsMinBandNumberShort[12] = { 12, 10, 10, 8, 6, 6, 4, 3, 3, 2, 2, 2 }; /**************************************//* Main/Low Profile TNS Parameters *//**************************************/static unsigned short tnsMaxBandsLongMainLow[12] = { 39, 42, 42, 42, 46, 46, 51, 42, 40, 34, 31, 31 };static unsigned short tnsMaxBandsShortMainLow[12] = { 14, 14, 14, 14, 14, 14, 14, 14, 14, 10, 9, 9 };static unsigned short tnsMaxOrderLongMain = 20;static unsigned short tnsMaxOrderLongLow = 12;static unsigned short tnsMaxOrderShortMainLow = 7;/**************************************//* SSR Profile TNS Parameters *//**************************************/static unsigned short tnsMaxBandsLongSSR[12] = { 19, 23, 23, 23, 29, 29, 26, 26, 26, 27, 28, 28 };static unsigned short tnsMaxBandsShortSSR[12] = { 7, 8, 8, 8, 7, 7, 6, 6, 6, 7, 7, 7 };static unsigned short tnsMaxOrderLongSSR = 12;static unsigned short tnsMaxOrderShortSSR = 7;/*****************************************************//* InitTns: *//*****************************************************/void TnsInit(long samplingRate,enum AAC_PROFILE profile,TNS_INFO* tnsInfo, QC_MOD_SELECT qc_select, int block_size_samples) { int fsIndex=0; /* Determine if sampling rate is supported */ while (samplingRate!=tnsSupportedSamplingRates[fsIndex]) { if (!tnsSupportedSamplingRates[fsIndex]) { CommonExit( 1, "InitTns: Sampling rate of %d not supported in TNS.\nExiting program...\n",samplingRate); } fsIndex++; } switch( profile ) { case MAIN : tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongMainLow[fsIndex]; tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLow[fsIndex]; tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongMain; tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortMainLow; break; case LOW : tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongMainLow[fsIndex]; tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortMainLow[fsIndex]; tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongLow; tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortMainLow; break; case SSR : tnsInfo->tnsMaxBandsLong = tnsMaxBandsLongSSR[fsIndex]; tnsInfo->tnsMaxBandsShort = tnsMaxBandsShortSSR[fsIndex]; tnsInfo->tnsMaxOrderLong = tnsMaxOrderLongSSR; tnsInfo->tnsMaxOrderShort = tnsMaxOrderShortSSR; break; default: CommonExit( 1, "InitTns: Profile not supported for TNS.\nExiting program\n"); } tnsInfo->tnsMinBandNumberLong = tnsMinBandNumberLong[fsIndex]; tnsInfo->tnsMinBandNumberShort = tnsMinBandNumberShort[fsIndex];}/*****************************************************//* TnsEncode: *//*****************************************************/void TnsEncode(int numberOfBands, /* Number of bands per window */ int maxSfb, /* max_sfb */ WINDOW_SEQUENCE blockType, /* block type */ int* sfbOffsetTable, /* Scalefactor band offset table */ double* spec, /* Spectral data array */ TNS_INFO* tnsInfo) /* TNS info */{ int numberOfWindows,windowSize; int startBand,stopBand,order; /* Bands over which to apply TNS */ int lengthInBands; /* Length to filter, in bands */ int w; int startIndex,length; double gain; switch( blockType ) { case EIGHT_SHORT_SEQUENCE : numberOfWindows = NSHORT; windowSize = SN2; startBand = tnsInfo->tnsMinBandNumberShort; stopBand = numberOfBands; lengthInBands = stopBand-startBand; order = tnsInfo->tnsMaxOrderShort; startBand = mymin(startBand,tnsInfo->tnsMaxBandsShort); stopBand = mymin(stopBand,tnsInfo->tnsMaxBandsShort); break; default: numberOfWindows = 1; windowSize = LN2; startBand = tnsInfo->tnsMinBandNumberLong; stopBand = numberOfBands; lengthInBands = stopBand - startBand; order = tnsInfo->tnsMaxOrderLong; startBand = mymin(startBand,tnsInfo->tnsMaxBandsLong); stopBand = mymin(stopBand,tnsInfo->tnsMaxBandsLong); break; } /* Make sure that start and stop bands < maxSfb */ /* Make sure that start and stop bands >= 0 */ startBand = mymin(startBand,maxSfb); stopBand = mymin(stopBand,maxSfb); startBand = mymax(startBand,0); stopBand = mymax(stopBand,0);/* fprintf(stderr,"(%d)TNS Start %5d : End %5d : lengthInBands %5d\n",(int)blockType,startBand,stopBand,lengthInBands); fprintf(stderr,"order %5d\n",order);*/ tnsInfo->tnsDataPresent=0; /* default TNS not used */ /* Perform analysis and filtering for each window */ for (w=0;w<numberOfWindows;w++) { TNS_WINDOW_DATA* windowData = &tnsInfo->windowData[w]; TNS_FILTER_DATA* tnsFilter = windowData->tnsFilter; double* k = tnsFilter->kCoeffs; /* reflection coeffs */ double* a = tnsFilter->aCoeffs; /* prediction coeffs */ windowData->numFilters=0; windowData->coefResolution = DEF_TNS_COEFF_RES; startIndex = w * windowSize + sfbOffsetTable[startBand]; length = sfbOffsetTable[stopBand] - sfbOffsetTable[startBand]; gain = LevinsonDurbin(order,length,&spec[startIndex],k); if (gain>DEF_TNS_GAIN_THRESH) { /* Use TNS */ int truncatedOrder; windowData->numFilters++; tnsInfo->tnsDataPresent=1; tnsFilter->direction = 0; tnsFilter->coefCompress = 0; tnsFilter->length = lengthInBands; QuantizeReflectionCoeffs(order,DEF_TNS_COEFF_RES,k,tnsFilter->index); truncatedOrder = TruncateCoeffs(order,DEF_TNS_COEFF_THRESH,k); tnsFilter->order = truncatedOrder; StepUp(truncatedOrder,k,a); /* Compute predictor coefficients */ TnsInvFilter(length,&spec[startIndex],tnsFilter); /* Filter */ } } }/*****************************************************//* TnsEncode2: *//* This is a stripped-down version of TnsEncode() *//* which performs TNS filtering only (no TNS calc.) *//*****************************************************/void TnsEncode2(int numberOfBands, /* Number of bands per window */ int maxSfb, /* max_sfb */ WINDOW_SEQUENCE blockType, /* block type */ int* sfbOffsetTable, /* Scalefactor band offset table */ double* spec, /* Spectral data array */ TNS_INFO* tnsInfo, /* TNS info */ int decodeFlag) /* Analysis ot synthesis filter. */{ int numberOfWindows,windowSize; int startBand,stopBand; /* Bands over which to apply TNS */ int w; int startIndex,length; switch( blockType ) { case EIGHT_SHORT_SEQUENCE : numberOfWindows = NSHORT; windowSize = SN2; startBand = tnsInfo->tnsMinBandNumberShort; stopBand = numberOfBands; startBand = mymin(startBand,tnsInfo->tnsMaxBandsShort); stopBand = mymin(stopBand,tnsInfo->tnsMaxBandsShort); break; default: numberOfWindows = 1; windowSize = LN2; startBand = tnsInfo->tnsMinBandNumberLong; stopBand = numberOfBands; startBand = mymin(startBand,tnsInfo->tnsMaxBandsLong); stopBand = mymin(stopBand,tnsInfo->tnsMaxBandsLong); break; } /* Make sure that start and stop bands < maxSfb */ /* Make sure that start and stop bands >= 0 */ startBand = mymin(startBand,maxSfb); stopBand = mymin(stopBand,maxSfb); startBand = mymax(startBand,0); stopBand = mymax(stopBand,0); /* Perform filtering for each window */ for (w=0;w<numberOfWindows;w++) { TNS_WINDOW_DATA* windowData = &tnsInfo->windowData[w]; TNS_FILTER_DATA* tnsFilter = windowData->tnsFilter; startIndex = w * windowSize + sfbOffsetTable[startBand]; length = sfbOffsetTable[stopBand] - sfbOffsetTable[startBand]; if (tnsInfo->tnsDataPresent && windowData->numFilters) { /* Use TNS */ if (decodeFlag) TnsFilter(length,&spec[startIndex],tnsFilter); else TnsInvFilter(length,&spec[startIndex],tnsFilter); } } }void TnsEncodeShortBlock(int numberOfBands, /* Number of bands per window */ int maxSfb, /* max_sfb */ int which_subblock, /* block number */ int* sfbOffsetTable, /* Scalefactor band offset table */ double* spec, /* Spectral data array */ TNS_INFO* tnsInfo) /* TNS info */{ int windowSize; int startBand,stopBand,order; /* Bands over which to apply TNS */ int w; int startIndex,length; windowSize = SN2; startBand = tnsInfo->tnsMinBandNumberShort; stopBand = numberOfBands; startBand = min(startBand,tnsInfo->tnsMaxBandsShort); stopBand = min(stopBand,tnsInfo->tnsMaxBandsShort); /* Make sure that start and stop bands < maxSfb */ /* Make sure that start and stop bands >= 0 */ startBand = min(startBand,maxSfb); stopBand = min(stopBand,maxSfb); startBand = max(startBand,0); stopBand = max(stopBand,0); /* Perform filtering for each window */ for (w = which_subblock; w < (which_subblock + 1); w++) { TNS_WINDOW_DATA* windowData = &tnsInfo->windowData[w]; TNS_FILTER_DATA* tnsFilter = windowData->tnsFilter; startIndex = sfbOffsetTable[startBand]; length = sfbOffsetTable[stopBand] - sfbOffsetTable[startBand]; if (tnsInfo->tnsDataPresent && windowData->numFilters) { /* Use TNS */ TnsInvFilter(length,&spec[startIndex],tnsFilter);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -