📄 id3tag.c
字号:
((int *)hdr)[1] = b3 | (b2<<8) | (b1<<16) | (b0<<24);#else ((int *)hdr)[1] = b0 | (b1<<8) | (b2<<16) | (b3<<24);#endif}// [RB] this function calls udivide() which is part of ARM MPEG library// [RB] so linking fails unless it is compiled in ARM mode#pragma PUSH#pragma ARMeDecoderStatus DecodeInfo2(sDecoderBitstream *bitstream, frame_params *fr_ps) //,t_SongInfos *songi){// frame_params *fr_ps = &Instance->fr_ps; layer *header = &fr_ps->header; tQuotient q; const char *bufptr; unsigned int packed_info, bits_required; unsigned int bitrate, numchans, rlay; //unsigned int free_format; // [RB] commented out to get rid of compiler warning unsigned int bitrate_index; unsigned int sample_index, sample_rate, version, lsf_bit, sfreq_group; unsigned int samplesPerFrame, bitsPerSlot; // Instance->gr = -1; fr_ps->samples_per_channel = 0; /* set length to zero in case of error */ /* * This is an internal function, which is only called if the * syncword has been located. Therefore, there is no need to * check for a syncword here. * * bufptr points to the beginning of the syncword. Ignore 11 * bits of syncword, and read the rest. */ bufptr = bitstream->data + bitstream->dataOffset; // pre-increment bufptr to ignore the first 8 bits of syncword packed_info = *++bufptr & 0x1f; // mask out remaining 3 bits of syncword packed_info = *++bufptr | (packed_info << 8); packed_info = *++bufptr | (packed_info << 8); //bitstream->dataOffset += 4; /* * Store packed info. */ #if ENABLECRC// Instance->crc_hdr_data = packed_info << 16;#endif /* * Decode the packed info bits into the frame header structure */ decode_packed_info(packed_info, header); sample_index = header->sampling_frequency; bitrate_index = header->bitrate_index; /* * Check for errors in the frame header */ if (sample_index==3) return kDecoderStatus_ReservedSamplingFrequency; if (bitrate_index==15) return kDecoderStatus_ReservedBitRate; if (hdr_to_frps2(fr_ps)) return kDecoderStatus_BrokenFrame; /* * Determine whether the frame is free format */ if (bitrate_index==0) { //free_format = 1; // [RB] unused bitrate_index = 14; } else { // free_format = 0; // [RB] unused //Instance->freeform_length = 0; } samplesPerFrame = 1152; bitsPerSlot = 8; version = header->version; lsf_bit = version & MPEG_VERSION_LSF_BIT; rlay = header->rlay; switch (rlay) {//#if INCLUDE_LAYER==LAYER1 case LAY1: samplesPerFrame = 384; bitsPerSlot = 32; break;//#endif//#if INCLUDE_LAYER==LAYER2 case LAY2: // samplesPerFrame = 1152; (default) // bitsPerSlot = 8; (default) break;//#endif//#if INCLUDE_LAYER==LAYER3 case LAY3: // samplesPerFrame = 1152; (default) // bitsPerSlot = 8; (default) if ( lsf_bit == 0) samplesPerFrame = 576; break;//#endif default: return kDecoderStatus_UnsupportedFeature; } /* * Report bitstream type (layer: eg. "MPG3") and bitrate. */ bitstream->bitstreamType = bitstreamTypes[rlay]; bitrate = 2000 * bitrate_div_2[lsf_bit][3 - rlay][bitrate_index]; bitstream->bitRate = bitrate; /* * Report sampling frequency */ sfreq_group = version; /* 0: LSF, 1: MPEG-1, 2: MPEG-2.5 */ sfreq_group = sfreq_group ^ 2; /* 0: MPEG-2.5, 2: LSF, 3: MPEG-1 */ if (sfreq_group) sfreq_group--; /* 0: MPEG-2.5, 1: LSF, 2: MPEG-1 */ // pmpeg_hdr->sample_rate = (tSampleRate)(sample_index + ( sfreq_group * 4) ); sample_rate = (unsigned int)s_freq_short[version][sample_index]; bitstream->sampleRate = (eDecoderSampleRate)sample_rate; #ifdef EVAL_VERSION if (sample_rate<=SR_22_05kHz) buzz_timing_shift = 1; if (sample_rate<=SR_11_025kHz) buzz_timing_shift = 2;#endif /* * Calculate the number of bits per frame: * * samples per frame * bitrate (bps) * Bits per frame = --------------------------------- + padding * samples per second (Hz) * * We have already consumed the frame header, so bits_required = Bits per frame - 32. * */ q = udivide( sample_rate, samplesPerFrame * bitrate ) ; if(rlay == LAY1) { //round to value devideable by 4 q.quotient >>= 5; q.quotient <<= 5; } bits_required = q.quotient - 32; if (header->padding) bits_required += bitsPerSlot; /* * Report bits required */ /*Instance->*/fr_ps->bytes_required = bitstream->frameRemain = bitstream->dataRequired = bits_required >> 3; /* * Report number of channels */ numchans = fr_ps->stereo; bitstream->channels.total = numchans; bitstream->channels.front = (unsigned char)numchans; bitstream->channels.side = 0; bitstream->channels.back = 0; bitstream->channels.lfe = 0; bitstream->formats.outputFormats = (bitstream->formats.outputFormats & OUTPUT_FORMAT_FLAGS_MASK) | numchans; /* * Report samples per channel */ /*Instance->*/ fr_ps->samples_per_channel = (short)samplesPerFrame; bitstream->samplesPerChannelPerFrame = samplesPerFrame; //songi->st_mode = (packed_info & 0xC0)>>6; //songi->emphasis = packed_info&3; return kDecoderStatus_NoError;}#pragma POPeDecoderStatus SearchForSyncword2( sDecoderBitstream *bitstream ){ const char *bufptr = bitstream->data + bitstream->dataOffset; int length = bitstream->dataLength - bitstream->dataOffset; int i; // The syncword must be fully contained within the buffer. Therefore it must start no // later than length - SYNCWORD_LEN_BYTES bytes from the start of the buffer. Note that // after subtracting SYNCWORD_LEN_BYTES, the inclusive range 0 ... length must be // searched, rather than 0 ... length-1. length -= 2; //SYNCWORD_LEN_BYTES; if (length < 0) { // Buffer too small--simply return the bitstream structure unmodified. return kDecoderStatus_MoreData; } // Main search for syncword i=length+1; do { int byte = *bufptr++; if (byte == 0xff) { // The first eight bits are all ones... byte = *bufptr; if ((byte & 0xe0) == 0xe0) { // ... and the next three bits are all ones, so have found a syncword at bufptr-1. bitstream->dataOffset = bitstream->headerOffset = bufptr - 1 - bitstream->data; return kDecoderStatus_NoError; } } } while (--i); // No syncword was found. bitstream->dataOffset += length; // at SYNCWORD_LEN_BYTES before the end of the input return kDecoderStatus_MoreData; //kDecoderStatus_NoFrameHeader;}GRESULT GetBitRate(t_SongInfos *songi){sDecoderBitstream bitstr;frame_params fr_pars;int framelen = 0;eDecoderStatus status;int framesOK = 0; // tells if frame comes immediately after pevious one//int frameCheck = 1; int bitrsum = 0;int bitrcnt = 0;int skip = 0;int offs,lastOffset=-1;int last_parse_offset,n;GRESULT res;uint8 *buffer = filesys_sectbuf; if (0 > XAR_SeekFile(songi, songi->parse_offset, 0)) { return E_INVALID_CACHE_SEEK; } songi->bitrate = 0; bitstr.data = (char*)buffer; bitstr.dataOffset = 0; //2048; bitstr.dataLength = 0; //2048; // read first data chunk, it can be less than 2K if file is very short res = XAR_ReadFile (songi, buffer, 2048,IO_READ_CACHE); if (!res) return E_READ_FAILURE; else bitstr.dataLength += res; do { if(bitstr.dataLength < 4096) // test if new data filling necessary { if(songi->parse_stop>songi->position) { // OT 301006 res = XAR_ReadFile (songi, buffer+bitstr.dataLength,\ wmin(4096-bitstr.dataLength, songi->parse_stop - songi->position),\ IO_READ_CACHE); // DBG_PRINTF("Reading file %d bytes\r\n",res); if(res) bitstr.dataLength += res; else return E_READ_FAILURE; } } if(!skip) { offs = bitstr.dataOffset; status = SearchForSyncword2(&bitstr); if(bitstr.dataOffset - offs) { // DBG_PRINTF("Syncword not found\r\n"); framesOK = 0; if(lastOffset>=0) { // DBG_PRINTF("Reset last position %d - %d \r\n",lastOffset,last_parse_offset); songi->parse_offset = last_parse_offset; bitstr.dataOffset = lastOffset; lastOffset = -1; skip = 2; } else { songi->parse_offset += (bitstr.dataOffset - offs); } } } if(!skip) { offs = bitstr.dataOffset + 4 ; //MP3_HEADER_SIZE_BYTES; // end of header if((status == kDecoderStatus_NoError) && (offs < bitstr.dataLength)) { status = DecodeInfo2(&bitstr,&fr_pars); //,songi); if (status == kDecoderStatus_NoError) { // DBG_PRINTF("Good syncword at position %d - %d \r\n",bitstr.dataOffset,songi->parse_offset); if((lastOffset<0)||(framesOK)) { lastOffset = bitstr.dataOffset + 1; // remember position for new sync search last_parse_offset = songi->parse_offset + 1; } framesOK++; if(framesOK>1) { bitrsum += bitstr.bitRate; bitrcnt++; songi->ch_num = bitstr.channels.total; songi->sampling_fr = bitstr.sampleRate; songi->bitstreamType = bitstr.bitstreamType; songi->st_mode = (buffer[bitstr.dataOffset+3] & 0xC0)>>6; songi->emphasis = buffer[bitstr.dataOffset+3] & 3; } framelen = 4 + fr_pars.bytes_required; skip = 1; } else // wrong header found { // DBG_PRINTF("Wrong Syncword found\r\n"); if(lastOffset>=0) { songi->parse_offset = last_parse_offset; bitstr.dataOffset = lastOffset; lastOffset = -1; } else { bitstr.dataOffset++; songi->parse_offset++; } framesOK = 0; } } } else // skip { if(skip==1) { if((framelen>4090)||(songi->parse_offset+framelen+4 >= songi->parse_stop )) break; if(bitstr.dataOffset + framelen < bitstr.dataLength) { // DBG_PRINTF("Skip whole Syncword: %d + %d \r\n",bitstr.dataOffset, framelen); bitstr.dataOffset += framelen; skip = 0; songi->parse_offset += framelen; //XAR_SeekFile (song_info, song_info->parse_offset,0); } } else { // jump back skip = 0; } } if(( bitstr.dataOffset >= lastOffset)&&(lastOffset>3)) { n = lastOffset & (~3); if(n>=128) { lastOffset -= n;//shift_dat: memcpy(buffer,buffer + n, bitstr.dataLength - n); bitstr.dataOffset -= n; bitstr.dataLength -= n; } //DBG_PRINTF("Copy down %d\r\n",n); } else { if(/*(lastOffset<0)&&*/(bitstr.dataOffset>3)) { n = bitstr.dataOffset&(~3) ; //goto shift_dat; if(n>=128) { if((lastOffset>=n)||(lastOffset<0)) { if(lastOffset>=0) lastOffset -= n; memcpy(buffer,buffer + n, bitstr.dataLength - n); bitstr.dataOffset -= n; bitstr.dataLength -= n; } } } } }while(songi->parse_offset < (songi->parse_stop - 4)); // MP3_HEADER_SIZE_BYTES if(bitrcnt) { songi->bitrate = ((bitrsum/bitrcnt)>>3); DBG_PRINTF("Bitrate %d \r\n",songi->bitrate); DBG_PRINTF("Num. of ch. %d \r\n",songi->ch_num); DBG_PRINTF("Fs %d \r\n",songi->sampling_fr); //DBG_PRINTF("Bitstream type %d \r\n",songi->bitstreamType); return S_OK; } return E_FAIL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -