Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenntom.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
1.7.6.1
|