pmp2dec.c

来自「瑞星微公司RK27XX系列芯片的SDK开发包」· C语言 代码 · 共 568 行 · 第 1/2 页

C
568
字号
                // There is no output buffer.
                pMP2->pOutput = 0;

                //----------
                // Success.
                return(1);
            }

            // Decode a frame of data.
        case SUBFN_CODEC_DECODE:
            {
                tMP2 *pMP2;
                short *psLeft, *psRight;
                long lLength;
                int i;

                // The first parameter is a pointer to the MP2 persistent state.
                pMP2 = (tMP2 *)ulParam1;

                // OutLength=(-1);
                OutLength = 1152;
                // Find the next frame in the bitstream.
                if (MP2FindNextFrame(pMP2) == 0)
                {
                    // We could not find another frame, so see if there is more
                    // data to be decoded.

                    int CurrPos = 0;

                    //CurrPos = RKFIO_FTell(pRawFileCache);

                    if ((CurrPos < pMP2->ulLength) ||
                            (((unsigned)pMP2->sBS.bufptr - (unsigned)pENCODED_DATA) <
                             pMP2->usValid))
                    {
                        // Re-initialize the MP2 library (to try and minimize the
                        // artifacting).
                        InitMP2Aud(pMP2->pMPEGInstance, (unsigned char *)pENCODED_DATA);

                        memset(pMP2->psLeft, 0, (MP2_PCM_BUFFER_SIZE));
                        memset(pMP2->psRight, 0, (MP2_PCM_BUFFER_SIZE));
                        CurrPos = RKFIO_FRead(pRawFileCache, pENCODED_DATA, MP2_ENCODED_DATA_SIZE);

                        if (CurrPos <= 0)
                            return 0;

                        pMP2->usValid = CurrPos;

                        pMP2->sBS.bufptr = (unsigned int *)(pENCODED_DATA);// + (ulFilePos & 508));
                        pMP2->sBS.bitidx = 0;// 8 * ((short)ulFilePos & 3);
                        return(1);
                    }
                    else
                    {
                        // There is no more data to be decoded, so return an error
                        // to indicate that we are at the end of the file.
                        return(0);
                    }
                }


                //MOD BY vincent 070917, has not been TESTED!
                psLeft = pMP2->psLeft;
                psRight = pMP2->psRight;

                // Decode the data frame.
                // MP2DecData函数的最后一个参数为MP2或DAB模式选择参数
                // 现已在库中限定
                pMP2->sStatus = (tMP2Status)MP2DecData(psLeft, psRight, &(pMP2->sBS));

                //pMP2->sStatus=0;
                if ((pMP2->sStatus != eNoErr) && (pMP2->sStatus != eFrameDiscarded))
                {
                    unsigned int CurrPos = 0;

                    //CurrPos = RKFIO_FTell(pRawFileCache);

                    if ((CurrPos < pMP2->ulLength) ||
                            (((unsigned)pMP2->sBS.bufptr - (unsigned)pENCODED_DATA) <
                             pMP2->usValid))
                    {
                        // There is more data to be decoded, so re-initialize the
                        // MP2 library (to try and minimize the artifacting).
                        InitMP2Aud(pMP2->pMPEGInstance, (unsigned char *)pENCODED_DATA);
                        memset(pMP2->psLeft, 0, (MP2_PCM_BUFFER_SIZE));
                        memset(pMP2->psRight, 0, (MP2_PCM_BUFFER_SIZE));
                        // Return "success".
                        return(1);
                    }
                    else
                    {
                        // There is no more data to be decoded, so return an error
                        // to indicate that we are at the end of the file.
                        return(0);
                    }
                }


                // Make sure that this frame did not use garbage at the end of the
                // encoded data buffer to complete the decode.
                if (((unsigned)pMP2->sBS.bufptr - (unsigned)pENCODED_DATA) >
                        pMP2->usValid)
                {
                    // All the data for this frame was not present, so see if there
                    // is more data in to be decoded.

                    unsigned int CurrPos = 0;

                    //CurrPos = RKFIO_FTell(pRawFileCache);

                    if (CurrPos < pMP2->ulLength)
                    {
                        // Re-initialize the MP2 library (to try and minimize the
                        // artifacting).
                        InitMP2Aud(pMP2->pMPEGInstance, (unsigned char *)pENCODED_DATA);
                        memset(pMP2->psLeft, 0, (MP2_PCM_BUFFER_SIZE));
                        memset(pMP2->psRight, 0, (MP2_PCM_BUFFER_SIZE));
                        // Return "success".
                        return(1);
                    }
                    else
                    {
                        // There is no more data to be decoded, so return an error
                        // to indicate that we are at the end of the file.
                        return(0);
                    }
                }

                // Determine the length of each frame, based on the sample rate of
                // the file.
                lLength = 1152;
                // If this frame was not discarded, then update the output buffer's
                // write pointer.
                /*
                if(pMP2->sStatus != eFrameDiscarded)
                {
                 OutLength=lLength;
                }*/
                OutLength = lLength;
                // Increment the time based on the number of samples.
                pMP2->ulTimePos += lLength;

                // Success.
                return(1);
            }

            // Seek to the specified time position.
        case SUBFN_CODEC_SEEK:
            {
                tMP2 *pMP2;
                unsigned long ulPos, ulFrameSize;
                int count = 256, i;
                // The first parameter is a pointer to the MP2 persistent state.
                pMP2 = (tMP2 *)ulParam1;

                // Make sure that the specified time is valid.
                if (ulParam2 > pMP2->ulTimeLength)
                {
                    ulParam2 = pMP2->ulTimeLength;
                }

                // If this file uses VBR, then we use the seek point table to
                // compute the new position.
                {
                    // Figure out the size of each frame based on the sample rate.
                    ulFrameSize = 1152;

                    // Compute the number of frames that occur before the requested
                    // time position.
                    ulPos = (((ulParam2 / 1000) * pMP2->usSampleRate) /
                             ulFrameSize) +
                            (((ulParam2 % 1000) * pMP2->usSampleRate) /
                             (ulFrameSize * 1000));

                    // Compute the time for the computed frame number.
                    pMP2->ulTimePos = ulPos = ulPos * ulFrameSize;

                    if (pMP2->usSampleRate == 0) return(0);

                    // Compute the file position based on the actual seek time.
                    ulPos = ((ulPos / pMP2->usSampleRate) *
                             (pMP2->ulBitRate / 8)) +
                            (((ulPos % pMP2->usSampleRate) *
                              (pMP2->ulBitRate / 8)) / pMP2->usSampleRate) +
                            pMP2->ulFirstFrame;

                    if (ulPos)
                    {
                        ulPos--;
                    }
                }

                // Initialize the MP2 library.
                InitMP2Aud(pMP2->pMPEGInstance, (unsigned char *) pENCODED_DATA);

                // Initialize the bitstream to the position.
                MP2InitBitstream(pMP2, ulPos);
                // Find the next frame in the input MP2 bitstream.
                //找下一帧,这里应对count的数目做限定。

                for (i = 0;i < count;i++)
                {
                    // Look for the next frame.
                    if (MP2FindNextFrame(pMP2) == 1)
                    {
                        // Make sure that the packed_info for the frame we found
                        // matches (where appropriate) the packed_info for the
                        // first frame in the file.
                        if ((pMP2->usSampleRate ==
                                usSRMap2[pMP2->sHdr.sample_rate]) &&
                                (pMP2->ucChannels == pMP2->sHdr.numchans))
                        {
                            break;
                        }
                    }

                }

                // Skip back one word so that the frame header will be available
                // the next time the decoder is called.
                pMP2->sBS.bufptr--;

                // Success.
                return(1);
            }

            // Cleanup after the codec.
        case SUBFN_CODEC_CLOSE:
            {
                // There's nothing to do, so return success.
                return(1);
            }

            // Return the name of the artist.
        case SUBFN_CODEC_GETARTIST:
            {
                char **ppcName;
                tMP2 *pMP2;

                // The first parameter is a pointer to the FLAC persistent data.
                pMP2 = (tMP2 *)ulParam1;

                // The second parameter is a pointer for the name.
                ppcName = (char **)ulParam2;

                // Return the name of the artist.
                *ppcName = (char *)ID3V2XInfo.mMetaData[ID3_ARTIST];

                // Success.
                return(1);
            }

            // Return the name of the song
        case SUBFN_CODEC_GETTITLE:
            {
                char **ppcName;
                tMP2 *pMP2;

                // The first parameter is a pointer to the FLAC persistent data.
                pMP2 = (tMP2*)ulParam1;

                // The second parameter is a pointer for the name.
                ppcName = (char **)ulParam2;

                // Return the name of the song.
                *ppcName = (char *)ID3V2XInfo.mMetaData[ID3_TITLE];

                // Success.
                return(1);
            }


            // We should never get here, but just in case...
        default:
            {
                // Return a failure.
                return(0);
            }
    }
}

#endif

⌨️ 快捷键说明

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