📄 mp3wrap.c
字号:
/************************************************** * * 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 + -