⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 音频编码
💻 C
📖 第 1 页 / 共 2 页
字号:
       sample_t *outbuf,       int desired_len,       sample_t *inbuf,       int len,       int *num_used,       int ch) {    lame_internal_flags *gfc=gfp->internal_flags;  int BLACKSIZE;  FLOAT offset,xvalue;  int i,j=0,k;  int filter_l;  FLOAT fcn,intratio;  FLOAT *inbuf_old;  int bpc;   /* number of convolution functions to pre-compute */  bpc = gfp->out_samplerate/gcd(gfp->out_samplerate,gfp->in_samplerate);  if (bpc>BPC) bpc = BPC;  intratio=( fabs(gfc->resample_ratio - floor(.5+gfc->resample_ratio)) < .0001 );  fcn = 1.00/gfc->resample_ratio;  if (fcn>1.00) fcn=1.00;  filter_l = gfp->quality < 7 ? 31 : 7;  filter_l = 31;  if (0==filter_l % 2 ) --filter_l;/* must be odd */  filter_l += intratio;            /* unless resample_ratio=int, it must be even */  BLACKSIZE = filter_l+1;  /* size of data needed for FIR */    if ( gfc->fill_buffer_resample_init == 0 ) {    gfc->inbuf_old[0]=calloc(BLACKSIZE,sizeof(gfc->inbuf_old[0][0]));    gfc->inbuf_old[1]=calloc(BLACKSIZE,sizeof(gfc->inbuf_old[0][0]));    for (i=0; i<=2*bpc; ++i)      gfc->blackfilt[i]=calloc(BLACKSIZE,sizeof(gfc->blackfilt[0][0]));    gfc->itime[0]=0;    gfc->itime[1]=0;    /* precompute blackman filter coefficients */    for ( j = 0; j <= 2*bpc; j++ ) {        FLOAT sum = 0.;         offset = (j-bpc) / (2.*bpc);        for ( i = 0; i <= filter_l; i++ )             sum += 	    gfc->blackfilt[j][i]  = blackman(i-offset,fcn,filter_l);	for ( i = 0; i <= filter_l; i++ ) 	  gfc->blackfilt[j][i] /= sum;    }    gfc->fill_buffer_resample_init = 1;  }    inbuf_old=gfc->inbuf_old[ch];  /* time of j'th element in inbuf = itime + j/ifreq; */  /* time of k'th element in outbuf   =  j/ofreq */  for (k=0;k<desired_len;k++) {    FLOAT time0;    int joff;    time0 = k*gfc->resample_ratio;       /* time of k'th output sample */    j = floor( time0 -gfc->itime[ch]  );    /* check if we need more input data */    if ((filter_l + j - filter_l/2) >= len) break;    /* blackman filter.  by default, window centered at j+.5(filter_l%2) */    /* but we want a window centered at time0.   */    offset = ( time0 -gfc->itime[ch] - (j + .5*(filter_l%2)));    assert(fabs(offset)<=.501);    /* find the closest precomputed window for this offset: */    joff = floor((offset*2*bpc) + bpc +.5);    xvalue = 0.;    for (i=0 ; i<=filter_l ; ++i) {      int j2 = i+j-filter_l/2;      sample_t y;      assert(j2<len);      assert(j2+BLACKSIZE >= 0);      y = (j2<0) ? inbuf_old[BLACKSIZE+j2] : inbuf[j2];#define PRECOMPUTE#ifdef PRECOMPUTE      xvalue += y*gfc->blackfilt[joff][i];#else      xvalue += y*blackman(i-offset,fcn,filter_l);  /* very slow! */#endif    }    outbuf[k]=xvalue;  }    /* k = number of samples added to outbuf */  /* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2]  */  /* how many samples of input data were used:  */  *num_used = Min(len,filter_l+j-filter_l/2);  /* adjust our input time counter.  Incriment by the number of samples used,   * then normalize so that next output sample is at time 0, next   * input buffer is at time itime[ch] */  gfc->itime[ch] += *num_used - k*gfc->resample_ratio;  /* save the last BLACKSIZE samples into the inbuf_old buffer */  if (*num_used >= BLACKSIZE) {      for (i=0;i<BLACKSIZE;i++)	  inbuf_old[i]=inbuf[*num_used + i -BLACKSIZE];  }else{      /* shift in *num_used samples into inbuf_old  */       int n_shift = BLACKSIZE-*num_used;  /* number of samples to shift */       /* shift n_shift samples by *num_used, to make room for the	* num_used new samples */       for (i=0; i<n_shift; ++i ) 	   inbuf_old[i] = inbuf_old[i+ *num_used];       /* shift in the *num_used samples */       for (j=0; i<BLACKSIZE; ++i, ++j ) 	   inbuf_old[i] = inbuf[j];       assert(j==*num_used);  }  return k;  /* return the number samples created at the new samplerate */}/*************************************************************************  Message Output************************************************************************/void  lame_debugf (const lame_internal_flags *gfc, const char* format, ... ){    va_list  args;    va_start ( args, format );    if ( gfc->report.debugf != NULL ) {        gfc->report.debugf( format, args );    } else {        (void) vfprintf ( stderr, format, args );        fflush ( stderr );      /* an debug function should flush immediately */    }    va_end   ( args );}void  lame_msgf (const lame_internal_flags *gfc, const char* format, ... ){    va_list  args;    va_start ( args, format );       if ( gfc->report.msgf != NULL ) {        gfc->report.msgf( format, args );    } else {        (void) vfprintf ( stderr, format, args );        fflush ( stderr );     /* we print to stderr, so me may want to flush */    }    va_end   ( args );}void  lame_errorf (const lame_internal_flags *gfc, const char* format, ... ){    va_list  args;    va_start ( args, format );        if ( gfc->report.errorf != NULL ) {        gfc->report.errorf( format, args );    } else {        (void) vfprintf ( stderr, format, args );        fflush   ( stderr );    /* an error function should flush immediately */    }    va_end   ( args );}/*********************************************************************** * *      routines to detect CPU specific features like 3DNow, MMX, SSE * *  donated by Frank Klemm *  added Robert Hegemann 2000-10-10 * ***********************************************************************/int  has_MMX ( void ){#ifdef HAVE_NASM     extern int has_MMX_nasm ( void );    return has_MMX_nasm ();#else    return 0;   /* don't know, assume not */#endif}    int  has_3DNow ( void ){#ifdef HAVE_NASM     extern int has_3DNow_nasm ( void );    return has_3DNow_nasm ();#else    return 0;   /* don't know, assume not */#endif}    int  has_SSE ( void ){#ifdef HAVE_NASM     extern int has_SSE_nasm ( void );    return has_SSE_nasm ();#else    return 0;   /* don't know, assume not */#endif}    int  has_SSE2 ( void ){#ifdef HAVE_NASM     extern int has_SSE2_nasm ( void );    return has_SSE2_nasm ();#else    return 0;   /* don't know, assume not */#endif}    void disable_FPE(void) {/* extremly system dependent stuff, move to a lib to make the code readable *//*==========================================================================*/    /*     *  Disable floating point exceptions     */#if defined(__FreeBSD__) && !defined(__alpha__)    {        /* seet floating point mask to the Linux default */        fp_except_t mask;        mask = fpgetmask();        /* if bit is set, we get SIGFPE on that error! */        fpsetmask(mask & ~(FP_X_INV | FP_X_DZ));        /*  DEBUGF("FreeBSD mask is 0x%x\n",mask); */    }#endif#if defined(__riscos__) && !defined(ABORTFP)    /* Disable FPE's under RISC OS */    /* if bit is set, we disable trapping that error! */    /*   _FPE_IVO : invalid operation */    /*   _FPE_DVZ : divide by zero */    /*   _FPE_OFL : overflow */    /*   _FPE_UFL : underflow */    /*   _FPE_INX : inexact */    DisableFPETraps(_FPE_IVO | _FPE_DVZ | _FPE_OFL);#endif    /*     *  Debugging stuff     *  The default is to ignore FPE's, unless compiled with -DABORTFP     *  so add code below to ENABLE FPE's.     */#if defined(ABORTFP)#if defined(_MSC_VER)    {   /* set affinity to a single CPU.  Fix for EAC/lame on SMP systems from     "Todd Richmond" <todd.richmond@openwave.com> */    SYSTEM_INFO si;    GetSystemInfo(&si);    SetProcessAffinityMask(GetCurrentProcess(), si.dwActiveProcessorMask);#include <float.h>        unsigned int mask;        mask = _controlfp(0, 0);        mask &= ~(_EM_OVERFLOW | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_INVALID);        mask = _controlfp(mask, _MCW_EM);    }#elif defined(__CYGWIN__)#  define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))#  define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))#  define _EM_INEXACT     0x00000020 /* inexact (precision) */#  define _EM_UNDERFLOW   0x00000010 /* underflow */#  define _EM_OVERFLOW    0x00000008 /* overflow */#  define _EM_ZERODIVIDE  0x00000004 /* zero divide */#  define _EM_INVALID     0x00000001 /* invalid */    {        unsigned int mask;        _FPU_GETCW(mask);        /* Set the FPU control word to abort on most FPEs */        mask &= ~(_EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID);        _FPU_SETCW(mask);    }# elif defined(__linux__)    {#  include <fpu_control.h>#  ifndef _FPU_GETCW#  define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))#  endif#  ifndef _FPU_SETCW#  define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))#  endif        /*          * Set the Linux mask to abort on most FPE's         * if bit is set, we _mask_ SIGFPE on that error!         *  mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM );         */        unsigned int mask;        _FPU_GETCW(mask);        mask &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);        _FPU_SETCW(mask);    }#endif#endif /* ABORTFP */}#ifdef USE_FAST_LOG/*********************************************************************** * * Fast Log Approximation for log2, used to approximate every other log * (log10 and log) * maximum absolute error for log10 is around 10-6 * maximum *relative* error can be high when x is almost 1 because error/log10(x) tends toward x/e * * use it if typical RESULT values are > 1e-5 (for example if x>1.00001 or x<0.99999) * or if the relative precision in the domain around 1 is not important (result in 1 is exact and 0) * ***********************************************************************/#define LOG2_SIZE       (512)#define LOG2_SIZE_L2    (9)static ieee754_float32_t log_table[LOG2_SIZE+1];void init_log_table(void){  int j;  static int init = 0;  /* Range for log2(x) over [1,2[ is [0,1[ */  assert((1<<LOG2_SIZE_L2)==LOG2_SIZE);    if(!init) {    for(j=0; j<LOG2_SIZE+1; j++)      log_table[j] = log(1.0f+j/(ieee754_float32_t)LOG2_SIZE)/log(2.0f);  }  init = 1;}ieee754_float32_t fast_log2(ieee754_float32_t x){  ieee754_float32_t log2val, partial;  union {    ieee754_float32_t f;    int     i;  } fi;  int mantisse;  fi.f = x;  mantisse = fi.i & 0x7fffff;  log2val = ((fi.i>>23) & 0xFF)-0x7f;  partial = (mantisse & ((1<<(23-LOG2_SIZE_L2))-1));  partial *= 1.0f/((1<<(23-LOG2_SIZE_L2)));  mantisse >>= (23-LOG2_SIZE_L2);  /* log2val += log_table[mantisse];  without interpolation the results are not good */  log2val += log_table[mantisse] * (1.0f-partial) + log_table[mantisse+1]*partial;  return log2val;}#else /* Don't use FAST_LOG */void init_log_table(void){}#endif/* end of util.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -