vrshoot

diff libs/vorbis/lpc.c @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/vorbis/lpc.c	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,160 @@
     1.4 +/********************************************************************
     1.5 + *                                                                  *
     1.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
     1.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
     1.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
     1.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
    1.10 + *                                                                  *
    1.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
    1.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
    1.13 + *                                                                  *
    1.14 + ********************************************************************
    1.15 +
    1.16 +  function: LPC low level routines
    1.17 +  last mod: $Id: lpc.c 16227 2009-07-08 06:58:46Z xiphmont $
    1.18 +
    1.19 + ********************************************************************/
    1.20 +
    1.21 +/* Some of these routines (autocorrelator, LPC coefficient estimator)
    1.22 +   are derived from code written by Jutta Degener and Carsten Bormann;
    1.23 +   thus we include their copyright below.  The entirety of this file
    1.24 +   is freely redistributable on the condition that both of these
    1.25 +   copyright notices are preserved without modification.  */
    1.26 +
    1.27 +/* Preserved Copyright: *********************************************/
    1.28 +
    1.29 +/* Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
    1.30 +Technische Universita"t Berlin
    1.31 +
    1.32 +Any use of this software is permitted provided that this notice is not
    1.33 +removed and that neither the authors nor the Technische Universita"t
    1.34 +Berlin are deemed to have made any representations as to the
    1.35 +suitability of this software for any purpose nor are held responsible
    1.36 +for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR
    1.37 +THIS SOFTWARE.
    1.38 +
    1.39 +As a matter of courtesy, the authors request to be informed about uses
    1.40 +this software has found, about bugs in this software, and about any
    1.41 +improvements that may be of general interest.
    1.42 +
    1.43 +Berlin, 28.11.1994
    1.44 +Jutta Degener
    1.45 +Carsten Bormann
    1.46 +
    1.47 +*********************************************************************/
    1.48 +
    1.49 +#include <stdlib.h>
    1.50 +#include <string.h>
    1.51 +#include <math.h>
    1.52 +#include "os.h"
    1.53 +#include "smallft.h"
    1.54 +#include "lpc.h"
    1.55 +#include "scales.h"
    1.56 +#include "misc.h"
    1.57 +
    1.58 +/* Autocorrelation LPC coeff generation algorithm invented by
    1.59 +   N. Levinson in 1947, modified by J. Durbin in 1959. */
    1.60 +
    1.61 +/* Input : n elements of time doamin data
    1.62 +   Output: m lpc coefficients, excitation energy */
    1.63 +
    1.64 +float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){
    1.65 +  double *aut=alloca(sizeof(*aut)*(m+1));
    1.66 +  double *lpc=alloca(sizeof(*lpc)*(m));
    1.67 +  double error;
    1.68 +  double epsilon;
    1.69 +  int i,j;
    1.70 +
    1.71 +  /* autocorrelation, p+1 lag coefficients */
    1.72 +  j=m+1;
    1.73 +  while(j--){
    1.74 +    double d=0; /* double needed for accumulator depth */
    1.75 +    for(i=j;i<n;i++)d+=(double)data[i]*data[i-j];
    1.76 +    aut[j]=d;
    1.77 +  }
    1.78 +
    1.79 +  /* Generate lpc coefficients from autocorr values */
    1.80 +
    1.81 +  /* set our noise floor to about -100dB */
    1.82 +  error=aut[0] * (1. + 1e-10);
    1.83 +  epsilon=1e-9*aut[0]+1e-10;
    1.84 +
    1.85 +  for(i=0;i<m;i++){
    1.86 +    double r= -aut[i+1];
    1.87 +
    1.88 +    if(error<epsilon){
    1.89 +      memset(lpc+i,0,(m-i)*sizeof(*lpc));
    1.90 +      goto done;
    1.91 +    }
    1.92 +
    1.93 +    /* Sum up this iteration's reflection coefficient; note that in
    1.94 +       Vorbis we don't save it.  If anyone wants to recycle this code
    1.95 +       and needs reflection coefficients, save the results of 'r' from
    1.96 +       each iteration. */
    1.97 +
    1.98 +    for(j=0;j<i;j++)r-=lpc[j]*aut[i-j];
    1.99 +    r/=error;
   1.100 +
   1.101 +    /* Update LPC coefficients and total error */
   1.102 +
   1.103 +    lpc[i]=r;
   1.104 +    for(j=0;j<i/2;j++){
   1.105 +      double tmp=lpc[j];
   1.106 +
   1.107 +      lpc[j]+=r*lpc[i-1-j];
   1.108 +      lpc[i-1-j]+=r*tmp;
   1.109 +    }
   1.110 +    if(i&1)lpc[j]+=lpc[j]*r;
   1.111 +
   1.112 +    error*=1.-r*r;
   1.113 +
   1.114 +  }
   1.115 +
   1.116 + done:
   1.117 +
   1.118 +  /* slightly damp the filter */
   1.119 +  {
   1.120 +    double g = .99;
   1.121 +    double damp = g;
   1.122 +    for(j=0;j<m;j++){
   1.123 +      lpc[j]*=damp;
   1.124 +      damp*=g;
   1.125 +    }
   1.126 +  }
   1.127 +
   1.128 +  for(j=0;j<m;j++)lpci[j]=(float)lpc[j];
   1.129 +
   1.130 +  /* we need the error value to know how big an impulse to hit the
   1.131 +     filter with later */
   1.132 +
   1.133 +  return error;
   1.134 +}
   1.135 +
   1.136 +void vorbis_lpc_predict(float *coeff,float *prime,int m,
   1.137 +                     float *data,long n){
   1.138 +
   1.139 +  /* in: coeff[0...m-1] LPC coefficients
   1.140 +         prime[0...m-1] initial values (allocated size of n+m-1)
   1.141 +    out: data[0...n-1] data samples */
   1.142 +
   1.143 +  long i,j,o,p;
   1.144 +  float y;
   1.145 +  float *work=alloca(sizeof(*work)*(m+n));
   1.146 +
   1.147 +  if(!prime)
   1.148 +    for(i=0;i<m;i++)
   1.149 +      work[i]=0.f;
   1.150 +  else
   1.151 +    for(i=0;i<m;i++)
   1.152 +      work[i]=prime[i];
   1.153 +
   1.154 +  for(i=0;i<n;i++){
   1.155 +    y=0;
   1.156 +    o=i;
   1.157 +    p=m;
   1.158 +    for(j=0;j<m;j++)
   1.159 +      y-=work[o++]*coeff[--p];
   1.160 +
   1.161 +    data[i]=work[o]=y;
   1.162 +  }
   1.163 +}