⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 omxacmp3_mdctinv_s32.c

📁 The OpenMAX DL (Development Layer) APIs contain a comprehensive set of audio, video, signal processi
💻 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 + -