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

📄 omxacmp3_synthpqmf_s32_s16.c

📁 The OpenMAX DL (Development Layer) APIs contain a comprehensive set of audio, video, signal processi
💻 C
字号:
/** *  * File Name:  omxACMP3_SynthPQMF_S32_S16.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 is used to do synthesis PQMF filtering */#include <math.h>#include "omxtypes.h"#include "armOMX.h"#include "omxAC.h"#include "armCOMM_Bitstream.h"#include "armCOMM.h"#include "armACMP3_Tables.h"#include "armACMP3_CommonTables.h"#include "armAC.h"#define ARM_MP3_VBUFFER_SZ_MASK (0x1ff)/** * Function:  omxACMP3_SynthPQMF_S32_S16   (3.1.3.4.2) * * Description: * Stage 2 of the hybrid synthesis filter bank; a critically-sampled  * 32-channel PQMF synthesis bank that generates 32 time-domain output samples  * for each 32-sample input block of IMDCT outputs. For each input block, the  * PQMF generates an output sequence of 16-bit signed little-endian PCM  * samples in the vector pointed to by pDstAudioOut. If mode equals 2, the  * left and right channel output samples are interleaved (i.e., LRLRLR), such  * that the left channel data is organized as follows: pDstAudioOut [2*i], i=0  * to 31. If mode equals 1, then the left and right channel outputs are not  * interleaved. A workspace buffer of size 512 x Number of Channels must be  * preallocated (pVBuffer). This buffer is referenced by the pointer pVBuffer,  * and its elements should be initialized to zero prior to the first call.  * During subsequent calls, the pVBuffer input for the current call should  * contain the pVbuffer output generated by the previous call. The state  * variable pVPosition should be initialized to zero and preserved between  * calls. The values contained in pVBuffer or pVPosition should be modified  * only during decoder reset, and the reset values should always be zero.  * Reference [ISO13818-3], sub-clause 2.5.3.3.2  * * Input Arguments: *    *   pSrcY - pointer to the block of 32 IMDCT sub-band input samples, in  *            Q7.24 format  *   pVBuffer - pointer to the input workspace buffer containing Q7.24 data.  *            The elements of this buffer should be initialized to zero during  *            decoder reset. During decoder operation, the values contained in  *            this buffer should be modified only by the PQMF function.  *   pVPosition - pointer to the internal workspace index; should be  *            initialized to zero during decoder reset. During decoder  *            operation, the value of this index should be preserved between  *            PQMF calls and should be modified only by the function.  *   mode - flag that indicates whether or not the PCM audio output channels  *            should be interleaved 1 - not interleaved 2 - interleaved  * * Output Arguments: *    *   pDstAudioOut - pointer to a block of 32 reconstructed PCM output samples  *            in 16-bit signed Q0.15 format (little-endian); left and right  *            channels are interleaved according to the mode flag. This should  *            be aligned on a 4-byte boundary  *   pVBuffer - pointer to the updated internal workspace buffer containing  *            Q7.24 data; see usage notes under input argument discussion  *   pVPosition - pointer to the updated internal workspace index; see usage  *            notes under input argument discussion  * * Return Value: *     *    OMX_Sts_NoErr - No errors  *    OMX_Sts_BadArgErr - bad arguments detected; one or more of the  *              following conditions is true: mode<1 or mode>2  *    -   *pVPosition is outside the range [0, 15] at least one of the  *              following pointers is NULL: pSrcY, pDstAudioOut, pVBuffer,  *              and/or pVPosition.  * */OMXResult omxACMP3_SynthPQMF_S32_S16(     OMX_S32 *pSrcY,     OMX_S16 *pDstAudioOut,     OMX_S32 *pVBuffer,     OMX_INT *pVPosition,     OMX_INT mode){    OMX_F64     acc, Angle;    OMX_F64     VPrime [ARM_MP3_VBUFFER_SZ], Src [ARM_MP3_PQMF_SZ];    OMX_F64     U [ARM_MP3_VBUFFER_SZ];    OMX_S32     i, j, k, J;    /* Arguments check */    armRetArgErrIf(pSrcY == NULL, OMX_Sts_BadArgErr)    armRetArgErrIf(pDstAudioOut == NULL, OMX_Sts_BadArgErr)    armRetArgErrIf(pVBuffer == NULL, OMX_Sts_BadArgErr)    armRetArgErrIf(pVPosition == NULL, OMX_Sts_BadArgErr)    armRetArgErrIf(mode < 1, OMX_Sts_BadArgErr)    armRetArgErrIf(mode > 2, OMX_Sts_BadArgErr)    /* Validate Arguments */    armRetArgErrIf(*pVPosition < 0, OMX_Sts_BadArgErr)    armRetArgErrIf(*pVPosition > 15, OMX_Sts_BadArgErr)    /* Get input */    for (i = 0; i < ARM_MP3_PQMF_SZ; i++)    {        /* Convert Q7.24 to float */        Src [i] = ((OMX_F64)pSrcY [i]) / (1 << 24);    }    for (i = 0; i < ARM_MP3_VBUFFER_SZ; i++)    {        /* Convert Q7.24 to float */        VPrime[i] = ((OMX_F64)pVBuffer [i]) / (1 << 24);    }    /*      *  Following equation given in MP3 standard (ISO/IEC 11172-3) is modified      *  to use a 32 point DCT and symmetry.     *     *                           31                  *              V[j*64+i] = sum  N[i][k] * S[k]     *                           k=0                        *                                  for 0 =< i =< 63, 0 =< j =< 15     *                          where N[i][k] = cos((16+i)*(2k+1)*PI/64)     *                                   S[k] = 32 sub-band samples     *      *  The implementation uses 32 point DCT followed by copy as given below.     *  This change is needed because OMX Spec uses a circular V buffer of size     *  512, and pointer to the current update position. 32 DCT outputs for the      *  current position will be stored after the function call.      *                           31                  *             V' [j*32+i] = sum  S[k] * cos(i*(2k + 1)*PI/64)     *                           k=0                        *                  where 0 =< k =< 31, 0 =< i =< 31, 0 =< j =< 15     *                  *             V[j*64+i+0]  =  V'[j*32+i+16]     *             V[j*64+i+17] = -V'[j*32+31-i]     *             V[j*64+i+32] = -V'[j*32+16-i]     *             V[j*64+i+48] = -V'[j*32+i]     *             V[j*64+16] = 0     *                  where 0 =< i =< 15, 0 =< j =< 15     */            /*      *  Variables used for implementing:     *     *  V        -> ISO defined buffer of size 1024, each call will update 64 values     *  VPrime   -> V'. Contains 32 point DCT values. V can be obtained from V'.     *  pVBuffer -> Same as VPrime, but with data type of function API, instead of float.     *  pVPointer-> Index to VPrime buffer for updating. Implements circular buffer.     *  U        -> ISO defined array of 512, created as from VPrime, to be multiplied by DWindow     *     */    /*      *  Indices used for implementing:     *     *  i        -> 32 point DCT output index, 0=<i=<32      *  k        -> ISO defined, 32 samples of one sub-band are indexed using k. 0=<k=<32      *  j        -> Sub-band index, VPrime contains 16 sub-bands     */    /* calculate 32pt DCT of Vi */        j = *pVPosition;        for (i = 0; i < ARM_MP3_PQMF_SZ; i++)    {        Angle = (PI / 64.0) * i;        acc = 0.0;        for (k = 0; k < ARM_MP3_PQMF_SZ; k++)        {            acc += cos (Angle * (2.0 * k + 1.0)) * Src [k];        }        VPrime [(ARM_MP3_PQMF_SZ * j) + i] = acc;        pVBuffer[(ARM_MP3_PQMF_SZ * j) + i] =             armSatRoundFloatToS32 (acc * (1 << 24));    }    /* update pVPosition */    k = ARM_MP3_PQMF_SZ * *pVPosition;    *pVPosition -= 1;    if (*pVPosition < 0)    {        *pVPosition = 15;    }        /*     * ISO defines calculation for U[512] as,     *          *     U[j*64+i] = V[j*128+i]     *     U[j*64+32+i] = V[j*128+96+i]     *           for 0 =< i =< 31, 0 =< j =< 7     *         *    Where V is ISO defined arry of size [16*64] (64 elements per DCT32+Add Matrixing operation)     * This calculation of U[512] is implemented using V' of size [16*32] (32 elements DCT32 elements)     *         */         /* Copy 64 element at a time to fill U of size [512] */    for (j = 0; j < 8; j++)    {        for (i = 0; i < 16; i++)        {            /* Copy first 32 elements */            /* Make U values from DCT32 values stored in V' buffer using equation             *   Relationship of U, V & V'                *      U [j*64+i] = V[j*128+i+0]  =  V'[k+i+16]             *      U [j*64+i+17] = V[j*128+i+17] = -V'[k+31-i]             *          Where 0 =< i =< 15, 0 =< j =< 7,  0 =< k-VPosition =< 15             */            U [j * 64 + i] = VPrime [k + i + 16];            U [j * 64 + i + 17] = -VPrime [k + 31 - i];        }                /* k wraps at the v-buffer boundary  */        k = (k + ARM_MP3_PQMF_SZ) & ARM_MP3_VBUFFER_SZ_MASK;        for (i = 0; i < 16; i++)        {            /* Copy next 32 elements */            /* Make U values from DCT32 values stored in V using equation             *   Relationship of U, V & V'                *      U [j*64+i+32] = V[j*128+96+i] = V'[k+16-i]             *      U [j*64+i+48] = V[j*128+96+i+17] = -V'[k+32+i]             *          Where 0 =< i =< 15, 0 =< j =< 7,,  0 =< k-VPosition-1 =< 15               */            U [j * 64 + i + 32] = -VPrime [k + 16 - i];            U [j * 64 + i + 48] = -VPrime [k + i];        }        U [j * 64 + 16] = 0;        /* k wraps at the v-buffer boundary  */        k = (k + ARM_MP3_PQMF_SZ) & ARM_MP3_VBUFFER_SZ_MASK;    }    for (i = 0; i < ARM_MP3_PQMF_SZ; i++)    {        acc = 0.0;        for (J = 0; J < 16; J++)        {            /* i+32*J */            k = i + J * ARM_MP3_PQMF_SZ;             acc += U [k] * armACMP3_DWindow [k];        }        /* Convert float to Q16.15 */        pDstAudioOut [i * mode] = armSatRoundFloatToS16 (acc * (1 << 15));    }    return OMX_Sts_NoErr;}/***************************************************************************** *                              END OF FILE *****************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -