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

📄 omxacaac_mdctinv_s32_s16.c

📁 The OpenMAX DL (Development Layer) APIs contain a comprehensive set of audio, video, signal processi
💻 C
字号:
/** *  * File Name:  omxACAAC_MDCTInv_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 file contains module for IMDCT 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_MDCTInv_S32_S16   (3.2.3.5.2) * * Description: * This function computes an inverse MDCT to generate 1024 reconstructed  * 16-bit signed little-endian PCM samples as output for each channel. In  * order to adapt the time/frequency resolution of the filterbank to the  * characteristics of the input signal, a block switching tool is also  * adopted. For each channel, 1024 time-frequency domain samples are  * transformed into the time domain via the IMDCT. After applying the  * windowing operation, the first half of the windowed sequence is added to  * the second half of the previous block windowed sequence to reconstruct 1024  * output samples for each channel. Output can be interleaved according to  * pcmMode.  * If pcmMode equals 2, output is in the sequence pDstPcmAudioOut[2*i],  * i=0 to 1023, i.e., 1024 output samples are stored in the sequence:  * *    pDstPcmAudioOut[0],  pDstPcmAudioOut[2],  *    pDstPcmAudioOut[4],  ...,  pDstPcmAudioOut[2046].  * * If pcmMode equals 1, output is in the sequence: *  *    pDstPcmAudioOut[i], i=0 to 1023.  * * Users must also preallocate an input-output buffer pointed by  * pSrcDstOverlapAddBuf for overlap-add operation. Reset this buffer to  * zero before first call, then use the output of the current call as the  * input of the next call for the same channel.  * * Reference: [ISO14496-3], sub-clause 4.6.11  * * Input Arguments: *    *   pSrcSpectralCoefs - pointer to the input time-frequency domain samples  *            in Q28.3 format. There are 1024 elements in the buffer pointed  *            by pSrcSpectralCoefs.  *   pSrcDstOverlapAddBuf - pointer to the overlap-add buffer which contains  *            the second half of the previous block windowed sequence in  *            Q28.3. There are 1024 elements in this buffer.  *   winSequence - analysis 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,  *            2=eight_short_sequence/short window,  *            3=long_stop_sequence/long_stop_window.  The function will return  *            an error if winSequence<0 or winSequence>3.  *   winShape - analysis 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.  *   prevWinShape - 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.  *   pcmMode - flag that indicates whether the PCM audio output is  *            interleaved (LRLRLR ) or not: 1 = not interleaved 2 =  *            interleaved  * * Output Arguments: *    *   pDstPcmAudioOut - Pointer to the output 1024 reconstructed 16-bit signed  *            little-endian PCM samples in Q15.0, interleaved if needed.  *   pSrcDstOverlapAddBuf - pointer to the overlap-add buffer which contains  *            the second half of the current block windowed sequence in Q28.3.  * * Return Value: *     *    OMX_Sts_NoErr - no error  *    OMX_Sts_BadArgErr - bad arguments  *    -    at least one of the pointers is NULL:  *           - pSrcSpectralCoefs,  *           - pSrcDstOverlapAddBuf, or  *           - pDstPcmAudioOut  *    -    winSequence < 0, or winSequence > 3  *    -    winShape < 0, or winShape > 1  *    -    prevWinShape < 0, or prevWinShape > 1  *    -    pcmMode < 1, or pcmMode > 2  * */OMXResult omxACAAC_MDCTInv_S32_S16(     const OMX_S32 *pSrcSpectralCoefs,     OMX_S16 *pDstPcmAudioOut,     OMX_S32 *pSrcDstOverlapAddBuf,     OMX_INT winSequence,     OMX_INT winShape,     OMX_INT prevWinShape,     OMX_INT pcmMode ){    const OMX_F64 *pLeftWinShortPrev = NULL,*pLeftWinShort = NULL,*pLeftWinLongPrev = NULL;    const OMX_F64 *pRightWinShort = NULL,*pRightWinLong = NULL; /*To avoid warnings*/        OMX_F64       *pDstCoeff,*pBuffer;    OMX_F64        dstCoeff[ARM_AAC_WIN_LONG << 1],buffer[ARM_AAC_WIN_SHORT];        OMX_F64        theta,PiByN,alpha,coeff;    OMX_F64        output,cosine,outCoeff0;    OMX_INT        outCoeff,inCoeff,winNum;            /* Argument Check */            armRetArgErrIf( pSrcSpectralCoefs    == NULL, OMX_Sts_BadArgErr);    armRetArgErrIf( pDstPcmAudioOut      == NULL, OMX_Sts_BadArgErr);    armRetArgErrIf( pSrcDstOverlapAddBuf == NULL, OMX_Sts_BadArgErr);    armRetArgErrIf( (winSequence > 3)  || (winSequence < 0) , OMX_Sts_BadArgErr);    armRetArgErrIf( (winShape > 1)     || (winShape < 0)    , OMX_Sts_BadArgErr);    armRetArgErrIf( (prevWinShape > 1) || (prevWinShape < 0), OMX_Sts_BadArgErr);    armRetArgErrIf( (pcmMode > 2)      || (pcmMode < 1)     , OMX_Sts_BadArgErr);    /* Processing */        /*Windowing pointer assignments*/        switch(prevWinShape)    {        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;                        pLeftWinShort  = armACAAC_winShortSine;                        break;                    case 1:            /*KBD window*/            pRightWinShort = armACAAC_winShortKBD + ARM_AAC_WIN_SHORT - 1;            pRightWinLong  = armACAAC_winLongKBD  + ARM_AAC_WIN_LONG - 1;                        pLeftWinShort  = armACAAC_winShortKBD;            break;            }            /*IMDCT*/    pDstCoeff = dstCoeff;    pBuffer   = buffer;    if(winSequence == ARM_AAC_EIGHT_SHORT_SEQUENCE)    {        /*Short IMDCT*/                outCoeff0 = 64.5;        PiByN     = armPI/(ARM_AAC_WIN_SHORT << 1);                /*Adding the Inital zeros to buffer*/                for(outCoeff = 0; outCoeff < 448 ; outCoeff++)        {            *pDstCoeff++ = 0;        }        for(winNum = 0; winNum < OMX_AAC_WIN_MAX ; winNum++)        {            for(outCoeff = 0 ; outCoeff < (ARM_AAC_WIN_SHORT << 1) ; outCoeff ++)             {                theta  = (2*PiByN)*( (OMX_F64)outCoeff + outCoeff0);                output = 0;                                for(inCoeff = 0; inCoeff < ARM_AAC_WIN_SHORT ; inCoeff ++)                {                    alpha  = theta * ( (OMX_F64)inCoeff + .5);                    cosine = cos(alpha);                    coeff  = pSrcSpectralCoefs[inCoeff]/ (OMX_F64)(1 << ARM_AAC_Q_FACTOR);                                        coeff  = cosine * coeff;                    output = output + coeff;                }                output = (output/ARM_AAC_WIN_SHORT);                                /*Windowing operation */                                             if(outCoeff < ARM_AAC_WIN_SHORT)                {                    /* First Half */                                        /*Window and store in the buffer*/                    if(winNum == 0)                    {                        output = pLeftWinShortPrev[outCoeff] * output;                    }                    else                    {                        output = pLeftWinShort[outCoeff] * output;                        output = pBuffer[outCoeff] + output;                        }                                        *pDstCoeff++ = output;                }                else                {                    /*Second Half*/                    output =  pRightWinShort[ARM_AAC_WIN_SHORT - outCoeff] * output;                    pBuffer[outCoeff - ARM_AAC_WIN_SHORT] = output;                }            }                        pSrcSpectralCoefs += ARM_AAC_WIN_SHORT;        }                for(outCoeff = 0 ; outCoeff < ARM_AAC_WIN_SHORT ; outCoeff++)        {            *pDstCoeff++ = pBuffer[outCoeff];        }                /*Adding the terminating zeros to the buffer*/                for(outCoeff = 0; outCoeff < 448 ; outCoeff++)        {            *pDstCoeff++ = 0;        }    }    else    {        /*Long IMDCT*/        outCoeff0 = 512.5;        PiByN     = armPI/(ARM_AAC_WIN_LONG << 1);                for(outCoeff = 0 ; outCoeff < (ARM_AAC_WIN_LONG << 1) ; outCoeff ++)         {            theta  = (2*PiByN)*( (OMX_F64)outCoeff + outCoeff0);            output = 0;                        for(inCoeff = 0; inCoeff < ARM_AAC_WIN_LONG ; inCoeff ++)            {                alpha  = theta * ( (OMX_F64)inCoeff + .5);                cosine = cos(alpha);                coeff  = pSrcSpectralCoefs[inCoeff]/ (OMX_F64)(1 << ARM_AAC_Q_FACTOR);                                coeff  = cosine * coeff;                output = output + coeff;            }            pDstCoeff[outCoeff] = (output/ARM_AAC_WIN_LONG);        }        }        pDstCoeff = dstCoeff;        /*Windowing*/    switch(winSequence)    {        case ARM_AAC_ONLY_LONG_SEQUENCE:            for(outCoeff = 0 ; outCoeff < ARM_AAC_WIN_LONG ; outCoeff ++)            {                /*Left Half*/                output  = pLeftWinLongPrev[outCoeff] * pDstCoeff[outCoeff] ;                pDstCoeff[outCoeff] = output;                            /*Right Half*/                output  = pRightWinLong[-outCoeff] * pDstCoeff[outCoeff + ARM_AAC_WIN_LONG] ;                pDstCoeff[outCoeff + ARM_AAC_WIN_LONG] = output;                            }                        break;                    case ARM_AAC_LONG_STOP_SEQUENCE:                        for(outCoeff = 0 ; outCoeff < 448 ; outCoeff ++)            {                pDstCoeff[outCoeff] = 0;            }            for(outCoeff = 448 ; outCoeff < 576 ; outCoeff ++)            {                output  = pLeftWinShortPrev[outCoeff - 448] * pDstCoeff[outCoeff];                pDstCoeff[outCoeff] = output;            }                        for(outCoeff = ARM_AAC_WIN_LONG ; outCoeff < (ARM_AAC_WIN_LONG << 1) ; outCoeff ++)            {                output  = pRightWinLong[ARM_AAC_WIN_LONG - outCoeff] * pDstCoeff[outCoeff];                                pDstCoeff[outCoeff] = output;            }                        break;        case ARM_AAC_LONG_START_SEQUENCE:            for(outCoeff = 0 ; outCoeff < ARM_AAC_WIN_LONG ; outCoeff ++)            {                output  = pLeftWinLongPrev[outCoeff] * pDstCoeff[outCoeff];                pDstCoeff[outCoeff] = output;            }            for(outCoeff = 1472 ; outCoeff < 1600 ; outCoeff ++)            {                output  = pRightWinShort[1472 - outCoeff] * pDstCoeff[outCoeff];                pDstCoeff[outCoeff] = output;            }                        for(outCoeff = 1600 ; outCoeff < (ARM_AAC_WIN_LONG << 1 ) ; outCoeff ++)            {                pDstCoeff[outCoeff] = 0;            }            break;                case ARM_AAC_EIGHT_SHORT_SEQUENCE:                    /*Windowing already done*/                break;    }            /*Overlap and Add*/    for(outCoeff = 0 ;outCoeff < ARM_AAC_WIN_LONG ; outCoeff++)    {        output                         = pDstCoeff[outCoeff] + pSrcDstOverlapAddBuf[outCoeff]/ (OMX_F64)(1 << ARM_AAC_Q_FACTOR);        pSrcDstOverlapAddBuf[outCoeff] = armSatRoundFloatToS32( (pDstCoeff[outCoeff + ARM_AAC_WIN_LONG]) * (1 << ARM_AAC_Q_FACTOR) );                /*Rounding*/        pDstPcmAudioOut[pcmMode * outCoeff] = (OMX_S16)armSatRoundFloatToS16(output);    }            return OMX_Sts_NoErr;}/*End of File*/

⌨️ 快捷键说明

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