00001 /******************************************************************** 00002 * * 00003 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * 00004 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 00005 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 00006 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 00007 * * 00008 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * 00009 * by the XIPHOPHORUS Company http://www.xiph.org/ * 00010 * * 00011 ******************************************************************** 00012 00013 function: LPC low level routines 00014 last mod: $Id: lpc.c 7187 2004-07-20 07:24:27Z xiphmont $ 00015 00016 ********************************************************************/ 00017 00018 /* Some of these routines (autocorrelator, LPC coefficient estimator) 00019 are derived from code written by Jutta Degener and Carsten Bormann; 00020 thus we include their copyright below. The entirety of this file 00021 is freely redistributable on the condition that both of these 00022 copyright notices are preserved without modification. */ 00023 00024 /* Preserved Copyright: *********************************************/ 00025 00026 /* Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, 00027 Technische Universita"t Berlin 00028 00029 Any use of this software is permitted provided that this notice is not 00030 removed and that neither the authors nor the Technische Universita"t 00031 Berlin are deemed to have made any representations as to the 00032 suitability of this software for any purpose nor are held responsible 00033 for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR 00034 THIS SOFTWARE. 00035 00036 As a matter of courtesy, the authors request to be informed about uses 00037 this software has found, about bugs in this software, and about any 00038 improvements that may be of general interest. 00039 00040 Berlin, 28.11.1994 00041 Jutta Degener 00042 Carsten Bormann 00043 00044 *********************************************************************/ 00045 00046 #include <stdlib.h> 00047 #include <string.h> 00048 #include <math.h> 00049 #include "os.h" 00050 #include "smallft.h" 00051 #include "lpc.h" 00052 #include "scales.h" 00053 #include "misc.h" 00054 00055 /* Autocorrelation LPC coeff generation algorithm invented by 00056 N. Levinson in 1947, modified by J. Durbin in 1959. */ 00057 00058 /* Input : n elements of time doamin data 00059 Output: m lpc coefficients, excitation energy */ 00060 00061 float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){ 00062 double *aut= (double*)_ogg_malloc(sizeof(*aut)*(m+1));//alloca(sizeof(*aut)*(m+1)); //patch 00063 double *lpc= (double*)_ogg_malloc(sizeof(*lpc)*(m));//alloca(sizeof(*lpc)*(m)); //patch 00064 double *aut_cpy = aut; //patch 00065 double *lpc_cpy = lpc; //patch 00066 00067 double error; 00068 int i,j; 00069 00070 /* autocorrelation, p+1 lag coefficients */ 00071 j=m+1; 00072 while(j--){ 00073 double d=0; /* double needed for accumulator depth */ 00074 for(i=j;i<n;i++)d+=(double)data[i]*data[i-j]; 00075 aut[j]=d; 00076 } 00077 00078 /* Generate lpc coefficients from autocorr values */ 00079 00080 error=aut[0]; 00081 00082 for(i=0;i<m;i++){ 00083 double r= -aut[i+1]; 00084 00085 if(error==0){ 00086 memset(lpci,0,m*sizeof(*lpci)); 00087 free(aut_cpy); 00088 free(lpc_cpy); 00089 return 0; 00090 } 00091 00092 /* Sum up this iteration's reflection coefficient; note that in 00093 Vorbis we don't save it. If anyone wants to recycle this code 00094 and needs reflection coefficients, save the results of 'r' from 00095 each iteration. */ 00096 00097 for(j=0;j<i;j++)r-=lpc[j]*aut[i-j]; 00098 r/=error; 00099 00100 /* Update LPC coefficients and total error */ 00101 00102 lpc[i]=r; 00103 for(j=0;j<i/2;j++){ 00104 double tmp=lpc[j]; 00105 00106 lpc[j]+=r*lpc[i-1-j]; 00107 lpc[i-1-j]+=r*tmp; 00108 } 00109 if(i%2)lpc[j]+=lpc[j]*r; 00110 00111 error*=1.f-r*r; 00112 } 00113 00114 for(j=0;j<m;j++)lpci[j]=(float)lpc[j]; 00115 00116 /* we need the error value to know how big an impulse to hit the 00117 filter with later */ 00118 free(aut_cpy); 00119 free(lpc_cpy); 00120 return error; 00121 } 00122 00123 void vorbis_lpc_predict(float *coeff,float *prime,int m, 00124 float *data,long n){ 00125 00126 /* in: coeff[0...m-1] LPC coefficients 00127 prime[0...m-1] initial values (allocated size of n+m-1) 00128 out: data[0...n-1] data samples */ 00129 00130 long i,j,o,p; 00131 float y; 00132 float *work= (float*)_ogg_malloc(sizeof(*work)*(m+n));//alloca(sizeof(*work)*(m+n)); //patch 00133 float *work_cpy = work; //patch 00134 00135 if(!prime) 00136 for(i=0;i<m;i++) 00137 work[i]=0.f; 00138 else 00139 for(i=0;i<m;i++) 00140 work[i]=prime[i]; 00141 00142 for(i=0;i<n;i++){ 00143 y=0; 00144 o=i; 00145 p=m; 00146 for(j=0;j<m;j++) 00147 y-=work[o++]*coeff[--p]; 00148 00149 data[i]=work[o]=y; 00150 } 00151 free(work_cpy); //patch 00152 } 00153 00154 00155 00156 00157