📄 omxacmp3_mdctinv_s32.c
字号:
/** * * File Name: omxACMP3_MDCTInv_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 function will do Alias reduction, Inverse MDCT, overlap add and * frequency inversion */#include <math.h>#include "omxtypes.h"#include "armOMX.h"#include "omxAC.h"#include "armCOMM_Bitstream.h"#include "armCOMM.h"#include "armACMP3_CommonTables.h"#include "armACMP3_Tables.h"#include "armAC.h"/** * Function: omxACMP3_MDCTInv_S32 (3.1.3.4.1) * * Description: * Stage 1 of the hybrid synthesis filter bank. This performs the following * operations: a) Alias reduction b) Inverse MDCT according to block size * specifiers and mixed block modes c) Overlap add of IMDCT outputs, and d) * Frequency inversion prior to PQMF bank Because the IMDCT is a lapped * transform, the user must preallocate a buffer referenced by * pSrcDstOverlapAdd to maintain the IMDCT overlap-add state. The buffer must * contain 576 elements. Prior to the first call to the synthesis filter bank, * all elements of the overlap-add buffer should be set equal to zero. In * between all subsequent calls, the contents of the overlap-add buffer should * be preserved. Upon entry to omxACMP3_MDCTInv_S32, the overlap-add buffer * should contain the IMDCT output generated by operating on the previous * granule; upon exit from omxACMP3_MDCTInv_S32, the overlap-add buffer will * contain the overlapped portion of the output generated by operating on the * current granule. Upon return from the function, the IMDCT sub-band output * samples are organized as follows: pDstY[j*32+subband], for j=0 to 17; * sub-band=0 to 31. Note: The pointers pSrcXr (input argument) and pDstY * (output argument) must reference different buffers. Reference [ISO13818-3], * sub-clause 2.5.3.3.2 * * Input Arguments: * * pSrcXr - pointer to the vector of requantized spectral samples for the * current channel and granule, represented in Q5.26 format. Note: * The vector buffer is used as a workspace buffer when the input * data has been processed. So the data in the buffer is * meaningless when exiting the function * pSrcDstOverlapAdd - pointer to the overlap-add buffer; contains the * overlapped portion of the previous granule s IMDCT output * nonZeroBound - the bound above which all spectral coefficients are zero * for the current granule and channel * pPrevNumOfImdct - pointer to the number of IMDCTs computed for the * current channel of the previous granule * blockType - block type indicator * mixedBlock - mixed block indicator * * Output Arguments: * * pDstY - pointer to the vector of IMDCT outputs in Q7.24 format, for * input to PQMF bank * pSrcDstOverlapAdd - pointer to the updated overlap-add buffer; contains * overlapped portion of the current granule s IMDCT output * pPrevNumOfImdct - pointer to the number of IMDCTs, for current granule, * current channel * * Return Value: * * OMX_Sts_NoErr - no error * OMX_Sts_BadArgErr - bad arguments detected; one or more of the pointers * pSrcXr, pDstY, pSrcDstOverlapAdd, and/or pPrevNumOfImdct is * NULL * OMX_Sts_Err - one or more of the following input data errors detected: * either blockType exceeds [0,3], mixedBlock exceeds [0,1], * nonZeroBound exceeds [0,576], or *pPrevNumOfImdctexceeds * [0,32] * */OMXResult omxACMP3_MDCTInv_S32 ( OMX_S32 *pSrcXr, OMX_S32 *pDstY, OMX_S32 *pSrcDstOverlapAdd, OMX_INT nonZeroBound, OMX_INT *pPrevNumOfImdct, OMX_INT blockType, OMX_INT mixedBlock){ OMX_S32 sb, i, N, Nby2, win, k, MaxSB; OMX_F64 xar [OMX_MP3_GRANULE_LEN], xr [OMX_MP3_GRANULE_LEN]; OMX_F64 out [ARM_MP3_WINDOW_SZ], Win [ARM_MP3_WINDOW_SZ]; OMX_F64 xi, tmp, temp [ARM_MP3_SHORTBLOCK_SZ]; OMX_F64 prvout [OMX_MP3_GRANULE_LEN]; /* Arguments check */ armRetArgErrIf(pSrcXr == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(pDstY == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(pSrcDstOverlapAdd == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(pPrevNumOfImdct == NULL, OMX_Sts_BadArgErr) /* Validate Arguments */ armRetArgErrIf(blockType < 0, OMX_Sts_Err) armRetArgErrIf(blockType > 3, OMX_Sts_Err) armRetArgErrIf(mixedBlock < 0, OMX_Sts_Err) armRetArgErrIf(mixedBlock > 1, OMX_Sts_Err) armRetArgErrIf(nonZeroBound < 0, OMX_Sts_Err) armRetArgErrIf(nonZeroBound > OMX_MP3_GRANULE_LEN, OMX_Sts_Err) armRetArgErrIf(*pPrevNumOfImdct < 0, OMX_Sts_Err) armRetArgErrIf(*pPrevNumOfImdct > ARM_MP3_NO_OF_SUBBANDS, OMX_Sts_Err) /* Copy into local float buffer */ for (i = 0; i < nonZeroBound; i++) { /* convert the Q5.26 into float */ xr [i] = (OMX_F64) pSrcXr [i] / (1 << 26); } for (; i < OMX_MP3_GRANULE_LEN; i++) { /* convert the Q5.26 into float */ xr [i] = 0; } for (i = 0; i < ARM_MP3_SUBBAND_SZ; i++) { for (sb = 0; sb < *pPrevNumOfImdct; sb++) { prvout [i * ARM_MP3_NO_OF_SUBBANDS + sb] = (OMX_F64) pSrcDstOverlapAdd [i * ARM_MP3_NO_OF_SUBBANDS + sb] / (1 << 24); } } /* create Widnow coeffs */ switch (blockType) { case 0: /* Normal Block */ for (i = 0; i < ARM_MP3_WINDOW_SZ; i++) { Win [i] = armACMP3_LongWindow [i]; } break; case 1: /* Start Block */ for (i = 0; i < 18; i++) { Win [i] = armACMP3_LongWindow [i]; } for (i = 18; i < 24; i++) { Win [i] = 1.0; } for (i = 24; i < 30; i++) { Win [i] = armACMP3_ShortWindow [i-18]; } for (i = 30; i < ARM_MP3_WINDOW_SZ; i++) { Win [i] = 0; } break; case 2: /* Short Block */ if (mixedBlock) { for (i = 0; i < ARM_MP3_WINDOW_SZ; i++) { Win [i] = armACMP3_LongWindow [i]; } } else { for (i = 0; i < ARM_MP3_SHORTBLOCK_SZ; i++) { Win [i] = armACMP3_ShortWindow [i]; } } break; case 3: /* Stop Block */ for (i = 0; i < 6; i++) { Win [i] = 0; } for (i = 6; i < 12; i++) { Win [i] = armACMP3_ShortWindow [i-6]; } for (i = 12; i < 18; i++) { Win [i] = 1.0; } for (i = 18; i < ARM_MP3_WINDOW_SZ; i++) { Win [i] = armACMP3_LongWindow [i]; } break; } MaxSB = nonZeroBound / ARM_MP3_SUBBAND_SZ; if ((MaxSB * ARM_MP3_SUBBAND_SZ) < nonZeroBound) { MaxSB++; } /* Alias Reduction */ for (i = 0; i < OMX_MP3_GRANULE_LEN; i++) { xar [i] = xr [i]; } /* get the No of sub-bands for alias reduction */ if (blockType == 2 && mixedBlock == 1) { N = 2; } else if (blockType != 2) { N = ARM_MP3_NO_OF_SUBBANDS; } else { /* case of pure short blocks */ N = 0; } for (sb = 1; sb < N; sb++) { for (i = 0; i < ARM_MP3_ALIAS_BFLY_NOS; i++) { xar [ARM_MP3_SUBBAND_SZ*sb - 1 - i] = xr [ARM_MP3_SUBBAND_SZ*sb - 1 - i] * armACMP3_BflyCoeffCS[i] - xr [ARM_MP3_SUBBAND_SZ*sb + i] * armACMP3_BflyCoeffCA[i]; xar [ARM_MP3_SUBBAND_SZ*sb + i] = xr [ARM_MP3_SUBBAND_SZ*sb + i] * armACMP3_BflyCoeffCS[i] + xr [ARM_MP3_SUBBAND_SZ*sb - 1 - i] * armACMP3_BflyCoeffCA[i]; } } /* Aliasing reduction will increase no of mdctinv needed by one */ if ((N != 0) && (MaxSB < ARM_MP3_NO_OF_SUBBANDS)) { MaxSB++; } /* IMDCT */ for (sb = 0; sb < MaxSB; sb++) { if ((blockType == 2 && mixedBlock == 0) || (blockType == 2 && mixedBlock == 1 && sb > 1)) { /* Short */ if (blockType == 2 && mixedBlock == 1 && sb == 2) { for (i = 0; i < ARM_MP3_SHORTBLOCK_SZ; i++) { Win [i] = armACMP3_ShortWindow [i]; } } N = ARM_MP3_SHORTBLOCK_SZ; Nby2 = N / 2; for (i = 0; i < ARM_MP3_WINDOW_SZ; i++) { out [i] = 0; } for (win = 0; win < 3; win++) { for (i = 0; i < N; i++) { tmp = ((2 * i + 1 + Nby2) * PI)/(2 * N); for (k = 0, xi = 0.0; k < Nby2; k++) { xi += xar [sb * 18 + Nby2*win + k] * cos (tmp * (2 * k + 1)); } temp [i] = xi * Win [i]; } for (i = 0; i < N; i++) { out [6*win+i+6] += temp [i]; } } } else { if(mixedBlock == 1) { if(blockType != 0 && sb < 2) { /* Normal Block */ for (i = 0; i < ARM_MP3_WINDOW_SZ; i++) { Win [i] = armACMP3_LongWindow [i]; } } else if(blockType == 1) { /* Start Block */ for (i = 0; i < 18; i++) { Win [i] = armACMP3_LongWindow [i]; } for (i = 18; i < 24; i++) { Win [i] = 1.0; } for (i = 24; i < 30; i++) { Win [i] = armACMP3_ShortWindow [i-18]; } for (i = 30; i < ARM_MP3_WINDOW_SZ; i++) { Win [i] = 0; } } else if(blockType == 3) { /* Stop Block */ for (i = 0; i < 6; i++) { Win [i] = 0; } for (i = 6; i < 12; i++) { Win [i] = armACMP3_ShortWindow [i-6]; } for (i = 12; i < 18; i++) { Win [i] = 1.0; } for (i = 18; i < ARM_MP3_WINDOW_SZ; i++) { Win [i] = armACMP3_LongWindow [i]; } } } /* Long */ /* Update IMDCT parameters */ N = ARM_MP3_LONGBLOCK_SZ; Nby2 = N / 2; for (i = 0; i < N; i++) { tmp = ((2 * i + 1 + Nby2) * PI)/(2 * N); for (k = 0, xi = 0.0; k < Nby2; k++) { xi += xar [sb * Nby2 + k] * cos (tmp * (2 * k + 1)); } out [i] = xi * Win [i]; } } /* Overlap addition */ if (sb < *pPrevNumOfImdct) { for (i = 0; i < ARM_MP3_SUBBAND_SZ; i++) { xr [i * ARM_MP3_NO_OF_SUBBANDS + sb] = prvout [i * ARM_MP3_NO_OF_SUBBANDS + sb] + out [i]; prvout [i * ARM_MP3_NO_OF_SUBBANDS + sb] = out [i + ARM_MP3_SUBBAND_SZ]; } } else { for (i = 0; i < ARM_MP3_SUBBAND_SZ; i++) { xr [i * ARM_MP3_NO_OF_SUBBANDS + sb] = out [i]; prvout [i * ARM_MP3_NO_OF_SUBBANDS + sb] = out [i + ARM_MP3_SUBBAND_SZ]; } } } /* Update remaining output values corresponding to zero imdct */ for (; sb < *pPrevNumOfImdct; sb++) { /* Overlap addition for zero values */ for (i = 0; i < ARM_MP3_SUBBAND_SZ; i++) { xr [i * ARM_MP3_NO_OF_SUBBANDS + sb] = prvout [i * ARM_MP3_NO_OF_SUBBANDS + sb]; } } /* Update number of IMDCT calculated for current granule */ *pPrevNumOfImdct = MaxSB; MaxSB = sb; /* Frequency Inversion */ for (sb = 1; sb < MaxSB; sb += 2) { for (i = 1; i < ARM_MP3_SUBBAND_SZ; i += 2) { xr [i * ARM_MP3_NO_OF_SUBBANDS + sb] = -xr [i * ARM_MP3_NO_OF_SUBBANDS + sb]; } } /* Copy from local float buffer */ for (i = 0; i < ARM_MP3_SUBBAND_SZ; i++) { for (sb = 0; sb < MaxSB; sb++) { /* convert to the Q7.24 from float */ pDstY [i * ARM_MP3_NO_OF_SUBBANDS + sb] = armSatRoundFloatToS32 (xr [i * ARM_MP3_NO_OF_SUBBANDS + sb] * (1 << 24)); } for (; sb < ARM_MP3_NO_OF_SUBBANDS; sb++) { /* convert to the Q7.24 from float */ pDstY [i * ARM_MP3_NO_OF_SUBBANDS + sb] = 0; } } for (i = 0; i < ARM_MP3_SUBBAND_SZ; i++) { for (sb = 0; sb < *pPrevNumOfImdct; sb++) { /* convert to the Q7.24 from float */ pSrcDstOverlapAdd [i * ARM_MP3_NO_OF_SUBBANDS + sb] = armSatRoundFloatToS32 (prvout [i * ARM_MP3_NO_OF_SUBBANDS + sb] * (1 << 24)); } for (; sb < ARM_MP3_NO_OF_SUBBANDS; sb++) { /* convert to the Q7.24 from float */ pSrcDstOverlapAdd [i * ARM_MP3_NO_OF_SUBBANDS + sb] = 0; } } return OMX_Sts_NoErr;}/***************************************************************************** * END OF FILE *****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -