ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

libmpg123.c
Go to the documentation of this file.
00001 /*
00002     libmpg123: MPEG Audio Decoder library
00003 
00004     copyright 1995-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 
00007 */
00008 
00009 #include "mpg123lib_intern.h"
00010 #include "icy2utf8.h"
00011 #include "debug.h"
00012 
00013 #ifdef GAPLESS
00014 #define SAMPLE_ADJUST(x)   ((x) - ((mh->p.flags & MPG123_GAPLESS) ? mh->begin_os : 0))
00015 #define SAMPLE_UNADJUST(x) ((x) + ((mh->p.flags & MPG123_GAPLESS) ? mh->begin_os : 0))
00016 #else
00017 #define SAMPLE_ADJUST(x)   (x)
00018 #define SAMPLE_UNADJUST(x) (x)
00019 #endif
00020 
00021 #define SEEKFRAME(mh) ((mh)->ignoreframe < 0 ? 0 : (mh)->ignoreframe)
00022 
00023 static int initialized = 0;
00024 
00025 #include "aligncheck.h"
00026 
00027 #ifdef GAPLESS
00028 /*
00029     Take the buffer after a frame decode (strictly: it is the data from frame fr->num!) and cut samples out.
00030     fr->buffer.fill may then be smaller than before...
00031 */
00032 static void frame_buffercheck(mpg123_handle *fr)
00033 {
00034     /* When we have no accurate position, gapless code does not make sense. */
00035     if(!fr->accurate) return;
00036 
00037     /* Important: We first cut samples from the end, then cut from beginning (including left-shift of the buffer).
00038        This order works also for the case where firstframe == lastframe. */
00039 
00040     /* The last interesting (planned) frame: Only use some leading samples.
00041        Note a difference from the below: The last frame and offset are unchanges by seeks.
00042        The lastoff keeps being valid. */
00043     if(fr->lastframe > -1 && fr->num >= fr->lastframe)
00044     {
00045         /* There can be more than one frame of padding at the end, so we ignore the whole frame if we are beyond lastframe. */
00046         off_t byteoff = (fr->num == fr->lastframe) ? samples_to_bytes(fr, fr->lastoff) : 0;
00047         if((off_t)fr->buffer.fill > byteoff)
00048         {
00049             fr->buffer.fill = byteoff;
00050         }
00051         debug1("Cut frame buffer on end of stream, fill now %"SIZE_P" bytes.", (size_p)fr->buffer.fill);
00052     }
00053 
00054     /* The first interesting frame: Skip some leading samples. */
00055     if(fr->firstoff && fr->num == fr->firstframe)
00056     {
00057         off_t byteoff = samples_to_bytes(fr, fr->firstoff);
00058         if((off_t)fr->buffer.fill > byteoff)
00059         {
00060             fr->buffer.fill -= byteoff;
00061             /* buffer.p != buffer.data only for own buffer */
00062             debug6("cutting %li samples/%li bytes on begin, own_buffer=%i at %p=%p, buf[1]=%i",
00063                     (long)fr->firstoff, (long)byteoff, fr->own_buffer, (void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]);
00064             if(fr->own_buffer) fr->buffer.p = fr->buffer.data + byteoff;
00065             else memmove(fr->buffer.data, fr->buffer.data + byteoff, fr->buffer.fill);
00066             debug3("done cutting, buffer at %p =? %p, buf[1]=%i",
00067                     (void*)fr->buffer.p, (void*)fr->buffer.data, ((short*)fr->buffer.p)[2]);
00068         }
00069         else fr->buffer.fill = 0;
00070         /* We can only reach this frame again by seeking. And on seeking, firstoff will be recomputed.
00071            So it is safe to null it here (and it makes the if() decision abort earlier). */
00072         fr->firstoff = 0;
00073     }
00074 }
00075 #endif
00076 
00077 int attribute_align_arg mpg123_init(void)
00078 {
00079     ALIGNCHECKK
00080     if((sizeof(short) != 2) || (sizeof(long) < 4)) return MPG123_BAD_TYPES;
00081 
00082     if(initialized) return MPG123_OK; /* no need to initialize twice */
00083 
00084 #ifndef NO_LAYER12
00085     init_layer12(); /* inits also shared tables with layer1 */
00086 #endif
00087 #ifndef NO_LAYER3
00088     init_layer3();
00089 #endif
00090     prepare_decode_tables();
00091     check_decoders();
00092     initialized = 1;
00093     return MPG123_OK;
00094 }
00095 
00096 void attribute_align_arg mpg123_exit(void)
00097 {
00098     /* nothing yet, but something later perhaps */
00099 }
00100 
00101 /* create a new handle with specified decoder, decoder can be "", "auto" or NULL for auto-detection */
00102 mpg123_handle attribute_align_arg *mpg123_new(const char* decoder, int *error)
00103 {
00104     return mpg123_parnew(NULL, decoder, error);
00105 }
00106 
00107 /* ...the full routine with optional initial parameters to override defaults. */
00108 mpg123_handle attribute_align_arg *mpg123_parnew(mpg123_pars *mp, const char* decoder, int *error)
00109 {
00110     mpg123_handle *fr = NULL;
00111     int err = MPG123_OK;
00112 #if (defined CCALIGN) && (defined NEED_ALIGNCHECK) && ((defined DEBUG) || (defined CHECK_ALIGN))
00113 #ifdef CCALIGN
00114     double ALIGNED(16) altest[4];
00115     if(((size_t)altest) % 16 != 0)
00116     {
00117         error("Stack variable is not aligned! Your combination of compiler/library is dangerous!");
00118         *error = MPG123_BAD_ALIGN;
00119         return NULL;
00120     }
00121 #endif
00122 #endif
00123     if(initialized) fr = (mpg123_handle*) malloc(sizeof(mpg123_handle));
00124     else err = MPG123_NOT_INITIALIZED;
00125     if(fr != NULL)
00126     {
00127         frame_init_par(fr, mp);
00128         debug("cpu opt setting");
00129         if(frame_cpu_opt(fr, decoder) != 1)
00130         {
00131             err = MPG123_BAD_DECODER;
00132             frame_exit(fr);
00133             free(fr);
00134             fr = NULL;
00135         }
00136     }
00137     if(fr != NULL)
00138     {
00139         /* Cleanup that mess! ... use mpg123_decoder / decode_update! */
00140         if(frame_outbuffer(fr) != 0)
00141         {
00142             err = MPG123_NO_BUFFERS;
00143             frame_exit(fr);
00144             free(fr);
00145             fr = NULL;
00146         }
00147         else
00148         {
00149             /* I smell cleanup here... with get_next_frame() */
00150 /*          if(decode_update(fr) != 0)
00151             {
00152                 err = fr->err != MPG123_OK ? fr->err : MPG123_BAD_DECODER;
00153                 frame_exit(fr);
00154                 free(fr);
00155                 fr = NULL;
00156             }
00157             else */
00158             fr->decoder_change = 1;
00159         }
00160     }
00161     else if(err == MPG123_OK) err = MPG123_OUT_OF_MEM;
00162 
00163     if(error != NULL) *error = err;
00164     return fr;
00165 }
00166 
00167 int attribute_align_arg mpg123_decoder(mpg123_handle *mh, const char* decoder)
00168 {
00169     enum optdec dt = dectype(decoder);
00170     ALIGNCHECK(mh);
00171     if(mh == NULL) return MPG123_ERR;
00172 
00173     if(dt == nodec)
00174     {
00175         mh->err = MPG123_BAD_DECODER;
00176         return MPG123_ERR;
00177     }
00178     if(dt == mh->cpu_opts.type) return MPG123_OK;
00179 
00180     /* Now really change. */
00181     /* frame_exit(mh);
00182     frame_init(mh); */
00183     debug("cpu opt setting");
00184     if(frame_cpu_opt(mh, decoder) != 1)
00185     {
00186         mh->err = MPG123_BAD_DECODER;
00187         frame_exit(mh);
00188         return MPG123_ERR;
00189     }
00190     /* New buffers for decoder are created in frame_buffers() */
00191     if((frame_outbuffer(mh) != 0))
00192     {
00193         mh->err = MPG123_NO_BUFFERS;
00194         frame_exit(mh);
00195         return MPG123_ERR;
00196     }
00197     /* I smell cleanup here... with get_next_frame() */
00198     decode_update(mh);
00199     mh->decoder_change = 1;
00200     return MPG123_OK;
00201 }
00202 
00203 int attribute_align_arg mpg123_param(mpg123_handle *mh, enum mpg123_parms key, long val, double fval)
00204 {
00205     int r;
00206     ALIGNCHECK(mh);
00207     if(mh == NULL) return MPG123_ERR;
00208     r = mpg123_par(&mh->p, key, val, fval);
00209     if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
00210     else
00211     { /* Special treatment for some settings. */
00212 #ifdef FRAME_INDEX
00213         if(key == MPG123_INDEX_SIZE)
00214         { /* Apply frame index size and grow property on the fly. */
00215             r = frame_index_setup(mh);
00216             if(r != MPG123_OK) mh->err = MPG123_INDEX_FAIL;
00217         }
00218 #endif
00219     }
00220     return r;
00221 }
00222 
00223 int attribute_align_arg mpg123_par(mpg123_pars *mp, enum mpg123_parms key, long val, double fval)
00224 {
00225     int ret = MPG123_OK;
00226     ALIGNCHECKK
00227     if(mp == NULL) return MPG123_BAD_PARS;
00228     switch(key)
00229     {
00230         case MPG123_VERBOSE:
00231             mp->verbose = val;
00232         break;
00233         case MPG123_FLAGS:
00234 #ifndef GAPLESS
00235             if(val & MPG123_GAPLESS) ret = MPG123_NO_GAPLESS;
00236 #endif
00237             if(ret == MPG123_OK) mp->flags = val;
00238             debug1("set flags to 0x%lx", (unsigned long) mp->flags);
00239         break;
00240         case MPG123_ADD_FLAGS:
00241 #ifndef GAPLESS
00242             /* Enabling of gapless mode doesn't work when it's not there, but disabling (below) is no problem. */
00243             if(val & MPG123_GAPLESS) ret = MPG123_NO_GAPLESS;
00244             else
00245 #endif
00246             mp->flags |= val;
00247             debug1("set flags to 0x%lx", (unsigned long) mp->flags);
00248         break;
00249         case MPG123_REMOVE_FLAGS:
00250             mp->flags &= ~val;
00251             debug1("set flags to 0x%lx", (unsigned long) mp->flags);
00252         break;
00253         case MPG123_FORCE_RATE: /* should this trigger something? */
00254 #ifdef NO_NTOM
00255             if(val > 0)
00256             ret = MPG123_BAD_RATE;
00257 #else
00258             if(val > 96000) ret = MPG123_BAD_RATE;
00259             else mp->force_rate = val < 0 ? 0 : val; /* >0 means enable, 0 disable */
00260 #endif
00261         break;
00262         case MPG123_DOWN_SAMPLE:
00263 #ifdef NO_DOWNSAMPLE
00264             if(val != 0) ret = MPG123_BAD_RATE;
00265 #else
00266             if(val < 0 || val > 2) ret = MPG123_BAD_RATE;
00267             else mp->down_sample = (int)val;
00268 #endif
00269         break;
00270         case MPG123_RVA:
00271             if(val < 0 || val > MPG123_RVA_MAX) ret = MPG123_BAD_RVA;
00272             else mp->rva = (int)val;
00273         break;
00274         case MPG123_DOWNSPEED:
00275             mp->halfspeed = val < 0 ? 0 : val;
00276         break;
00277         case MPG123_UPSPEED:
00278             mp->doublespeed = val < 0 ? 0 : val;
00279         break;
00280         case MPG123_ICY_INTERVAL:
00281 #ifndef NO_ICY
00282             mp->icy_interval = val > 0 ? val : 0;
00283 #else
00284             if(val > 0) ret = MPG123_BAD_PARAM;
00285 #endif
00286         break;
00287         case MPG123_OUTSCALE:
00288             /* Choose the value that is non-zero, if any.
00289                Downscaling integers to 1.0 . */
00290             mp->outscale = val == 0 ? fval : (double)val/SHORT_SCALE;
00291         break;
00292         case MPG123_TIMEOUT:
00293 #ifdef TIMEOUT_READ
00294             mp->timeout = val >= 0 ? val : 0;
00295 #else
00296             if(val > 0) ret = MPG123_NO_TIMEOUT;
00297 #endif
00298         break;
00299         case MPG123_RESYNC_LIMIT:
00300             mp->resync_limit = val;
00301         break;
00302         case MPG123_INDEX_SIZE:
00303 #ifdef FRAME_INDEX
00304             mp->index_size = val;
00305 #else
00306             ret = MPG123_NO_INDEX;
00307 #endif
00308         break;
00309         case MPG123_PREFRAMES:
00310             if(val >= 0) mp->preframes = val;
00311             else ret = MPG123_BAD_VALUE;
00312         break;
00313         default:
00314             ret = MPG123_BAD_PARAM;
00315     }
00316     return ret;
00317 }
00318 
00319 int attribute_align_arg mpg123_getparam(mpg123_handle *mh, enum mpg123_parms key, long *val, double *fval)
00320 {
00321     int r;
00322     ALIGNCHECK(mh);
00323     if(mh == NULL) return MPG123_ERR;
00324     r = mpg123_getpar(&mh->p, key, val, fval);
00325     if(r != MPG123_OK){ mh->err = r; r = MPG123_ERR; }
00326     return r;
00327 }
00328 
00329 int attribute_align_arg mpg123_getpar(mpg123_pars *mp, enum mpg123_parms key, long *val, double *fval)
00330 {
00331     int ret = 0;
00332     ALIGNCHECKK
00333     if(mp == NULL) return MPG123_BAD_PARS;
00334     switch(key)
00335     {
00336         case MPG123_VERBOSE:
00337             if(val) *val = mp->verbose;
00338         break;
00339         case MPG123_FLAGS:
00340         case MPG123_ADD_FLAGS:
00341             if(val) *val = mp->flags;
00342         break;
00343         case MPG123_FORCE_RATE:
00344             if(val) 
00345 #ifdef NO_NTOM
00346             *val = 0;
00347 #else
00348             *val = mp->force_rate;
00349 #endif
00350         break;
00351         case MPG123_DOWN_SAMPLE:
00352             if(val) *val = mp->down_sample;
00353         break;
00354         case MPG123_RVA:
00355             if(val) *val = mp->rva;
00356         break;
00357         case MPG123_DOWNSPEED:
00358             if(val) *val = mp->halfspeed;
00359         break;
00360         case MPG123_UPSPEED:
00361             if(val) *val = mp->doublespeed;
00362         break;
00363         case MPG123_ICY_INTERVAL:
00364 #ifndef NO_ICY
00365             if(val) *val = (long)mp->icy_interval;
00366 #else
00367             if(val) *val = 0;
00368 #endif
00369         break;
00370         case MPG123_OUTSCALE:
00371             if(fval) *fval = mp->outscale;
00372             if(val) *val = (long)(mp->outscale*SHORT_SCALE);
00373         break;
00374         case MPG123_RESYNC_LIMIT:
00375             if(val) *val = mp->resync_limit;
00376         break;
00377         case MPG123_INDEX_SIZE:
00378             if(val)
00379 #ifdef FRAME_INDEX
00380             *val = mp->index_size;
00381 #else
00382             *val = 0; /* graceful fallback: no index is index of zero size */
00383 #endif
00384         break;
00385         case MPG123_PREFRAMES:
00386             *val = mp->preframes;
00387         break;
00388         default:
00389             ret = MPG123_BAD_PARAM;
00390     }
00391     return ret;
00392 }
00393 
00394 int attribute_align_arg mpg123_getstate(mpg123_handle *mh, enum mpg123_state key, long *val, double *fval)
00395 {
00396     int ret = MPG123_OK;
00397     long theval = 0;
00398     double thefval = 0.;
00399     ALIGNCHECK(mh);
00400     if(mh == NULL) return MPG123_ERR;
00401 
00402     switch(key)
00403     {
00404         case MPG123_ACCURATE:
00405             theval = mh->accurate;
00406         break;
00407         default:
00408             mh->err = MPG123_BAD_KEY;
00409             ret = MPG123_ERR;
00410     }
00411 
00412     if(val  != NULL) *val  = theval;
00413     if(fval != NULL) *fval = thefval;
00414 
00415     return ret;
00416 }
00417 
00418 int attribute_align_arg mpg123_eq(mpg123_handle *mh, enum mpg123_channels channel, int band, double val)
00419 {
00420     ALIGNCHECK(mh);
00421     if(mh == NULL) return MPG123_ERR;
00422     if(band < 0 || band > 31){ mh->err = MPG123_BAD_BAND; return MPG123_ERR; }
00423     switch(channel)
00424     {
00425         case MPG123_LEFT|MPG123_RIGHT:
00426             mh->equalizer[0][band] = mh->equalizer[1][band] = DOUBLE_TO_REAL(val);
00427         break;
00428         case MPG123_LEFT:  mh->equalizer[0][band] = DOUBLE_TO_REAL(val); break;
00429         case MPG123_RIGHT: mh->equalizer[1][band] = DOUBLE_TO_REAL(val); break;
00430         default:
00431             mh->err=MPG123_BAD_CHANNEL;
00432             return MPG123_ERR;
00433     }
00434     mh->have_eq_settings = TRUE;
00435     return MPG123_OK;
00436 }
00437 
00438 double attribute_align_arg mpg123_geteq(mpg123_handle *mh, enum mpg123_channels channel, int band)
00439 {
00440     double ret = 0.;
00441     ALIGNCHECK(mh);
00442     if(mh == NULL) return MPG123_ERR;
00443 
00444     /* Handle this gracefully. When there is no band, it has no volume. */
00445     if(band > -1 && band < 32)
00446     switch(channel)
00447     {
00448         case MPG123_LEFT|MPG123_RIGHT:
00449             ret = 0.5*(REAL_TO_DOUBLE(mh->equalizer[0][band])+REAL_TO_DOUBLE(mh->equalizer[1][band]));
00450         break;
00451         case MPG123_LEFT:  ret = REAL_TO_DOUBLE(mh->equalizer[0][band]); break;
00452         case MPG123_RIGHT: ret = REAL_TO_DOUBLE(mh->equalizer[1][band]); break;
00453         /* Default case is already handled: ret = 0 */
00454     }
00455 
00456     return ret;
00457 }
00458 
00459 
00460 /* plain file access, no http! */
00461 int attribute_align_arg mpg123_open(mpg123_handle *mh, const char *path)
00462 {
00463     ALIGNCHECK(mh);
00464     if(mh == NULL) return MPG123_ERR;
00465 
00466     mpg123_close(mh);
00467     return open_stream(mh, path, -1);
00468 }
00469 
00470 int attribute_align_arg mpg123_open_fd(mpg123_handle *mh, int fd)
00471 {
00472     ALIGNCHECK(mh);
00473     if(mh == NULL) return MPG123_ERR;
00474 
00475     mpg123_close(mh);
00476     return open_stream(mh, NULL, fd);
00477 }
00478 
00479 int attribute_align_arg mpg123_open_handle(mpg123_handle *mh, void *iohandle)
00480 {
00481     ALIGNCHECK(mh);
00482     if(mh == NULL) return MPG123_ERR;
00483 
00484     mpg123_close(mh);
00485     if(mh->rdat.r_read_handle == NULL)
00486     {
00487         mh->err = MPG123_BAD_CUSTOM_IO;
00488         return MPG123_ERR;
00489     }
00490     return open_stream_handle(mh, iohandle);
00491 }
00492 
00493 int attribute_align_arg mpg123_open_feed(mpg123_handle *mh)
00494 {
00495     ALIGNCHECK(mh);
00496     if(mh == NULL) return MPG123_ERR;
00497 
00498     mpg123_close(mh);
00499     return open_feed(mh);
00500 }
00501 
00502 int attribute_align_arg mpg123_replace_reader( mpg123_handle *mh,
00503                            long (*r_read) (int, void *, size_t),
00504                            off_t   (*r_lseek)(int, off_t, int) )
00505 {
00506     ALIGNCHECK(mh);
00507     if(mh == NULL) return MPG123_ERR;
00508 
00509     mpg123_close(mh);
00510     mh->rdat.r_read = r_read;
00511     mh->rdat.r_lseek = r_lseek;
00512     return MPG123_OK;
00513 }
00514 
00515 int attribute_align_arg mpg123_replace_reader_handle( mpg123_handle *mh,
00516                            long (*r_read) (void*, void *, size_t),
00517                            off_t   (*r_lseek)(void*, off_t, int),
00518                            void    (*cleanup)(void*)  )
00519 {
00520     ALIGNCHECK(mh);
00521     if(mh == NULL) return MPG123_ERR;
00522 
00523     mpg123_close(mh);
00524     mh->rdat.r_read_handle = r_read;
00525     mh->rdat.r_lseek_handle = r_lseek;
00526     mh->rdat.cleanup_handle = cleanup;
00527     return MPG123_OK;
00528 }
00529 
00530 int decode_update(mpg123_handle *mh)
00531 {
00532     long native_rate;
00533     int b;
00534     ALIGNCHECK(mh);
00535     native_rate = frame_freq(mh);
00536 
00537     b = frame_output_format(mh); /* Select the new output format based on given constraints. */
00538     if(b < 0) return MPG123_ERR;
00539 
00540     if(b == 1) mh->new_format = 1; /* Store for later... */
00541 
00542     debug3("updating decoder structure with native rate %li and af.rate %li (new format: %i)", native_rate, mh->af.rate, mh->new_format);
00543     if(mh->af.rate == native_rate) mh->down_sample = 0;
00544     else if(mh->af.rate == native_rate>>1) mh->down_sample = 1;
00545     else if(mh->af.rate == native_rate>>2) mh->down_sample = 2;
00546     else mh->down_sample = 3; /* flexible (fixed) rate */
00547     switch(mh->down_sample)
00548     {
00549         case 0:
00550         case 1:
00551         case 2:
00552             mh->down_sample_sblimit = SBLIMIT>>(mh->down_sample);
00553             /* With downsampling I get less samples per frame */
00554             mh->outblock = samples_to_bytes(mh, (spf(mh)>>mh->down_sample));
00555         break;
00556 #ifndef NO_NTOM
00557         case 3:
00558         {
00559             if(synth_ntom_set_step(mh) != 0) return -1;
00560             if(frame_freq(mh) > mh->af.rate)
00561             {
00562                 mh->down_sample_sblimit = SBLIMIT * mh->af.rate;
00563                 mh->down_sample_sblimit /= frame_freq(mh);
00564             }
00565             else mh->down_sample_sblimit = SBLIMIT;
00566             mh->outblock = mh->af.encsize * mh->af.channels *
00567                            ( ( NTOM_MUL-1+spf(mh)
00568                                * (((size_t)NTOM_MUL*mh->af.rate)/frame_freq(mh))
00569                              )/NTOM_MUL );
00570         }
00571         break;
00572 #endif
00573     }
00574 
00575     if(!(mh->p.flags & MPG123_FORCE_MONO))
00576     {
00577         if(mh->af.channels == 1) mh->single = SINGLE_MIX;
00578         else mh->single = SINGLE_STEREO;
00579     }
00580     else mh->single = (mh->p.flags & MPG123_FORCE_MONO)-1;
00581     if(set_synth_functions(mh) != 0) return -1;;
00582 
00583     do_rva(mh);
00584     debug3("done updating decoder structure with native rate %li and af.rate %li and down_sample %i", frame_freq(mh), mh->af.rate, mh->down_sample);
00585 
00586     return 0;
00587 }
00588 
00589 size_t attribute_align_arg mpg123_safe_buffer(void)
00590 {
00591     /* real is the largest possible output (it's 32bit float, 32bit int or 64bit double). */
00592     return sizeof(real)*2*1152*NTOM_MAX;
00593 }
00594 
00595 size_t attribute_align_arg mpg123_outblock(mpg123_handle *mh)
00596 {
00597     if(mh != NULL) return mh->outblock;
00598     else return mpg123_safe_buffer();
00599 }
00600 
00601 static int get_next_frame(mpg123_handle *mh)
00602 {
00603     int change = mh->decoder_change;
00604     do
00605     {
00606         int b;
00607         /* Decode & discard some frame(s) before beginning. */
00608         if(mh->to_ignore && mh->num < mh->firstframe && mh->num >= mh->ignoreframe)
00609         {
00610             debug1("ignoring frame %li", (long)mh->num);
00611             /* Decoder structure must be current! decode_update has been called before... */
00612             (mh->do_layer)(mh); mh->buffer.fill = 0;
00613 #ifndef NO_NTOM
00614             /* The ignored decoding may have failed. Make sure ntom stays consistent. */
00615             if(mh->down_sample == 3) ntom_set_ntom(mh, mh->num+1);
00616 #endif
00617             mh->to_ignore = mh->to_decode = FALSE;
00618         }
00619         /* Read new frame data; possibly breaking out here for MPG123_NEED_MORE. */
00620         debug("read frame");
00621         mh->to_decode = FALSE;
00622         b = read_frame(mh); /* That sets to_decode only if a full frame was read. */
00623         debug4("read of frame %li returned %i (to_decode=%i) at sample %li", (long)mh->num, b, mh->to_decode, (long)mpg123_tell(mh));
00624         if(b == MPG123_NEED_MORE) return MPG123_NEED_MORE; /* need another call with data */
00625         else if(b <= 0)
00626         {
00627             /* More sophisticated error control? */
00628             if(b==0 || mh->rdat.filepos == mh->rdat.filelen)
00629             { /* We simply reached the end. */
00630                 mh->track_frames = mh->num + 1;
00631                 debug("What about updating/checking gapless sample count here?");
00632                 return MPG123_DONE;
00633             }
00634             else return MPG123_ERR; /* Some real error. */
00635         }
00636         /* Now, there should be new data to decode ... and also possibly new stream properties */
00637         if(mh->header_change > 1)
00638         {
00639             debug("big header change");
00640             change = 1;
00641         }
00642         /* Now some accounting: Look at the numbers and decide if we want this frame. */
00643         ++mh->playnum;
00644         /* Plain skipping without decoding, only when frame is not ignored on next cycle. */
00645         if(mh->num < mh->firstframe || (mh->p.doublespeed && (mh->playnum % mh->p.doublespeed)))
00646         {
00647             if(!(mh->to_ignore && mh->num < mh->firstframe && mh->num >= mh->ignoreframe))
00648             {
00649                 frame_skip(mh);
00650                 /* Should one fix NtoM here or not?
00651                    It is not work the trouble for doublespeed, but what with leading frames? */
00652             }
00653         }
00654         /* Or, we are finally done and have a new frame. */
00655         else break;
00656     } while(1);
00657 
00658     if(change)
00659     {
00660         if(decode_update(mh) < 0)  /* dito... */
00661         return MPG123_ERR;
00662 
00663 debug1("new format: %i", mh->new_format);
00664 
00665         mh->decoder_change = 0;
00666         if(mh->fresh)
00667         {
00668 #ifdef GAPLESS
00669             int b=0;
00670             /* Prepare offsets for gapless decoding. */
00671             debug1("preparing gapless stuff with native rate %li", frame_freq(mh));
00672             frame_gapless_realinit(mh);
00673             frame_set_frameseek(mh, mh->num);
00674 #endif
00675             mh->fresh = 0;
00676 #ifdef GAPLESS
00677             /* Could this possibly happen? With a real big gapless offset... */
00678             if(mh->num < mh->firstframe) b = get_next_frame(mh);
00679             if(b < 0) return b; /* Could be error, need for more, new format... */
00680 #endif
00681         }
00682     }
00683     return MPG123_OK;
00684 }
00685 
00686 /* Assumption: A buffer full of zero samples can be constructed by repetition of this byte.
00687    Only to be used by decode_the_frame() ... */
00688 static int zero_byte(mpg123_handle *fr)
00689 {
00690 #ifndef NO_8BIT
00691     return fr->af.encoding & MPG123_ENC_8 ? fr->conv16to8[0] : 0;
00692 #else
00693     return 0; /* All normal signed formats have the zero here (even in byte form -- that may be an assumption for your funny machine...). */
00694 #endif
00695 }
00696 
00697 /*
00698     Not part of the api. This just decodes the frame and fills missing bits with zeroes.
00699     There can be frames that are broken and thus make do_layer() fail.
00700 */
00701 void decode_the_frame(mpg123_handle *fr)
00702 {
00703     size_t needed_bytes = samples_to_bytes(fr, frame_expect_outsamples(fr));    fr->clip += (fr->do_layer)(fr);
00704     /*fprintf(stderr, "frame %"OFF_P": got %"SIZE_P" / %"SIZE_P"\n", fr->num,(size_p)fr->buffer.fill, (size_p)needed_bytes);*/
00705     /* There could be less data than promised.
00706        Also, then debugging, we look out for coding errors that could result in _more_ data than expected. */
00707 #ifdef DEBUG
00708     if(fr->buffer.fill != needed_bytes)
00709     {
00710 #endif
00711         if(fr->buffer.fill < needed_bytes)
00712         {
00713             if(VERBOSE2)
00714             fprintf(stderr, "Note: broken frame %li, filling up with %"SIZE_P" zeroes, from %"SIZE_P"\n", (long)fr->num, (size_p)(needed_bytes-fr->buffer.fill), (size_p)fr->buffer.fill);
00715 
00716             /*
00717                 One could do a loop with individual samples instead... but zero is zero
00718                 Actually, that is wrong: zero is mostly a series of null bytes,
00719                 but we have funny 8bit formats that have a different opinion on zero...
00720                 Unsigned 16 or 32 bit formats are handled later.
00721             */
00722             memset( fr->buffer.data + fr->buffer.fill, zero_byte(fr), needed_bytes - fr->buffer.fill );
00723 
00724             fr->buffer.fill = needed_bytes;
00725 #ifndef NO_NTOM
00726             /* ntom_val will be wrong when the decoding wasn't carried out completely */
00727             ntom_set_ntom(fr, fr->num+1);
00728 #endif
00729         }
00730 #ifdef DEBUG
00731         else
00732         {
00733             if(NOQUIET)
00734             error2("I got _more_ bytes than expected (%"SIZE_P" / %"SIZE_P"), that should not be possible!", (size_p)fr->buffer.fill, (size_p)needed_bytes);
00735         }
00736     }
00737 #endif
00738     /* Handle unsigned output formats via reshifting after decode here. */
00739 #ifndef NO_32BIT
00740     if(fr->af.encoding == MPG123_ENC_UNSIGNED_32)
00741     { /* 32bit signed -> unsigned */
00742         size_t i;
00743         int32_t *ssamples;
00744         uint32_t *usamples;
00745         ssamples = (int32_t*)fr->buffer.data;
00746         usamples = (uint32_t*)fr->buffer.data;
00747         debug("converting output to unsigned 32 bit integer");
00748         for(i=0; i<fr->buffer.fill/sizeof(int32_t); ++i)
00749         {
00750             /* Different strategy since we don't have a larger type at hand.
00751                  Also watch out for silly +-1 fun because integer constants are signed in C90! */
00752             if(ssamples[i] >= 0)
00753             usamples[i] = (uint32_t)ssamples[i] + 2147483647+1;
00754             /* The smalles value goes zero. */
00755             else if(ssamples[i] == ((int32_t)-2147483647-1))
00756             usamples[i] = 0;
00757             /* Now -value is in the positive range of signed int ... so it's a possible value at all. */
00758             else
00759             usamples[i] = (uint32_t)2147483647+1 - (uint32_t)(-ssamples[i]);
00760         }
00761     }
00762 #endif
00763 #ifndef NO_16BIT
00764     if(fr->af.encoding == MPG123_ENC_UNSIGNED_16)
00765     {
00766         size_t i;
00767         short *ssamples;
00768         unsigned short *usamples;
00769         ssamples = (short*)fr->buffer.data;
00770         usamples = (unsigned short*)fr->buffer.data;
00771         debug("converting output to unsigned 16 bit integer");
00772         for(i=0; i<fr->buffer.fill/sizeof(short); ++i)
00773         {
00774             long tmp = (long)ssamples[i]+32768;
00775             usamples[i] = (unsigned short)tmp;
00776         }
00777     }
00778 #endif
00779 }
00780 
00781 /*
00782     Decode the current frame into the frame structure's buffer, accessible at the location stored in <audio>, with <bytes> bytes available.
00783     <num> will contain the last decoded frame number. This function should be called after mpg123_framebyframe_next positioned the stream at a
00784     valid mp3 frame. The buffer contents will get lost on the next call to mpg123_framebyframe_next or mpg123_framebyframe_decode.
00785     returns
00786     MPG123_OK -- successfully decoded or ignored the frame, you get your output data or in case of ignored frames 0 bytes
00787     MPG123_DONE -- decoding finished, should not happen
00788     MPG123_ERR -- some error occured.
00789     MPG123_ERR_NULL -- audio or bytes are not pointing to valid storage addresses
00790     MPG123_BAD_HANDLE -- mh has not been initialized
00791     MPG123_NO_SPACE -- not enough space in buffer for safe decoding, should not happen
00792 */
00793 int attribute_align_arg mpg123_framebyframe_decode(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes)
00794 {
00795     ALIGNCHECK(mh);
00796     if(bytes == NULL) return MPG123_ERR_NULL;
00797     if(audio == NULL) return MPG123_ERR_NULL;
00798     if(mh == NULL) return MPG123_BAD_HANDLE;
00799     if(mh->buffer.size < mh->outblock) return MPG123_NO_SPACE;
00800 
00801     *bytes = 0;
00802     mh->buffer.fill = 0; /* always start fresh */
00803     if(!mh->to_decode) return MPG123_OK;
00804 
00805     if(num != NULL) *num = mh->num;
00806     debug("decoding");
00807     decode_the_frame(mh);
00808     mh->to_decode = mh->to_ignore = FALSE;
00809     mh->buffer.p = mh->buffer.data;
00810 #ifdef GAPLESS
00811     /* This checks for individual samples to skip, for gapless mode or sample-accurate seek. */
00812     frame_buffercheck(mh);
00813 #endif
00814     *audio = mh->buffer.p;
00815     *bytes = mh->buffer.fill;
00816     return MPG123_OK;
00817 }
00818 
00819 /*
00820     Find, read and parse the next mp3 frame while skipping junk and parsing id3 tags, lame headers, etc.
00821     Prepares everything for decoding using mpg123_framebyframe_decode.
00822     returns
00823     MPG123_OK -- new frame was read and parsed, call mpg123_framebyframe_decode to actually decode
00824     MPG123_NEW_FORMAT -- new frame was read, it results in changed output format, call mpg123_framebyframe_decode to actually decode
00825     MPG123_BAD_HANDLE -- mh has not been initialized
00826     MPG123_NEED_MORE  -- more input data is needed to advance to the next frame. supply more input data using mpg123_feed
00827 */
00828 int attribute_align_arg mpg123_framebyframe_next(mpg123_handle *mh)
00829 {
00830     int b;
00831     if(mh == NULL) return MPG123_BAD_HANDLE;
00832 
00833     mh->to_decode = mh->to_ignore = FALSE;
00834     mh->buffer.fill = 0;
00835 
00836     b = get_next_frame(mh);
00837     if(b < 0) return b;
00838     debug1("got next frame, %i", mh->to_decode);
00839 
00840     /* mpg123_framebyframe_decode will return MPG123_OK with 0 bytes decoded if mh->to_decode is 0 */
00841     if(!mh->to_decode)
00842         return MPG123_OK;
00843 
00844     if(mh->new_format)
00845     {
00846         debug("notifiying new format");
00847         mh->new_format = 0;
00848         return MPG123_NEW_FORMAT;
00849     }
00850 
00851     return MPG123_OK;
00852 }
00853 
00854 /*
00855     Put _one_ decoded frame into the frame structure's buffer, accessible at the location stored in <audio>, with <bytes> bytes available.
00856     The buffer contents will be lost on next call to mpg123_decode_frame.
00857     MPG123_OK -- successfully decoded the frame, you get your output data
00858     MPg123_DONE -- This is it. End.
00859     MPG123_ERR -- some error occured...
00860     MPG123_NEW_FORMAT -- new frame was read, it results in changed output format -> will be decoded on next call
00861     MPG123_NEED_MORE  -- that should not happen as this function is intended for in-library stream reader but if you force it...
00862     MPG123_NO_SPACE   -- not enough space in buffer for safe decoding, also should not happen
00863 
00864     num will be updated to the last decoded frame number (may possibly _not_ increase, p.ex. when format changed).
00865 */
00866 int attribute_align_arg mpg123_decode_frame(mpg123_handle *mh, off_t *num, unsigned char **audio, size_t *bytes)
00867 {
00868     ALIGNCHECK(mh);
00869     if(bytes != NULL) *bytes = 0;
00870     if(mh == NULL) return MPG123_ERR;
00871     if(mh->buffer.size < mh->outblock) return MPG123_NO_SPACE;
00872     mh->buffer.fill = 0; /* always start fresh */
00873     while(TRUE)
00874     {
00875         /* decode if possible */
00876         if(mh->to_decode)
00877         {
00878             if(mh->new_format)
00879             {
00880                 debug("notifiying new format");
00881                 mh->new_format = 0;
00882                 return MPG123_NEW_FORMAT;
00883             }
00884             if(num != NULL) *num = mh->num;
00885             debug("decoding");
00886 
00887             decode_the_frame(mh);
00888 
00889             mh->to_decode = mh->to_ignore = FALSE;
00890             mh->buffer.p = mh->buffer.data;
00891 #ifdef GAPLESS
00892             /* This checks for individual samples to skip, for gapless mode or sample-accurate seek. */
00893             frame_buffercheck(mh);
00894 #endif
00895             if(audio != NULL) *audio = mh->buffer.p;
00896             if(bytes != NULL) *bytes = mh->buffer.fill;
00897 
00898             return MPG123_OK;
00899         }
00900         else
00901         {
00902             int b = get_next_frame(mh);
00903             if(b < 0) return b;
00904             debug1("got next frame, %i", mh->to_decode);
00905         }
00906     }
00907 }
00908 
00909 int attribute_align_arg mpg123_read(mpg123_handle *mh, unsigned char *out, size_t size, size_t *done)
00910 {
00911     return mpg123_decode(mh, NULL, 0, out, size, done);
00912 }
00913 
00914 int attribute_align_arg mpg123_feed(mpg123_handle *mh, const unsigned char *in, size_t size)
00915 {
00916     if(mh == NULL) return MPG123_ERR;
00917     if(size > 0)
00918     {
00919         if(in != NULL)
00920         {
00921             if(feed_more(mh, in, size) != 0) return MPG123_ERR;
00922             else
00923             {
00924                 /* The need for more data might have triggered an error.
00925                    This one is outdated now with the new data. */
00926                 if(mh->err == MPG123_ERR_READER) mh->err = MPG123_OK;
00927 
00928                 return MPG123_OK;
00929             }
00930         }
00931         else
00932         {
00933             mh->err = MPG123_NULL_BUFFER;
00934             return MPG123_ERR;
00935         }
00936     }
00937     return MPG123_OK;
00938 }
00939 
00940 /*
00941     The old picture:
00942     while(1) {
00943         len = read(0,buf,16384);
00944         if(len <= 0)
00945             break;
00946         ret = decodeMP3(&mp,buf,len,out,8192,&size);
00947         while(ret == MP3_OK) {
00948             write(1,out,size);
00949             ret = decodeMP3(&mp,NULL,0,out,8192,&size);
00950         }
00951     }
00952 */
00953 
00954 int attribute_align_arg mpg123_decode(mpg123_handle *mh, const unsigned char *inmemory, size_t inmemsize, unsigned char *outmemory, size_t outmemsize, size_t *done)
00955 {
00956     int ret = MPG123_OK;
00957     size_t mdone = 0;
00958     ALIGNCHECK(mh);
00959     if(done != NULL) *done = 0;
00960     if(mh == NULL) return MPG123_ERR;
00961     if(inmemsize > 0 && mpg123_feed(mh, inmemory, inmemsize) != MPG123_OK)
00962     {
00963         ret = MPG123_ERR;
00964         goto decodeend;
00965     }
00966     if(outmemory == NULL) outmemsize = 0; /* Not just give error, give chance to get a status message. */
00967 
00968     while(ret == MPG123_OK)
00969     {
00970         debug4("decode loop, fill %i (%li vs. %li); to_decode: %i", (int)mh->buffer.fill, (long)mh->num, (long)mh->firstframe, mh->to_decode);
00971         /* Decode a frame that has been read before.
00972            This only happens when buffer is empty! */
00973         if(mh->to_decode)
00974         {
00975             if(mh->new_format)
00976             {
00977                 debug("notifiying new format");
00978                 mh->new_format = 0;
00979                 ret = MPG123_NEW_FORMAT;
00980                 goto decodeend;
00981             }
00982             if(mh->buffer.size - mh->buffer.fill < mh->outblock)
00983             {
00984                 ret = MPG123_NO_SPACE;
00985                 goto decodeend;
00986             }
00987             decode_the_frame(mh);
00988             mh->to_decode = mh->to_ignore = FALSE;
00989             mh->buffer.p = mh->buffer.data;
00990             debug2("decoded frame %li, got %li samples in buffer", (long)mh->num, (long)(mh->buffer.fill / (samples_to_bytes(mh, 1))));
00991 #ifdef GAPLESS
00992             frame_buffercheck(mh); /* Seek & gapless. */
00993 #endif
00994         }
00995         if(mh->buffer.fill) /* Copy (part of) the decoded data to the caller's buffer. */
00996         {
00997             /* get what is needed - or just what is there */
00998             int a = mh->buffer.fill > (outmemsize - mdone) ? outmemsize - mdone : mh->buffer.fill;
00999             debug4("buffer fill: %i; copying %i (%i - %li)", (int)mh->buffer.fill, a, (int)outmemsize, (long)mdone);
01000             memcpy(outmemory, mh->buffer.p, a);
01001             /* less data in frame buffer, less needed, output pointer increase, more data given... */
01002             mh->buffer.fill -= a;
01003             outmemory  += a;
01004             mdone += a;
01005             mh->buffer.p += a;
01006             if(!(outmemsize > mdone)) goto decodeend;
01007         }
01008         else /* If we didn't have data, get a new frame. */
01009         {
01010             int b = get_next_frame(mh);
01011             if(b < 0){ ret = b; goto decodeend; }
01012         }
01013     }
01014 decodeend:
01015     if(done != NULL) *done = mdone;
01016     return ret;
01017 }
01018 
01019 long attribute_align_arg mpg123_clip(mpg123_handle *mh)
01020 {
01021     long ret = 0;
01022     ALIGNCHECK(mh);
01023     if(mh != NULL)
01024     {
01025         ret = mh->clip;
01026         mh->clip = 0;
01027     }
01028     return ret;
01029 }
01030 
01031 #define track_need_init(mh) (!(mh)->to_decode && (mh)->fresh)
01032 
01033 static int init_track(mpg123_handle *mh)
01034 {
01035     if(track_need_init(mh))
01036     {
01037         /* Fresh track, need first frame for basic info. */
01038         int b = get_next_frame(mh);
01039         if(b < 0) return b;
01040     }
01041     return 0;
01042 }
01043 
01044 int attribute_align_arg mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
01045 {
01046     int b;
01047     ALIGNCHECK(mh);
01048     if(mh == NULL) return MPG123_ERR;
01049     b = init_track(mh);
01050     if(b < 0) return b;
01051 
01052     if(rate != NULL) *rate = mh->af.rate;
01053     if(channels != NULL) *channels = mh->af.channels;
01054     if(encoding != NULL) *encoding = mh->af.encoding;
01055     mh->new_format = 0;
01056     return MPG123_OK;
01057 }
01058 
01059 off_t attribute_align_arg mpg123_timeframe(mpg123_handle *mh, double seconds)
01060 {
01061     off_t b;
01062     ALIGNCHECK(mh);
01063     if(mh == NULL) return MPG123_ERR;
01064     b = init_track(mh);
01065     if(b<0) return b;
01066     return (off_t)(seconds/mpg123_tpf(mh));
01067 }
01068 
01069 /*
01070     Now, where are we? We need to know the last decoded frame... and what's left of it in buffer.
01071     The current frame number can mean the last decoded frame or the to-be-decoded frame.
01072     If mh->to_decode, then mh->num frames have been decoded, the frame mh->num now coming next.
01073     If not, we have the possibility of mh->num+1 frames being decoded or nothing at all.
01074     Then, there is firstframe...when we didn't reach it yet, then the next data will come from there.
01075     mh->num starts with -1
01076 */
01077 off_t attribute_align_arg mpg123_tell(mpg123_handle *mh)
01078 {
01079     ALIGNCHECK(mh);
01080     if(mh == NULL) return MPG123_ERR;
01081     if(track_need_init(mh)) return 0;
01082     /* Now we have all the info at hand. */
01083     debug5("tell: %li/%i first %li buffer %lu; frame_outs=%li", (long)mh->num, mh->to_decode, (long)mh->firstframe, (unsigned long)mh->buffer.fill, (long)frame_outs(mh, mh->num));
01084 
01085     { /* Funny block to keep C89 happy. */
01086         off_t pos = 0;
01087         if((mh->num < mh->firstframe) || (mh->num == mh->firstframe && mh->to_decode))
01088         { /* We are at the beginning, expect output from firstframe on. */
01089             pos = frame_outs(mh, mh->firstframe);
01090 #ifdef GAPLESS
01091             pos += mh->firstoff;
01092 #endif
01093         }
01094         else if(mh->to_decode)
01095         { /* We start fresh with this frame. Buffer should be empty, but we make sure to count it in.  */
01096             pos = frame_outs(mh, mh->num) - bytes_to_samples(mh, mh->buffer.fill);
01097         }
01098         else
01099         { /* We serve what we have in buffer and then the beginning of next frame... */
01100             pos = frame_outs(mh, mh->num+1) - bytes_to_samples(mh, mh->buffer.fill);
01101         }
01102         /* Substract padding and delay from the beginning. */
01103         pos = SAMPLE_ADJUST(pos);
01104         /* Negative sample offsets are not right, less than nothing is still nothing. */
01105         return pos>0 ? pos : 0;
01106     }
01107 }
01108 
01109 off_t attribute_align_arg mpg123_tellframe(mpg123_handle *mh)
01110 {
01111     ALIGNCHECK(mh);
01112     if(mh == NULL) return MPG123_ERR;
01113     if(mh->num < mh->firstframe) return mh->firstframe;
01114     if(mh->to_decode) return mh->num;
01115     /* Consider firstoff? */
01116     return mh->buffer.fill ? mh->num : mh->num + 1;
01117 }
01118 
01119 off_t attribute_align_arg mpg123_tell_stream(mpg123_handle *mh)
01120 {
01121     ALIGNCHECK(mh);
01122     if(mh == NULL) return MPG123_ERR;
01123     /* mh->rd is at least a bad_reader, so no worry. */
01124     return mh->rd->tell(mh);
01125 }
01126 
01127 static int do_the_seek(mpg123_handle *mh)
01128 {
01129     int b;
01130     off_t fnum = SEEKFRAME(mh);
01131     mh->buffer.fill = 0;
01132 
01133     /* If we are inside the ignoreframe - firstframe window, we may get away without actual seeking. */
01134     if(mh->num < mh->firstframe)
01135     {
01136         mh->to_decode = FALSE; /* In any case, don't decode the current frame, perhaps ignore instead. */
01137         if(mh->num > fnum) return MPG123_OK;
01138     }
01139 
01140     /* If we are already there, we are fine either for decoding or for ignoring. */
01141     if(mh->num == fnum && (mh->to_decode || fnum < mh->firstframe)) return MPG123_OK;
01142     /* We have the frame before... just go ahead as normal. */
01143     if(mh->num == fnum-1)
01144     {
01145         mh->to_decode = FALSE;
01146         return MPG123_OK;
01147     }
01148 
01149     /* OK, real seeking follows... clear buffers and go for it. */
01150     frame_buffers_reset(mh);
01151 #ifndef NO_NTOM
01152     if(mh->down_sample == 3)
01153     {
01154         ntom_set_ntom(mh, fnum);
01155         debug3("fixed ntom for frame %"OFF_P" to %lu, num=%"OFF_P, (off_p)fnum, mh->ntom_val[0], (off_p)mh->num);
01156     }
01157 #endif
01158     b = mh->rd->seek_frame(mh, fnum);
01159     debug1("seek_frame returned: %i", b);
01160     if(b<0) return b;
01161     /* Only mh->to_ignore is TRUE. */
01162     if(mh->num < mh->firstframe) mh->to_decode = FALSE;
01163 
01164     mh->playnum = mh->num;
01165     return 0;
01166 }
01167 
01168 off_t attribute_align_arg mpg123_seek(mpg123_handle *mh, off_t sampleoff, int whence)
01169 {
01170     int b;
01171     off_t pos;
01172     ALIGNCHECK(mh);
01173     pos = mpg123_tell(mh); /* adjusted samples */
01174     /* pos < 0 also can mean that simply a former seek failed at the lower levels.
01175       In that case, we only allow absolute seeks. */
01176     if(pos < 0 && whence != SEEK_SET)
01177     { /* Unless we got the obvious error of NULL handle, this is a special seek failure. */
01178         if(mh != NULL) mh->err = MPG123_NO_RELSEEK;
01179         return MPG123_ERR;
01180     }
01181     if((b=init_track(mh)) < 0) return b;
01182     switch(whence)
01183     {
01184         case SEEK_CUR: pos += sampleoff; break;
01185         case SEEK_SET: pos  = sampleoff; break;
01186         case SEEK_END:
01187             /* When we do not know the end already, we can try to find it. */
01188             if(mh->track_frames < 1 && (mh->rdat.flags & READER_SEEKABLE))
01189             mpg123_scan(mh);
01190 #ifdef GAPLESS
01191             if(mh->end_os > 0) pos = SAMPLE_ADJUST(mh->end_os) - sampleoff;
01192 #else
01193             if(mh->track_frames > 0) pos = SAMPLE_ADJUST(frame_outs(mh, mh->track_frames)) - sampleoff;
01194 #endif
01195             else
01196             {
01197                 mh->err = MPG123_NO_SEEK_FROM_END;
01198                 return MPG123_ERR;
01199             }
01200         break;
01201         default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR;
01202     }
01203     if(pos < 0) pos = 0;
01204     /* pos now holds the wanted sample offset in adjusted samples */
01205     frame_set_seek(mh, SAMPLE_UNADJUST(pos));
01206     pos = do_the_seek(mh);
01207     if(pos < 0) return pos;
01208 
01209     return mpg123_tell(mh);
01210 }
01211 
01212 /*
01213     A bit more tricky... libmpg123 does not do the seeking itself.
01214     All it can do is to ignore frames until the wanted one is there.
01215     The caller doesn't know where a specific frame starts and mpg123 also only knows the general region after it scanned the file.
01216     Well, it is tricky...
01217 */
01218 off_t attribute_align_arg mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset)
01219 {
01220     int b;
01221     off_t pos;
01222     ALIGNCHECK(mh);
01223     pos = mpg123_tell(mh); /* adjusted samples */
01224     debug3("seek from %li to %li (whence=%i)", (long)pos, (long)sampleoff, whence);
01225     /* The special seek error handling does not apply here... there is no lowlevel I/O. */
01226     if(pos < 0) return pos; /* mh == NULL is covered in mpg123_tell() */
01227     if(input_offset == NULL)
01228     {
01229         mh->err = MPG123_NULL_POINTER;
01230         return MPG123_ERR;
01231     }
01232 
01233     if((b=init_track(mh)) < 0) return b; /* May need more to do anything at all. */
01234 
01235     switch(whence)
01236     {
01237         case SEEK_CUR: pos += sampleoff; break;
01238         case SEEK_SET: pos  = sampleoff; break;
01239         case SEEK_END:
01240 #ifdef GAPLESS
01241             if(mh->end_os >= 0) pos = SAMPLE_ADJUST(mh->end_os) - sampleoff;
01242 #else
01243             if(mh->track_frames > 0) pos = SAMPLE_ADJUST(frame_outs(mh, mh->track_frames)) - sampleoff;
01244 #endif
01245             else
01246             {
01247                 mh->err = MPG123_NO_SEEK_FROM_END;
01248                 return MPG123_ERR;
01249             }
01250         break;
01251         default: mh->err = MPG123_BAD_WHENCE; return MPG123_ERR;
01252     }
01253     if(pos < 0) pos = 0;
01254     frame_set_seek(mh, SAMPLE_UNADJUST(pos));
01255     pos = SEEKFRAME(mh);
01256     mh->buffer.fill = 0;
01257 
01258     /* Shortcuts without modifying input stream. */
01259     *input_offset = mh->rdat.buffer.fileoff + mh->rdat.buffer.size;
01260     if(mh->num < mh->firstframe) mh->to_decode = FALSE;
01261     if(mh->num == pos && mh->to_decode) goto feedseekend;
01262     if(mh->num == pos-1) goto feedseekend;
01263     /* Whole way. */
01264     *input_offset = feed_set_pos(mh, frame_index_find(mh, SEEKFRAME(mh), &pos));
01265     mh->num = pos-1; /* The next read frame will have num = pos. */
01266     if(*input_offset < 0) return MPG123_ERR;
01267 
01268 feedseekend:
01269     return mpg123_tell(mh);
01270 }
01271 
01272 off_t attribute_align_arg mpg123_seek_frame(mpg123_handle *mh, off_t offset, int whence)
01273 {
01274     int b;
01275     off_t pos = 0;
01276     ALIGNCHECK(mh);
01277     if(mh == NULL) return MPG123_ERR;
01278     if((b=init_track(mh)) < 0) return b;
01279 
01280     /* Could play games here with to_decode... */
01281     pos = mh->num;
01282     switch(whence)
01283     {
01284         case SEEK_CUR: pos += offset; break;
01285         case SEEK_SET: pos  = offset; break;
01286         case SEEK_END:
01287             if(mh->track_frames > 0) pos = mh->track_frames - offset;
01288             else
01289             {
01290                 mh->err = MPG123_NO_SEEK_FROM_END;
01291                 return MPG123_ERR;
01292             }
01293         break;
01294         default:
01295             mh->err = MPG123_BAD_WHENCE;
01296             return MPG123_ERR;
01297     }
01298     if(pos < 0) pos = 0;
01299     /* Hm, do we need to seek right past the end? */
01300     else if(mh->track_frames > 0 && pos >= mh->track_frames) pos = mh->track_frames;
01301 
01302     frame_set_frameseek(mh, pos);
01303     pos = do_the_seek(mh);
01304     if(pos < 0) return pos;
01305 
01306     return mpg123_tellframe(mh);
01307 }
01308 
01309 int attribute_align_arg mpg123_set_filesize(mpg123_handle *mh, off_t size)
01310 {
01311     ALIGNCHECK(mh);
01312     if(mh == NULL) return MPG123_ERR;
01313 
01314     mh->rdat.filelen = size;
01315     return MPG123_OK;
01316 }
01317 
01318 off_t attribute_align_arg mpg123_length(mpg123_handle *mh)
01319 {
01320     int b;
01321     off_t length;
01322     ALIGNCHECK(mh);
01323     if(mh == NULL) return MPG123_ERR;
01324     b = init_track(mh);
01325     if(b<0) return b;
01326     if(mh->track_samples > -1) length = mh->track_samples;
01327     else if(mh->track_frames > 0) length = mh->track_frames*spf(mh);
01328     else if(mh->rdat.filelen > 0) /* Let the case of 0 length just fall through. */
01329     {
01330         /* A bad estimate. Ignoring tags 'n stuff. */
01331         double bpf = mh->mean_framesize ? mh->mean_framesize : compute_bpf(mh);
01332         length = (off_t)((double)(mh->rdat.filelen)/bpf*spf(mh));
01333     }
01334     else if(mh->rdat.filelen == 0) return mpg123_tell(mh); /* we could be in feeder mode */
01335     else return MPG123_ERR; /* No length info there! */
01336 
01337     debug1("mpg123_length: internal sample length: %"OFF_P, (off_p)length);
01338 
01339     length = frame_ins2outs(mh, length);
01340     debug1("mpg123_length: external sample length: %"OFF_P, (off_p)length);
01341 #ifdef GAPLESS
01342     if(mh->p.flags & MPG123_GAPLESS)
01343     {
01344         debug2("mpg123_length: begin_os = %"OFF_P", end_os = %"OFF_P, (off_p)mh->begin_os, (off_p)mh->end_os);
01345         if(mh->end_os > 0 && length > mh->end_os) length = mh->end_os;
01346         length -= mh->begin_os;
01347         debug1("mpg123_length: after gapless correction: %"OFF_P, (off_p)length);
01348     }
01349 #endif
01350     return length;
01351 }
01352 
01353 int attribute_align_arg mpg123_scan(mpg123_handle *mh)
01354 {
01355     int b;
01356     off_t backframe;
01357     int to_decode, to_ignore;
01358     ALIGNCHECK(mh);
01359     if(mh == NULL) return MPG123_ERR;
01360     if(!(mh->rdat.flags & READER_SEEKABLE)){ mh->err = MPG123_NO_SEEK; return MPG123_ERR; }
01361     /* Scan through the _whole_ file, since the current position is no count but computed assuming constant samples per frame. */
01362     /* Also, we can just keep the current buffer and seek settings. Just operate on input frames here. */
01363     debug("issuing scan");
01364     b = init_track(mh); /* mh->num >= 0 !! */
01365     if(b<0)
01366     {
01367         if(b == MPG123_DONE) return MPG123_OK;
01368         else return MPG123_ERR; /* Must be error here, NEED_MORE is not for seekable streams. */
01369     }
01370     backframe = mh->num;
01371     to_decode = mh->to_decode;
01372     to_ignore = mh->to_ignore;
01373     b = mh->rd->seek_frame(mh, 0);
01374     if(b<0 || mh->num != 0) return MPG123_ERR;
01375     /* One frame must be there now. */
01376     mh->track_frames = 1;
01377     mh->track_samples = spf(mh); /* Internal samples. */
01378     debug("TODO: We should disable gapless code when encountering inconsistent spf(mh)!");
01379     while(read_frame(mh) == 1)
01380     {
01381         ++mh->track_frames;
01382         mh->track_samples += spf(mh);
01383     }
01384     debug2("Scanning yielded %"OFF_P" track samples, %"OFF_P" frames.", (off_p)mh->track_samples, (off_p)mh->track_frames);
01385 #ifdef GAPLESS
01386     /* Also, think about usefulness of that extra value track_samples ... it could be used for consistency checking. */
01387     frame_gapless_update(mh, mh->track_samples);
01388 #endif  
01389     b = mh->rd->seek_frame(mh, backframe);
01390     if(b<0 || mh->num != backframe) return MPG123_ERR;
01391     mh->to_decode = to_decode;
01392     mh->to_ignore = to_ignore;
01393     return MPG123_OK;
01394 }
01395 
01396 int attribute_align_arg mpg123_meta_check(mpg123_handle *mh)
01397 {
01398     if(mh != NULL) return mh->metaflags;
01399     else return 0;
01400 }
01401 
01402 int attribute_align_arg mpg123_id3(mpg123_handle *mh, mpg123_id3v1 **v1, mpg123_id3v2 **v2)
01403 {
01404     ALIGNCHECK(mh);
01405     if(v1 != NULL) *v1 = NULL;
01406     if(v2 != NULL) *v2 = NULL;
01407     if(mh == NULL) return MPG123_ERR;
01408 
01409     if(mh->metaflags & MPG123_ID3)
01410     {
01411         id3_link(mh);
01412         if(v1 != NULL && mh->rdat.flags & READER_ID3TAG) *v1 = (mpg123_id3v1*) mh->id3buf;
01413         if(v2 != NULL)
01414 #ifdef NO_ID3V2
01415         *v2 = NULL;
01416 #else
01417         *v2 = &mh->id3v2;
01418 #endif
01419 
01420         mh->metaflags |= MPG123_ID3;
01421         mh->metaflags &= ~MPG123_NEW_ID3;
01422     }
01423     return MPG123_OK;
01424 }
01425 
01426 int attribute_align_arg mpg123_icy(mpg123_handle *mh, char **icy_meta)
01427 {
01428     ALIGNCHECK(mh);
01429     if(mh == NULL) return MPG123_ERR;
01430 #ifndef NO_ICY
01431     if(icy_meta == NULL)
01432     {
01433         mh->err = MPG123_NULL_POINTER;
01434         return MPG123_ERR;
01435     }
01436     *icy_meta = NULL;
01437 
01438     if(mh->metaflags & MPG123_ICY)
01439     {
01440         *icy_meta = mh->icy.data;
01441         mh->metaflags |= MPG123_ICY;
01442         mh->metaflags &= ~MPG123_NEW_ICY;
01443     }
01444     return MPG123_OK;
01445 #else
01446     mh->err = MPG123_MISSING_FEATURE;
01447     return MPG123_ERR;
01448 #endif
01449 }
01450 
01451 /*
01452     Simple utility functions that do not possibly call code with extra alignment requirements do not use the ALIGNCHECK.
01453     I am aware of the chance that the compiler could have introduced such code outside assembly functions, but such a modern compiler (gcc) can also honour attribute_align_arg.
01454 */
01455 
01456 char* attribute_align_arg mpg123_icy2utf8(const char* icy_text)
01457 {
01458 #ifndef NO_ICY
01459     return icy2utf8(icy_text, 0);
01460 #else
01461     return NULL;
01462 #endif
01463 }
01464 
01465 /* That one is always defined... it's not worth it to remove it for NO_ID3V2. */
01466 enum mpg123_text_encoding attribute_align_arg mpg123_enc_from_id3(unsigned char id3_enc_byte)
01467 {
01468     switch(id3_enc_byte)
01469     {
01470         case mpg123_id3_latin1:   return mpg123_text_latin1;
01471         case mpg123_id3_utf16bom: return mpg123_text_utf16bom; /* ID3v2.3 has UCS-2 with BOM here. */
01472         case mpg123_id3_utf16be:  return mpg123_text_utf16be;
01473         case mpg123_id3_utf8:     return mpg123_text_utf8;
01474         default: return mpg123_text_unknown;
01475     }
01476 }
01477 
01478 #ifndef NO_STRING
01479 int mpg123_store_utf8(mpg123_string *sb, enum mpg123_text_encoding enc, const unsigned char *source, size_t source_size)
01480 {
01481     switch(enc)
01482     {
01483 #ifndef NO_ID3V2
01484         /* The encodings we get from ID3v2 tags. */
01485         case mpg123_text_utf8:
01486             id3_to_utf8(sb, mpg123_id3_utf8, source, source_size, 0);
01487         break;
01488         case mpg123_text_latin1:
01489             id3_to_utf8(sb, mpg123_id3_latin1, source, source_size, 0);
01490         break;
01491         case mpg123_text_utf16bom:
01492         case mpg123_text_utf16:
01493             id3_to_utf8(sb, mpg123_id3_utf16bom, source, source_size, 0);
01494         break;
01495         /* Special because one cannot skip zero bytes here. */
01496         case mpg123_text_utf16be:
01497             id3_to_utf8(sb, mpg123_id3_utf16be, source, source_size, 0);
01498         break;
01499 #endif
01500 #ifndef NO_ICY
01501         /* ICY encoding... */
01502         case mpg123_text_icy:
01503         case mpg123_text_cp1252:
01504         {
01505             mpg123_free_string(sb);
01506             /* Paranoia: Make sure that the string ends inside the buffer... */
01507             if(source[source_size-1] == 0)
01508             {
01509                 /* Convert from ICY encoding... with force applied or not. */
01510                 char *tmpstring = icy2utf8((const char*)source, enc == mpg123_text_cp1252 ? 1 : 0);
01511                 if(tmpstring != NULL)
01512                 {
01513                     mpg123_set_string(sb, tmpstring);
01514                     free(tmpstring);
01515                 }
01516             }
01517         }
01518         break;
01519 #endif
01520         default:
01521             mpg123_free_string(sb);
01522     }
01523     /* At least a trailing null of some form should be there... */
01524     return (sb->fill > 0) ? 1 : 0;
01525 }
01526 #endif
01527 
01528 int attribute_align_arg mpg123_index(mpg123_handle *mh, off_t **offsets, off_t *step, size_t *fill)
01529 {
01530     ALIGNCHECK(mh);
01531     if(mh == NULL) return MPG123_ERR;
01532     if(offsets == NULL || step == NULL || fill == NULL)
01533     {
01534         mh->err = MPG123_BAD_INDEX_PAR;
01535         return MPG123_ERR;
01536     }
01537 #ifdef FRAME_INDEX
01538     *offsets = mh->index.data;
01539     *step    = mh->index.step;
01540     *fill    = mh->index.fill;
01541 #else
01542     *offsets = NULL;
01543     *step    = 0;
01544     *fill    = 0;
01545 #endif
01546     return MPG123_OK;
01547 }
01548 
01549 int attribute_align_arg mpg123_set_index(mpg123_handle *mh, off_t *offsets, off_t step, size_t fill)
01550 {
01551     ALIGNCHECK(mh);
01552     if(mh == NULL) return MPG123_ERR;
01553 #ifdef FRAME_INDEX
01554     if(step == 0)
01555     {
01556         mh->err = MPG123_BAD_INDEX_PAR;
01557         return MPG123_ERR;
01558     }
01559     if(fi_set(&mh->index, offsets, step, fill) == -1)
01560     {
01561         mh->err = MPG123_OUT_OF_MEM;
01562         return MPG123_ERR;
01563     }
01564     return MPG123_OK;
01565 #else
01566     mh->err = MPG123_MISSING_FEATURE;
01567     return MPG123_ERR;
01568 #endif
01569 }
01570 
01571 int attribute_align_arg mpg123_close(mpg123_handle *mh)
01572 {
01573     ALIGNCHECK(mh);
01574     if(mh == NULL) return MPG123_ERR;
01575     if(mh->rd != NULL && mh->rd->close != NULL) mh->rd->close(mh);
01576     mh->rd = NULL;
01577     if(mh->new_format)
01578     {
01579         debug("Hey, we are closing a track before the new format has been queried...");
01580         invalidate_format(&mh->af);
01581         mh->new_format = 0;
01582     }
01583     /* Always reset the frame buffers on close, so we cannot forget it in funky opening routines (wrappers, even). */
01584     frame_reset(mh);
01585     return MPG123_OK;
01586 }
01587 
01588 void attribute_align_arg mpg123_delete(mpg123_handle *mh)
01589 {
01590     if(mh != NULL)
01591     {
01592         mpg123_close(mh);
01593         frame_exit(mh); /* free buffers in frame */
01594         free(mh); /* free struct; cast? */
01595     }
01596 }
01597 
01598 static const char *mpg123_error[] =
01599 {
01600     "No error... (code 0)",
01601     "Unable to set up output format! (code 1)",
01602     "Invalid channel number specified. (code 2)",
01603     "Invalid sample rate specified. (code 3)",
01604     "Unable to allocate memory for 16 to 8 converter table! (code 4)",
01605     "Bad parameter id! (code 5)",
01606     "Bad buffer given -- invalid pointer or too small size. (code 6)",
01607     "Out of memory -- some malloc() failed. (code 7)",
01608     "You didn't initialize the library! (code 8)",
01609     "Invalid decoder choice. (code 9)",
01610     "Invalid mpg123 handle. (code 10)",
01611     "Unable to initialize frame buffers (out of memory?)! (code 11)",
01612     "Invalid RVA mode. (code 12)",
01613     "This build doesn't support gapless decoding. (code 13)",
01614     "Not enough buffer space. (code 14)",
01615     "Incompatible numeric data types. (code 15)",
01616     "Bad equalizer band. (code 16)",
01617     "Null pointer given where valid storage address needed. (code 17)",
01618     "Error reading the stream. (code 18)",
01619     "Cannot seek from end (end is not known). (code 19)",
01620     "Invalid 'whence' for seek function. (code 20)",
01621     "Build does not support stream timeouts. (code 21)",
01622     "File access error. (code 22)",
01623     "Seek not supported by stream. (code 23)",
01624     "No stream opened. (code 24)",
01625     "Bad parameter handle. (code 25)",
01626     "Invalid parameter addresses for index retrieval. (code 26)",
01627     "Lost track in the bytestream and did not attempt resync. (code 27)",
01628     "Failed to find valid MPEG data within limit on resync. (code 28)",
01629     "No 8bit encoding possible. (code 29)",
01630     "Stack alignment is not good. (code 30)",
01631     "You gave me a NULL buffer? (code 31)",
01632     "File position is screwed up, please do an absolute seek (code 32)",
01633     "Inappropriate NULL-pointer provided.",
01634     "Bad key value given.",
01635     "There is no frame index (disabled in this build).",
01636     "Frame index operation failed.",
01637     "Decoder setup failed (invalid combination of settings?)",
01638     "Feature not in this build."
01639     ,"Some bad value has been provided."
01640     ,"Low-level seeking has failed (call to lseek(), usually)."
01641     ,"Custom I/O obviously not prepared."
01642     ,"Overflow in LFS (large file support) conversion."
01643 };
01644 
01645 const char* attribute_align_arg mpg123_plain_strerror(int errcode)
01646 {
01647     if(errcode >= 0 && errcode < sizeof(mpg123_error)/sizeof(char*))
01648     return mpg123_error[errcode];
01649     else switch(errcode)
01650     {
01651         case MPG123_ERR:
01652             return "A generic mpg123 error.";
01653         case MPG123_DONE:
01654             return "Message: I am done with this track.";
01655         case MPG123_NEED_MORE:
01656             return "Message: Feed me more input data!";
01657         case MPG123_NEW_FORMAT:
01658             return "Message: Prepare for a changed audio format (query the new one)!";
01659         default:
01660             return "I have no idea - an unknown error code!";
01661     }
01662 }
01663 
01664 int attribute_align_arg mpg123_errcode(mpg123_handle *mh)
01665 {
01666     if(mh != NULL) return mh->err;
01667     return MPG123_BAD_HANDLE;
01668 }
01669 
01670 const char* attribute_align_arg mpg123_strerror(mpg123_handle *mh)
01671 {
01672     return mpg123_plain_strerror(mpg123_errcode(mh));
01673 }

Generated on Sun May 27 2012 04:34:10 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.