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

📄 mp3wrap.c

📁 本程序为ST公司开发的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************** * * mp3wrap.c * * CVS ID:   $Id: mp3wrap.c,v 1.55 2007/09/21 05:26:35 hara Exp $ * Author:   Raffaele Belardi [RB] - STM) * Date:     $Date: 2007/09/21 05:26:35 $ * Revision: $Revision: 1.55 $ * * Description: * * Wrapper functions around the ARM MP3 library functions. * *************************************************** * * COPYRIGHT (C) ST Microelectronics  2005 *            All Rights Reserved * *************************************************** * * STM CVS Log: * * $Log: mp3wrap.c,v $ * Revision 1.55  2007/09/21 05:26:35  hara * Initial implementation for WMDRM feature into A+. * * Revision 1.54  2007/02/27 09:38:10  belardi * Removed requirement to compile in ARM mode since the libraries are now in Thumb * * Revision 1.53  2007/02/01 16:49:13  chlapik * fixed bug - song_number * * Revision 1.52  2007/01/30 09:38:16  chlapik * fixed bug: * song_number and xid sent from CTR to PLY is not set in CTR task but it is provided by DEC to AB * * Revision 1.51  2007/01/18 09:02:29  chlapik * fixed bug - overflow for evaluation of reporting time in case of big files * * Revision 1.50  2006/10/31 14:14:19  chlapik * support for Layer I & II: * - Layer type, sample rate and channel number are determined by BitrateParser before playback * - mp3 decoder checks if these parameters found in valid header matches, if not scan bitstream per bytes * * Revision 1.49  2006/10/25 13:09:12  chlapik * fixed bugs: * - problem in DecodeHeader(), if data wrong aligned in 4 bytes groups, then missed header (set DecoderOffset to 1 in case of error) * - sometimes BOS missed, if in first FB element no header found, then we didn't catch BOS at all (check BOS also in case of searching header) * * Revision 1.48  2006/10/20 12:27:33  belardi * Removed unused variable to remove compiler warning * * Revision 1.47  2006/10/17 09:52:23  trubac * pragma ARM * cosmetic, commented prototypes, whitespaces, newlines * * Revision 1.44  2006/09/15 19:40:24  belardi * Merged the m8_cav2_cm80506_cs3563. * - renamed _EVENT_TEP_NOEVENT * * ***************************************************/#include <stdio.h>#include <string.h>#include "gendef.h"#include "osal.h"#include "allocation.h"#include "decoder_task.h"#include "MP3/mp3dec.h"#include "mp3wrap.h"#include "framebuffer.h"#include "audiobuffer.h"#include "controller.h"#if (DEBUG_INCLUDE_COUNTERS==1)extern uint32 countMP3GoodFrames;extern uint32 countMP3BadFrames;#endif/***** OS related stuff *******/extern uint16 decoder_command;         // Command buffer//extern uint32 g_currentFileStartOffset;   // from controller.cuint32 g_currentFileStartOffset = 0;      // from controller.cFrameBufferElement pBufferElement;extern unsigned char g_FB_readFrom;     // from framebuffer.cextern eDecoderSampleRate CurrentSampleRateConverterFrequency;          //[LL] extern: audiobuffer.c, type: decoder_defines.h/* amount of bytes to be skipped in fast seek mode */extern int g_decoderFastSeekJumpBytes;    // from decoder.c           //[LL] extern: decoder_task.cextern t_PlayMode decoderPlayMode;                        //[LL] extern: decoder_task.c, type: decoder_defines.h//char WaitingMode = 0;                             //[LL]CADecoderStateType MP3DecoderNextState = notInitialized;            //[LL] type: decoder_task.hextern char WaitingMode;                            //[LL] extern: decoder_task.c//make mp3 decoder more robustextern uint16 CurrentSampling_fr;extern uint8 CurrentCh_num;extern uint32 CurrentBistreamType;static uint32 unreported_subcode_event_type;// Variables required by the ARM MP3 librarystatic oDecoderHandle MP3DecoderHandle;static sDecoderRequirements *MP3Requirements_p;static sDecoderFormats *MP3Formats_p;static void *MP3Scratch_p;static void *MP3InstanceState_p;static sDecoderBitstream *MP3Bitstream_p;static sDecoderOutput *MP3Output_p;// MP3 libary private datastatic void *outputChannelArray[2];//__align(4) static char outputChannelOne[outputBufferSamplesNumber * sizeOfSampleInBytes];//__align(4) static char outputChannelTwo[outputBufferSamplesNumber * sizeOfSampleInBytes];static uint32 channelOffsetsArray[2];static sDecoderFormats decoderFormatsStructure;static sDecoderRequirements decoderRequirementsStructure;static sDecoderOutput decoderOutputStructure;static sDecoderBitstream decoderBitstreamStructure;/***** FUNCTIONS *******/void zeroMemory(char *pt, int size){  char *end_pt = pt + size;  while (pt < end_pt)    *pt++ = 0;}MP3UpdateStatus MP3UpdateBitstream(sDecoderBitstream *Bitstream, int flag){  // chceck whether there was Controller request to stop (NEXT/PREV/STOP/FF/FR)  if (decoderStopRequest())  {    return immediateEOF;  }  if (WaitingMode)  {    //continue after wake up    WaitingMode = 0;    while (Bitstream->dataRequired > Bitstream->dataLength)    {      //was the previous FBE 'the last' ?      if (pBufferElement.ElementFlag & FT_LAST)      {        // if so return EOF        return dataEOF;      }      if (pBufferElement.ElementFlag & FT_FSLAST)      { // Fast Seek reached end of play block        return dataEOPB;      }      if (pBufferElement.en == FrameBufferElements)      {        //we read last element in FB, we want next data        //copy dataLength bytes from data+dataOffset position to 0.element#if (0 != HAVE_WMDRM_LARGE_BUFFER)        if (Bitstream->dataLength & 0x1)        {                                                                                        /* Change 8 bits boundary to 16 bit : Bitstream->dataLength++, Bitstream->data-- */          memcpy16(FrameBuffer[1].data - Bitstream->dataLength - 1, Bitstream->data - 1, Bitstream->dataLength + 1);        }        else        {          memcpy16(FrameBuffer[1].data - Bitstream->dataLength, Bitstream->data, Bitstream->dataLength);        }        #else        memmove(FrameBuffer[1].data - Bitstream->dataLength, Bitstream->data, Bitstream->dataLength);#endif        //set read elements as empty        SetEmptyFBE(GetElementNumber((unsigned char *)(Bitstream->data)), FrameBufferElements + 1);        //update bitstream pointers        Bitstream->data = (char *)(FrameBuffer[1].data - Bitstream->dataLength);        pBufferElement = FrameBuffer[0];      }      if (FrameBufferGetData(&pBufferElement, 1) == fbDataReady)      {        //we have next data        Bitstream->dataLength += pBufferElement.availableDataLength;        if (pBufferElement.ElementFlag & FT_LAST)        {          // is EOF          return dataEOF;        }        if (pBufferElement.ElementFlag & FT_FSLAST)        { // Fast Seek reached end of play block          return dataEOPB;        }      }      else      {        WaitingMode = 1;        {          return waitingForData;        }      }    }    //end while    return dataReady;  }  if (Bitstream->dataOffset + Bitstream->dataRequired <= Bitstream->dataLength)  { //we have enough data, update bitstream pointers    Bitstream->data += Bitstream->dataOffset;    Bitstream->dataLength -= Bitstream->dataOffset;    return dataReady;  }  else  { //we don't have enough data    //update bitstream pointers    Bitstream->data += Bitstream->dataOffset;    Bitstream->dataLength -= Bitstream->dataOffset;    //add more data    while (Bitstream->dataRequired > Bitstream->dataLength)    {      //was the previous FBE 'the last' ?      if (pBufferElement.ElementFlag & FT_LAST)      {        // if so return EOF        return dataEOF;      }      if (pBufferElement.ElementFlag & FT_FSLAST)      { // Fast Seek reached end of play block        return dataEOPB;      }      if (pBufferElement.en == FrameBufferElements)      { //we read last element in FB, we want next data        //copy dataLength bytes from data+dataOffset position to 0.element#if (0 != HAVE_WMDRM_LARGE_BUFFER)        if (Bitstream->dataLength & 0x1)        {                                                                                        /* Change 8 bits boundary to 16 bit : Bitstream->dataLength++, Bitstream->data-- */          memcpy16(FrameBuffer[1].data - Bitstream->dataLength - 1, Bitstream->data - 1, Bitstream->dataLength + 1);        }        else        {          memcpy16(FrameBuffer[1].data - Bitstream->dataLength, Bitstream->data, Bitstream->dataLength);        }        #else        memmove(FrameBuffer[1].data - Bitstream->dataLength, Bitstream->data, Bitstream->dataLength);#endif        //set read elements as empty        SetEmptyFBE(GetElementNumber((unsigned char *)(Bitstream->data)), FrameBufferElements + 1);        //update bitstream pointers        Bitstream->data = (char *)(FrameBuffer[1].data - Bitstream->dataLength);        pBufferElement = FrameBuffer[0];      }      if (FrameBufferGetData(&pBufferElement, 1) == fbDataReady)      { //we have next data        Bitstream->dataLength += pBufferElement.availableDataLength;        if (pBufferElement.ElementFlag & FT_LAST)        { //is EOF          return dataEOF;        }        if (pBufferElement.ElementFlag & FT_FSLAST)        { // Fast Seek reached end of play block          return dataEOPB;        }      }      else      { //we don't have next data        WaitingMode = 1;        return waitingForData;      }    } //end while    return dataReady;  }}void MP3Init(void){  /*eDecoderStatus ret;*/       //[LL] TBD - MP3Init could return  // Define our required features for MP3 decoder  MP3Formats_p = &decoderFormatsStructure;  // to avoid having to explicitely set every field of the MP3formats  // it is better to initialize it here.  zeroMemory((char *) MP3Formats_p, sizeof(sDecoderFormats));  // 0x02 is the number of requested channels  //MP3Formats_p->outputFormats = OUTPUT_FORMAT_16BIT | 0x02; //OUTPUT_FORMAT_32BIT | 0x02;  MP3Formats_p->outputFormats = OUTPUT_FORMAT_32BIT                              | OUTPUT_FORMAT_INTERLEAVED                              | OUTPUT_FORMAT_STEREO;  MP3Formats_p->decoderFeatures = DECODER_FEATURE_NONE;  // Check decoder requirements  MP3Requirements_p = &decoderRequirementsStructure;  /*ret = MP3DecoderRequirements(MP3DecoderHPQ.DecoderReference, MP3Requirements_p, MP3Formats_p);*/  MP3DecoderRequirements(MP3DecoderHPQ.DecoderReference, MP3Requirements_p, MP3Formats_p);  // Create decoder  MP3InstanceState_p = MALLOC(MP3Requirements_p->instanceStateSize);  MP3Scratch_p = MALLOC(MP3Requirements_p->scratchSize);  MP3DecoderHandle = MP3DecoderCreate(MP3DecoderHPQ.DecoderReference,                                      MP3InstanceState_p,                                      MP3Scratch_p,                                      MP3Formats_p);  //create input bitstream  MP3Bitstream_p = &decoderBitstreamStructure;  //create output buffer  MP3Output_p = &decoderOutputStructure;  MP3Output_p->channelsRequired = NULL;  MP3Output_p->numberOfChannels = 2;  /*  MP3Output_p->maxNumberOfSamples = outputBufferSamplesNumber;  MP3Output_p->channels = (void *) outputChannelArray;  MP3Output_p->channels[0] = (void *) outputChannelOne;  MP3Output_p->channels[1] = (void *) outputChannelTwo;  MP3Output_p->channelOffsets = (int *)&channelOffsetsArray[0];  MP3Output_p->channelOffsets[0] = 0;  MP3Output_p->channelOffsets[1] = 0;  */  MP3Output_p->maxNumberOfSamples = AUDIO_BUFFER_ELEMENT_LENGTH / 2;  MP3Output_p->channels = (void *) outputChannelArray;  //MP3Output_p->channels[0] = (void *) AudioBuffer[0].data;  //MP3Output_p->channels[1] = (void *)(AudioBuffer[0].data + 1); // 4 bytes per sample  MP3Output_p->channelOffsets = (int *)&channelOffsetsArray[0];  MP3Output_p->channelOffsets[0] = 2;  MP3Output_p->channelOffsets[1] = 2;  // Cannot assume data is already present in FrameBuffer  // so leave the decoder in not initialized state  MP3DecoderNextState = notInitialized;    unreported_subcode_event_type = 0;    decoderPlayMode = playModePlay;}decoderReturnType MP3Decode(int flag){  eDecoderStatus ret;  pAudioBufferData AudioBuffer_p;  //unsigned int previousDataRequired;  //static unsigned int decodedNumOfFrames;  //static unsigned long long int decoderSeekPlayedSamples;  //static unsigned long long int requiredNumOfOutputSamples;  static ElementFlagType nextElementFlag;  static uint8 Mp3DataEOF;  static uint8 Mp3DataEOPB;     // For Fast Seek - reached end of play block  static CADecoderStateType NextStateAfterWaitAB; //MP3DecoderNextState  static uint32 LastReportedFragment;  uint32 Fragment;  uint8 FB_clearFrom;  uint8 FB_clearTill;  int32 sample;  uint32 CurrentBitRate; // in fact ByteRate  uint32 CurrentFilePosAfterTAG;  tDecoderTime_event time_event;  t_position position;  while (1)  {    switch (MP3DecoderNextState)    {    case notInitialized:      {        // set pointer according to g_FB_readFrom        MP3Bitstream_p->data = (char *) FrameBuffer[(g_FB_readFrom % FrameBufferElements) + 1].data;        MP3Bitstream_p->dataLength = 0;      LastReportedFragment = 0xFFFFFFFF; //to ensure to report 1st time        nextElementFlag = FT_FIRST;              ret = MP3DecoderOpenBitstream(MP3DecoderHandle, MP3Scratch_p, MP3Bitstream_p, MP3Formats_p);

⌨️ 快捷键说明

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