FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lpc.c
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 FFmpeg.
6  *
7  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/common.h"
23 #include "libavutil/lls.h"
24 
25 #define LPC_USE_DOUBLE
26 #include "lpc.h"
27 #include "libavutil/avassert.h"
28 
29 
30 /**
31  * Apply Welch window function to audio block
32  */
33 static void lpc_apply_welch_window_c(const int32_t *data, int len,
34  double *w_data)
35 {
36  int i, n2;
37  double w;
38  double c;
39 
40  n2 = (len >> 1);
41  c = 2.0 / (len - 1.0);
42 
43  if (len & 1) {
44  for(i=0; i<n2; i++) {
45  w = c - i - 1.0;
46  w = 1.0 - (w * w);
47  w_data[i] = data[i] * w;
48  w_data[len-1-i] = data[len-1-i] * w;
49  }
50  return;
51  }
52 
53  w_data+=n2;
54  data+=n2;
55  for(i=0; i<n2; i++) {
56  w = c - n2 + i;
57  w = 1.0 - (w * w);
58  w_data[-i-1] = data[-i-1] * w;
59  w_data[+i ] = data[+i ] * w;
60  }
61 }
62 
63 /**
64  * Calculate autocorrelation data from audio samples
65  * A Welch window function is applied before calculation.
66  */
67 static void lpc_compute_autocorr_c(const double *data, int len, int lag,
68  double *autoc)
69 {
70  int i, j;
71 
72  for(j=0; j<lag; j+=2){
73  double sum0 = 1.0, sum1 = 1.0;
74  for(i=j; i<len; i++){
75  sum0 += data[i] * data[i-j];
76  sum1 += data[i] * data[i-j-1];
77  }
78  autoc[j ] = sum0;
79  autoc[j+1] = sum1;
80  }
81 
82  if(j==lag){
83  double sum = 1.0;
84  for(i=j-1; i<len; i+=2){
85  sum += data[i ] * data[i-j ]
86  + data[i+1] * data[i-j+1];
87  }
88  autoc[j] = sum;
89  }
90 }
91 
92 /**
93  * Quantize LPC coefficients
94  */
95 static void quantize_lpc_coefs(double *lpc_in, int order, int precision,
96  int32_t *lpc_out, int *shift, int max_shift, int zero_shift)
97 {
98  int i;
99  double cmax, error;
100  int32_t qmax;
101  int sh;
102 
103  /* define maximum levels */
104  qmax = (1 << (precision - 1)) - 1;
105 
106  /* find maximum coefficient value */
107  cmax = 0.0;
108  for(i=0; i<order; i++) {
109  cmax= FFMAX(cmax, fabs(lpc_in[i]));
110  }
111 
112  /* if maximum value quantizes to zero, return all zeros */
113  if(cmax * (1 << max_shift) < 1.0) {
114  *shift = zero_shift;
115  memset(lpc_out, 0, sizeof(int32_t) * order);
116  return;
117  }
118 
119  /* calculate level shift which scales max coeff to available bits */
120  sh = max_shift;
121  while((cmax * (1 << sh) > qmax) && (sh > 0)) {
122  sh--;
123  }
124 
125  /* since negative shift values are unsupported in decoder, scale down
126  coefficients instead */
127  if(sh == 0 && cmax > qmax) {
128  double scale = ((double)qmax) / cmax;
129  for(i=0; i<order; i++) {
130  lpc_in[i] *= scale;
131  }
132  }
133 
134  /* output quantized coefficients and level shift */
135  error=0;
136  for(i=0; i<order; i++) {
137  error -= lpc_in[i] * (1 << sh);
138  lpc_out[i] = av_clip(lrintf(error), -qmax, qmax);
139  error -= lpc_out[i];
140  }
141  *shift = sh;
142 }
143 
144 static int estimate_best_order(double *ref, int min_order, int max_order)
145 {
146  int i, est;
147 
148  est = min_order;
149  for(i=max_order-1; i>=min_order-1; i--) {
150  if(ref[i] > 0.10) {
151  est = i+1;
152  break;
153  }
154  }
155  return est;
156 }
157 
159  const int32_t *samples, int order, double *ref)
160 {
161  double autoc[MAX_LPC_ORDER + 1];
162 
164  s->lpc_compute_autocorr(s->windowed_samples, s->blocksize, order, autoc);
165  compute_ref_coefs(autoc, order, ref, NULL);
166 
167  return order;
168 }
169 
170 double ff_lpc_calc_ref_coefs_f(LPCContext *s, const float *samples, int len,
171  int order, double *ref)
172 {
173  int i;
174  double signal = 0.0f, avg_err = 0.0f;
175  double autoc[MAX_LPC_ORDER+1] = {0}, error[MAX_LPC_ORDER+1] = {0};
176  const double a = 0.5f, b = 1.0f - a;
177 
178  /* Apply windowing */
179  for (i = 0; i <= len / 2; i++) {
180  double weight = a - b*cos((2*M_PI*i)/(len - 1));
181  s->windowed_samples[i] = weight*samples[i];
182  s->windowed_samples[len-1-i] = weight*samples[len-1-i];
183  }
184 
185  s->lpc_compute_autocorr(s->windowed_samples, len, order, autoc);
186  signal = autoc[0];
187  compute_ref_coefs(autoc, order, ref, error);
188  for (i = 0; i < order; i++)
189  avg_err = (avg_err + error[i])/2.0f;
190  return signal/avg_err;
191 }
192 
193 /**
194  * Calculate LPC coefficients for multiple orders
195  *
196  * @param lpc_type LPC method for determining coefficients,
197  * see #FFLPCType for details
198  */
200  const int32_t *samples, int blocksize, int min_order,
201  int max_order, int precision,
202  int32_t coefs[][MAX_LPC_ORDER], int *shift,
203  enum FFLPCType lpc_type, int lpc_passes,
204  int omethod, int max_shift, int zero_shift)
205 {
206  double autoc[MAX_LPC_ORDER+1];
207  double ref[MAX_LPC_ORDER] = { 0 };
208  double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER];
209  int i, j, pass = 0;
210  int opt_order;
211 
212  av_assert2(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER &&
213  lpc_type > FF_LPC_TYPE_FIXED);
214  av_assert0(lpc_type == FF_LPC_TYPE_CHOLESKY || lpc_type == FF_LPC_TYPE_LEVINSON);
215 
216  /* reinit LPC context if parameters have changed */
217  if (blocksize != s->blocksize || max_order != s->max_order ||
218  lpc_type != s->lpc_type) {
219  ff_lpc_end(s);
220  ff_lpc_init(s, blocksize, max_order, lpc_type);
221  }
222 
223  if(lpc_passes <= 0)
224  lpc_passes = 2;
225 
226  if (lpc_type == FF_LPC_TYPE_LEVINSON || (lpc_type == FF_LPC_TYPE_CHOLESKY && lpc_passes > 1)) {
227  s->lpc_apply_welch_window(samples, blocksize, s->windowed_samples);
228 
229  s->lpc_compute_autocorr(s->windowed_samples, blocksize, max_order, autoc);
230 
231  compute_lpc_coefs(autoc, max_order, &lpc[0][0], MAX_LPC_ORDER, 0, 1);
232 
233  for(i=0; i<max_order; i++)
234  ref[i] = fabs(lpc[i][i]);
235 
236  pass++;
237  }
238 
239  if (lpc_type == FF_LPC_TYPE_CHOLESKY) {
240  LLSModel *m = s->lls_models;
241  LOCAL_ALIGNED(32, double, var, [FFALIGN(MAX_LPC_ORDER+1,4)]);
242  double av_uninit(weight);
243  memset(var, 0, FFALIGN(MAX_LPC_ORDER+1,4)*sizeof(*var));
244 
245  for(j=0; j<max_order; j++)
246  m[0].coeff[max_order-1][j] = -lpc[max_order-1][j];
247 
248  for(; pass<lpc_passes; pass++){
249  avpriv_init_lls(&m[pass&1], max_order);
250 
251  weight=0;
252  for(i=max_order; i<blocksize; i++){
253  for(j=0; j<=max_order; j++)
254  var[j]= samples[i-j];
255 
256  if(pass){
257  double eval, inv, rinv;
258  eval= m[pass&1].evaluate_lls(&m[(pass-1)&1], var+1, max_order-1);
259  eval= (512>>pass) + fabs(eval - var[0]);
260  inv = 1/eval;
261  rinv = sqrt(inv);
262  for(j=0; j<=max_order; j++)
263  var[j] *= rinv;
264  weight += inv;
265  }else
266  weight++;
267 
268  m[pass&1].update_lls(&m[pass&1], var);
269  }
270  avpriv_solve_lls(&m[pass&1], 0.001, 0);
271  }
272 
273  for(i=0; i<max_order; i++){
274  for(j=0; j<max_order; j++)
275  lpc[i][j]=-m[(pass-1)&1].coeff[i][j];
276  ref[i]= sqrt(m[(pass-1)&1].variance[i] / weight) * (blocksize - max_order) / 4000;
277  }
278  for(i=max_order-1; i>0; i--)
279  ref[i] = ref[i-1] - ref[i];
280  }
281 
282  opt_order = max_order;
283 
284  if(omethod == ORDER_METHOD_EST) {
285  opt_order = estimate_best_order(ref, min_order, max_order);
286  i = opt_order-1;
287  quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift);
288  } else {
289  for(i=min_order-1; i<max_order; i++) {
290  quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift);
291  }
292  }
293 
294  return opt_order;
295 }
296 
297 av_cold int ff_lpc_init(LPCContext *s, int blocksize, int max_order,
298  enum FFLPCType lpc_type)
299 {
300  s->blocksize = blocksize;
301  s->max_order = max_order;
302  s->lpc_type = lpc_type;
303 
304  s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) *
305  sizeof(*s->windowed_samples));
306  if (!s->windowed_buffer)
307  return AVERROR(ENOMEM);
308  s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4);
309 
312 
313  if (ARCH_X86)
314  ff_lpc_init_x86(s);
315 
316  return 0;
317 }
318 
320 {
322 }
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:631
static int shift(int a, int b)
Definition: sonic.c:82
Linear least squares model.
Definition: lls.h:38
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
Definition: lpc.h:52
#define MAX_LPC_ORDER
Definition: lpc.h:38
int ff_lpc_calc_coefs(LPCContext *s, const int32_t *samples, int blocksize, int min_order, int max_order, int precision, int32_t coefs[][MAX_LPC_ORDER], int *shift, enum FFLPCType lpc_type, int lpc_passes, int omethod, int max_shift, int zero_shift)
Calculate LPC coefficients for multiple orders.
Definition: lpc.c:199
static void lpc_compute_autocorr_c(const double *data, int len, int lag, double *autoc)
Calculate autocorrelation data from audio samples A Welch window function is applied before calculati...
Definition: lpc.c:67
const char * b
Definition: vf_curves.c:109
static void compute_ref_coefs(const LPC_TYPE *autoc, int max_order, LPC_TYPE *ref, LPC_TYPE *error)
Schur recursion.
Definition: lpc.h:132
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
enum FFLPCType lpc_type
Definition: lpc.h:55
av_cold void ff_lpc_init_x86(LPCContext *c)
Definition: lpc.c:152
#define av_cold
Definition: attributes.h:82
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:63
double * windowed_buffer
Definition: lpc.h:56
#define lrintf(x)
Definition: libm_mips.h:70
int ff_lpc_calc_ref_coefs(LPCContext *s, const int32_t *samples, int order, double *ref)
Definition: lpc.c:158
#define FFALIGN(x, a)
Definition: macros.h:48
unsigned m
Definition: audioconvert.c:187
int max_order
Definition: lpc.h:54
#define AVERROR(e)
Definition: error.h:43
int blocksize
Definition: lpc.h:53
simple assert() macros that are a bit more flexible than ISO C assert().
av_cold void avpriv_init_lls(LLSModel *m, int indep_count)
Definition: lls.c:115
#define FFMAX(a, b)
Definition: common.h:94
#define pass
Definition: fft_template.c:532
static int estimate_best_order(double *ref, int min_order, int max_order)
Definition: lpc.c:144
av_cold void ff_lpc_end(LPCContext *s)
Uninitialize LPCContext.
Definition: lpc.c:319
static void lpc_apply_welch_window_c(const int32_t *data, int len, double *w_data)
Apply Welch window function to audio block.
Definition: lpc.c:33
LLSModel lls_models[2]
Definition: lpc.h:86
int32_t
static int AAC_RENAME() compute_lpc_coefs(const LPC_TYPE *autoc, int max_order, LPC_TYPE *lpc, int lpc_stride, int fail, int normalize)
Levinson-Durbin recursion.
Definition: lpc.h:163
static void quantize_lpc_coefs(double *lpc_in, int order, int precision, int32_t *lpc_out, int *shift, int max_shift, int zero_shift)
Quantize LPC coefficients.
Definition: lpc.c:95
void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order)
Definition: lls.c:47
#define MIN_LPC_ORDER
Definition: lpc.h:37
double(* evaluate_lls)(struct LLSModel *m, const double *var, int order)
Inner product of var[] and the LPC coefs.
Definition: lls.h:57
Levinson-Durbin recursion.
Definition: lpc.h:47
#define ORDER_METHOD_EST
Definition: lpc.h:30
double ff_lpc_calc_ref_coefs_f(LPCContext *s, const float *samples, int len, int order, double *ref)
Definition: lpc.c:170
double * windowed_samples
Definition: lpc.h:57
av_cold int ff_lpc_init(LPCContext *s, int blocksize, int max_order, enum FFLPCType lpc_type)
Initialize LPCContext.
Definition: lpc.c:297
static int weight(int i, int blen, int offset)
Definition: diracdec.c:1429
FFLPCType
LPC analysis type.
Definition: lpc.h:43
Cholesky factorization.
Definition: lpc.h:48
common internal and external API header
double coeff[32][32]
Definition: lls.h:40
#define LOCAL_ALIGNED(a, t, v,...)
Definition: internal.h:110
void(* update_lls)(struct LLSModel *m, const double *var)
Take the outer-product of var[] with itself, and add to the covariance matrix.
Definition: lls.h:50
static double c[64]
fixed LPC coefficients
Definition: lpc.h:46
void(* lpc_compute_autocorr)(const double *data, int len, int lag, double *autoc)
Perform autocorrelation on input samples with delay of 0 to lag.
Definition: lpc.h:82
int len
static const double coeff[2][5]
Definition: vf_owdenoise.c:71
#define av_uninit(x)
Definition: attributes.h:149
#define av_freep(p)
#define M_PI
Definition: mathematics.h:46
void(* lpc_apply_welch_window)(const int32_t *data, int len, double *w_data)
Apply a Welch window to an array of input samples.
Definition: lpc.h:67
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:252