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

ntom.c
Go to the documentation of this file.
00001 /*
00002     ntom.c: N->M down/up sampling; the setup code.
00003 
00004     copyright 1995-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
00005     see COPYING and AUTHORS files in distribution or http://mpg123.org
00006     initially written by Michael Hipp
00007 */
00008 
00009 #define SAFE_NTOM /* Do not depend on off_t*off_t with big values still being in the range... */
00010 #include "mpg123lib_intern.h"
00011 #include "debug.h"
00012 
00013 int synth_ntom_set_step(mpg123_handle *fr)
00014 {
00015     long m,n;
00016     m = frame_freq(fr);
00017     n = fr->af.rate;
00018     if(VERBOSE2)
00019         fprintf(stderr,"Init rate converter: %ld->%ld\n",m,n);
00020 
00021     if(n > NTOM_MAX_FREQ || m > NTOM_MAX_FREQ || m <= 0 || n <= 0) {
00022         if(NOQUIET) error("NtoM converter: illegal rates");
00023         fr->err = MPG123_BAD_RATE;
00024         return -1;
00025     }
00026 
00027     n *= NTOM_MUL;
00028     fr->ntom_step = (unsigned long) n / m;
00029 
00030     if(fr->ntom_step > (unsigned long)NTOM_MAX*NTOM_MUL) {
00031         if(NOQUIET) error3("max. 1:%i conversion allowed (%lu vs %lu)!", NTOM_MAX, fr->ntom_step, (unsigned long)8*NTOM_MUL);
00032         fr->err = MPG123_BAD_RATE;
00033         return -1;
00034     }
00035 
00036     fr->ntom_val[0] = fr->ntom_val[1] = ntom_val(fr, fr->num);
00037     return 0;
00038 }
00039 
00040 /*
00041     The SAFE_NTOM does iterative loops instead of straight multiplication.
00042     The safety is not just about the algorithm closely mimicking the decoder instead of applying some formula,
00043     it is more about avoiding multiplication of possibly big sample offsets (a 32bit off_t could overflow too easily).
00044 */
00045 
00046 unsigned long ntom_val(mpg123_handle *fr, off_t frame)
00047 {
00048     off_t ntm;
00049 #ifdef SAFE_NTOM /* Carry out the loop, without the threatening integer overflow. */
00050     off_t f;
00051     ntm = NTOM_MUL>>1; /* for frame 0 */
00052     for(f=0; f<frame; ++f)   /* for frame > 0 */
00053     {
00054         ntm += spf(fr)*fr->ntom_step;
00055         ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
00056     }
00057 #else /* Just make one computation with overall sample offset. */
00058     ntm  = (NTOM_MUL>>1) + spf(fr)*frame*fr->ntom_step;
00059     ntm -= (ntm/NTOM_MUL)*NTOM_MUL;
00060 #endif
00061     return (unsigned long) ntm;
00062 }
00063 
00064 /* Set the ntom value for next expected frame to be decoded.
00065    This is for keeping output consistent across seeks. */
00066 void ntom_set_ntom(mpg123_handle *fr, off_t num)
00067 {
00068     fr->ntom_val[1] = fr->ntom_val[0] = ntom_val(fr, num);
00069 }
00070 
00071 /* Carry out the ntom sample count operation for this one frame. 
00072    No fear of integer overflow here. */
00073 off_t ntom_frame_outsamples(mpg123_handle *fr)
00074 {
00075     /* The do this before decoding the separate channels, so there is only one common ntom value. */
00076     int ntm = fr->ntom_val[0];
00077     ntm += spf(fr)*fr->ntom_step;
00078     return ntm/NTOM_MUL;
00079 }
00080 
00081 /* Convert frame offset to unadjusted output sample offset. */
00082 off_t ntom_frmouts(mpg123_handle *fr, off_t frame)
00083 {
00084 #ifdef SAFE_NTOM
00085     off_t f;
00086 #endif
00087     off_t soff = 0;
00088     off_t ntm = ntom_val(fr,0);
00089 #ifdef SAFE_NTOM
00090     if(frame <= 0) return 0;
00091     for(f=0; f<frame; ++f)
00092     {
00093         ntm  += spf(fr)*fr->ntom_step;
00094         soff += ntm/NTOM_MUL;
00095         ntm  -= (ntm/NTOM_MUL)*NTOM_MUL;
00096     }
00097 #else
00098     soff = (ntm + frame*(off_t)spf(fr)*(off_t)fr->ntom_step)/(off_t)NTOM_MUL;
00099 #endif
00100     return soff;
00101 }
00102 
00103 /* Convert input samples to unadjusted output samples. */
00104 off_t ntom_ins2outs(mpg123_handle *fr, off_t ins)
00105 {
00106     off_t soff = 0;
00107     off_t ntm = ntom_val(fr,0);
00108 #ifdef SAFE_NTOM
00109     {
00110         off_t block = spf(fr);
00111         if(ins <= 0) return 0;
00112         do
00113         {
00114             off_t nowblock = ins > block ? block : ins;
00115             ntm  += nowblock*fr->ntom_step;
00116             soff += ntm/NTOM_MUL;
00117             ntm  -= (ntm/NTOM_MUL)*NTOM_MUL;
00118             ins -= nowblock;
00119         } while(ins > 0);
00120     }
00121 #else
00122     /* Beware of overflows: when off_t is 32bits, the multiplication blows too easily.
00123        Of course, it blows for 64bits, too, in theory, but that's for _really_ large files. */
00124     soff = ((off_t)ntm + (off_t)ins*(off_t)fr->ntom_step)/(off_t)NTOM_MUL;
00125 #endif
00126     return soff;
00127 }
00128 
00129 /* Determine frame offset from unadjusted output sample offset. */
00130 off_t ntom_frameoff(mpg123_handle *fr, off_t soff)
00131 {
00132     off_t ioff = 0; /* frames or samples */
00133     off_t ntm = ntom_val(fr,0);
00134 #ifdef SAFE_NTOM
00135     if(soff <= 0) return 0;
00136     for(ioff=0; 1; ++ioff)
00137     {
00138         ntm  += spf(fr)*fr->ntom_step;
00139         if(ntm/NTOM_MUL > soff) break;
00140         soff -= ntm/NTOM_MUL;
00141         ntm  -= (ntm/NTOM_MUL)*NTOM_MUL;
00142     }
00143     return ioff;
00144 #else
00145     ioff = (soff*(off_t)NTOM_MUL-ntm)/(off_t)fr->ntom_step;
00146     return ioff/(off_t)spf(fr);
00147 #endif
00148 }

Generated on Sat May 26 2012 04:33:01 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.