Libav
lpc.h
Go to the documentation of this file.
1 /*
2  * LPC utility code
3  * Copyright (c) 2006 Justin Ruggles <justin.ruggles@gmail.com>
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #ifndef AVCODEC_LPC_H
23 #define AVCODEC_LPC_H
24 
25 #include <stdint.h>
26 
27 #define ORDER_METHOD_EST 0
28 #define ORDER_METHOD_2LEVEL 1
29 #define ORDER_METHOD_4LEVEL 2
30 #define ORDER_METHOD_8LEVEL 3
31 #define ORDER_METHOD_SEARCH 4
32 #define ORDER_METHOD_LOG 5
33 
34 #define MIN_LPC_ORDER 1
35 #define MAX_LPC_ORDER 32
36 
40 enum FFLPCType {
47 };
48 
49 typedef struct LPCContext {
50  int blocksize;
51  int max_order;
53  double *windowed_buffer;
55 
65  double *w_data);
79  void (*lpc_compute_autocorr)(const double *data, int len, int lag,
80  double *autoc);
81 } LPCContext;
82 
83 
88  const int32_t *samples, int blocksize, int min_order,
89  int max_order, int precision,
90  int32_t coefs[][MAX_LPC_ORDER], int *shift,
91  enum FFLPCType lpc_type, int lpc_passes,
92  int omethod, int max_shift, int zero_shift);
93 
95  const int32_t *samples, int order, double *ref);
96 
100 int ff_lpc_init(LPCContext *s, int blocksize, int max_order,
101  enum FFLPCType lpc_type);
102 void ff_lpc_init_x86(LPCContext *s);
103 
107 void ff_lpc_end(LPCContext *s);
108 
109 #ifdef LPC_USE_DOUBLE
110 #define LPC_TYPE double
111 #else
112 #define LPC_TYPE float
113 #endif
114 
119 static inline void compute_ref_coefs(const LPC_TYPE *autoc, int max_order,
120  LPC_TYPE *ref, LPC_TYPE *error)
121 {
122  int i, j;
123  LPC_TYPE err;
124  LPC_TYPE gen0[MAX_LPC_ORDER], gen1[MAX_LPC_ORDER];
125 
126  for (i = 0; i < max_order; i++)
127  gen0[i] = gen1[i] = autoc[i + 1];
128 
129  err = autoc[0];
130  ref[0] = -gen1[0] / err;
131  err += gen1[0] * ref[0];
132  if (error)
133  error[0] = err;
134  for (i = 1; i < max_order; i++) {
135  for (j = 0; j < max_order - i; j++) {
136  gen1[j] = gen1[j + 1] + ref[i - 1] * gen0[j];
137  gen0[j] = gen1[j + 1] * ref[i - 1] + gen0[j];
138  }
139  ref[i] = -gen1[0] / err;
140  err += gen1[0] * ref[i];
141  if (error)
142  error[i] = err;
143  }
144 }
145 
150 static inline int compute_lpc_coefs(const LPC_TYPE *autoc, int max_order,
151  LPC_TYPE *lpc, int lpc_stride, int fail,
152  int normalize)
153 {
154  int i, j;
155  LPC_TYPE err;
156  LPC_TYPE *lpc_last = lpc;
157 
158  if (normalize)
159  err = *autoc++;
160 
161  if (fail && (autoc[max_order - 1] == 0 || err <= 0))
162  return -1;
163 
164  for(i=0; i<max_order; i++) {
165  LPC_TYPE r = -autoc[i];
166 
167  if (normalize) {
168  for(j=0; j<i; j++)
169  r -= lpc_last[j] * autoc[i-j-1];
170 
171  r /= err;
172  err *= 1.0 - (r * r);
173  }
174 
175  lpc[i] = r;
176 
177  for(j=0; j < (i+1)>>1; j++) {
178  LPC_TYPE f = lpc_last[ j];
179  LPC_TYPE b = lpc_last[i-1-j];
180  lpc[ j] = f + r * b;
181  lpc[i-1-j] = b + r * f;
182  }
183 
184  if (fail && err < 0)
185  return -1;
186 
187  lpc_last = lpc;
188  lpc += lpc_stride;
189  }
190 
191  return 0;
192 }
193 
194 #endif /* AVCODEC_LPC_H */