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

📄 mp3wrap.c

📁 本程序为ST公司开发的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        // Don't leave the loop, there may be more data already available        MP3DecoderNextState = searchingHeader;        pBufferElement = FrameBuffer[0]; // reset last pBufferElement, not to copy the last                break;      }    case searchingHeader:      {        // We are searching for the first frame header in the        // compressed bistream. No data decoding happens here.        Mp3DataEOF = 0; // clear        Mp3DataEOPB = 0;        // Update bitstream data pointers before decoding        switch (MP3UpdateBitstream(MP3Bitstream_p, flag))        {        case waitingForData: // not enough data          return decoderWaitingFBdata;        case dataEOF: // EOF          Mp3DataEOF = 1; // set          break;        case dataReady: // data ready          break;        case immediateEOF: // request from Controller          return decoderEOF_immediate;        case dataEOPB: // end of play block (FF/FB)          Mp3DataEOPB = 1; // to wrap and start header decoding again          break;        }        ret = MP3DecodeHeader(MP3DecoderHandle, MP3Scratch_p, MP3Bitstream_p);        //modify dataOffset externally if >1 to 1 in 2 special cases:        // 1) in case of error, try one byte further, not per 4 bytes (dataOffset) as ARM library wants - bug in ARM lib        // 2) in case of no_error (so valid header found), check 3 params: sample rate, chan.num. and bistream type        if (((ret != kDecoderStatus_NoError) && (ret != kDecoderStatus_MoreData))   //is error          || ((ret == kDecoderStatus_NoError)                                       //no error           &&((MP3Bitstream_p->sampleRate != CurrentSampling_fr)                    //wrong sampl. rate           || (MP3Bitstream_p->channels.total != CurrentCh_num)                     //wrong chan. num.           || (MP3Bitstream_p->bitstreamType != CurrentBistreamType))))             //wrong layer type        {            if(MP3Bitstream_p->dataOffset > 1)          { //scan per bytes            MP3Bitstream_p->dataOffset = 1;            //dprintf("dataOffset forced to 1\r\n");          }        }                // set number of DECODED bytes        SetDecodedBytes(MP3Bitstream_p->dataLength - MP3Bitstream_p->dataOffset);        //decoderDecodedBytes = decoderReadBytes - (MP3Bitstream_p->dataLength - MP3Bitstream_p->dataOffset);        //clear used FB elements        FB_clearFrom = GetElementNumber((unsigned char *)(MP3Bitstream_p->data));        FB_clearTill = GetElementNumber((unsigned char *)                                        (MP3Bitstream_p->data + MP3Bitstream_p->dataOffset));        SetEmptyFBE(FB_clearFrom, FB_clearTill);        unreported_subcode_event_type |= pBufferElement.subcode.event_type;                //check if sample_rate and channels are the same values as before        //to make mp3 decoder more robust against lost of synchronization        //especially in case of fast seek        //check if sample_rate, channels, bistream type are meaning values at all        if ((ret != kDecoderStatus_NoError) && (ret != kDecoderStatus_MoreData))        {            //dprintf("Decode header error: %d\r\n",ret);          break;        }                //if they are meaning values, check if they match with values from BitrateParser        if(ret == kDecoderStatus_NoError)        {            if(MP3Bitstream_p->sampleRate != CurrentSampling_fr)            {              //dprintf("Sample rate error: %u\r\n",MP3Bitstream_p->sampleRate);              break;            }                        if(MP3Bitstream_p->channels.total != CurrentCh_num)            {              //dprintf("Channel number error: %u\r\n",MP3Bitstream_p->channels.total);              break;            }            if(MP3Bitstream_p->bitstreamType != CurrentBistreamType)            {              //dprintf("Layer error: %u\r\n",MP3Bitstream_p->bitstreamType);              break;            }        }                //next processing        switch (ret)        {        case kDecoderStatus_NoError:          // cannot start decoding if AB is full, as AudioBuffer is used inplace to decode mp3          if ((AudioBuffer_p = AudioBufferHaveSpace(MP3Bitstream_p->sampleRate)) == NULL)          { //output buffer is full            NextStateAfterWaitAB = decodingFrames;            MP3DecoderNextState = waitingAudioBuffer;            return decoderWaitingABempty;          }          // re-set output pointers to consecutive AudioBuffer element          MP3Output_p->channels[0] = (void *) AudioBuffer_p;          MP3Output_p->channels[1] = (void *)(AudioBuffer_p + 1); // 4 bytes per sample          // Do not leave the loop, there may be more data available for decoding.          MP3DecoderNextState = decodingFrames;          break;        case kDecoderStatus_MoreData:          // Can't proceed till mode data available,          if (!(Mp3DataEOF || Mp3DataEOPB))            break;        // there are more data to process          //clear used FB elements          FB_clearFrom = GetElementNumber((unsigned char *)(MP3Bitstream_p->data));          SetEmptyFBE(FB_clearFrom, pBufferElement.en);          //if last element not cleared before, then do it here          ClearFBElement(pBufferElement.en);          if (Mp3DataEOPB)          {            MP3DecoderCloseBitstream(MP3DecoderHandle, MP3Scratch_p);            MP3DecoderNextState = notInitialized;            break;          }          else // if (Mp3DataEOF)          {            return decoderEOF;          }        case kDecoderStatus_NoFrameHeader:        case kDecoderStatus_BrokenFrame:        case kDecoderStatus_ReservedBitRate:        case kDecoderStatus_ReservedSamplingFrequency:        case kDecoderStatus_UnsupportedFeature:          // Assume a false header was detected, continue silently          // (hoping to reach a good sync point), but update the          // data pointers otherwise we'll detect the same header!          break;        case kDecoderStatus_InvalidArgument:          break;        } //switch ret        break;      } //case searchingHeader    case decodingFrames:      {        // Decoding of copressed data is ongoing. Continue until        // - no more compressd data is available        // - not enough space in output buffer available        // - error conditions        Mp3DataEOPB = 0;        switch (MP3UpdateBitstream(MP3Bitstream_p, flag))        {        case waitingForData: //not enough data          return decoderWaitingFBdata;          //return decoderOk;        case dataEOF: //EOF          break;        case dataReady: //data ready          break;        case immediateEOF: // request from Controller          return decoderEOF_immediate;        case dataEOPB: // end of play block (FF/FB)          Mp3DataEOPB = 1; // to wrap and start header decoding          break;        }        // Update bitstream data pointers        ret = MP3DecodeFrame(MP3DecoderHandle, MP3Scratch_p, MP3Output_p, MP3Bitstream_p);        if (MP3Bitstream_p->channels.total == 1)        { // mono          for (sample = 0; sample < MP3Output_p->numberOfSamples; sample++)          {            *((int32 *)(MP3Output_p->channels[1]) + (sample << 1)) = *((int32 *)                                                                        (MP3Output_p->channels[0])                                                                      + (sample << 1));          }        }        // set number of DECODED bytes        SetDecodedBytes(MP3Bitstream_p->dataLength - MP3Bitstream_p->dataOffset);        //decoderDecodedBytes = decoderReadBytes - (MP3Bitstream_p->dataLength - MP3Bitstream_p->dataOffset);        CurrentBitRate = (uint32)GetCurrentBitRate();        GetCurrentPosition(&position); // xid,playlist        position.offset = GetDecodedBytes();        time_event.subcode.event_type = CAPTURE_EVENT_SUBCODE_NONE;        CurrentFilePosAfterTAG = GetDecodedBytes() - GetCurrentStartOffset() + (CurrentBitRate >> 1);        Fragment = (CurrentFilePosAfterTAG                  / (CurrentBitRate * (DECODER_TIME_INTERVAL / 1000) +                   ((DECODER_TIME_INTERVAL % 1000) * CurrentBitRate / 1000)));        if (Fragment != LastReportedFragment)        {          LastReportedFragment = Fragment;          pBufferElement.subcode.event_type |= CAPTURE_EVENT_SUBCODE_REL_TIME;        }        // if error occured before, now attach the last event        pBufferElement.subcode.event_type |= unreported_subcode_event_type;        if (pBufferElement.subcode.event_type          & (CAPTURE_EVENT_SUBCODE_BEGIN_OF_SONG | CAPTURE_EVENT_SUBCODE_REL_TIME) )        {#ifdef APM_PICKUP          //APM: time in miliseconds (overflow?):          time_event.ms.rel_time = (CurrentFilePosAfterTAG * 1000) / CurrentBitRate;          time_event.ms.event_type = pBufferElement.subcode.event_type;#else          //STM: calculate time into MSF format:          time_event.subcode.event_type = pBufferElement.subcode.event_type;          time_event.subcode.q_subcode.q_min = CurrentFilePosAfterTAG / (60*CurrentBitRate);  // min;          time_event.subcode.q_subcode.q_sec = (CurrentFilePosAfterTAG / CurrentBitRate) % 60;  // sec;          time_event.subcode.q_subcode.q_frame = 0; // frame;          time_event.subcode.q_subcode.q_tno = position.song_number;           time_event.subcode.q_subcode.xid = position.xfile;          //timeinfo_msf += ((absolute_outcnt % CurrentSampleRateConverterFrequency) * 75) / CurrentSampleRateConverterFrequency; // frame#endif          time_event.subcode.event_subcode = 0; // CA - info for AB to enable/disable de-emphasis          // store event time not to lose it (if error)          unreported_subcode_event_type = pBufferElement.subcode.event_type;          pBufferElement.subcode.event_type = CAPTURE_EVENT_SUBCODE_NONE;        }        //clear used FB elements        FB_clearFrom = GetElementNumber((unsigned char *)(MP3Bitstream_p->data));        FB_clearTill = GetElementNumber((unsigned char *)                                        (MP3Bitstream_p->data + MP3Bitstream_p->dataOffset));        SetEmptyFBE(FB_clearFrom, FB_clearTill);        switch (ret)        {        case kDecoderStatus_NoError:          // check the play mode:#if (DEBUG_INCLUDE_COUNTERS==1)          countMP3GoodFrames++;#endif          if (MP3Output_p->numberOfSamples == 0)          {            MP3DecoderNextState = searchingHeader;            break; // nothing to do          }          //some output samples have been generated          AudioBufferSetFull(MP3Output_p->numberOfSamples, nextElementFlag, &time_event, &position);          unreported_subcode_event_type = 0;          nextElementFlag = FT_MIDDLE;          MP3DecoderNextState = searchingHeader;          break;        case kDecoderStatus_MoreData:          //some output samples may have been generated          if (MP3Output_p->numberOfSamples > 0)          {            AudioBufferSetFull(MP3Output_p->numberOfSamples, nextElementFlag, &time_event, &position);            unreported_subcode_event_type = 0;            nextElementFlag = FT_MIDDLE;          }          //clear used FB elements          FB_clearFrom = GetElementNumber((unsigned char *)(MP3Bitstream_p->data));          SetEmptyFBE(FB_clearFrom, pBufferElement.en);          //if last element not cleared before, then do it here          ClearFBElement(pBufferElement.en);          if (Mp3DataEOPB)          { // kDecoderStatus_MoreData because EOPB (Play Block) has been reached (no EOF)            MP3DecoderCloseBitstream(MP3DecoderHandle, MP3Scratch_p);            MP3DecoderNextState = notInitialized;            break;          }          return decoderEOF;        case kDecoderStatus_MoreSamples:          // The decoder has filled AudioBuffer. Empty it and continue with MP3DecodeFrame          if (MP3Output_p->numberOfSamples == 0)          {            MP3DecoderNextState = searchingHeader;            break; // nothing to do          }          //some output samples have been generated          AudioBufferSetFull(MP3Output_p->numberOfSamples, nextElementFlag, &time_event, &position);          unreported_subcode_event_type = 0;          nextElementFlag = FT_MIDDLE;          NextStateAfterWaitAB = decodingFrames;          if ((AudioBuffer_p = AudioBufferHaveSpace(MP3Bitstream_p->sampleRate)) == NULL)          { //output buffer is full            MP3DecoderNextState = waitingAudioBuffer;            return decoderWaitingABempty;          }          // re-set output pointers to consecutive AudioBuffer element          MP3Output_p->channels[0] = (void *) AudioBuffer_p;          MP3Output_p->channels[1] = (void *)(AudioBuffer_p + 1); // 4 bytes per sample          break;        case kDecoderStatus_BrokenFrame:        case kDecoderStatus_FrameDiscarded:        case kDecoderStatus_CRCError:          // The only thing we can do about these errors          // is to skip to the next frame, just like the normal case,          // but also signal to the Controller, who may want to mute the output#if (DEBUG_INCLUDE_COUNTERS==1)          countMP3BadFrames++; // [RB]#endif          MP3DecoderNextState = searchingHeader;          break;        case kDecoderStatus_InvalidChannelConfiguration:        case kDecoderStatus_TooFewOutputChannels:        case kDecoderStatus_InvalidArgument:          break;        case kDecoderStatus_Fatal_Error:        case kDecoderStatus_Fatal_UnsupportedFeature:        case kDecoderStatus_Fatal_TooManyChannels:          // Cannot proceed, request upper layer to discard the file          MP3DecoderNextState = fatalError;          return decoderFatalError;        default:          break;        }        break;      } //case decodingFrames    case waitingAudioBuffer:      {        // Decoding of compressed data is going on, but the decoder        // ran out of space in the AudioBuffer. This means we        // decoding data faster than it is being consumed by        // the audio hardware. Return to caller to be put to sleep.        if ((AudioBuffer_p = AudioBufferHaveSpace(MP3Bitstream_p->sampleRate)) == NULL)        { //output buffer is full          return decoderWaitingABempty;        }        // re-set output pointers to consecutive AudioBuffer element        MP3Output_p->channels[0] = (void *) AudioBuffer_p;        MP3Output_p->channels[1] = (void *)(AudioBuffer_p + 1); // 4 bytes per sample        MP3DecoderNextState = NextStateAfterWaitAB;        break;      } //case waitingAudioBuffer    } //switch MP3DecoderNextState  } //while}void MP3Kill(DecoderKillType killType){  /*eDecoderStatus ret;*/         //[LL] TBD - could return something  if (killType == closeOnly)  {    /*ret = MP3DecoderCloseBitstream(MP3DecoderHandle, MP3Scratch_p);*/    MP3DecoderCloseBitstream(MP3DecoderHandle, MP3Scratch_p);    MP3DecoderNextState = notInitialized;  }  else if (killType == destroy)  {    //ret = MP3DecoderCloseBitstream(MP3DecoderHandle, MP3Scratch_p);    //MP3DecoderNextState = notInitialized;    //FREE(MP3Requirements_p->instanceStateSize);    //FREE(MP3Requirements_p->scratchSize);  }  FREE(MP3InstanceState_p);  FREE(MP3Scratch_p);  INIT_FAST_MALLOC();     //[LL] to ensure 1000% NONE items allocated}

⌨️ 快捷键说明

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