Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenframe.c
Go to the documentation of this file.
00001 /* 00002 frame: Heap of routines dealing with the core mpg123 data structure. 00003 00004 copyright 2008-2010 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 Thomas Orgis 00007 */ 00008 00009 #include "mpg123lib_intern.h" 00010 #include "getcpuflags.h" 00011 #include "debug.h" 00012 00013 static void frame_fixed_reset(mpg123_handle *fr); 00014 00015 /* that's doubled in decode_ntom.c */ 00016 #define NTOM_MUL (32768) 00017 00018 #define aligned_pointer(p, type, alignment) align_the_pointer(p, alignment) 00019 static void *align_the_pointer(void *base, unsigned int alignment) 00020 { 00021 /* 00022 Work in unsigned integer realm, explicitly. 00023 Tricking the compiler into integer operations like % by invoking base-NULL is dangerous: It results into ptrdiff_t, which gets negative on big addresses. Big screw up, that. 00024 I try to do it "properly" here: Casting only to uintptr_t and no artihmethic with void*. 00025 */ 00026 uintptr_t baseval = (uintptr_t)(char*)base; 00027 uintptr_t aoff = baseval % alignment; 00028 00029 debug3("align_the_pointer: pointer %p is off by %u from %u", 00030 base, (unsigned int)aoff, alignment); 00031 00032 if(aoff) return (char*)base+alignment-aoff; 00033 else return base; 00034 } 00035 00036 void frame_default_pars(mpg123_pars *mp) 00037 { 00038 mp->outscale = 1.0; 00039 #ifdef GAPLESS 00040 mp->flags = MPG123_GAPLESS; 00041 #else 00042 mp->flags = 0; 00043 #endif 00044 #ifndef NO_NTOM 00045 mp->force_rate = 0; 00046 #endif 00047 mp->down_sample = 0; 00048 mp->rva = 0; 00049 mp->halfspeed = 0; 00050 mp->doublespeed = 0; 00051 mp->verbose = 0; 00052 #ifndef NO_ICY 00053 mp->icy_interval = 0; 00054 #endif 00055 mp->timeout = 0; 00056 mp->resync_limit = 1024; 00057 #ifdef FRAME_INDEX 00058 mp->index_size = INDEX_SIZE; 00059 #endif 00060 mp->preframes = 4; /* That's good for layer 3 ISO compliance bitstream. */ 00061 mpg123_fmt_all(mp); 00062 } 00063 00064 void frame_init(mpg123_handle *fr) 00065 { 00066 frame_init_par(fr, NULL); 00067 } 00068 00069 void frame_init_par(mpg123_handle *fr, mpg123_pars *mp) 00070 { 00071 fr->own_buffer = FALSE; 00072 fr->buffer.data = NULL; 00073 fr->rawbuffs = NULL; 00074 fr->rawbuffss = 0; 00075 fr->rawdecwin = NULL; 00076 fr->rawdecwins = 0; 00077 #ifndef NO_8BIT 00078 fr->conv16to8_buf = NULL; 00079 #endif 00080 #ifdef OPT_DITHER 00081 fr->dithernoise = NULL; 00082 #endif 00083 fr->layerscratch = NULL; 00084 fr->xing_toc = NULL; 00085 fr->cpu_opts.type = defdec(); 00086 fr->cpu_opts.class = decclass(fr->cpu_opts.type); 00087 #ifndef NO_NTOM 00088 /* these two look unnecessary, check guarantee for synth_ntom_set_step (in control_generic, even)! */ 00089 fr->ntom_val[0] = NTOM_MUL>>1; 00090 fr->ntom_val[1] = NTOM_MUL>>1; 00091 fr->ntom_step = NTOM_MUL; 00092 #endif 00093 /* unnecessary: fr->buffer.size = fr->buffer.fill = 0; */ 00094 mpg123_reset_eq(fr); 00095 init_icy(&fr->icy); 00096 init_id3(fr); 00097 /* frame_outbuffer is missing... */ 00098 /* frame_buffers is missing... that one needs cpu opt setting! */ 00099 /* after these... frame_reset is needed before starting full decode */ 00100 invalidate_format(&fr->af); 00101 fr->rdat.r_read = NULL; 00102 fr->rdat.r_lseek = NULL; 00103 fr->rdat.iohandle = NULL; 00104 fr->rdat.r_read_handle = NULL; 00105 fr->rdat.r_lseek_handle = NULL; 00106 fr->rdat.cleanup_handle = NULL; 00107 fr->wrapperdata = NULL; 00108 fr->wrapperclean = NULL; 00109 fr->decoder_change = 1; 00110 fr->err = MPG123_OK; 00111 if(mp == NULL) frame_default_pars(&fr->p); 00112 else memcpy(&fr->p, mp, sizeof(struct mpg123_pars_struct)); 00113 00114 fr->down_sample = 0; /* Initialize to silence harmless errors when debugging. */ 00115 frame_fixed_reset(fr); /* Reset only the fixed data, dynamic buffers are not there yet! */ 00116 fr->synth = NULL; 00117 fr->synth_mono = NULL; 00118 fr->make_decode_tables = NULL; 00119 #ifdef FRAME_INDEX 00120 fi_init(&fr->index); 00121 frame_index_setup(fr); /* Apply the size setting. */ 00122 #endif 00123 } 00124 00125 #ifdef OPT_DITHER 00126 /* Also, only allocate the memory for the table on demand. 00127 In future, one could create special noise for different sampling frequencies(?). */ 00128 int frame_dither_init(mpg123_handle *fr) 00129 { 00130 /* run-time dither noise table generation */ 00131 if(fr->dithernoise == NULL) 00132 { 00133 fr->dithernoise = malloc(sizeof(float)*DITHERSIZE); 00134 if(fr->dithernoise == NULL) return 0; 00135 00136 dither_table_init(fr->dithernoise); 00137 } 00138 return 1; 00139 } 00140 #endif 00141 00142 mpg123_pars attribute_align_arg *mpg123_new_pars(int *error) 00143 { 00144 mpg123_pars *mp = malloc(sizeof(struct mpg123_pars_struct)); 00145 if(mp != NULL){ frame_default_pars(mp); if(error != NULL) *error = MPG123_OK; } 00146 else if(error != NULL) *error = MPG123_OUT_OF_MEM; 00147 return mp; 00148 } 00149 00150 void attribute_align_arg mpg123_delete_pars(mpg123_pars* mp) 00151 { 00152 if(mp != NULL) free(mp); 00153 } 00154 00155 int attribute_align_arg mpg123_reset_eq(mpg123_handle *mh) 00156 { 00157 int i; 00158 mh->have_eq_settings = 0; 00159 for(i=0; i < 32; ++i) mh->equalizer[0][i] = mh->equalizer[1][i] = DOUBLE_TO_REAL(1.0); 00160 00161 return MPG123_OK; 00162 } 00163 00164 int frame_outbuffer(mpg123_handle *fr) 00165 { 00166 size_t size = mpg123_safe_buffer()*AUDIOBUFSIZE; 00167 if(!fr->own_buffer) fr->buffer.data = NULL; 00168 if(fr->buffer.data != NULL && fr->buffer.size != size) 00169 { 00170 free(fr->buffer.data); 00171 fr->buffer.data = NULL; 00172 } 00173 fr->buffer.size = size; 00174 if(fr->buffer.data == NULL) fr->buffer.data = (unsigned char*) malloc(fr->buffer.size); 00175 if(fr->buffer.data == NULL) 00176 { 00177 fr->err = MPG123_OUT_OF_MEM; 00178 return -1; 00179 } 00180 fr->own_buffer = TRUE; 00181 fr->buffer.fill = 0; 00182 return 0; 00183 } 00184 00185 int attribute_align_arg mpg123_replace_buffer(mpg123_handle *mh, unsigned char *data, size_t size) 00186 { 00187 if(data == NULL || size < mpg123_safe_buffer()) 00188 { 00189 mh->err = MPG123_BAD_BUFFER; 00190 return MPG123_ERR; 00191 } 00192 if(mh->own_buffer && mh->buffer.data != NULL) free(mh->buffer.data); 00193 mh->own_buffer = FALSE; 00194 mh->buffer.data = data; 00195 mh->buffer.size = size; 00196 mh->buffer.fill = 0; 00197 return MPG123_OK; 00198 } 00199 00200 #ifdef FRAME_INDEX 00201 int frame_index_setup(mpg123_handle *fr) 00202 { 00203 int ret = MPG123_ERR; 00204 if(fr->p.index_size >= 0) 00205 { /* Simple fixed index. */ 00206 fr->index.grow_size = 0; 00207 debug1("resizing index to %li", fr->p.index_size); 00208 ret = fi_resize(&fr->index, (size_t)fr->p.index_size); 00209 debug2("index resized... %lu at %p", (unsigned long)fr->index.size, (void*)fr->index.data); 00210 } 00211 else 00212 { /* A growing index. We give it a start, though. */ 00213 fr->index.grow_size = (size_t)(- fr->p.index_size); 00214 if(fr->index.size < fr->index.grow_size) 00215 ret = fi_resize(&fr->index, fr->index.grow_size); 00216 else 00217 ret = MPG123_OK; /* We have minimal size already... and since growing is OK... */ 00218 } 00219 debug2("set up frame index of size %lu (ret=%i)", (unsigned long)fr->index.size, ret); 00220 00221 return ret; 00222 } 00223 #endif 00224 00225 static void frame_decode_buffers_reset(mpg123_handle *fr) 00226 { 00227 memset(fr->rawbuffs, 0, fr->rawbuffss); 00228 } 00229 00230 int frame_buffers(mpg123_handle *fr) 00231 { 00232 int buffssize = 0; 00233 debug1("frame %p buffer", (void*)fr); 00234 /* 00235 the used-to-be-static buffer of the synth functions, has some subtly different types/sizes 00236 00237 2to1, 4to1, ntom, generic, i386: real[2][2][0x110] 00238 mmx, sse: short[2][2][0x110] 00239 i586(_dither): 4352 bytes; int/long[2][2][0x110] 00240 i486: int[2][2][17*FIR_BUFFER_SIZE] 00241 altivec: static real __attribute__ ((aligned (16))) buffs[4][4][0x110] 00242 00243 Huh, altivec looks like fun. Well, let it be large... then, the 16 byte alignment seems to be implicit on MacOSX malloc anyway. 00244 Let's make a reasonable attempt to allocate enough memory... 00245 Keep in mind: biggest ones are i486 and altivec (mutually exclusive!), then follows i586 and normal real. 00246 mmx/sse use short but also real for resampling. 00247 Thus, minimum is 2*2*0x110*sizeof(real). 00248 */ 00249 if(fr->cpu_opts.type == altivec) buffssize = 4*4*0x110*sizeof(real); 00250 #ifdef OPT_I486 00251 else if(fr->cpu_opts.type == ivier) buffssize = 2*2*17*FIR_BUFFER_SIZE*sizeof(int); 00252 #endif 00253 else if(fr->cpu_opts.type == ifuenf || fr->cpu_opts.type == ifuenf_dither || fr->cpu_opts.type == dreidnow) 00254 buffssize = 2*2*0x110*4; /* don't rely on type real, we need 4352 bytes */ 00255 00256 if(2*2*0x110*sizeof(real) > buffssize) 00257 buffssize = 2*2*0x110*sizeof(real); 00258 buffssize += 15; /* For 16-byte alignment (SSE likes that). */ 00259 00260 if(fr->rawbuffs != NULL && fr->rawbuffss != buffssize) 00261 { 00262 free(fr->rawbuffs); 00263 fr->rawbuffs = NULL; 00264 } 00265 00266 if(fr->rawbuffs == NULL) fr->rawbuffs = (unsigned char*) malloc(buffssize); 00267 if(fr->rawbuffs == NULL) return -1; 00268 fr->rawbuffss = buffssize; 00269 fr->short_buffs[0][0] = aligned_pointer(fr->rawbuffs,short,16); 00270 fr->short_buffs[0][1] = fr->short_buffs[0][0] + 0x110; 00271 fr->short_buffs[1][0] = fr->short_buffs[0][1] + 0x110; 00272 fr->short_buffs[1][1] = fr->short_buffs[1][0] + 0x110; 00273 fr->real_buffs[0][0] = aligned_pointer(fr->rawbuffs,real,16); 00274 fr->real_buffs[0][1] = fr->real_buffs[0][0] + 0x110; 00275 fr->real_buffs[1][0] = fr->real_buffs[0][1] + 0x110; 00276 fr->real_buffs[1][1] = fr->real_buffs[1][0] + 0x110; 00277 #ifdef OPT_I486 00278 if(fr->cpu_opts.type == ivier) 00279 { 00280 fr->int_buffs[0][0] = (int*) fr->rawbuffs; 00281 fr->int_buffs[0][1] = fr->int_buffs[0][0] + 17*FIR_BUFFER_SIZE; 00282 fr->int_buffs[1][0] = fr->int_buffs[0][1] + 17*FIR_BUFFER_SIZE; 00283 fr->int_buffs[1][1] = fr->int_buffs[1][0] + 17*FIR_BUFFER_SIZE; 00284 } 00285 #endif 00286 #ifdef OPT_ALTIVEC 00287 if(fr->cpu_opts.type == altivec) 00288 { 00289 int i,j; 00290 fr->areal_buffs[0][0] = (real*) fr->rawbuffs; 00291 for(i=0; i<4; ++i) for(j=0; j<4; ++j) 00292 fr->areal_buffs[i][j] = fr->areal_buffs[0][0] + (i*4+j)*0x110; 00293 } 00294 #endif 00295 /* now the different decwins... all of the same size, actually */ 00296 /* The MMX ones want 32byte alignment, which I'll try to ensure manually */ 00297 { 00298 int decwin_size = (512+32)*sizeof(real); 00299 #ifdef OPT_MMXORSSE 00300 #ifdef OPT_MULTI 00301 if(fr->cpu_opts.class == mmxsse) 00302 { 00303 #endif 00304 /* decwin_mmx will share, decwins will be appended ... sizeof(float)==4 */ 00305 if(decwin_size < (512+32)*4) decwin_size = (512+32)*4; 00306 00307 /* the second window + alignment zone -- we align for 32 bytes for SSE as 00308 requirement, 64 byte for matching cache line size (that matters!) */ 00309 decwin_size += (512+32)*4 + 63; 00310 /* (512+32)*4/32 == 2176/32 == 68, so one decwin block retains alignment for 32 or 64 bytes */ 00311 #ifdef OPT_MULTI 00312 } 00313 #endif 00314 #endif 00315 #if defined(OPT_ALTIVEC) || defined(OPT_ARM) 00316 if(decwin_size < (512+32)*4) decwin_size = (512+32)*4; 00317 decwin_size += 512*4; 00318 #endif 00319 /* Hm, that's basically realloc() ... */ 00320 if(fr->rawdecwin != NULL && fr->rawdecwins != decwin_size) 00321 { 00322 free(fr->rawdecwin); 00323 fr->rawdecwin = NULL; 00324 } 00325 00326 if(fr->rawdecwin == NULL) 00327 fr->rawdecwin = (unsigned char*) malloc(decwin_size); 00328 00329 if(fr->rawdecwin == NULL) return -1; 00330 00331 fr->rawdecwins = decwin_size; 00332 fr->decwin = (real*) fr->rawdecwin; 00333 #ifdef OPT_MMXORSSE 00334 #ifdef OPT_MULTI 00335 if(fr->cpu_opts.class == mmxsse) 00336 { 00337 #endif 00338 /* align decwin, assign that to decwin_mmx, append decwins */ 00339 /* I need to add to decwin what is missing to the next full 64 byte -- also I want to make gcc -pedantic happy... */ 00340 fr->decwin = aligned_pointer(fr->rawdecwin,real,64); 00341 debug1("aligned decwin: %p", (void*)fr->decwin); 00342 fr->decwin_mmx = (float*)fr->decwin; 00343 fr->decwins = fr->decwin_mmx+512+32; 00344 #ifdef OPT_MULTI 00345 } 00346 else debug("no decwins/decwin_mmx for that class"); 00347 #endif 00348 #endif 00349 } 00350 00351 /* Layer scratch buffers are of compile-time fixed size, so allocate only once. */ 00352 if(fr->layerscratch == NULL) 00353 { 00354 /* Allocate specific layer1/2/3 buffers, so that we know they'll work for SSE. */ 00355 size_t scratchsize = 0; 00356 real *scratcher; 00357 #ifndef NO_LAYER1 00358 scratchsize += sizeof(real) * 2 * SBLIMIT; 00359 #endif 00360 #ifndef NO_LAYER2 00361 scratchsize += sizeof(real) * 2 * 4 * SBLIMIT; 00362 #endif 00363 #ifndef NO_LAYER3 00364 scratchsize += sizeof(real) * 2 * SBLIMIT * SSLIMIT; /* hybrid_in */ 00365 scratchsize += sizeof(real) * 2 * SSLIMIT * SBLIMIT; /* hybrid_out */ 00366 #endif 00367 /* 00368 Now figure out correct alignment: 00369 We need 16 byte minimum, smallest unit of the blocks is 2*SBLIMIT*sizeof(real), which is 64*4=256. Let's do 64bytes as heuristic for cache line (as proven useful in buffs above). 00370 */ 00371 fr->layerscratch = malloc(scratchsize+63); 00372 if(fr->layerscratch == NULL) return -1; 00373 00374 /* Get aligned part of the memory, then divide it up. */ 00375 scratcher = aligned_pointer(fr->layerscratch,real,64); 00376 /* Those funky pointer casts silence compilers... 00377 One might change the code at hand to really just use 1D arrays, but in practice, that would not make a (positive) difference. */ 00378 #ifndef NO_LAYER1 00379 fr->layer1.fraction = (real(*)[SBLIMIT])scratcher; 00380 scratcher += 2 * SBLIMIT; 00381 #endif 00382 #ifndef NO_LAYER2 00383 fr->layer2.fraction = (real(*)[4][SBLIMIT])scratcher; 00384 scratcher += 2 * 4 * SBLIMIT; 00385 #endif 00386 #ifndef NO_LAYER3 00387 fr->layer3.hybrid_in = (real(*)[SBLIMIT][SSLIMIT])scratcher; 00388 scratcher += 2 * SBLIMIT * SSLIMIT; 00389 fr->layer3.hybrid_out = (real(*)[SSLIMIT][SBLIMIT])scratcher; 00390 scratcher += 2 * SSLIMIT * SBLIMIT; 00391 #endif 00392 /* Note: These buffers don't need resetting here. */ 00393 } 00394 00395 /* Only reset the buffers we created just now. */ 00396 frame_decode_buffers_reset(fr); 00397 00398 debug1("frame %p buffer done", (void*)fr); 00399 return 0; 00400 } 00401 00402 int frame_buffers_reset(mpg123_handle *fr) 00403 { 00404 fr->buffer.fill = 0; /* hm, reset buffer fill... did we do a flush? */ 00405 fr->bsnum = 0; 00406 /* Wondering: could it be actually _wanted_ to retain buffer contents over different files? (special gapless / cut stuff) */ 00407 fr->bsbuf = fr->bsspace[1]; 00408 fr->bsbufold = fr->bsbuf; 00409 fr->bitreservoir = 0; /* Not entirely sure if this is the right place for that counter. */ 00410 frame_decode_buffers_reset(fr); 00411 memset(fr->bsspace, 0, 2*(MAXFRAMESIZE+512)); 00412 memset(fr->ssave, 0, 34); 00413 fr->hybrid_blc[0] = fr->hybrid_blc[1] = 0; 00414 memset(fr->hybrid_block, 0, sizeof(real)*2*2*SBLIMIT*SSLIMIT); 00415 return 0; 00416 } 00417 00418 void frame_icy_reset(mpg123_handle* fr) 00419 { 00420 #ifndef NO_ICY 00421 if(fr->icy.data != NULL) free(fr->icy.data); 00422 fr->icy.data = NULL; 00423 fr->icy.interval = 0; 00424 fr->icy.next = 0; 00425 #endif 00426 } 00427 00428 void frame_free_toc(mpg123_handle *fr) 00429 { 00430 if(fr->xing_toc != NULL){ free(fr->xing_toc); fr->xing_toc = NULL; } 00431 } 00432 00433 /* Just copy the Xing TOC over... */ 00434 int frame_fill_toc(mpg123_handle *fr, unsigned char* in) 00435 { 00436 if(fr->xing_toc == NULL) fr->xing_toc = malloc(100); 00437 if(fr->xing_toc != NULL) 00438 { 00439 memcpy(fr->xing_toc, in, 100); 00440 #ifdef DEBUG 00441 debug("Got a TOC! Showing the values..."); 00442 { 00443 int i; 00444 for(i=0; i<100; ++i) 00445 debug2("entry %i = %i", i, fr->xing_toc[i]); 00446 } 00447 #endif 00448 return TRUE; 00449 } 00450 return FALSE; 00451 } 00452 00453 /* Prepare the handle for a new track. 00454 Reset variables, buffers... */ 00455 int frame_reset(mpg123_handle* fr) 00456 { 00457 frame_buffers_reset(fr); 00458 frame_fixed_reset(fr); 00459 frame_free_toc(fr); 00460 #ifdef FRAME_INDEX 00461 fi_reset(&fr->index); 00462 #endif 00463 00464 return 0; 00465 } 00466 00467 /* Reset everythign except dynamic memory. */ 00468 static void frame_fixed_reset(mpg123_handle *fr) 00469 { 00470 frame_icy_reset(fr); 00471 open_bad(fr); 00472 fr->to_decode = FALSE; 00473 fr->to_ignore = FALSE; 00474 fr->metaflags = 0; 00475 fr->outblock = mpg123_safe_buffer(); 00476 fr->num = -1; 00477 fr->playnum = -1; 00478 fr->accurate = TRUE; 00479 fr->silent_resync = 0; 00480 fr->audio_start = 0; 00481 fr->clip = 0; 00482 fr->oldhead = 0; 00483 fr->firsthead = 0; 00484 fr->vbr = MPG123_CBR; 00485 fr->abr_rate = 0; 00486 fr->track_frames = 0; 00487 fr->track_samples = -1; 00488 fr->framesize=0; 00489 fr->mean_frames = 0; 00490 fr->mean_framesize = 0; 00491 fr->freesize = 0; 00492 fr->lastscale = -1; 00493 fr->rva.level[0] = -1; 00494 fr->rva.level[1] = -1; 00495 fr->rva.gain[0] = 0; 00496 fr->rva.gain[1] = 0; 00497 fr->rva.peak[0] = 0; 00498 fr->rva.peak[1] = 0; 00499 fr->fsizeold = 0; 00500 fr->firstframe = 0; 00501 fr->ignoreframe = fr->firstframe-fr->p.preframes; 00502 fr->lastframe = -1; 00503 fr->fresh = 1; 00504 fr->new_format = 0; 00505 #ifdef GAPLESS 00506 frame_gapless_init(fr,0,0); 00507 fr->lastoff = 0; 00508 fr->firstoff = 0; 00509 #endif 00510 #ifdef OPT_I486 00511 fr->i486bo[0] = fr->i486bo[1] = FIR_SIZE-1; 00512 #endif 00513 fr->bo = 1; /* the usual bo */ 00514 #ifdef OPT_DITHER 00515 fr->ditherindex = 0; 00516 #endif 00517 reset_id3(fr); 00518 reset_icy(&fr->icy); 00519 /* ICY stuff should go into icy.c, eh? */ 00520 #ifndef NO_ICY 00521 fr->icy.interval = 0; 00522 fr->icy.next = 0; 00523 #endif 00524 fr->halfphase = 0; /* here or indeed only on first-time init? */ 00525 fr->error_protection = 0; 00526 fr->freeformat_framesize = -1; 00527 } 00528 00529 void frame_free_buffers(mpg123_handle *fr) 00530 { 00531 if(fr->rawbuffs != NULL) free(fr->rawbuffs); 00532 fr->rawbuffs = NULL; 00533 fr->rawbuffss = 0; 00534 if(fr->rawdecwin != NULL) free(fr->rawdecwin); 00535 fr->rawdecwin = NULL; 00536 fr->rawdecwins = 0; 00537 #ifndef NO_8BIT 00538 if(fr->conv16to8_buf != NULL) free(fr->conv16to8_buf); 00539 fr->conv16to8_buf = NULL; 00540 #endif 00541 if(fr->layerscratch != NULL) free(fr->layerscratch); 00542 } 00543 00544 void frame_exit(mpg123_handle *fr) 00545 { 00546 if(fr->own_buffer && fr->buffer.data != NULL) 00547 { 00548 debug1("freeing buffer at %p", (void*)fr->buffer.data); 00549 free(fr->buffer.data); 00550 } 00551 fr->buffer.data = NULL; 00552 frame_free_buffers(fr); 00553 frame_free_toc(fr); 00554 #ifdef FRAME_INDEX 00555 fi_exit(&fr->index); 00556 #endif 00557 #ifdef OPT_DITHER 00558 if(fr->dithernoise != NULL) 00559 { 00560 free(fr->dithernoise); 00561 fr->dithernoise = NULL; 00562 } 00563 #endif 00564 exit_id3(fr); 00565 clear_icy(&fr->icy); 00566 /* Clean up possible mess from LFS wrapper. */ 00567 if(fr->wrapperclean != NULL) 00568 { 00569 fr->wrapperclean(fr->wrapperdata); 00570 fr->wrapperdata = NULL; 00571 } 00572 } 00573 00574 int attribute_align_arg mpg123_info(mpg123_handle *mh, struct mpg123_frameinfo *mi) 00575 { 00576 if(mh == NULL) return MPG123_ERR; 00577 if(mi == NULL) 00578 { 00579 mh->err = MPG123_ERR_NULL; 00580 return MPG123_ERR; 00581 } 00582 mi->version = mh->mpeg25 ? MPG123_2_5 : (mh->lsf ? MPG123_2_0 : MPG123_1_0); 00583 mi->layer = mh->lay; 00584 mi->rate = frame_freq(mh); 00585 switch(mh->mode) 00586 { 00587 case 0: mi->mode = MPG123_M_STEREO; break; 00588 case 1: mi->mode = MPG123_M_JOINT; break; 00589 case 2: mi->mode = MPG123_M_DUAL; break; 00590 case 3: mi->mode = MPG123_M_MONO; break; 00591 default: error("That mode cannot be!"); 00592 } 00593 mi->mode_ext = mh->mode_ext; 00594 mi->framesize = mh->framesize+4; /* Include header. */ 00595 mi->flags = 0; 00596 if(mh->error_protection) mi->flags |= MPG123_CRC; 00597 if(mh->copyright) mi->flags |= MPG123_COPYRIGHT; 00598 if(mh->extension) mi->flags |= MPG123_PRIVATE; 00599 if(mh->original) mi->flags |= MPG123_ORIGINAL; 00600 mi->emphasis = mh->emphasis; 00601 mi->bitrate = frame_bitrate(mh); 00602 mi->abr_rate = mh->abr_rate; 00603 mi->vbr = mh->vbr; 00604 return MPG123_OK; 00605 } 00606 00607 00608 /* 00609 Fuzzy frame offset searching (guessing). 00610 When we don't have an accurate position, we may use an inaccurate one. 00611 Possibilities: 00612 - use approximate positions from Xing TOC (not yet parsed) 00613 - guess wildly from mean framesize and offset of first frame / beginning of file. 00614 */ 00615 00616 off_t frame_fuzzy_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame) 00617 { 00618 /* Default is to go to the beginning. */ 00619 off_t ret = fr->audio_start; 00620 *get_frame = 0; 00621 00622 /* But we try to find something better. */ 00623 /* Xing VBR TOC works with relative positions, both in terms of audio frames and stream bytes. 00624 Thus, it only works when whe know the length of things. 00625 Oh... I assume the offsets are relative to the _total_ file length. */ 00626 if(fr->xing_toc != NULL && fr->track_frames > 0 && fr->rdat.filelen > 0) 00627 { 00628 /* One could round... */ 00629 int toc_entry = (int) ((double)want_frame*100./fr->track_frames); 00630 /* It is an index in the 100-entry table. */ 00631 if(toc_entry < 0) toc_entry = 0; 00632 if(toc_entry > 99) toc_entry = 99; 00633 00634 /* Now estimate back what frame we get. */ 00635 *get_frame = (off_t) ((double)toc_entry/100. * fr->track_frames); 00636 fr->accurate = FALSE; 00637 fr->silent_resync = 1; 00638 /* Question: Is the TOC for whole file size (with/without ID3) or the "real" audio data only? 00639 ID3v1 info could also matter. */ 00640 ret = (off_t) ((double)fr->xing_toc[toc_entry]/256.* fr->rdat.filelen); 00641 } 00642 else if(fr->mean_framesize > 0) 00643 { /* Just guess with mean framesize (may be exact with CBR files). */ 00644 /* Query filelen here or not? */ 00645 fr->accurate = FALSE; /* Fuzzy! */ 00646 fr->silent_resync = 1; 00647 *get_frame = want_frame; 00648 ret = (off_t) (fr->audio_start+fr->mean_framesize*want_frame); 00649 } 00650 debug5("fuzzy: want %li of %li, get %li at %li B of %li B", 00651 (long)want_frame, (long)fr->track_frames, (long)*get_frame, (long)ret, (long)(fr->rdat.filelen-fr->audio_start)); 00652 return ret; 00653 } 00654 00655 /* 00656 find the best frame in index just before the wanted one, seek to there 00657 then step to just before wanted one with read_frame 00658 do not care tabout the stuff that was in buffer but not played back 00659 everything that left the decoder is counted as played 00660 00661 Decide if you want low latency reaction and accurate timing info or stable long-time playback with buffer! 00662 */ 00663 00664 off_t frame_index_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame) 00665 { 00666 /* default is file start if no index position */ 00667 off_t gopos = 0; 00668 *get_frame = 0; 00669 #ifdef FRAME_INDEX 00670 /* Possibly use VBRI index, too? I'd need an example for this... */ 00671 if(fr->index.fill) 00672 { 00673 /* find in index */ 00674 size_t fi; 00675 /* at index fi there is frame step*fi... */ 00676 fi = want_frame/fr->index.step; 00677 if(fi >= fr->index.fill) /* If we are beyond the end of frame index...*/ 00678 { 00679 /* When fuzzy seek is allowed, we have some limited tolerance for the frames we want to read rather then jump over. */ 00680 if(fr->p.flags & MPG123_FUZZY && want_frame - (fr->index.fill-1)*fr->index.step > 10) 00681 { 00682 gopos = frame_fuzzy_find(fr, want_frame, get_frame); 00683 if(gopos > fr->audio_start) return gopos; /* Only in that case, we have a useful guess. */ 00684 /* Else... just continue, fuzzyness didn't help. */ 00685 } 00686 /* Use the last available position, slowly advancing from that one. */ 00687 fi = fr->index.fill - 1; 00688 } 00689 /* We have index position, that yields frame and byte offsets. */ 00690 *get_frame = fi*fr->index.step; 00691 gopos = fr->index.data[fi]; 00692 fr->accurate = TRUE; /* When using the frame index, we are accurate. */ 00693 } 00694 else 00695 { 00696 #endif 00697 if(fr->p.flags & MPG123_FUZZY) 00698 return frame_fuzzy_find(fr, want_frame, get_frame); 00699 /* A bit hackish here... but we need to be fresh when looking for the first header again. */ 00700 fr->firsthead = 0; 00701 fr->oldhead = 0; 00702 #ifdef FRAME_INDEX 00703 } 00704 #endif 00705 debug2("index: 0x%lx for frame %li", (unsigned long)gopos, (long) *get_frame); 00706 return gopos; 00707 } 00708 00709 off_t frame_ins2outs(mpg123_handle *fr, off_t ins) 00710 { 00711 off_t outs = 0; 00712 switch(fr->down_sample) 00713 { 00714 case 0: 00715 # ifndef NO_DOWNSAMPLE 00716 case 1: 00717 case 2: 00718 # endif 00719 outs = ins>>fr->down_sample; 00720 break; 00721 # ifndef NO_NTOM 00722 case 3: outs = ntom_ins2outs(fr, ins); break; 00723 # endif 00724 default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample); 00725 } 00726 return outs; 00727 } 00728 00729 off_t frame_outs(mpg123_handle *fr, off_t num) 00730 { 00731 off_t outs = 0; 00732 switch(fr->down_sample) 00733 { 00734 case 0: 00735 # ifndef NO_DOWNSAMPLE 00736 case 1: 00737 case 2: 00738 # endif 00739 outs = (spf(fr)>>fr->down_sample)*num; 00740 break; 00741 #ifndef NO_NTOM 00742 case 3: outs = ntom_frmouts(fr, num); break; 00743 #endif 00744 default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample); 00745 } 00746 return outs; 00747 } 00748 00749 /* Compute the number of output samples we expect from this frame. 00750 This is either simple spf() or a tad more elaborate for ntom. */ 00751 off_t frame_expect_outsamples(mpg123_handle *fr) 00752 { 00753 off_t outs = 0; 00754 switch(fr->down_sample) 00755 { 00756 case 0: 00757 # ifndef NO_DOWNSAMPLE 00758 case 1: 00759 case 2: 00760 # endif 00761 outs = spf(fr)>>fr->down_sample; 00762 break; 00763 #ifndef NO_NTOM 00764 case 3: outs = ntom_frame_outsamples(fr); break; 00765 #endif 00766 default: error1("Bad down_sample (%i) ... should not be possible!!", fr->down_sample); 00767 } 00768 return outs; 00769 } 00770 00771 off_t frame_offset(mpg123_handle *fr, off_t outs) 00772 { 00773 off_t num = 0; 00774 switch(fr->down_sample) 00775 { 00776 case 0: 00777 # ifndef NO_DOWNSAMPLE 00778 case 1: 00779 case 2: 00780 # endif 00781 num = outs/(spf(fr)>>fr->down_sample); 00782 break; 00783 #ifndef NO_NTOM 00784 case 3: num = ntom_frameoff(fr, outs); break; 00785 #endif 00786 default: error("Bad down_sample ... should not be possible!!"); 00787 } 00788 return num; 00789 } 00790 00791 #ifdef GAPLESS 00792 /* input in _input_ samples */ 00793 void frame_gapless_init(mpg123_handle *fr, off_t b, off_t e) 00794 { 00795 fr->begin_s = b; 00796 fr->end_s = e; 00797 /* These will get proper values later, from above plus resampling info. */ 00798 fr->begin_os = 0; 00799 fr->end_os = 0; 00800 debug2("frame_gapless_init: from %lu to %lu samples", (long unsigned)fr->begin_s, (long unsigned)fr->end_s); 00801 } 00802 00803 void frame_gapless_realinit(mpg123_handle *fr) 00804 { 00805 fr->begin_os = frame_ins2outs(fr, fr->begin_s); 00806 fr->end_os = frame_ins2outs(fr, fr->end_s); 00807 debug2("frame_gapless_realinit: from %lu to %lu samples", (long unsigned)fr->begin_os, (long unsigned)fr->end_os); 00808 } 00809 00810 /* When we got a new sample count, update the gaplessness. */ 00811 void frame_gapless_update(mpg123_handle *fr, off_t total_samples) 00812 { 00813 if(fr->end_s < 1) 00814 { 00815 fr->end_s = total_samples; 00816 frame_gapless_realinit(fr); 00817 } 00818 else if(fr->end_s > total_samples) 00819 { 00820 if(NOQUIET) error2("end sample count smaller than gapless end! (%"OFF_P" < %"OFF_P").", (off_p)total_samples, (off_p)fr->end_s); 00821 /* Humbly disabling gapless stuff on track end. */ 00822 fr->end_s = 0; 00823 frame_gapless_realinit(fr); 00824 fr->lastframe = -1; 00825 fr->lastoff = 0; 00826 } 00827 } 00828 00829 #endif 00830 00831 /* Compute the needed frame to ignore from, for getting accurate/consistent output for intended firstframe. */ 00832 static off_t ignoreframe(mpg123_handle *fr) 00833 { 00834 off_t preshift = fr->p.preframes; 00835 /* Layer 3 _really_ needs at least one frame before. */ 00836 if(fr->lay==3 && preshift < 1) preshift = 1; 00837 /* Layer 1 & 2 reall do not need more than 2. */ 00838 if(fr->lay!=3 && preshift > 2) preshift = 2; 00839 00840 return fr->firstframe - preshift; 00841 } 00842 00843 /* The frame seek... This is not simply the seek to fe*spf(fr) samples in output because we think of _input_ frames here. 00844 Seek to frame offset 1 may be just seek to 200 samples offset in output since the beginning of first frame is delay/padding. 00845 Hm, is that right? OK for the padding stuff, but actually, should the decoder delay be better totally hidden or not? 00846 With gapless, even the whole frame position could be advanced further than requested (since Homey don't play dat). */ 00847 void frame_set_frameseek(mpg123_handle *fr, off_t fe) 00848 { 00849 fr->firstframe = fe; 00850 #ifdef GAPLESS 00851 if(fr->p.flags & MPG123_GAPLESS) 00852 { 00853 /* Take care of the beginning... */ 00854 off_t beg_f = frame_offset(fr, fr->begin_os); 00855 if(fe <= beg_f) 00856 { 00857 fr->firstframe = beg_f; 00858 fr->firstoff = fr->begin_os - frame_outs(fr, beg_f); 00859 } 00860 else fr->firstoff = 0; 00861 /* The end is set once for a track at least, on the frame_set_frameseek called in get_next_frame() */ 00862 if(fr->end_os > 0) 00863 { 00864 fr->lastframe = frame_offset(fr,fr->end_os); 00865 fr->lastoff = fr->end_os - frame_outs(fr, fr->lastframe); 00866 } else fr->lastoff = 0; 00867 } else { fr->firstoff = fr->lastoff = 0; fr->lastframe = -1; } 00868 #endif 00869 fr->ignoreframe = ignoreframe(fr); 00870 #ifdef GAPLESS 00871 debug5("frame_set_frameseek: begin at %li frames and %li samples, end at %li and %li; ignore from %li", 00872 (long) fr->firstframe, (long) fr->firstoff, 00873 (long) fr->lastframe, (long) fr->lastoff, (long) fr->ignoreframe); 00874 #else 00875 debug3("frame_set_frameseek: begin at %li frames, end at %li; ignore from %li", 00876 (long) fr->firstframe, (long) fr->lastframe, (long) fr->ignoreframe); 00877 #endif 00878 } 00879 00880 void frame_skip(mpg123_handle *fr) 00881 { 00882 #ifndef NO_LAYER3 00883 if(fr->lay == 3) set_pointer(fr, 512); 00884 #endif 00885 } 00886 00887 /* Sample accurate seek prepare for decoder. */ 00888 /* This gets unadjusted output samples and takes resampling into account */ 00889 void frame_set_seek(mpg123_handle *fr, off_t sp) 00890 { 00891 fr->firstframe = frame_offset(fr, sp); 00892 #ifndef NO_NTOM 00893 if(fr->down_sample == 3) ntom_set_ntom(fr, fr->firstframe); 00894 #endif 00895 fr->ignoreframe = ignoreframe(fr); 00896 #ifdef GAPLESS /* The sample offset is used for non-gapless mode, too! */ 00897 fr->firstoff = sp - frame_outs(fr, fr->firstframe); 00898 debug5("frame_set_seek: begin at %li frames and %li samples, end at %li and %li; ignore from %li", 00899 (long) fr->firstframe, (long) fr->firstoff, 00900 (long) fr->lastframe, (long) fr->lastoff, (long) fr->ignoreframe); 00901 #else 00902 debug3("frame_set_seek: begin at %li frames, end at %li; ignore from %li", 00903 (long) fr->firstframe, (long) fr->lastframe, (long) fr->ignoreframe); 00904 #endif 00905 /* Old bit reservoir should be invalid, eh? */ 00906 fr->bitreservoir = 0; 00907 } 00908 00909 int attribute_align_arg mpg123_volume_change(mpg123_handle *mh, double change) 00910 { 00911 if(mh == NULL) return MPG123_ERR; 00912 return mpg123_volume(mh, change + (double) mh->p.outscale); 00913 } 00914 00915 int attribute_align_arg mpg123_volume(mpg123_handle *mh, double vol) 00916 { 00917 if(mh == NULL) return MPG123_ERR; 00918 00919 if(vol >= 0) mh->p.outscale = vol; 00920 else mh->p.outscale = 0.; 00921 00922 do_rva(mh); 00923 return MPG123_OK; 00924 } 00925 00926 static int get_rva(mpg123_handle *fr, double *peak, double *gain) 00927 { 00928 double p = -1; 00929 double g = 0; 00930 int ret = 0; 00931 if(fr->p.rva) 00932 { 00933 int rt = 0; 00934 /* Should one assume a zero RVA as no RVA? */ 00935 if(fr->p.rva == 2 && fr->rva.level[1] != -1) rt = 1; 00936 if(fr->rva.level[rt] != -1) 00937 { 00938 p = fr->rva.peak[rt]; 00939 g = fr->rva.gain[rt]; 00940 ret = 1; /* Success. */ 00941 } 00942 } 00943 if(peak != NULL) *peak = p; 00944 if(gain != NULL) *gain = g; 00945 return ret; 00946 } 00947 00948 /* adjust the volume, taking both fr->outscale and rva values into account */ 00949 void do_rva(mpg123_handle *fr) 00950 { 00951 double peak = 0; 00952 double gain = 0; 00953 double newscale; 00954 double rvafact = 1; 00955 if(get_rva(fr, &peak, &gain)) 00956 { 00957 if(NOQUIET && fr->p.verbose > 1) fprintf(stderr, "Note: doing RVA with gain %f\n", gain); 00958 rvafact = pow(10,gain/20); 00959 } 00960 00961 newscale = fr->p.outscale*rvafact; 00962 00963 /* if peak is unknown (== 0) this check won't hurt */ 00964 if((peak*newscale) > 1.0) 00965 { 00966 newscale = 1.0/peak; 00967 warning2("limiting scale value to %f to prevent clipping with indicated peak factor of %f", newscale, peak); 00968 } 00969 /* first rva setting is forced with fr->lastscale < 0 */ 00970 if(newscale != fr->lastscale || fr->decoder_change) 00971 { 00972 debug3("changing scale value from %f to %f (peak estimated to %f)", fr->lastscale != -1 ? fr->lastscale : fr->p.outscale, newscale, (double) (newscale*peak)); 00973 fr->lastscale = newscale; 00974 /* It may be too early, actually. */ 00975 if(fr->make_decode_tables != NULL) fr->make_decode_tables(fr); /* the actual work */ 00976 } 00977 } 00978 00979 00980 int attribute_align_arg mpg123_getvolume(mpg123_handle *mh, double *base, double *really, double *rva_db) 00981 { 00982 if(mh == NULL) return MPG123_ERR; 00983 if(base) *base = mh->p.outscale; 00984 if(really) *really = mh->lastscale; 00985 get_rva(mh, NULL, rva_db); 00986 return MPG123_OK; 00987 } 00988 Generated on Sat May 26 2012 04:24:50 for ReactOS by
1.7.6.1
|