📄 wmawrap.c
字号:
SizeOfChannel = AUDIO_BUFFER_ELEMENT_LENGTH / 2; /* for (the same amount) stereo samples */ break; case cWMA_C_Stereo: //1.SizeOfChannel = AUDIO_BUFFER_ELEMENT_LENGTH*4; SizeOfChannel = AUDIO_BUFFER_ELEMENT_LENGTH; break; default: return decoderFatalError; } /* AB can hold up to "tmp" decoded stereo samples */#if 0 /* reduction 2 */ tmp = SizeOfChannel >> MemoryUsage; /* 2 means each second U16word 0x0000 is redundancy - LL00RR00(hex) */#else /* reduction 2 */ tmp = SizeOfChannel >> 1; /* this is real size of the AB element in stereo samples */#endif /* reduction 2 */ if (nSamplesToTake > tmp) /* to provide the last chunk will be of maximum length */ nSamplesToTake -= tmp; nRemainingStereoSamples = nSamplesToTake % tmp; if (nRemainingStereoSamples != 0) /* doesn't fit to AB data buffer all at once */ { if (nRemainingStereoSamples < AB_UNDERFLOW_LIMIT) nSamplesToTake = AB_UNDERFLOW_LIMIT; else nSamplesToTake = nRemainingStereoSamples; } else { /* fits to AB data buffer */ nSamplesToTake = tmp; } /* Data interleaved into AudioBuffer_p. Right channel doesn't exist (NULL). */ num_samples_stereo = WMAFileGetPCM (iWMA_state, (tWMA_I16 *)AudioBuffer_p, NULL, SizeOfChannel*sizeof(AudioBufferData), nSamplesToTake, ptPresTime); /* duplicate mono data */ if (NoOfChannels == cWMA_C_Mono) {/* for (count = (uint32)SizeOfChannel - 1; count >= 0; count--) { AudioBuffer_p[count * 2] = AudioBuffer_p[count]; AudioBuffer_p[count * 2 + 1] = AudioBuffer_p[count]; }*/ //count=(uint32)SizeOfChannel - 1; pAudioBuffer_src = AudioBuffer_p + (uint32)SizeOfChannel - 1; pAudioBuffer_dst = AudioBuffer_p + 2*(uint32)SizeOfChannel - 1; do { AudioBufferTmp = *pAudioBuffer_src--; *pAudioBuffer_dst-- = AudioBufferTmp; *pAudioBuffer_dst-- = AudioBufferTmp; //count--; } while (pAudioBuffer_src != AudioBuffer_p); AudioBufferTmp = *pAudioBuffer_src--; *pAudioBuffer_dst-- = AudioBufferTmp; *pAudioBuffer_dst-- = AudioBufferTmp; } return num_samples_stereo;}/************************************* WMADecode()** Description:** Starts or resumes wma decoding.*************************************/decoderReturnType WMADecode(int flag){ int cCountGetPCM = 0; //float fltDiff; //float fltTimeExpected = 0; //float fltDiffMax = 0.0F; tWMAFileStatus rc; tWMA_U32 num_samples; tWMA_I64 tPresTime; pAudioBufferData AudioBuffer_p; static ElementFlagType nextABElementFlag; /* time info */ uint32 tPresTimeMiliSec; tDecoderTime_event time_event; static uint32 unreported_subcode_event_type; static uint32 LastReportedFragment; uint32 Fragment; t_position position; // uint32 CurrentBitRate; // [RB] unused // uint32 CurrentFilePosAfterTAG; // [RB] unused tWMAFileStateInternal *pInt; /* reset global values for each file call. */ g_ulOutputSamples = 0; /* decoding loop */ while (1) { switch (WMADecoderNextState) { case notInitialized: { WMA_FBufferRemain = 0; WMA_DecodedSamples = 0; WMA_FetchedSamples = 0; /* header length is equal to payload offset */ WMA_PlusFBufferOffset = (*((tWMAFileStateInternal *)*WMA_pStateDecoder)).hdr_parse.cbHeader; g_FB_clearFrom = (g_FB_readFrom % FrameBufferElements) + 1; nextABElementFlag = FT_FIRST; /* reset last WMABufferElement, not to copy the last */ WMABufferElement = FrameBuffer[0]; unreported_subcode_event_type = 0; /* obtain asf_header information from Controller now in 'wmaudio.c' part of WMAInit() */ WMADecoderNextState = waitingFBreadyAfterFS;#if (WMA_WRAP_DEBUG != 0) WMADecodeDBG.prev_offset = 0;#endif /*WMA_WRAP_DEBUG*/#if (IN_BUF != 0) pFBTmpBuf = FBTmpBuf; FBTmpCount = 0;#endif /*IN_BUF*/ break; } case waitingFrameData: /* Falls into */ case decodingFrames: /* See WMAFileFBGetData for details */ { /* check whether there was Controller request to stop (NEXT/PREV/STOP/FF/FR) */ if (decoderStopRequest()) { return decoderEOF_immediate; }#if (WMA_WRAP_DEBUG != 0) // set_gpio(PORT_B, GPIO_4, TRUE);#endif /*WMA_WRAP_DEBUG*/ rc = WMAFileDecodeData(*WMA_pStateDecoder, &WMA_DecodedSamples); if (rc != cWMA_NoErr) { // store event time not to lose it (if error) unreported_subcode_event_type |= WMABufferElement.subcode.event_type; if (rc == cWMA_FBEnotReady) /* FrameBufferElement not ready */ { if (WMABufferElement.ElementFlag == FT_LAST) { /* for fast seek, not whole file read, but there is nothing to play */ /* force wma decoder to be killed */ WMABufferElement.ElementFlag = FT_MIDDLE; WMADecoderNextState = notInitialized; return decoderEOF; } else return decoderWaitingFBdata; /* goto sleep */ }/* if ( rc == cWMA_NoMoreFrames || rc == cWMA_Failed ) { WMADecoderNextState = notInitialized; return decoderEOF; // * close bitstream... } else if(rc == cWMA_FBElastFS)*/ if (rc == cWMA_FBElastFS) { /* fast seek mode, reset wma decoder, continue with next playable part */ WMADecoderNextState = waitingFBreadyAfterFS; break; } else { //natural EOF declared by decoder or error //return decoderFatalError; pInt = (tWMAFileStateInternal *)*WMA_pStateDecoder; // seek to the next packet in case of corrupted bitstream if (audecReset(pInt->hWMA) != WMA_OK) return decoderFatalError; pInt->audecState = audecStateInput; (pInt->hdr_parse.currPacketOffset)++; //pInt->hdr_parse.cbPacketSize; pInt->hdr_parse.nextPacketOffset = pInt->hdr_parse.currPacketOffset; /* if (pInt->hdr_parse.nextPacketOffset > pInt->hdr_parse.cbLastPacketOffset) { // there are no next packets in the file to be decoded WMADecoderNextState = notInitialized; return decoderEOF; // close bitstream... }*/ pInt->parse_state = csWMA_NewAsfPacket; ((tWMAFileHdrStateInternal *)(&WMA_HdrState))->currPacketOffset = pInt->hdr_parse.currPacketOffset; ((tWMAFileHdrStateInternal *)(&WMA_HdrState))->nextPacketOffset = pInt->hdr_parse.currPacketOffset; pInt->g_PayloadHeaderState = 0; pInt->g_PacketHeaderState = 0; WaitingMode = 0; WMADecoderNextState = decodingFrames; break; } } WMA_FetchedSamples = 0; WMADecoderNextState = waitingAudioBuffer; break; } case waitingFBreadyAfterFS: /* check if next FB element is prepared, but do not update read pointer */ if (FrameBufferGetData(&WMABufferElement, 0) == fbDataReady) { LastReportedFragment = 0xFFFFFFFF; //to ensure to report time next time WMABufferElement.ElementFlag = FT_MIDDLE; /* not to be checked inside WMAFileFBGetData() */ pInt = (tWMAFileStateInternal *)*WMA_pStateDecoder; if (audecReset(pInt->hWMA) != WMA_OK) return decoderFatalError; pInt->audecState = audecStateInput; pInt->hdr_parse.currPacketOffset = WMABufferElement.startOffset - WMABufferElement.availableDataLength; pInt->hdr_parse.nextPacketOffset = pInt->hdr_parse.currPacketOffset; pInt->parse_state = csWMA_NewAsfPacket; pInt->g_PayloadHeaderState = 0; pInt->g_PacketHeaderState = 0; ((tWMAFileHdrStateInternal *)(&WMA_HdrState))->currPacketOffset = pInt->hdr_parse.currPacketOffset; ((tWMAFileHdrStateInternal *)(&WMA_HdrState))->nextPacketOffset = pInt->hdr_parse.currPacketOffset; WMA_PlusFBufferOffset = 0; WMADecoderNextState = waitingFrameData; break; } return decoderWaitingFBdata; case waitingAudioBuffer: { do { /* check whether there was Controller request to stop (NEXT/PREV/STOP/FF/FR) */ if (decoderStopRequest()) { return decoderEOF_immediate; } pInt = (tWMAFileStateInternal *)*WMA_pStateDecoder; if (pInt->audecState != audecStateGetPCM) { /* [OK] if we are not in the audecStateGetPCM, there is nothing to be written to AudioBuffer. Continue with decoding. */ unreported_subcode_event_type |= WMABufferElement.subcode.event_type; break; } /* Now test if there is enought space for next output */ AudioBuffer_p = AudioBufferHaveSpace((eDecoderSampleRate) WMA_SampleRate); if (AudioBuffer_p == NULL) { /* Return immediately so we go to sleep again. */ return decoderWaitingABempty; } tPresTime = 0; //fltDiff = 0; cCountGetPCM++; /* take decoded data */ // [OK] num_samples = WMAFileGetPCM (WMA_state, WMA_pLeft, WMA_pRight, sizeof(WMA_pLeft), // WMA_DecodedSamples - WMA_FetchedSamples, &tPresTime); num_samples = WMAGetStereoData(*WMA_pStateDecoder, AudioBuffer_p, WMA_DecodedSamples - WMA_FetchedSamples, &tPresTime);#if (WMA_WRAP_DEBUG != 0) if (WMA_DecodedSamples > AUDIO_BUFFER_ELEMENT_LENGTH/2) set_gpio(PORT_B, GPIO_4, TRUE); WMADecodeDBG.num_samples_tmp_buf[WMADecodeDBG.count1] = num_samples; WMADecodeDBG.g_nDecSamples[WMADecodeDBG.count1++] = WMA_DecodedSamples - WMA_FetchedSamples; WMADecodeDBG.count1 %= NUM_SAMPLES_TMP_BUF_LEN; WMADecodeDBG.num_samples_tmp_buf[WMADecodeDBG.count1] = 0; WMADecodeDBG.g_nDecSamples[WMADecodeDBG.count1] = 0; if (WMADecodeDBG.max_num_samples < WMA_DecodedSamples) WMADecodeDBG.max_num_samples = WMA_DecodedSamples; //DBG_PRINTF("WMA: GetPCM() - %d", num_samples);#endif /*WMA_WRAP_DEBUG*/ if (num_samples != 0) { time_event.subcode.event_type = CAPTURE_EVENT_SUBCODE_NONE; tPresTimeMiliSec = (tPresTime + 5000) / 10000; /* round to miliseconds */ Fragment = tPresTimeMiliSec / DECODER_TIME_INTERVAL; if (Fragment != LastReportedFragment) { WMABufferElement.subcode.event_type |= CAPTURE_EVENT_SUBCODE_REL_TIME; LastReportedFragment = Fragment; } GetCurrentPosition(&position); // xid,playlist position.offset = GetDecodedBytes(); // if error occured before, now attach the last event WMABufferElement.subcode.event_type |= unreported_subcode_event_type; if (WMABufferElement.subcode.event_type
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -