lpc.java

来自「java ogg player library. for play back o」· Java 代码 · 共 255 行

JAVA
255
字号
/* JOrbis * Copyright (C) 2000 ymnk, JCraft,Inc. *   * Written by: 2000 ymnk<ymnk@jcraft.com> *    * Many thanks to  *   Monty <monty@xiph.org> and  *   The XIPHOPHORUS Company http://www.xiph.org/ . * JOrbis has been based on their awesome works, Vorbis codec. *    * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version.    * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU Library General Public License for more details. *  * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */package com.jcraft.jorbis;class Lpc{  // en/decode lookups  Drft fft=new Drft();;  int ln;  int m;  // Autocorrelation LPC coeff generation algorithm invented by  // N. Levinson in 1947, modified by J. Durbin in 1959.  // Input : n elements of time doamin data  // Output: m lpc coefficients, excitation energy  static float lpc_from_data(float[] data, float[] lpc,int n,int m){    float[] aut=new float[m+1];    float error;    int i,j;    // autocorrelation, p+1 lag coefficients    j=m+1;    while(j--!=0){      float d=0;      for(i=j;i<n;i++)d+=data[i]*data[i-j];      aut[j]=d;    }      // Generate lpc coefficients from autocorr values    error=aut[0];    /*    if(error==0){      for(int k=0; k<m; k++) lpc[k]=0.0f;      return 0;    }    */      for(i=0;i<m;i++){      float r=-aut[i+1];      if(error==0){        for(int k=0; k<m; k++) lpc[k]=0.0f;        return 0;      }      // Sum up this iteration's reflection coefficient; note that in      // Vorbis we don't save it.  If anyone wants to recycle this code      // and needs reflection coefficients, save the results of 'r' from      // each iteration.      for(j=0;j<i;j++)r-=lpc[j]*aut[i-j];      r/=error;       // Update LPC coefficients and total error          lpc[i]=r;      for(j=0;j<i/2;j++){	float tmp=lpc[j];	lpc[j]+=r*lpc[i-1-j];	lpc[i-1-j]+=r*tmp;      }      if(i%2!=0)lpc[j]+=lpc[j]*r;          error*=1.0-r*r;    }      // we need the error value to know how big an impulse to hit the    // filter with later      return error;  }  // Input : n element envelope spectral curve  // Output: m lpc coefficients, excitation energy  float lpc_from_curve(float[] curve, float[] lpc){    int n=ln;    float[] work=new float[n+n];    float fscale=(float)(.5/n);    int i,j;      // input is a real curve. make it complex-real    // This mixes phase, but the LPC generation doesn't care.    for(i=0;i<n;i++){      work[i*2]=curve[i]*fscale;      work[i*2+1]=0;    }    work[n*2-1]=curve[n-1]*fscale;      n*=2;    fft.backward(work);      // The autocorrelation will not be circular.  Shift, else we lose    // most of the power in the edges.      for(i=0,j=n/2;i<n/2;){      float temp=work[i];      work[i++]=work[j];      work[j++]=temp;    }      return(lpc_from_data(work,lpc,n,m));  }  void init(int mapped, int m){    //memset(l,0,sizeof(lpc_lookup));    ln=mapped;    this.m=m;    // we cheat decoding the LPC spectrum via FFTs    fft.init(mapped*2);  }  void clear(){    fft.clear();  }  static float FAST_HYPOT(float a, float b){    return (float)Math.sqrt((a)*(a) + (b)*(b));  }  // One can do this the long way by generating the transfer function in  // the time domain and taking the forward FFT of the result.  The  // results from direct calculation are cleaner and faster.   //  // This version does a linear curve generation and then later  // interpolates the log curve from the linear curve.  void lpc_to_curve(float[] curve, float[] lpc, float amp){    //memset(curve,0,sizeof(float)*l->ln*2);    for(int i=0; i<ln*2; i++)curve[i]=0.0f;    if(amp==0)return;    for(int i=0;i<m;i++){      curve[i*2+1]=lpc[i]/(4*amp);      curve[i*2+2]=-lpc[i]/(4*amp);    }    fft.backward(curve); // reappropriated ;-)    {      int l2=ln*2;      float unit=(float)(1./amp);      curve[0]=(float)(1./(curve[0]*2+unit));      for(int i=1;i<ln;i++){	float real=(curve[i]+curve[l2-i]);	float imag=(curve[i]-curve[l2-i]);	float a = real + unit;	curve[i] = (float)(1.0 / FAST_HYPOT(a, imag));      }    }  }  /*  // subtract or add an lpc filter to data.  Vorbis doesn't actually use this.  static void lpc_residue(float[] coeff, float[] prime,int m,			  float[] data, int n){    // in: coeff[0...m-1] LPC coefficients     //     prime[0...m-1] initial values     //     data[0...n-1] data samples     // out: data[0...n-1] residuals from LPC prediction    float[] work=new float[m+n];    float y;    if(prime==null){      for(int i=0;i<m;i++){	work[i]=0;      }    }    else{      for(int i=0;i<m;i++){	work[i]=prime[i];      }    }    for(int i=0;i<n;i++){      y=0;      for(int j=0;j<m;j++){	y-=work[i+j]*coeff[m-j-1];      }      work[i+m]=data[i];      data[i]-=y;    }  }  static void lpc_predict(float[] coeff, float[] prime,int m,			  float[] data, int n){    // in: coeff[0...m-1] LPC coefficients     //     prime[0...m-1] initial values (allocated size of n+m-1)    //     data[0...n-1] residuals from LPC prediction       // out: data[0...n-1] data samples    int o,p;    float y;    float[] work=new float[m+n];    if(prime==null){      for(int i=0;i<m;i++){	work[i]=0.f;      }    }    else{      for(int i=0;i<m;i++){	work[i]=prime[i];      }    }    for(int i=0;i<n;i++){      y=data[i];      o=i;      p=m;      for(int j=0;j<m;j++){	y-=work[o++]*coeff[--p];      }      data[i]=work[o]=y;    }  }*/}

⌨️ 快捷键说明

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