annotate src/libvorbis-1.3.3/lib/lpc.c @ 36:55ece8862b6d

Merge
author Chris Cannam
date Wed, 11 Mar 2015 13:32:44 +0000
parents 05aa0afa9217
children
rev   line source
Chris@1 1 /********************************************************************
Chris@1 2 * *
Chris@1 3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
Chris@1 4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
Chris@1 5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
Chris@1 6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
Chris@1 7 * *
Chris@1 8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
Chris@1 9 * by the Xiph.Org Foundation http://www.xiph.org/ *
Chris@1 10 * *
Chris@1 11 ********************************************************************
Chris@1 12
Chris@1 13 function: LPC low level routines
Chris@1 14 last mod: $Id: lpc.c 16227 2009-07-08 06:58:46Z xiphmont $
Chris@1 15
Chris@1 16 ********************************************************************/
Chris@1 17
Chris@1 18 /* Some of these routines (autocorrelator, LPC coefficient estimator)
Chris@1 19 are derived from code written by Jutta Degener and Carsten Bormann;
Chris@1 20 thus we include their copyright below. The entirety of this file
Chris@1 21 is freely redistributable on the condition that both of these
Chris@1 22 copyright notices are preserved without modification. */
Chris@1 23
Chris@1 24 /* Preserved Copyright: *********************************************/
Chris@1 25
Chris@1 26 /* Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
Chris@1 27 Technische Universita"t Berlin
Chris@1 28
Chris@1 29 Any use of this software is permitted provided that this notice is not
Chris@1 30 removed and that neither the authors nor the Technische Universita"t
Chris@1 31 Berlin are deemed to have made any representations as to the
Chris@1 32 suitability of this software for any purpose nor are held responsible
Chris@1 33 for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR
Chris@1 34 THIS SOFTWARE.
Chris@1 35
Chris@1 36 As a matter of courtesy, the authors request to be informed about uses
Chris@1 37 this software has found, about bugs in this software, and about any
Chris@1 38 improvements that may be of general interest.
Chris@1 39
Chris@1 40 Berlin, 28.11.1994
Chris@1 41 Jutta Degener
Chris@1 42 Carsten Bormann
Chris@1 43
Chris@1 44 *********************************************************************/
Chris@1 45
Chris@1 46 #include <stdlib.h>
Chris@1 47 #include <string.h>
Chris@1 48 #include <math.h>
Chris@1 49 #include "os.h"
Chris@1 50 #include "smallft.h"
Chris@1 51 #include "lpc.h"
Chris@1 52 #include "scales.h"
Chris@1 53 #include "misc.h"
Chris@1 54
Chris@1 55 /* Autocorrelation LPC coeff generation algorithm invented by
Chris@1 56 N. Levinson in 1947, modified by J. Durbin in 1959. */
Chris@1 57
Chris@1 58 /* Input : n elements of time doamin data
Chris@1 59 Output: m lpc coefficients, excitation energy */
Chris@1 60
Chris@1 61 float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){
Chris@1 62 double *aut=alloca(sizeof(*aut)*(m+1));
Chris@1 63 double *lpc=alloca(sizeof(*lpc)*(m));
Chris@1 64 double error;
Chris@1 65 double epsilon;
Chris@1 66 int i,j;
Chris@1 67
Chris@1 68 /* autocorrelation, p+1 lag coefficients */
Chris@1 69 j=m+1;
Chris@1 70 while(j--){
Chris@1 71 double d=0; /* double needed for accumulator depth */
Chris@1 72 for(i=j;i<n;i++)d+=(double)data[i]*data[i-j];
Chris@1 73 aut[j]=d;
Chris@1 74 }
Chris@1 75
Chris@1 76 /* Generate lpc coefficients from autocorr values */
Chris@1 77
Chris@1 78 /* set our noise floor to about -100dB */
Chris@1 79 error=aut[0] * (1. + 1e-10);
Chris@1 80 epsilon=1e-9*aut[0]+1e-10;
Chris@1 81
Chris@1 82 for(i=0;i<m;i++){
Chris@1 83 double r= -aut[i+1];
Chris@1 84
Chris@1 85 if(error<epsilon){
Chris@1 86 memset(lpc+i,0,(m-i)*sizeof(*lpc));
Chris@1 87 goto done;
Chris@1 88 }
Chris@1 89
Chris@1 90 /* Sum up this iteration's reflection coefficient; note that in
Chris@1 91 Vorbis we don't save it. If anyone wants to recycle this code
Chris@1 92 and needs reflection coefficients, save the results of 'r' from
Chris@1 93 each iteration. */
Chris@1 94
Chris@1 95 for(j=0;j<i;j++)r-=lpc[j]*aut[i-j];
Chris@1 96 r/=error;
Chris@1 97
Chris@1 98 /* Update LPC coefficients and total error */
Chris@1 99
Chris@1 100 lpc[i]=r;
Chris@1 101 for(j=0;j<i/2;j++){
Chris@1 102 double tmp=lpc[j];
Chris@1 103
Chris@1 104 lpc[j]+=r*lpc[i-1-j];
Chris@1 105 lpc[i-1-j]+=r*tmp;
Chris@1 106 }
Chris@1 107 if(i&1)lpc[j]+=lpc[j]*r;
Chris@1 108
Chris@1 109 error*=1.-r*r;
Chris@1 110
Chris@1 111 }
Chris@1 112
Chris@1 113 done:
Chris@1 114
Chris@1 115 /* slightly damp the filter */
Chris@1 116 {
Chris@1 117 double g = .99;
Chris@1 118 double damp = g;
Chris@1 119 for(j=0;j<m;j++){
Chris@1 120 lpc[j]*=damp;
Chris@1 121 damp*=g;
Chris@1 122 }
Chris@1 123 }
Chris@1 124
Chris@1 125 for(j=0;j<m;j++)lpci[j]=(float)lpc[j];
Chris@1 126
Chris@1 127 /* we need the error value to know how big an impulse to hit the
Chris@1 128 filter with later */
Chris@1 129
Chris@1 130 return error;
Chris@1 131 }
Chris@1 132
Chris@1 133 void vorbis_lpc_predict(float *coeff,float *prime,int m,
Chris@1 134 float *data,long n){
Chris@1 135
Chris@1 136 /* in: coeff[0...m-1] LPC coefficients
Chris@1 137 prime[0...m-1] initial values (allocated size of n+m-1)
Chris@1 138 out: data[0...n-1] data samples */
Chris@1 139
Chris@1 140 long i,j,o,p;
Chris@1 141 float y;
Chris@1 142 float *work=alloca(sizeof(*work)*(m+n));
Chris@1 143
Chris@1 144 if(!prime)
Chris@1 145 for(i=0;i<m;i++)
Chris@1 146 work[i]=0.f;
Chris@1 147 else
Chris@1 148 for(i=0;i<m;i++)
Chris@1 149 work[i]=prime[i];
Chris@1 150
Chris@1 151 for(i=0;i<n;i++){
Chris@1 152 y=0;
Chris@1 153 o=i;
Chris@1 154 p=m;
Chris@1 155 for(j=0;j<m;j++)
Chris@1 156 y-=work[o++]*coeff[--p];
Chris@1 157
Chris@1 158 data[i]=work[o]=y;
Chris@1 159 }
Chris@1 160 }