📄 parse.c
字号:
/* flip/init buffer for Layer 3 */ { unsigned char *newbuf = fr->bsspace[fr->bsnum]+512; /* read main data into memory */ if((ret=fr->rd->read_frame_body(fr,newbuf,fr->framesize))<0) { /* if failed: flip back */ debug("need more?"); goto read_frame_bad; } fr->bsbufold = fr->bsbuf; fr->bsbuf = newbuf; } fr->bsnum = (fr->bsnum + 1) & 1; if(!fr->firsthead) { /* In practice, Xing/LAME tags are layer 3 only. */ if(fr->lay == 3 && check_lame_tag(fr) == 1) { if(fr->rd->forget != NULL) fr->rd->forget(fr); fr->oldhead = 0; goto read_again; } fr->firsthead = newhead; /* _now_ it's time to store it... the first real header */ debug1("fr->firsthead: %08lx", fr->firsthead); /* now adjust volume */ do_rva(fr); } fr->bitindex = 0; fr->wordpointer = (unsigned char *) fr->bsbuf; if(++fr->mean_frames != 0) { fr->mean_framesize = ((fr->mean_frames-1)*fr->mean_framesize+compute_bpf(fr)) / fr->mean_frames ; } ++fr->num; /* 0 for first frame! */ debug4("Frame %li %08lx %i, next filepos=0x%lx", (long)fr->num, newhead, fr->framesize, (long unsigned)fr->rd->tell(fr)); /* save for repetition */ if(fr->p.halfspeed && fr->lay == 3) { debug("halfspeed - reusing old bsbuf "); memcpy (fr->ssave, fr->bsbuf, fr->ssize); } /* index the position */ if(INDEX_SIZE > 0 && fr->rdat.flags & READER_SEEKABLE) /* any sane compiler should make a no-brainer out of this */ { if(fr->num == fr->index.fill*fr->index.step) { if(fr->index.fill == INDEX_SIZE) { size_t c; /* increase step, reduce fill */ fr->index.step *= 2; fr->index.fill /= 2; /* divisable by 2! */ for(c = 0; c < fr->index.fill; ++c) { fr->index.data[c] = fr->index.data[2*c]; } } if(fr->num == fr->index.fill*fr->index.step) { fr->index.data[fr->index.fill] = framepos; ++fr->index.fill; } } } if(fr->rd->forget != NULL) fr->rd->forget(fr); fr->to_decode = fr->to_ignore = TRUE; if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */ return 1;read_frame_bad: if(fr->err == MPG123_OK) fr->err = MPG123_ERR_READER; fr->framesize = oldsize; fr->halfphase = oldphase; return ret;}/* * decode a header and write the information * into the frame structure */static int decode_header(mpg123_handle *fr,unsigned long newhead){ if(!head_check(newhead)) { if(NOQUIET) error("tried to decode obviously invalid header"); return 0; } if( newhead & (1<<20) ) { fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1; fr->mpeg25 = 0; } else { fr->lsf = 1; fr->mpeg25 = 1; } if ((fr->p.flags & MPG123_NO_RESYNC) || !fr->oldhead || (((fr->oldhead>>19)&0x3) ^ ((newhead>>19)&0x3))) { /* If "tryresync" is false, assume that certain parameters do not change within the stream! Force an update if lsf or mpeg25 settings have changed. */ fr->lay = 4-((newhead>>17)&3); if( ((newhead>>10)&0x3) == 0x3) { if(NOQUIET) error("Stream error"); return 0; /* exit() here really is too much, isn't it? */ } if(fr->mpeg25) { fr->sampling_frequency = 6 + ((newhead>>10)&0x3); } else fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3); } #ifdef DEBUG if((((newhead>>16)&0x1)^0x1) != fr->error_protection) debug("changed crc bit!"); #endif fr->error_protection = ((newhead>>16)&0x1)^0x1; /* seen a file where this varies (old lame tag without crc, track with crc) */ fr->bitrate_index = ((newhead>>12)&0xf); fr->padding = ((newhead>>9)&0x1); fr->extension = ((newhead>>8)&0x1); fr->mode = ((newhead>>6)&0x3); fr->mode_ext = ((newhead>>4)&0x3); fr->copyright = ((newhead>>3)&0x1); fr->original = ((newhead>>2)&0x1); fr->emphasis = newhead & 0x3; fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2; fr->oldhead = newhead; if(!fr->bitrate_index) { if(NOQUIET) error1("encountered free format header %08lx in decode_header - not supported yet",newhead); return (0); } switch(fr->lay) { case 1: fr->do_layer = do_layer1;#ifdef VARMODESUPPORT if (varmode) { if(NOQUIET) error("Sorry, layer-1 not supported in varmode."); return (0); }#endif fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000; fr->framesize /= freqs[fr->sampling_frequency]; fr->framesize = ((fr->framesize+fr->padding)<<2)-4; break; case 2: fr->do_layer = do_layer2;#ifdef VARMODESUPPORT if (varmode) { if(NOQUIET) error("Sorry, layer-2 not supported in varmode."); return (0); }#endifdebug2("bitrate index: %i (%i)", fr->bitrate_index, tabsel_123[fr->lsf][1][fr->bitrate_index] ); fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000; fr->framesize /= freqs[fr->sampling_frequency]; fr->framesize += fr->padding - 4; break; case 3: fr->do_layer = do_layer3; if(fr->lsf) fr->ssize = (fr->stereo == 1) ? 9 : 17; else fr->ssize = (fr->stereo == 1) ? 17 : 32; if(fr->error_protection) fr->ssize += 2; fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000; fr->framesize /= freqs[fr->sampling_frequency]<<(fr->lsf); fr->framesize = fr->framesize + fr->padding - 4; break; default: if(NOQUIET) error("unknown layer type (!!)"); return (0); } if (fr->framesize > MAXFRAMESIZE) { if(NOQUIET) error1("Frame size too big: %d", fr->framesize+4-fr->padding); return (0); } return 1;}void set_pointer(mpg123_handle *fr, long backstep){ fr->wordpointer = fr->bsbuf + fr->ssize - backstep; if (backstep) memcpy(fr->wordpointer,fr->bsbufold+fr->fsizeold-backstep,backstep); fr->bitindex = 0; }/********************************/double compute_bpf(mpg123_handle *fr){ double bpf; switch(fr->lay) { case 1: bpf = tabsel_123[fr->lsf][0][fr->bitrate_index]; bpf *= 12000.0 * 4.0; bpf /= freqs[fr->sampling_frequency] <<(fr->lsf); break; case 2: case 3: bpf = tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index]; bpf *= 144000; bpf /= freqs[fr->sampling_frequency] << (fr->lsf); break; default: bpf = 1.0; } return bpf;}double mpg123_tpf(mpg123_handle *fr){ static int bs[4] = { 0,384,1152,1152 }; double tpf; if(fr == NULL) return -1; tpf = (double) bs[fr->lay]; tpf /= freqs[fr->sampling_frequency] << (fr->lsf); return tpf;}int mpg123_position(mpg123_handle *fr, off_t no, off_t buffsize, off_t *current_frame, off_t *frames_left, double *current_seconds, double *seconds_left){ double tpf; double dt = 0.0; off_t cur, left; double curs, lefts; if(!fr || !fr->rd) /* Isn't this too paranoid? */ { debug("reader troubles!"); return MPG123_ERR; } no += fr->num; /* no starts out as offset */ cur = no; tpf = mpg123_tpf(fr); if(buffsize > 0 && fr->af.rate > 0 && fr->af.channels > 0) { dt = (double) buffsize / fr->af.rate / fr->af.channels; if(fr->af.encoding & MPG123_ENC_16) dt *= 0.5; } left = 0; if((fr->track_frames != 0) && (fr->track_frames >= fr->num)) left = no < fr->track_frames ? fr->track_frames - no : 0; else if(fr->rdat.filelen >= 0) { double bpf; off_t t = fr->rd->tell(fr); bpf = fr->mean_framesize ? fr->mean_framesize : compute_bpf(fr); left = (off_t)((double)(fr->rdat.filelen-t)/bpf); /* no can be different for prophetic purposes, file pointer is always associated with fr->num! */ if(fr->num != no) { if(fr->num > no) left += fr->num - no; else { if(left >= (no - fr->num)) left -= no - fr->num; else left = 0; /* uh, oh! */ } } /* I totally don't understand why we should re-estimate the given correct(?) value */ /* fr->num = (unsigned long)((double)t/bpf); */ } /* beginning with 0 or 1?*/ curs = (double) no*tpf-dt; lefts = (double)left*tpf+dt;#if 0 curs = curs < 0 ? 0.0 : curs;#endif if(left < 0 || lefts < 0) { /* That is the case for non-seekable streams. */ left = 0; lefts = 0.0; } if(current_frame != NULL) *current_frame = cur; if(frames_left != NULL) *frames_left = left; if(current_seconds != NULL) *current_seconds = curs; if(seconds_left != NULL) *seconds_left = lefts; return MPG123_OK;}int get_songlen(mpg123_handle *fr,int no){ double tpf; if(!fr) return 0; if(no < 0) { if(!fr->rd || fr->rdat.filelen < 0) return 0; no = (double) fr->rdat.filelen / compute_bpf(fr); } tpf = mpg123_tpf(fr); return no*tpf;}/* take into account: channels, bytes per sample -- NOT resampling!*/off_t samples_to_bytes(mpg123_handle *fr , off_t s){ return s#ifdef FLOATOUT * 4#else * ((fr->af.encoding & MPG123_ENC_16) ? 2 : 1)#endif * fr->af.channels;}off_t bytes_to_samples(mpg123_handle *fr , off_t b){ return b#ifdef FLOATOUT / 4#else / ((fr->af.encoding & MPG123_ENC_16) ? 2 : 1)#endif / fr->af.channels;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -