📄 omxacaac_mdctfwd_s32.c
字号:
/** * * File Name: omxACAAC_MDCTFwd_S32.c * OpenMAX DL: v1.0.2 * Revision: 10586 * Date: Wednesday, March 5, 2008 * * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. * * * * Description: * This file contains module for MDCT for an AAC decoder * */#include<math.h> #include "omxtypes.h" #include "armOMX.h"#include "omxAC.h"#include "armAC.h"#include "armCOMM.h"#include "armACAAC_Tables.h"/** * Function: omxACAAC_MDCTFwd_S32 (3.2.3.7.2) * * Description: * Forward MDCT portion of the LTP loop; used only for audio objects of type * LTP. * * Reference: [ISO14496-3], sub-clause 4.6.7.3 * * Input Arguments: * * pSrc - pointer to the time-domain input sequence; samples are * represented using Q28.3 * winSequence - window sequence specifier for the current block; the * following values are allowed: 0=only_long_sequence/long_window, * 1=long_start_sequence/long_start_window, * 3=long_stop_sequence/long_stop_window. The function will return * an error if winSequence==2,as short window sequences are not * allowed in the LTP reconstruction loop for AAC LTP audio * objects. * winShape - window shape specifier for the current block. The following * values are allowed: 0=sine window, 1=Kaiser-Bessel derived * (KBD) window. The function will return an error if this * parameter is not equal to either 0 or 1. * preWinShape - analysis window shape specifier for the previous block. * The following values are allowed: 0=sine window, 1=Kaiser-Bessel * derived (KBD) window. The function will return an error if this * parameter is not equal to either 0 or 1. * pWindowedBuf - work buffer; minimum length 2048 elements * * Output Arguments: * * pDst - pointer to MDCT output sequence; coefficients are represented * using Q28.3 * * Return Value: * * OMX_Sts_NoErr - no error * OMX_Sts_BadArgErr - bad arguments * - one or more of the following pointers is NULL: pSrc, pDst, or * pWindowedBuf * - winShape is outside the range [0,1] * - preWinShape is outside the range [0,1] * - winSequence== 2 (eight_short_sequence/short_window) * */ OMXResult omxACAAC_MDCTFwd_S32( OMX_S32 *pSrc, OMX_S32 *pDst, OMX_INT winSequence, OMX_INT winShape, OMX_INT preWinShape, OMX_S32 *pWindowedBuf ) { const OMX_F64 *pLeftWinShortPrev = NULL,*pLeftWinLongPrev = NULL; const OMX_F64 *pRightWinShort = NULL,*pRightWinLong = NULL; /*To avoid warnings*/ OMX_F64 buffer[ARM_AAC_WIN_LONG << 1],PiByN,outCoeff0; OMX_F64 theta,output,coeff,alpha,cosine; OMX_INT inCoeff,outCoeff; /* Argument Check */ armRetArgErrIf( pSrc == NULL, OMX_Sts_BadArgErr); armRetArgErrIf( pDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf( pWindowedBuf == NULL, OMX_Sts_BadArgErr); armRetArgErrIf( (winSequence > 3) || (winSequence < 0), OMX_Sts_BadArgErr); armRetArgErrIf( winSequence == 2 , OMX_Sts_BadArgErr); armRetArgErrIf( (winShape > 1) || (winShape < 0) , OMX_Sts_BadArgErr); armRetArgErrIf( (preWinShape > 1) || (preWinShape < 0), OMX_Sts_BadArgErr); /* Processing */ /*Windowing pointer assignments*/ switch(preWinShape) { case 0: /*sine window*/ pLeftWinShortPrev = armACAAC_winShortSine; pLeftWinLongPrev = armACAAC_winLongSine; break; case 1: /*KBD window*/ pLeftWinShortPrev = armACAAC_winShortKBD; pLeftWinLongPrev = armACAAC_winLongKBD; break; } switch(winShape) { case 0: /*sine window*/ pRightWinShort = armACAAC_winShortSine + ARM_AAC_WIN_SHORT - 1; pRightWinLong = armACAAC_winLongSine + ARM_AAC_WIN_LONG - 1; break; case 1: /*KBD window*/ pRightWinShort = armACAAC_winShortKBD + ARM_AAC_WIN_SHORT - 1; pRightWinLong = armACAAC_winLongKBD + ARM_AAC_WIN_LONG - 1; break; } /*Windowing*/ switch(winSequence) { case ARM_AAC_ONLY_LONG_SEQUENCE: for(inCoeff = 0; inCoeff < ARM_AAC_WIN_LONG ; inCoeff ++) { /*Left Half*/ coeff = pSrc[inCoeff] / (OMX_F64)(1 << ARM_AAC_Q_FACTOR) ; coeff = coeff * pLeftWinLongPrev[inCoeff] ; buffer[inCoeff] = coeff; /*Right Half*/ coeff = pSrc[inCoeff + ARM_AAC_WIN_LONG] / (OMX_F64)(1 << ARM_AAC_Q_FACTOR) ; coeff = coeff * pRightWinLong [-inCoeff] ; buffer[inCoeff + ARM_AAC_WIN_LONG] = coeff; } break; case ARM_AAC_LONG_START_SEQUENCE: for(inCoeff = 0 ; inCoeff < ARM_AAC_WIN_LONG ; inCoeff ++) { coeff = pSrc[inCoeff] / (OMX_F64)(1 << ARM_AAC_Q_FACTOR) ; coeff = pLeftWinLongPrev[inCoeff] * coeff; buffer[inCoeff] = coeff; } for(inCoeff = ARM_AAC_WIN_LONG ; inCoeff < 1472 ; inCoeff ++) { buffer[inCoeff] = pSrc[inCoeff] / (OMX_F64)(1 << ARM_AAC_Q_FACTOR) ; } for(inCoeff = 1472 ; inCoeff < 1600 ; inCoeff ++) { coeff = pSrc[inCoeff] / (OMX_F64)(1 << ARM_AAC_Q_FACTOR) ; coeff = pRightWinShort[1472 - inCoeff] * coeff; buffer[inCoeff] = coeff; } for(inCoeff = 1600 ; inCoeff < (ARM_AAC_WIN_LONG << 1 ) ; inCoeff ++) { buffer[inCoeff] = 0; } break; case ARM_AAC_LONG_STOP_SEQUENCE: for(inCoeff = 0 ; inCoeff < 448 ; inCoeff ++) { buffer[inCoeff] = 0; } for(inCoeff = 448 ; inCoeff < 576 ; inCoeff ++) { coeff = pSrc[inCoeff] / (OMX_F64)(1 << ARM_AAC_Q_FACTOR) ; coeff = pLeftWinShortPrev[inCoeff - 448] * coeff; buffer[inCoeff] = coeff; } for(inCoeff = 576 ; inCoeff < ARM_AAC_WIN_LONG ; inCoeff ++) { buffer[inCoeff] = pSrc[inCoeff] / (OMX_F64)(1 << ARM_AAC_Q_FACTOR) ; } for(inCoeff = ARM_AAC_WIN_LONG ; inCoeff < (ARM_AAC_WIN_LONG << 1) ; inCoeff ++) { coeff = pSrc[inCoeff] / (OMX_F64)(1 << ARM_AAC_Q_FACTOR) ; coeff = pRightWinLong[ARM_AAC_WIN_LONG - inCoeff] * coeff; buffer[inCoeff] = coeff; } break; } /*Long MDCT*/ outCoeff0 = 512.5; PiByN = armPI/(ARM_AAC_WIN_LONG << 1); for(outCoeff = 0 ; outCoeff < ARM_AAC_WIN_LONG ; outCoeff ++) { theta = (2*PiByN)*( (OMX_F64)outCoeff + .5); output = 0; for(inCoeff = 0; inCoeff < ( ARM_AAC_WIN_LONG << 1 ) ; inCoeff ++) { alpha = theta * ( (OMX_F64)inCoeff + outCoeff0); cosine = cos(alpha); coeff = cosine * buffer[inCoeff]; output = output + coeff; } pDst[outCoeff] = armSatRoundFloatToS32(2 * output * (1 << ARM_AAC_Q_FACTOR) ); } return OMX_Sts_NoErr;} /*End of File*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -