media/libvorbis/lib/vorbis_lpc.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial