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

📄 rateconv.c

📁 AAC音频解码算法程序
💻 C
📖 第 1 页 / 共 2 页
字号:

  l=r=0.0;
  ka=k+j;	kb=k+ov2fac-j;
  i<<=1;
  xa=x+i;	xb=x+i+2;

  n=htaps2+1;
  do
    {
      l+=xa[0]*ka[ 0] + xb[0]*kb[ 0];
      r+=xa[0]*ka[ 1] + xb[0]*kb[-1];

      ka+=ov2fac;
      kb+=ov2fac;
      xa-=2;
      xb+=2;
    }
  while (--n);

  *(*out)++ = (float) (l+h*(r-l));
}

static void ctp2_s(complex *x,double p,real *k,float **out)
{
  register long	n,i,j;
  register double	h,l0,l1,r0,r1;
  register real	*ka,*kb;
  register complex *xa,*xb;

  h=ov2fac*p;
  i=(long) h;
  h-=(double) i;

  j=i&(ov2fac-1); i>>=ov2exp;

  l0=l1=r0=r1=0.0;
  ka=k+j;	kb=k+ov2fac-j;
  xa=x+i;	xb=x+i+1;

  n=htaps2+1;
  do
    {
      l0+=xa[0].re*ka[ 0] + xb[0].re*kb[ 0];
      l1+=xa[0].im*ka[ 0] + xb[0].im*kb[ 0];
      r0+=xa[0].re*ka[ 1] + xb[0].re*kb[-1];
      r1+=xa[0].im*ka[ 1] + xb[0].im*kb[-1];

      ka+=ov2fac;
      kb+=ov2fac;
      xa--;
      xb++;
    }
  while (--n);

  *(*out)++ = (float) (l0+h*(r0-l0));
  *(*out)++ = (float) (l1+h*(r1-l1));
}

static void ctp1_1(complex *x,real *tp1,real *wtab,long fm)
{
  register long	i,fn2;

  fn2=1<<(fm-1);
  r4fft(wtab,(real *) x,fm);
  for (i=0; i<fn2; i++)
    {
      x[i+fn2].re*=tp1[fn2-i];
      x[i+fn2].im*=tp1[fn2-i];
      x[i    ].re*=tp1[i    ];
      x[i    ].im*=tp1[i    ];
    }
  r4ifft(wtab,(real *) x,fm);
}

static void ctp1_2(complex *x,real *tp1,real *wtab,long fm)
{
  register long	i,fn2;

  fn2=1<<(fm-1);

  r4fft(wtab+(1<<fm),(real *) x,fm-1);
  for (i=0; i<fn2; i++)
    {
      x[i+fn2].re=x[i].re*tp1[fn2-i];
      x[i+fn2].im=x[i].im*tp1[fn2-i];
      x[i].re*=tp1[i];
      x[i].im*=tp1[i];
    }
  r4ifft(wtab,(real *) x,fm);
}


/* ---------- functions ---------- */

/* RateConvInit() */
/* Init audio sample rate conversion. */

RCBuf *RateConvInit (
  int debugLevel,		/* in: debug level */
				/*     0=off  1=basic  2=full */
  double ratio,			/* in: outputRate / inputRate */
  int numChannel,		/* in: number of channels */
  int htaps1,			/* in: num taps */
				/*      -1 = auto */
  float a1,			/* in: alpha for Kaiser window */
				/*      -1 = auto */
  float fc,			/* in: 6dB cutoff freq / input bandwidth */
				/*      -1 = auto */
  float fd,			/* in: 100dB cutoff freq / input bandwidth */
				/*      -1 = auto */
  long *numSampleIn)		/* out: num input samples / frame */
				/* returns: */
				/*  buffer (handle) */
				/*  or NULL if error */
{
  real *wtab;
  complex *x;
  real *tp1;
  real *tp2;
  complex *ibuf;

  long nfn;
  long adv;
  long istart;
  long numode;
  long fm;
  double p1;
  double d1;

  double sf2;
  double trw2;
  long fn;
  long fn2;
  long i;
  double h;
  double a;

  RCBuf *buf;

  RCdebugLevel = debugLevel;
  if (RCdebugLevel)
    printf("RateConvInit: debugLevel=%d ratio=%f numChannel=%d\n"
	   "htaps1=%d a1=%f fc=%f fd=%f\n",
	   RCdebugLevel,ratio,numChannel,htaps1,a1,fc,fd);

  buf=(RCBuf*)malloc(sizeof(RCBuf));
//  if (!(buf=(RCBuf*)malloc(sizeof(RCBuf))))
//    CommonExit(-1,"RateConvInit: Can not allocate memory");
  buf->currentSampleIn = 0;
  buf->currentSampleOut = 0;
  buf->numChannel = numChannel;

  if (htaps1<0)
    htaps1 = deftaps1;
  htaps1 /= 2;	/* NM 991104 */
  if (a1<0)
    a1 = 10.0;
  numode = 0;
  for (fm=2; (1<<fm)<8*htaps1; fm+=2);
  fn=1<<fm;
  fn2=fn/2;

  wtab=(real *) malloc((4*fn + fn2+1 + (htaps2+2)*ov2fac)*sizeof(real));
//  if (!(wtab=
//	(real *) malloc((4*fn + fn2+1 + (htaps2+2)*ov2fac)*sizeof(real))))
//    CommonExit(-1,"RateConvInit: Can not allocate memory");
  x=((complex *) wtab)+fn;
  tp1=(real *) (x+fn);
  tp2=tp1+fn2+1;

  mkeiwutab(wtab,fn);
  mktp1(x,0.5,a1,fn,htaps1);
  r4fft(wtab,(real *) x,fm);
  h=x[0].re*x[0].re*1.0e-10;
  for (i=fn/2; x[i].re*x[i].re<h; i--);
  trw2=((double) (i-(fn2/2)))/((double) (fn2/2));

  sf2 = ratio;
  if ( sf2<0.0 ) sf2=1.0;

  d1=1.0/sf2;
  p1=htaps1+htaps2+2;		/* delay compensation */

  if ( fc<0.0 )
    {
      if ( fd<0.0 )
	{
	  fc=1.0/d1-trw2;
	  if ( fc<0.5-0.5*trw2 ) { numode=1; fc=2.0/d1-trw2; }
	  if ( fc>1.0-trw2 ) fc=1.0-trw2;
	}
      else
	{
	  fc=fd-trw2;
	  if ( fd<=0.5 ) { numode=1; fc=2.0*fd-trw2; }
	}
    }
  else
    {
      if ( fc<0.5-trw2 ) { numode=1; fc+=fc; }
    }

  if ( fc>2.0 ) fc=2.0;

  if ( fc<=0.0 ) {
//    CommonWarning("RateConvInit: cutoff frequency to low: %f %f %f\n",
//		  fc,fd,trw2);
    free(wtab);
    free(buf);
    return NULL;
  }

  nfn=fn;
  adv=fn-2*(htaps1+htaps2+2);
  istart=htaps1+htaps2+2;
  if ( !numode ) { nfn>>=1; adv>>=1; d1+=d1; }

  mktp1(x,0.5*fc,a1,fn,htaps1);
  r4fft(wtab,(real *) x,fm);
  a=1.0/((double) (((1+numode)*fn2)));
  for (i=0; i<=fn2 ; i++) tp1[i]=a*x[i].re;

  mktp2(tp2,cutoff2,alpha2);

  *numSampleIn = 2*adv;
  buf->outSize = (long)((2*adv+4)*ratio+4);
  buf->out=(float*)malloc(buf->outSize*sizeof(float));
//  if (!(buf->out=(float*)malloc(buf->outSize*sizeof(float))))
//    CommonExit(-1,"RateConvInit: Can not allocate memory");

  ibuf = (complex *) malloc((nfn-adv)*sizeof(complex));
//  if (!(ibuf = (complex *) malloc((nfn-adv)*sizeof(complex))))
//    CommonExit(-1,"RateConvInit: Can not allocate memory");


  if ( buf->numChannel==1 ) {
    /* ibuf[?].im not used ... */
    for (i=0; i<(nfn-adv)/2; i++)
      ibuf[i].re=0.0;
    for (   ; i<(nfn-adv)  ; i++)
      ibuf[i].re=0.0;
    /* ibuf[i].re=(real) dataIn[idxIn++]; */
  }
  else {
    for (i=0; i<  (nfn-adv); i++)
      ((real *) ibuf)[i]=0.0;
    for (   ; i<2*(nfn-adv); i++)
      ((real *) ibuf)[i]=0.0;
    /* ((real *) ibuf)[i]=(real) dataIn[idxIn++]; */
  }

  if (RCdebugLevel)
    printf("RateConvInit: inSize=%ld outSize=%ld\n"
	   "  output/input ratio : %8.2f\n"
	   "  cutoff frequency   : %10.4f\n"
	   "  Kaiser parameter   : %10.4f\n"
	   "  filter 1 taps      : %5li\n"
	   "  filter 1 transition: %10.4f\n"
	   "  FFT length         : %5li\n"
	   "  oversampling factor: %5li\n",
	   2*adv,buf->outSize,
	   sf2,fc/(1+numode),a1,(long)2*htaps1+1,0.5*trw2,
	   fn,ov2fac*(2-numode));

  buf->wtab = wtab;
  buf->x= x;
  buf->tp1 = tp1;
  buf->tp2 = tp2;
  buf->ibuf = ibuf;

  buf->nfn = nfn;
  buf->adv = adv;
  buf->istart = istart;
  buf->numode = numode;
  buf->fm = fm;
  buf->p1 = p1;
  buf->d1 = d1;

  return buf;
}


/* RateConv() */
/* Convert sample rate for one frame of audio data. */

long RateConv (
  RCBuf *buf,			/* in: buffer (handle) */
  short *dataIn,		/* in: input data[] */
  long numSampleIn,		/* in: number of input samples */
  float **dataOut)		/* out: output data[] */
				/* returns: */
				/*  numSampleOut */
{
  real *wtab = buf->wtab;
  complex *x = buf->x;
  real *tp1 = buf->tp1;
  real *tp2 = buf->tp2;
  complex *ibuf = buf->ibuf;

  long nfn = buf->nfn;
  long adv = buf->adv;
  long istart = buf->istart;
  long numode = buf->numode;
  long fm = buf->fm;
  double p1 = buf->p1;
  double d1 = buf->d1;

  long i;
  double p,h;

  long idxIn,numOut;
  float *out;

  if (RCdebugLevel)
    printf("RateConv: numSampleIn=%ld\n",numSampleIn);

//  if (numSampleIn != 2*adv)
//    CommonExit(-1,"RateConv: wrong numSampleIn");

  idxIn = 0;
  out = buf->out;

  if ( buf->numChannel==1 ) {
    /* ibuf[?].im not used ... */
    for (i=0      ; i<nfn-adv; i++)
      x[i].re=ibuf[i].re;
    for (         ; i<    adv; i++)
      x[i].re=(real) dataIn[idxIn++];
    for (         ; i<    nfn; i++)
      x[i].re=x[i-adv].im=(real) dataIn[idxIn++];
    for (i=nfn-adv; i<    adv; i++)
      x[i].im=(real) dataIn[idxIn++];
    for (         ; i<    nfn; i++)
      x[i].im=ibuf[i-adv].re=(real) dataIn[idxIn++];
      
    if ( numode )
      ctp1_1(x,tp1,wtab,fm);
    else
      ctp1_2(x,tp1,wtab,fm);
      
    i=adv;
    h=(double) ((2*i)>>numode);
    for (p=p1; p<h; p+=d1) ctp2_m(&(x[istart].re),p,tp2,&out);
    p1=p-h;
      
    i=adv;
    h=(double) ((2*i)>>numode);
    for (p=p1; p<h; p+=d1) ctp2_m(&(x[istart].im),p,tp2,&out);
    p1=p-h;
  }
  else {
    for (i=0; i<nfn-adv; i++)
      x[i]=ibuf[i];
    for (; i<adv; i++) {
      x[i].re=(real) dataIn[idxIn++];
      x[i].im=(real) dataIn[idxIn++];
    }
    for (; i<nfn; i++) {
      x[i].re=ibuf[i-adv].re=(real) dataIn[idxIn++];
      x[i].im=ibuf[i-adv].im=(real) dataIn[idxIn++];
    }
      
    if ( numode )
      ctp1_1(x,tp1,wtab,fm);
    else
      ctp1_2(x,tp1,wtab,fm);
      
    i=2*adv;
    h=(double) (i>>numode);
    for (p=p1; p<h; p+=d1) ctp2_s(x+istart,p,tp2,&out);
    p1=p-h;
  }

  buf->p1 = p1;

  *dataOut = buf->out;
  numOut = out - buf->out;
//  if (numOut > buf->outSize)
//    CommonExit(-1,"RateConv: output buffer size troubles");
  buf->currentSampleIn += 2*adv;
  buf->currentSampleOut += numOut;
  
  return numOut;
}


/* RateConvFree() */
/* Free RateConv buffers. */

void RateConvFree (
  RCBuf *buf)			/* in: buffer (handle) */
{
  if (RCdebugLevel)
    printf("RateConvFree: sampleIn=%ld sampleOut=%ld\n",
	   buf->currentSampleIn,buf->currentSampleOut);
  free(buf->out);
  free(buf->wtab);
  free(buf->ibuf);
  free(buf);
}


/* end of rateconv.c */

⌨️ 快捷键说明

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