Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenparse.c
Go to the documentation of this file.
00001 /* 00002 parse: spawned from common; clustering around stream/frame parsing 00003 00004 copyright ?-2009 by the mpg123 project - free software under the terms of the LGPL 2.1 00005 see COPYING and AUTHORS files in distribution or http://mpg123.org 00006 initially written by Michael Hipp & Thomas Orgis 00007 */ 00008 00009 #include "mpg123lib_intern.h" 00010 00011 #include <sys/stat.h> 00012 #include <fcntl.h> 00013 00014 #include "getbits.h" 00015 00016 #if defined (WANT_WIN32_SOCKETS) 00017 #include <winsock2.h> 00018 #include <ws2tcpip.h> 00019 #endif 00020 00021 /* a limit for number of frames in a track; beyond that unsigned long may not be enough to hold byte addresses */ 00022 #ifdef HAVE_LIMITS_H 00023 #include <limits.h> 00024 #endif 00025 #ifndef ULONG_MAX 00026 /* hm, is this portable across preprocessors? */ 00027 #define ULONG_MAX ((unsigned long)-1) 00028 #endif 00029 #define TRACK_MAX_FRAMES ULONG_MAX/4/1152 00030 00031 #include "debug.h" 00032 00033 #define bsbufid(fr) (fr)->bsbuf==(fr)->bsspace[0] ? 0 : ((fr)->bsbuf==fr->bsspace[1] ? 1 : ( (fr)->bsbuf==(fr)->bsspace[0]+512 ? 2 : ((fr)->bsbuf==fr->bsspace[1]+512 ? 3 : -1) ) ) 00034 00035 /* 00036 AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM 00037 A: sync 00038 B: mpeg version 00039 C: layer 00040 D: CRC 00041 E: bitrate 00042 F:sampling rate 00043 G: padding 00044 H: private 00045 I: channel mode 00046 J: mode ext 00047 K: copyright 00048 L: original 00049 M: emphasis 00050 00051 old compare mask 0xfffffd00: 00052 11111111 11111111 11111101 00000000 00053 00054 means: everything must match excluding padding and channel mode, ext mode, ... 00055 But a vbr stream's headers will differ in bitrate! 00056 We are already strict in allowing only frames of same type in stream, we should at least watch out for VBR while being strict. 00057 00058 So a better mask is: 00059 11111111 11111111 00001101 00000000 00060 00061 Even more, I'll allow varying crc bit. 00062 11111111 11111110 00001101 00000000 00063 00064 (still unsure about this private bit) 00065 */ 00066 #define HDRCMPMASK 0xfffe0d00 00067 #define HDRSAMPMASK 0xc00 /* 1100 00000000, FF bits (sample rate) */ 00068 00069 /* bitrates for [mpeg1/2][layer] */ 00070 static const int tabsel_123[2][3][16] = 00071 { 00072 { 00073 {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, 00074 {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, 00075 {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} 00076 }, 00077 { 00078 {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,}, 00079 {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,}, 00080 {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} 00081 } 00082 }; 00083 00084 const long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 }; 00085 00086 static int decode_header(mpg123_handle *fr,unsigned long newhead); 00087 00088 /* These two are to be replaced by one function that gives all the frame parameters (for outsiders).*/ 00089 00090 int frame_bitrate(mpg123_handle *fr) 00091 { 00092 return tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index]; 00093 } 00094 00095 long frame_freq(mpg123_handle *fr) 00096 { 00097 return freqs[fr->sampling_frequency]; 00098 } 00099 00100 #define free_format_header(head) ( ((head & 0xffe00000) == 0xffe00000) && ((head>>17)&3) && (((head>>12)&0xf) == 0x0) && (((head>>10)&0x3) != 0x3 )) 00101 00102 /* compiler is smart enought to inline this one or should I really do it as macro...? */ 00103 int head_check(unsigned long head) 00104 { 00105 if 00106 ( 00107 /* first 11 bits are set to 1 for frame sync */ 00108 ((head & 0xffe00000) != 0xffe00000) 00109 || 00110 /* layer: 01,10,11 is 1,2,3; 00 is reserved */ 00111 (!((head>>17)&3)) 00112 || 00113 /* 1111 means bad bitrate */ 00114 (((head>>12)&0xf) == 0xf) 00115 || 00116 /* sampling freq: 11 is reserved */ 00117 (((head>>10)&0x3) == 0x3 ) 00118 /* here used to be a mpeg 2.5 check... re-enabled 2.5 decoding due to lack of evidence that it is really not good */ 00119 ) 00120 { 00121 return FALSE; 00122 } 00123 /* if no check failed, the header is valid (hopefully)*/ 00124 else 00125 { 00126 return TRUE; 00127 } 00128 } 00129 00130 static int check_lame_tag(mpg123_handle *fr) 00131 { 00132 /* 00133 going to look for Xing or Info at some position after the header 00134 MPEG 1 MPEG 2/2.5 (LSF) 00135 Stereo, Joint Stereo, Dual Channel 32 17 00136 Mono 17 9 00137 00138 Also, how to avoid false positives? I guess I should interpret more of the header to rule that out(?). 00139 I hope that ensuring all zeros until tag start is enough. 00140 */ 00141 int lame_offset = (fr->stereo == 2) ? (fr->lsf ? 17 : 32 ) : (fr->lsf ? 9 : 17); 00142 /* At least skip the decoder delay. */ 00143 #ifdef GAPLESS 00144 if(fr->p.flags & MPG123_GAPLESS) 00145 { 00146 if(fr->begin_s == 0) frame_gapless_init(fr, GAPLESS_DELAY, 0); 00147 } 00148 #endif 00149 00150 if(fr->framesize >= 120+lame_offset) /* traditional Xing header is 120 bytes */ 00151 { 00152 int i; 00153 int lame_type = 0; 00154 debug("do we have lame tag?"); 00155 /* only search for tag when all zero before it (apart from checksum) */ 00156 for(i=2; i < lame_offset; ++i) if(fr->bsbuf[i] != 0) break; 00157 if(i == lame_offset) 00158 { 00159 debug("possibly..."); 00160 if 00161 ( 00162 (fr->bsbuf[lame_offset] == 'I') 00163 && (fr->bsbuf[lame_offset+1] == 'n') 00164 && (fr->bsbuf[lame_offset+2] == 'f') 00165 && (fr->bsbuf[lame_offset+3] == 'o') 00166 ) 00167 { 00168 lame_type = 1; /* We still have to see what there is */ 00169 } 00170 else if 00171 ( 00172 (fr->bsbuf[lame_offset] == 'X') 00173 && (fr->bsbuf[lame_offset+1] == 'i') 00174 && (fr->bsbuf[lame_offset+2] == 'n') 00175 && (fr->bsbuf[lame_offset+3] == 'g') 00176 ) 00177 { 00178 lame_type = 2; 00179 fr->vbr = MPG123_VBR; /* Xing header means always VBR */ 00180 } 00181 if(lame_type) 00182 { 00183 unsigned long xing_flags; 00184 00185 /* we have one of these headers... */ 00186 if(VERBOSE2) fprintf(stderr, "Note: Xing/Lame/Info header detected\n"); 00187 /* now interpret the Xing part, I have 120 bytes total for sure */ 00188 /* there are 4 bytes for flags, but only the last byte contains known ones */ 00189 lame_offset += 4; /* now first byte after Xing/Name */ 00190 /* 4 bytes dword for flags */ 00191 #define make_long(a, o) ((((unsigned long) a[o]) << 24) | (((unsigned long) a[o+1]) << 16) | (((unsigned long) a[o+2]) << 8) | ((unsigned long) a[o+3])) 00192 /* 16 bit */ 00193 #define make_short(a,o) ((((unsigned short) a[o]) << 8) | ((unsigned short) a[o+1])) 00194 xing_flags = make_long(fr->bsbuf, lame_offset); 00195 lame_offset += 4; 00196 debug1("Xing: flags 0x%08lx", xing_flags); 00197 if(xing_flags & 1) /* frames */ 00198 { 00199 if(fr->p.flags & MPG123_IGNORE_STREAMLENGTH) 00200 { 00201 if(VERBOSE3) 00202 fprintf(stderr, "Note: Ignoring Xing frames because of MPG123_IGNORE_STREAMLENGTH\n"); 00203 } 00204 else 00205 { 00206 /* 00207 In theory, one should use that value for skipping... 00208 When I know the exact number of samples I could simply count in flush_output, 00209 but that's problematic with seeking and such. 00210 I still miss the real solution for detecting the end. 00211 */ 00212 fr->track_frames = (off_t) make_long(fr->bsbuf, lame_offset); 00213 if(fr->track_frames > TRACK_MAX_FRAMES) fr->track_frames = 0; /* endless stream? */ 00214 #ifdef GAPLESS 00215 /* if no further info there, remove/add at least the decoder delay */ 00216 if(fr->p.flags & MPG123_GAPLESS) 00217 { 00218 off_t length = fr->track_frames * spf(fr); 00219 if(length > 1) 00220 frame_gapless_init(fr, GAPLESS_DELAY, length+GAPLESS_DELAY); 00221 } 00222 #endif 00223 if(VERBOSE3) fprintf(stderr, "Note: Xing: %lu frames\n", (long unsigned)fr->track_frames); 00224 } 00225 00226 lame_offset += 4; 00227 } 00228 if(xing_flags & 0x2) /* bytes */ 00229 { 00230 if(fr->p.flags & MPG123_IGNORE_STREAMLENGTH) 00231 { 00232 if(VERBOSE3) 00233 fprintf(stderr, "Note: Ignoring Xing bytes because of MPG123_IGNORE_STREAMLENGTH\n"); 00234 } 00235 else 00236 { 00237 unsigned long xing_bytes = make_long(fr->bsbuf, lame_offset); /* We assume that this is the _total_ size of the file, including Xing frame ... and ID3 frames... 00238 It's not that clearly documented... */ 00239 if(fr->rdat.filelen < 1) 00240 fr->rdat.filelen = (off_t) xing_bytes; /* One could start caring for overflow here. */ 00241 else 00242 { 00243 if((off_t) xing_bytes != fr->rdat.filelen && NOQUIET) 00244 { 00245 double diff = 1.0/fr->rdat.filelen * (fr->rdat.filelen - (off_t)xing_bytes); 00246 if(diff < 0.) diff = -diff; 00247 00248 if(VERBOSE3) 00249 fprintf(stderr, "Note: Xing stream size %lu differs by %f%% from determined/given file size!\n", xing_bytes, diff); 00250 00251 if(diff > 1.) 00252 fprintf(stderr, "Warning: Xing stream size off by more than 1%%, fuzzy seeking may be even more fuzzy than by design!\n"); 00253 } 00254 } 00255 00256 if(VERBOSE3) 00257 fprintf(stderr, "Note: Xing: %lu bytes\n", (long unsigned)xing_bytes); 00258 } 00259 00260 lame_offset += 4; 00261 } 00262 if(xing_flags & 0x4) /* TOC */ 00263 { 00264 frame_fill_toc(fr, fr->bsbuf+lame_offset); 00265 lame_offset += 100; /* just skip */ 00266 } 00267 if(xing_flags & 0x8) /* VBR quality */ 00268 { 00269 if(VERBOSE3) 00270 { 00271 unsigned long xing_quality = make_long(fr->bsbuf, lame_offset); 00272 fprintf(stderr, "Note: Xing: quality = %lu\n", (long unsigned)xing_quality); 00273 } 00274 lame_offset += 4; 00275 } 00276 /* I guess that either 0 or LAME extra data follows */ 00277 /* there may this crc16 be floating around... (?) */ 00278 if(fr->bsbuf[lame_offset] != 0) 00279 { 00280 unsigned char lame_vbr; 00281 float replay_gain[2] = {0,0}; 00282 float peak = 0; 00283 float gain_offset = 0; /* going to be +6 for old lame that used 83dB */ 00284 char nb[10]; 00285 memcpy(nb, fr->bsbuf+lame_offset, 9); 00286 nb[9] = 0; 00287 if(VERBOSE3) fprintf(stderr, "Note: Info: Encoder: %s\n", nb); 00288 if(!strncmp("LAME", nb, 4)) 00289 { 00290 gain_offset = 6; 00291 debug("TODO: finish lame detetcion..."); 00292 } 00293 lame_offset += 9; 00294 /* the 4 big bits are tag revision, the small bits vbr method */ 00295 lame_vbr = fr->bsbuf[lame_offset] & 15; 00296 if(VERBOSE3) 00297 { 00298 fprintf(stderr, "Note: Info: rev %u\n", fr->bsbuf[lame_offset] >> 4); 00299 fprintf(stderr, "Note: Info: vbr mode %u\n", lame_vbr); 00300 } 00301 lame_offset += 1; 00302 switch(lame_vbr) 00303 { 00304 /* from rev1 proposal... not sure if all good in practice */ 00305 case 1: 00306 case 8: fr->vbr = MPG123_CBR; break; 00307 case 2: 00308 case 9: fr->vbr = MPG123_ABR; break; 00309 default: fr->vbr = MPG123_VBR; /* 00==unknown is taken as VBR */ 00310 } 00311 /* skipping: lowpass filter value */ 00312 lame_offset += 1; 00313 /* replaygain */ 00314 /* 32bit float: peak amplitude -- why did I parse it as int before??*/ 00315 /* Ah, yes, lame seems to store it as int since some day in 2003; I've only seen zeros anyway until now, bah! */ 00316 if 00317 ( 00318 (fr->bsbuf[lame_offset] != 0) 00319 || (fr->bsbuf[lame_offset+1] != 0) 00320 || (fr->bsbuf[lame_offset+2] != 0) 00321 || (fr->bsbuf[lame_offset+3] != 0) 00322 ) 00323 { 00324 debug("Wow! Is there _really_ a non-zero peak value? Now is it stored as float or int - how should I know?"); 00325 /* byte*peak_bytes = (byte*) &peak; 00326 ... endianess ... just copy bytes to avoid floating point operation on unaligned memory? 00327 peak_bytes[0] = ... 00328 peak = *(float*) (fr->bsbuf+lame_offset); */ 00329 } 00330 if(VERBOSE3) fprintf(stderr, "Note: Info: peak = %f (I won't use this)\n", peak); 00331 peak = 0; /* until better times arrived */ 00332 lame_offset += 4; 00333 /* 00334 ReplayGain values - lame only writes radio mode gain... 00335 16bit gain, 3 bits name, 3 bits originator, sign (1=-, 0=+), dB value*10 in 9 bits (fixed point) 00336 ignore the setting if name or originator == 000! 00337 radio 0 0 1 0 1 1 1 0 0 1 1 1 1 1 0 1 00338 audiophile 0 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 00339 */ 00340 00341 for(i =0; i < 2; ++i) 00342 { 00343 unsigned char origin = (fr->bsbuf[lame_offset] >> 2) & 0x7; /* the 3 bits after that... */ 00344 if(origin != 0) 00345 { 00346 unsigned char gt = fr->bsbuf[lame_offset] >> 5; /* only first 3 bits */ 00347 if(gt == 1) gt = 0; /* radio */ 00348 else if(gt == 2) gt = 1; /* audiophile */ 00349 else continue; 00350 /* get the 9 bits into a number, divide by 10, multiply sign... happy bit banging */ 00351 replay_gain[0] = (float) ((fr->bsbuf[lame_offset] & 0x2) ? -0.1 : 0.1) * (make_short(fr->bsbuf, lame_offset) & 0x1f); 00352 } 00353 lame_offset += 2; 00354 } 00355 if(VERBOSE3) 00356 { 00357 fprintf(stderr, "Note: Info: Radio Gain = %03.1fdB\n", replay_gain[0]); 00358 fprintf(stderr, "Note: Info: Audiophile Gain = %03.1fdB\n", replay_gain[1]); 00359 } 00360 for(i=0; i < 2; ++i) 00361 { 00362 if(fr->rva.level[i] <= 0) 00363 { 00364 fr->rva.peak[i] = 0; /* at some time the parsed peak should be used */ 00365 fr->rva.gain[i] = replay_gain[i]; 00366 fr->rva.level[i] = 0; 00367 } 00368 } 00369 lame_offset += 1; /* skipping encoding flags byte */ 00370 if(fr->vbr == MPG123_ABR) 00371 { 00372 fr->abr_rate = fr->bsbuf[lame_offset]; 00373 if(VERBOSE3) fprintf(stderr, "Note: Info: ABR rate = %u\n", fr->abr_rate); 00374 } 00375 lame_offset += 1; 00376 /* encoder delay and padding, two 12 bit values... lame does write them from int ...*/ 00377 if(VERBOSE3) 00378 fprintf(stderr, "Note: Encoder delay = %i; padding = %i\n", 00379 ((((int) fr->bsbuf[lame_offset]) << 4) | (((int) fr->bsbuf[lame_offset+1]) >> 4)), 00380 (((((int) fr->bsbuf[lame_offset+1]) << 8) | (((int) fr->bsbuf[lame_offset+2]))) & 0xfff) ); 00381 #ifdef GAPLESS 00382 if(fr->p.flags & MPG123_GAPLESS) 00383 { 00384 off_t length = fr->track_frames * spf(fr); 00385 off_t skipbegin = GAPLESS_DELAY + ((((int) fr->bsbuf[lame_offset]) << 4) | (((int) fr->bsbuf[lame_offset+1]) >> 4)); 00386 off_t skipend = -GAPLESS_DELAY + (((((int) fr->bsbuf[lame_offset+1]) << 8) | (((int) fr->bsbuf[lame_offset+2]))) & 0xfff); 00387 debug3("preparing gapless mode for layer3: length %lu, skipbegin %lu, skipend %lu", 00388 (long unsigned)length, (long unsigned)skipbegin, (long unsigned)skipend); 00389 if(length > 1) 00390 frame_gapless_init(fr, skipbegin, (skipend < length) ? length-skipend : length); 00391 } 00392 #endif 00393 } 00394 /* switch buffer back ... */ 00395 fr->bsbuf = fr->bsspace[fr->bsnum]+512; 00396 fr->bsnum = (fr->bsnum + 1) & 1; 00397 return 1; /* got it! */ 00398 } 00399 } 00400 } 00401 return 0; /* no lame tag */ 00402 } 00403 00404 /* Just tell if the header is some mono. */ 00405 static int header_mono(unsigned long newhead) 00406 { 00407 return ((newhead>>6)&0x3) == MPG_MD_MONO ? TRUE : FALSE; 00408 } 00409 00410 /* 00411 That's a big one: read the next frame. 1 is success, <= 0 is some error 00412 Special error READER_MORE means: Please feed more data and try again. 00413 */ 00414 int read_frame(mpg123_handle *fr) 00415 { 00416 /* TODO: rework this thing */ 00417 unsigned long newhead; 00418 off_t framepos; 00419 int ret; 00420 /* stuff that needs resetting if complete frame reading fails */ 00421 int oldsize = fr->framesize; 00422 int oldphase = fr->halfphase; 00423 00424 /* The counter for the search-first-header loop. 00425 It is persistent outside the loop to prevent seemingly endless loops 00426 when repeatedly headers are found that do not have valid followup headers. */ 00427 int headcount = 0; 00428 00429 fr->fsizeold=fr->framesize; /* for Layer3 */ 00430 00431 /* Speed-down hack: Play it again, Sam (the frame, I mean). */ 00432 if (fr->p.halfspeed) 00433 { 00434 if(fr->halfphase) /* repeat last frame */ 00435 { 00436 debug("repeat!"); 00437 fr->to_decode = fr->to_ignore = TRUE; 00438 --fr->halfphase; 00439 fr->bitindex = 0; 00440 fr->wordpointer = (unsigned char *) fr->bsbuf; 00441 if(fr->lay == 3) memcpy (fr->bsbuf, fr->ssave, fr->ssize); 00442 if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */ 00443 return 1; 00444 } 00445 else 00446 { 00447 fr->halfphase = fr->p.halfspeed - 1; 00448 } 00449 } 00450 00451 read_again: 00452 /* In case we are looping to find a valid frame, discard any buffered data before the current position. 00453 This is essential to prevent endless looping, always going back to the beginning when feeder buffer is exhausted. */ 00454 if(fr->rd->forget != NULL) fr->rd->forget(fr); 00455 00456 debug2("trying to get frame %"OFF_P" at %"OFF_P, (off_p)fr->num+1, (off_p)fr->rd->tell(fr)); 00457 if((ret = fr->rd->head_read(fr,&newhead)) <= 0){ debug("need more?"); goto read_frame_bad;} 00458 00459 init_resync: 00460 00461 fr->header_change = 2; /* output format change is possible... */ 00462 if(fr->oldhead) /* check a following header for change */ 00463 { 00464 if(fr->oldhead == newhead) fr->header_change = 0; 00465 else 00466 /* If they have the same sample rate. Note that only is _not_ the case for the first header, as we enforce sample rate match for following frames. 00467 So, during one stream, only change of stereoness is possible and indicated by header_change == 2. */ 00468 if((fr->oldhead & HDRSAMPMASK) == (newhead & HDRSAMPMASK)) 00469 { 00470 /* Now if both channel modes are mono or both stereo, it's no big deal. */ 00471 if( header_mono(fr->oldhead) == header_mono(newhead)) 00472 fr->header_change = 1; 00473 } 00474 } 00475 00476 #ifdef SKIP_JUNK 00477 /* watch out for junk/tags on beginning of stream by invalid header */ 00478 if(!fr->firsthead && !head_check(newhead)) { 00479 00480 /* check for id3v2; first three bytes (of 4) are "ID3" */ 00481 if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300) 00482 { 00483 int id3ret = 0; 00484 id3ret = parse_new_id3(fr, newhead); 00485 if (id3ret < 0){ debug("need more?"); ret = id3ret; goto read_frame_bad; } 00486 #ifndef NO_ID3V2 00487 else if(id3ret > 0){ debug("got ID3v2"); fr->metaflags |= MPG123_NEW_ID3|MPG123_ID3; } 00488 else debug("no useful ID3v2"); 00489 #endif 00490 00491 fr->oldhead = 0; 00492 goto read_again; /* Also in case of invalid ID3 tag (ret==0), try to get on track again. */ 00493 } 00494 else if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr,"Note: Junk at the beginning (0x%08lx)\n",newhead); 00495 00496 /* I even saw RIFF headers at the beginning of MPEG streams ;( */ 00497 if(newhead == ('R'<<24)+('I'<<16)+('F'<<8)+'F') { 00498 if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr, "Note: Looks like a RIFF header.\n"); 00499 00500 if((ret=fr->rd->head_read(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; } 00501 00502 while(newhead != ('d'<<24)+('a'<<16)+('t'<<8)+'a') 00503 { 00504 if((ret=fr->rd->head_shift(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; } 00505 } 00506 if((ret=fr->rd->head_read(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; } 00507 00508 if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr,"Note: Skipped RIFF header!\n"); 00509 00510 fr->oldhead = 0; 00511 goto read_again; 00512 } 00513 /* unhandled junk... just continue search for a header */ 00514 /* step in byte steps through next 64K */ 00515 debug("searching for header..."); 00516 00517 ret = 0; /* We will check the value after the loop. */ 00518 for(; headcount<65536; headcount++) 00519 { 00520 if((ret=fr->rd->head_shift(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; } 00521 /* if(head_check(newhead)) */ 00522 if(head_check(newhead) && (ret=decode_header(fr, newhead))) 00523 break; 00524 } 00525 if(ret<0){ debug("need more?"); goto read_frame_bad; } 00526 00527 if(headcount == 65536) 00528 { 00529 if(NOQUIET) error("Giving up searching valid MPEG header after (over) 64K of junk."); 00530 return 0; 00531 } 00532 else debug1("hopefully found one at %"OFF_P, (off_p)fr->rd->tell(fr)); 00533 /* 00534 * should we additionaly check, whether a new frame starts at 00535 * the next expected position? (some kind of read ahead) 00536 * We could implement this easily, at least for files. 00537 */ 00538 } 00539 #endif 00540 00541 /* first attempt of read ahead check to find the real first header; cannot believe what junk is out there! */ 00542 if(!fr->firsthead && fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED) && head_check(newhead) && (ret=decode_header(fr, newhead))) 00543 { 00544 unsigned long nexthead = 0; 00545 int hd = 0; 00546 off_t start = fr->rd->tell(fr); 00547 if(ret<0){ debug("need more?"); goto read_frame_bad; } 00548 00549 debug2("doing ahead check with BPF %d at %"OFF_P, fr->framesize+4, (off_p)start); 00550 /* step framesize bytes forward and read next possible header*/ 00551 if((ret=fr->rd->skip_bytes(fr, fr->framesize))<0) 00552 { 00553 if(ret==READER_ERROR && NOQUIET) error("cannot seek!"); 00554 goto read_frame_bad; 00555 } 00556 hd = fr->rd->head_read(fr,&nexthead); 00557 if(hd==MPG123_NEED_MORE){ debug("need more?"); ret = hd; goto read_frame_bad; } 00558 if((ret=fr->rd->back_bytes(fr, fr->rd->tell(fr)-start))<0) 00559 { 00560 if(ret==READER_ERROR && NOQUIET) error("cannot seek!"); 00561 else debug("need more?"); 00562 goto read_frame_bad; 00563 } 00564 debug1("After fetching next header, at %"OFF_P, (off_p)fr->rd->tell(fr)); 00565 if(!hd) 00566 { 00567 if(NOQUIET) warning("cannot read next header, a one-frame stream? Duh..."); 00568 } 00569 else 00570 { 00571 debug2("does next header 0x%08lx match first 0x%08lx?", nexthead, newhead); 00572 /* not allowing free format yet */ 00573 if(!head_check(nexthead) || (nexthead & HDRCMPMASK) != (newhead & HDRCMPMASK)) 00574 { 00575 debug("No, the header was not valid, start from beginning..."); 00576 fr->oldhead = 0; /* start over */ 00577 /* try next byte for valid header */ 00578 if((ret=fr->rd->back_bytes(fr, 3))<0) 00579 { 00580 if(NOQUIET) error("cannot seek!"); 00581 else debug("need more?"); 00582 goto read_frame_bad; 00583 } 00584 goto read_again; 00585 } 00586 } 00587 } 00588 00589 /* why has this head check been avoided here before? */ 00590 if(!head_check(newhead)) 00591 { 00592 /* and those ugly ID3 tags */ 00593 if((newhead & 0xffffff00) == ('T'<<24)+('A'<<16)+('G'<<8)) 00594 { 00595 fr->id3buf[0] = (unsigned char) ((newhead >> 24) & 0xff); 00596 fr->id3buf[1] = (unsigned char) ((newhead >> 16) & 0xff); 00597 fr->id3buf[2] = (unsigned char) ((newhead >> 8) & 0xff); 00598 fr->id3buf[3] = (unsigned char) ( newhead & 0xff); 00599 if((ret=fr->rd->fullread(fr,fr->id3buf+4,124)) < 0){ debug("need more?"); goto read_frame_bad; } 00600 fr->metaflags |= MPG123_NEW_ID3|MPG123_ID3; 00601 fr->rdat.flags |= READER_ID3TAG; /* that marks id3v1 */ 00602 if (VERBOSE3) fprintf(stderr,"Note: Skipped ID3v1 tag.\n"); 00603 goto read_again; 00604 } 00605 /* duplicated code from above! */ 00606 /* check for id3v2; first three bytes (of 4) are "ID3" */ 00607 if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300) 00608 { 00609 int id3length = 0; 00610 id3length = parse_new_id3(fr, newhead); 00611 if(id3length < 0){ debug("need more?"); ret = id3length; goto read_frame_bad; } 00612 00613 fr->metaflags |= MPG123_NEW_ID3|MPG123_ID3; 00614 goto read_again; 00615 } 00616 else if(NOQUIET && fr->silent_resync == 0) 00617 { 00618 fprintf(stderr,"Note: Illegal Audio-MPEG-Header 0x%08lx at offset %"OFF_P".\n", 00619 newhead, (off_p)fr->rd->tell(fr)-4); 00620 } 00621 00622 if(NOQUIET && (newhead & 0xffffff00) == ('b'<<24)+('m'<<16)+('p'<<8)) fprintf(stderr,"Note: Could be a BMP album art.\n"); 00623 /* Do resync if not forbidden by flag. 00624 I used to have a check for not-icy-meta here, but concluded that the desync issues came from a reader bug, not the stream. */ 00625 if( !(fr->p.flags & MPG123_NO_RESYNC) ) 00626 { 00627 long try = 0; 00628 long limit = fr->p.resync_limit; 00629 00630 /* If a resync is needed the bitreservoir of previous frames is no longer valid */ 00631 fr->bitreservoir = 0; 00632 00633 /* TODO: make this more robust, I'd like to cat two mp3 fragments together (in a dirty way) and still have mpg123 beign able to decode all it somehow. */ 00634 if(NOQUIET && fr->silent_resync == 0) fprintf(stderr, "Note: Trying to resync...\n"); 00635 /* Read more bytes until we find something that looks 00636 reasonably like a valid header. This is not a 00637 perfect strategy, but it should get us back on the 00638 track within a short time (and hopefully without 00639 too much distortion in the audio output). */ 00640 do 00641 { 00642 ++try; 00643 if(limit >= 0 && try >= limit) break; 00644 00645 if((ret=fr->rd->head_shift(fr,&newhead)) <= 0) 00646 { 00647 debug("need more?"); 00648 if(NOQUIET) fprintf (stderr, "Note: Hit end of (available) data during resync.\n"); 00649 00650 goto read_frame_bad; 00651 } 00652 if(VERBOSE3) debug3("resync try %li at %"OFF_P", got newhead 0x%08lx", try, (off_p)fr->rd->tell(fr), newhead); 00653 00654 if(!fr->oldhead) 00655 { 00656 debug("going to init_resync..."); 00657 goto init_resync; /* "considered harmful", eh? */ 00658 } 00659 /* we should perhaps collect a list of valid headers that occured in file... there can be more */ 00660 /* Michael's new resync routine seems to work better with the one frame readahead (and some input buffering?) */ 00661 } while 00662 ( 00663 !head_check(newhead) /* Simply check for any valid header... we have the readahead to get it straight now(?) */ 00664 /* (newhead & HDRCMPMASK) != (fr->oldhead & HDRCMPMASK) 00665 && (newhead & HDRCMPMASK) != (fr->firsthead & HDRCMPMASK)*/ 00666 ); 00667 /* too many false positives 00668 }while (!(head_check(newhead) && decode_header(fr, newhead))); */ 00669 if(NOQUIET && fr->silent_resync == 0) fprintf (stderr, "Note: Skipped %li bytes in input.\n", try); 00670 00671 if(limit >= 0 && try >= limit) 00672 { 00673 if(NOQUIET) 00674 error1("Giving up resync after %li bytes - your stream is not nice... (maybe increasing resync limit could help).", try); 00675 00676 fr->err = MPG123_RESYNC_FAIL; 00677 return READER_ERROR; 00678 } 00679 else 00680 { 00681 debug1("Found valid header 0x%lx... unsetting firsthead to reinit stream.", newhead); 00682 fr->firsthead = 0; 00683 goto init_resync; 00684 } 00685 } 00686 else 00687 { 00688 if(NOQUIET) error("not attempting to resync..."); 00689 00690 fr->err = MPG123_OUT_OF_SYNC; 00691 return READER_ERROR; 00692 } 00693 } 00694 00695 /* Man, that code looks awfully redundant... 00696 I need to untangle the spaghetti here in a future version. */ 00697 if(!fr->firsthead) 00698 { 00699 ret=decode_header(fr,newhead); 00700 if(ret == 0) 00701 { 00702 if(NOQUIET) error("decode header failed before first valid one, going to read again"); 00703 00704 goto read_again; 00705 } 00706 else if(ret < 0){ debug("need more?"); goto read_frame_bad; } 00707 } 00708 else 00709 { 00710 ret=decode_header(fr,newhead); 00711 if(ret == 0) 00712 { 00713 if(NOQUIET) error("decode header failed - goto resync"); 00714 /* return 0; */ 00715 goto init_resync; 00716 } 00717 else if(ret < 0){ debug("need more?"); goto read_frame_bad; } 00718 } 00719 00720 /* if filepos is invalid, so is framepos */ 00721 framepos = fr->rd->tell(fr) - 4; 00722 /* flip/init buffer for Layer 3 */ 00723 { 00724 unsigned char *newbuf = fr->bsspace[fr->bsnum]+512; 00725 /* read main data into memory */ 00726 if((ret=fr->rd->read_frame_body(fr,newbuf,fr->framesize))<0) 00727 { 00728 /* if failed: flip back */ 00729 debug("need more?"); 00730 goto read_frame_bad; 00731 } 00732 fr->bsbufold = fr->bsbuf; 00733 fr->bsbuf = newbuf; 00734 } 00735 fr->bsnum = (fr->bsnum + 1) & 1; 00736 00737 if(!fr->firsthead) 00738 { 00739 fr->firsthead = newhead; /* _now_ it's time to store it... the first real header */ 00740 /* This is the first header of our current stream segment. 00741 It is only the actual first header of the whole stream when fr->num is still below zero! 00742 Think of resyncs where firsthead has been reset for format flexibility. */ 00743 if(fr->num < 0) 00744 { 00745 fr->audio_start = framepos; 00746 /* Only check for LAME tag at beginning of whole stream 00747 ... when there indeed is one in between, it's the user's problem. */ 00748 if(fr->lay == 3 && check_lame_tag(fr) == 1) 00749 { /* ...in practice, Xing/LAME tags are layer 3 only. */ 00750 if(fr->rd->forget != NULL) fr->rd->forget(fr); 00751 00752 fr->oldhead = 0; 00753 goto read_again; 00754 } 00755 /* now adjust volume */ 00756 do_rva(fr); 00757 } 00758 00759 debug2("fr->firsthead: %08lx, audio_start: %li", fr->firsthead, (long int)fr->audio_start); 00760 } 00761 00762 fr->bitindex = 0; 00763 fr->wordpointer = (unsigned char *) fr->bsbuf; 00764 /* Question: How bad does the floating point value get with repeated recomputation? 00765 Also, considering that we can play the file or parts of many times. */ 00766 if(++fr->mean_frames != 0) 00767 { 00768 fr->mean_framesize = ((fr->mean_frames-1)*fr->mean_framesize+compute_bpf(fr)) / fr->mean_frames ; 00769 } 00770 ++fr->num; /* 0 for first frame! */ 00771 debug4("Frame %"OFF_P" %08lx %i, next filepos=%"OFF_P, 00772 (off_p)fr->num, newhead, fr->framesize, (off_p)fr->rd->tell(fr)); 00773 00774 /* save for repetition */ 00775 if(fr->p.halfspeed && fr->lay == 3) 00776 { 00777 debug("halfspeed - reusing old bsbuf "); 00778 memcpy (fr->ssave, fr->bsbuf, fr->ssize); 00779 } 00780 00781 /* index the position */ 00782 #ifdef FRAME_INDEX 00783 /* Keep track of true frame positions in our frame index. 00784 but only do so when we are sure that the frame number is accurate... */ 00785 if(fr->accurate && FI_NEXT(fr->index, fr->num)) 00786 fi_add(&fr->index, framepos); 00787 #endif 00788 00789 if(fr->silent_resync > 0) --fr->silent_resync; 00790 00791 if(fr->rd->forget != NULL) fr->rd->forget(fr); 00792 00793 fr->to_decode = fr->to_ignore = TRUE; 00794 if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */ 00795 00796 return 1; 00797 read_frame_bad: 00798 /* Also if we searched for valid data in vain, we can forget skipped data. 00799 Otherwise, the feeder would hold every dead old byte in memory until the first valid frame! */ 00800 if(fr->rd->forget != NULL) fr->rd->forget(fr); 00801 00802 fr->silent_resync = 0; 00803 if(fr->err == MPG123_OK) fr->err = MPG123_ERR_READER; 00804 fr->framesize = oldsize; 00805 fr->halfphase = oldphase; 00806 /* That return code might be inherited from some feeder action, or reader error. */ 00807 return ret; 00808 } 00809 00810 00811 /* 00812 * read ahead and find the next MPEG header, to guess framesize 00813 * return value: success code 00814 * 1: found a valid frame size (stored in the handle). 00815 * <0: error codes, possibly from feeder buffer (NEED_MORE) 00816 * 0: cannot get the framesize for some reason and shall silentry try the next possible header (if this is no free format stream after all...) 00817 */ 00818 static int guess_freeformat_framesize(mpg123_handle *fr) 00819 { 00820 long i; 00821 int ret; 00822 unsigned long head; 00823 if(!(fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED))) 00824 { 00825 if(NOQUIET) error("Cannot look for freeformat frame size with non-seekable and non-buffered stream!"); 00826 00827 return 0; 00828 } 00829 if((ret=fr->rd->head_read(fr,&head))<=0) 00830 return ret; 00831 00832 /* We are already 4 bytes into it */ 00833 /* fix that limit to be absolute for the first header search! */ 00834 for(i=4;i<65536;i++) { 00835 if((ret=fr->rd->head_shift(fr,&head))<=0) 00836 { 00837 return ret; 00838 } 00839 if(head_check(head)) 00840 { 00841 int sampling_frequency,mpeg25,lsf; 00842 00843 if(head & (1<<20)) 00844 { 00845 lsf = (head & (1<<19)) ? 0x0 : 0x1; 00846 mpeg25 = 0; 00847 } 00848 else 00849 { 00850 lsf = 1; 00851 mpeg25 = 1; 00852 } 00853 00854 if(mpeg25) 00855 sampling_frequency = 6 + ((head>>10)&0x3); 00856 else 00857 sampling_frequency = ((head>>10)&0x3) + (lsf*3); 00858 00859 if((lsf==fr->lsf) && (mpeg25==fr->mpeg25) && (sampling_frequency == fr->sampling_frequency)) 00860 { 00861 fr->rd->back_bytes(fr,i+1); 00862 fr->framesize = i-3; 00863 return 1; /* Success! */ 00864 } 00865 } 00866 } 00867 fr->rd->back_bytes(fr,i); 00868 return 0; 00869 } 00870 00871 00872 /* 00873 * decode a header and write the information 00874 * into the frame structure 00875 * Return values are compatible with those of read_frame, namely: 00876 * 1: success 00877 * 0: no valid header 00878 * <0: some error 00879 */ 00880 static int decode_header(mpg123_handle *fr,unsigned long newhead) 00881 { 00882 if(!head_check(newhead)) 00883 { 00884 if(NOQUIET) error("tried to decode obviously invalid header"); 00885 00886 return 0; 00887 } 00888 if( newhead & (1<<20) ) 00889 { 00890 fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1; 00891 fr->mpeg25 = 0; 00892 } 00893 else 00894 { 00895 fr->lsf = 1; 00896 fr->mpeg25 = 1; 00897 } 00898 00899 if( (fr->p.flags & MPG123_NO_RESYNC) || !fr->oldhead 00900 || (((fr->oldhead>>19)&0x3) ^ ((newhead>>19)&0x3)) ) 00901 { 00902 /* If "tryresync" is false, assume that certain 00903 parameters do not change within the stream! 00904 Force an update if lsf or mpeg25 settings 00905 have changed. */ 00906 fr->lay = 4-((newhead>>17)&3); 00907 if( ((newhead>>10)&0x3) == 0x3) 00908 { 00909 if(NOQUIET) error("Stream error"); 00910 00911 return 0; /* exit() here really is too much, isn't it? */ 00912 } 00913 if(fr->mpeg25) 00914 fr->sampling_frequency = 6 + ((newhead>>10)&0x3); 00915 else 00916 fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3); 00917 } 00918 00919 #ifdef DEBUG 00920 if((((newhead>>16)&0x1)^0x1) != fr->error_protection) debug("changed crc bit!"); 00921 #endif 00922 fr->error_protection = ((newhead>>16)&0x1)^0x1; /* seen a file where this varies (old lame tag without crc, track with crc) */ 00923 fr->bitrate_index = ((newhead>>12)&0xf); 00924 fr->padding = ((newhead>>9)&0x1); 00925 fr->extension = ((newhead>>8)&0x1); 00926 fr->mode = ((newhead>>6)&0x3); 00927 fr->mode_ext = ((newhead>>4)&0x3); 00928 fr->copyright = ((newhead>>3)&0x1); 00929 fr->original = ((newhead>>2)&0x1); 00930 fr->emphasis = newhead & 0x3; 00931 fr->freeformat = free_format_header(newhead); 00932 00933 fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2; 00934 00935 fr->oldhead = newhead; 00936 00937 /* we can't use tabsel_123 for freeformat, so trying to guess framesize... */ 00938 if(fr->freeformat) 00939 { 00940 /* when we first encounter the frame with freeformat, guess framesize */ 00941 if(fr->freeformat_framesize < 0) 00942 { 00943 int ret; 00944 ret = guess_freeformat_framesize(fr); 00945 if(ret>0) 00946 { 00947 fr->freeformat_framesize = fr->framesize - fr->padding; 00948 if(VERBOSE2) 00949 fprintf(stderr, "Note: free format frame size %li\n", fr->freeformat_framesize); 00950 } 00951 else 00952 { 00953 if(ret == MPG123_NEED_MORE) 00954 debug("Need more data to guess free format frame size."); 00955 else 00956 error("Encountered free format header, but failed to guess frame size."); 00957 return ret; 00958 } 00959 } 00960 /* freeformat should be CBR, so the same framesize can be used at the 2nd reading or later */ 00961 else 00962 { 00963 fr->framesize = fr->freeformat_framesize + fr->padding; 00964 } 00965 } 00966 00967 switch(fr->lay) 00968 { 00969 #ifndef NO_LAYER1 00970 case 1: 00971 fr->do_layer = do_layer1; 00972 if(!fr->freeformat) 00973 { 00974 fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000; 00975 fr->framesize /= freqs[fr->sampling_frequency]; 00976 fr->framesize = ((fr->framesize+fr->padding)<<2)-4; 00977 } 00978 break; 00979 #endif 00980 #ifndef NO_LAYER2 00981 case 2: 00982 fr->do_layer = do_layer2; 00983 if(!fr->freeformat) 00984 { 00985 debug2("bitrate index: %i (%i)", fr->bitrate_index, tabsel_123[fr->lsf][1][fr->bitrate_index] ); 00986 fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000; 00987 fr->framesize /= freqs[fr->sampling_frequency]; 00988 fr->framesize += fr->padding - 4; 00989 } 00990 break; 00991 #endif 00992 #ifndef NO_LAYER3 00993 case 3: 00994 fr->do_layer = do_layer3; 00995 if(fr->lsf) 00996 fr->ssize = (fr->stereo == 1) ? 9 : 17; 00997 else 00998 fr->ssize = (fr->stereo == 1) ? 17 : 32; 00999 01000 if(fr->error_protection) 01001 fr->ssize += 2; 01002 01003 if(!fr->freeformat) 01004 { 01005 fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000; 01006 fr->framesize /= freqs[fr->sampling_frequency]<<(fr->lsf); 01007 fr->framesize = fr->framesize + fr->padding - 4; 01008 } 01009 break; 01010 #endif 01011 default: 01012 if(NOQUIET) error1("Layer type %i not supported in this build!", fr->lay); 01013 01014 return 0; 01015 } 01016 if (fr->framesize > MAXFRAMESIZE) 01017 { 01018 if(NOQUIET) error1("Frame size too big: %d", fr->framesize+4-fr->padding); 01019 01020 return (0); 01021 } 01022 return 1; 01023 } 01024 01025 void set_pointer(mpg123_handle *fr, long backstep) 01026 { 01027 fr->wordpointer = fr->bsbuf + fr->ssize - backstep; 01028 if (backstep) 01029 memcpy(fr->wordpointer,fr->bsbufold+fr->fsizeold-backstep,backstep); 01030 01031 fr->bitindex = 0; 01032 } 01033 01034 /********************************/ 01035 01036 double compute_bpf(mpg123_handle *fr) 01037 { 01038 double bpf; 01039 01040 switch(fr->lay) 01041 { 01042 case 1: 01043 bpf = tabsel_123[fr->lsf][0][fr->bitrate_index]; 01044 bpf *= 12000.0 * 4.0; 01045 bpf /= freqs[fr->sampling_frequency] <<(fr->lsf); 01046 break; 01047 case 2: 01048 case 3: 01049 bpf = tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index]; 01050 bpf *= 144000; 01051 bpf /= freqs[fr->sampling_frequency] << (fr->lsf); 01052 break; 01053 default: 01054 bpf = 1.0; 01055 } 01056 01057 return bpf; 01058 } 01059 01060 double attribute_align_arg mpg123_tpf(mpg123_handle *fr) 01061 { 01062 static int bs[4] = { 0,384,1152,1152 }; 01063 double tpf; 01064 if(fr == NULL) return -1; 01065 01066 tpf = (double) bs[fr->lay]; 01067 tpf /= freqs[fr->sampling_frequency] << (fr->lsf); 01068 return tpf; 01069 } 01070 01071 int attribute_align_arg mpg123_position(mpg123_handle *fr, off_t no, off_t buffsize, 01072 off_t *current_frame, off_t *frames_left, 01073 double *current_seconds, double *seconds_left) 01074 { 01075 double tpf; 01076 double dt = 0.0; 01077 off_t cur, left; 01078 double curs, lefts; 01079 01080 if(!fr || !fr->rd) /* Isn't this too paranoid? */ 01081 { 01082 debug("reader troubles!"); 01083 return MPG123_ERR; 01084 } 01085 01086 no += fr->num; /* no starts out as offset */ 01087 cur = no; 01088 tpf = mpg123_tpf(fr); 01089 if(buffsize > 0 && fr->af.rate > 0 && fr->af.channels > 0) 01090 { 01091 dt = (double) buffsize / fr->af.rate / fr->af.channels; 01092 if(fr->af.encoding & MPG123_ENC_16) dt *= 0.5; 01093 } 01094 01095 left = 0; 01096 01097 if((fr->track_frames != 0) && (fr->track_frames >= fr->num)) left = no < fr->track_frames ? fr->track_frames - no : 0; 01098 else 01099 if(fr->rdat.filelen >= 0) 01100 { 01101 double bpf; 01102 off_t t = fr->rd->tell(fr); 01103 bpf = fr->mean_framesize ? fr->mean_framesize : compute_bpf(fr); 01104 left = (off_t)((double)(fr->rdat.filelen-t)/bpf); 01105 /* no can be different for prophetic purposes, file pointer is always associated with fr->num! */ 01106 if(fr->num != no) 01107 { 01108 if(fr->num > no) left += fr->num - no; 01109 else 01110 { 01111 if(left >= (no - fr->num)) left -= no - fr->num; 01112 else left = 0; /* uh, oh! */ 01113 } 01114 } 01115 /* I totally don't understand why we should re-estimate the given correct(?) value */ 01116 /* fr->num = (unsigned long)((double)t/bpf); */ 01117 } 01118 01119 /* beginning with 0 or 1?*/ 01120 curs = (double) no*tpf-dt; 01121 lefts = (double)left*tpf+dt; 01122 #if 0 01123 curs = curs < 0 ? 0.0 : curs; 01124 #endif 01125 if(left < 0 || lefts < 0) 01126 { /* That is the case for non-seekable streams. */ 01127 left = 0; 01128 lefts = 0.0; 01129 } 01130 if(current_frame != NULL) *current_frame = cur; 01131 if(frames_left != NULL) *frames_left = left; 01132 if(current_seconds != NULL) *current_seconds = curs; 01133 if(seconds_left != NULL) *seconds_left = lefts; 01134 return MPG123_OK; 01135 } 01136 01137 int get_songlen(mpg123_handle *fr,int no) 01138 { 01139 double tpf; 01140 01141 if(!fr) 01142 return 0; 01143 01144 if(no < 0) { 01145 if(!fr->rd || fr->rdat.filelen < 0) 01146 return 0; 01147 no = (int) ((double) fr->rdat.filelen / compute_bpf(fr)); 01148 } 01149 01150 tpf = mpg123_tpf(fr); 01151 return (int) (no*tpf); 01152 } Generated on Sat May 26 2012 04:18:02 for ReactOS by
1.7.6.1
|