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  /* The optimization in commit fa4ed8c does not support odd len.
41  * If someone wants odd len extend that change. */
42  av_assert2(!(len & 1));
43 
44  n2 = (len >> 1);
45  c = 2.0 / (len - 1.0);
46 
47  w_data+=n2;
48  data+=n2;
49  for(i=0; i<n2; i++) {
50  w = c - n2 + i;
51  w = 1.0 - (w * w);
52  w_data[-i-1] = data[-i-1] * w;
53  w_data[+i ] = data[+i ] * w;
54  }
55 }
56 
57 /**
58  * Calculate autocorrelation data from audio samples
59  * A Welch window function is applied before calculation.
60  */
61 static void lpc_compute_autocorr_c(const double *data, int len, int lag,
62  double *autoc)
63 {
64  int i, j;
65 
66  for(j=0; j<lag; j+=2){
67  double sum0 = 1.0, sum1 = 1.0;
68  for(i=j; i<len; i++){
69  sum0 += data[i] * data[i-j];
70  sum1 += data[i] * data[i-j-1];
71  }
72  autoc[j ] = sum0;
73  autoc[j+1] = sum1;
74  }
75 
76  if(j==lag){
77  double sum = 1.0;
78  for(i=j-1; i<len; i+=2){
79  sum += data[i ] * data[i-j ]
80  + data[i+1] * data[i-j+1];
81  }
82  autoc[j] = sum;
83  }
84 }
85 
86 /**
87  * Quantize LPC coefficients
88  */
89 static void quantize_lpc_coefs(double *lpc_in, int order, int precision,
90  int32_t *lpc_out, int *shift, int max_shift, int zero_shift)
91 {
92  int i;
93  double cmax, error;
94  int32_t qmax;
95  int sh;
96 
97  /* define maximum levels */
98  qmax = (1 << (precision - 1)) - 1;
99 
100  /* find maximum coefficient value */
101  cmax = 0.0;
102  for(i=0; i<order; i++) {
103  cmax= FFMAX(cmax, fabs(lpc_in[i]));
104  }
105 
106  /* if maximum value quantizes to zero, return all zeros */
107  if(cmax * (1 << max_shift) < 1.0) {
108  *shift = zero_shift;
109  memset(lpc_out, 0, sizeof(int32_t) * order);
110  return;
111  }
112 
113  /* calculate level shift which scales max coeff to available bits */
114  sh = max_shift;
115  while((cmax * (1 << sh) > qmax) && (sh > 0)) {
116  sh--;
117  }
118 
119  /* since negative shift values are unsupported in decoder, scale down
120  coefficients instead */
121  if(sh == 0 && cmax > qmax) {
122  double scale = ((double)qmax) / cmax;
123  for(i=0; i<order; i++) {
124  lpc_in[i] *= scale;
125  }
126  }
127 
128  /* output quantized coefficients and level shift */
129  error=0;
130  for(i=0; i<order; i++) {
131  error -= lpc_in[i] * (1 << sh);
132  lpc_out[i] = av_clip(lrintf(error), -qmax, qmax);
133  error -= lpc_out[i];
134  }
135  *shift = sh;
136 }
137 
138 static int estimate_best_order(double *ref, int min_order, int max_order)
139 {
140  int i, est;
141 
142  est = min_order;
143  for(i=max_order-1; i>=min_order-1; i--) {
144  if(ref[i] > 0.10) {
145  est = i+1;
146  break;
147  }
148  }
149  return est;
150 }
151 
153  const int32_t *samples, int order, double *ref)
154 {
155  double autoc[MAX_LPC_ORDER + 1];
156 
158  s->lpc_compute_autocorr(s->windowed_samples, s->blocksize, order, autoc);
159  compute_ref_coefs(autoc, order, ref, NULL);
160 
161  return order;
162 }
163 
164 /**
165  * Calculate LPC coefficients for multiple orders
166  *
167  * @param lpc_type LPC method for determining coefficients,
168  * see #FFLPCType for details
169  */
171  const int32_t *samples, int blocksize, int min_order,
172  int max_order, int precision,
173  int32_t coefs[][MAX_LPC_ORDER], int *shift,
174  enum FFLPCType lpc_type, int lpc_passes,
175  int omethod, int max_shift, int zero_shift)
176 {
177  double autoc[MAX_LPC_ORDER+1];
178  double ref[MAX_LPC_ORDER];
179  double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER];
180  int i, j, pass;
181  int opt_order;
182 
183  av_assert2(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER &&
184  lpc_type > FF_LPC_TYPE_FIXED);
185 
186  /* reinit LPC context if parameters have changed */
187  if (blocksize != s->blocksize || max_order != s->max_order ||
188  lpc_type != s->lpc_type) {
189  ff_lpc_end(s);
190  ff_lpc_init(s, blocksize, max_order, lpc_type);
191  }
192 
193  if (lpc_type == FF_LPC_TYPE_LEVINSON) {
194  s->lpc_apply_welch_window(samples, blocksize, s->windowed_samples);
195 
196  s->lpc_compute_autocorr(s->windowed_samples, blocksize, max_order, autoc);
197 
198  compute_lpc_coefs(autoc, max_order, &lpc[0][0], MAX_LPC_ORDER, 0, 1);
199 
200  for(i=0; i<max_order; i++)
201  ref[i] = fabs(lpc[i][i]);
202  } else if (lpc_type == FF_LPC_TYPE_CHOLESKY) {
203  LLSModel m[2];
204  double var[MAX_LPC_ORDER+1], av_uninit(weight);
205 
206  if(lpc_passes <= 0)
207  lpc_passes = 2;
208 
209  for(pass=0; pass<lpc_passes; pass++){
210  avpriv_init_lls(&m[pass&1], max_order);
211 
212  weight=0;
213  for(i=max_order; i<blocksize; i++){
214  for(j=0; j<=max_order; j++)
215  var[j]= samples[i-j];
216 
217  if(pass){
218  double eval, inv, rinv;
219  eval= avpriv_evaluate_lls(&m[(pass-1)&1], var+1, max_order-1);
220  eval= (512>>pass) + fabs(eval - var[0]);
221  inv = 1/eval;
222  rinv = sqrt(inv);
223  for(j=0; j<=max_order; j++)
224  var[j] *= rinv;
225  weight += inv;
226  }else
227  weight++;
228 
229  avpriv_update_lls(&m[pass&1], var, 1.0);
230  }
231  avpriv_solve_lls(&m[pass&1], 0.001, 0);
232  }
233 
234  for(i=0; i<max_order; i++){
235  for(j=0; j<max_order; j++)
236  lpc[i][j]=-m[(pass-1)&1].coeff[i][j];
237  ref[i]= sqrt(m[(pass-1)&1].variance[i] / weight) * (blocksize - max_order) / 4000;
238  }
239  for(i=max_order-1; i>0; i--)
240  ref[i] = ref[i-1] - ref[i];
241  } else
242  av_assert0(0);
243  opt_order = max_order;
244 
245  if(omethod == ORDER_METHOD_EST) {
246  opt_order = estimate_best_order(ref, min_order, max_order);
247  i = opt_order-1;
248  quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift);
249  } else {
250  for(i=min_order-1; i<max_order; i++) {
251  quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift);
252  }
253  }
254 
255  return opt_order;
256 }
257 
258 av_cold int ff_lpc_init(LPCContext *s, int blocksize, int max_order,
259  enum FFLPCType lpc_type)
260 {
261  s->blocksize = blocksize;
262  s->max_order = max_order;
263  s->lpc_type = lpc_type;
264 
265  if (lpc_type == FF_LPC_TYPE_LEVINSON) {
266  s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) *
267  sizeof(*s->windowed_samples));
268  if (!s->windowed_buffer)
269  return AVERROR(ENOMEM);
270  s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4);
271  } else {
272  s->windowed_samples = NULL;
273  }
274 
277 
278  if (ARCH_X86)
279  ff_lpc_init_x86(s);
280 
281  return 0;
282 }
283 
285 {
287 }
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:205
const char * s
Definition: avisynth_c.h:668
void avpriv_init_lls(LLSModel *m, int indep_count)
Definition: lls.c:34
static int shift(int a, int b)
Definition: sonic.c:86
FIXME Range Coding of cr are ref
Definition: snow.txt:367
Linear least squares model.
Definition: lls.h:35
Definition: lpc.h:50
#define MAX_LPC_ORDER
Definition: lpc.h:36
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:170
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:61
#define pass
Definition: fft.c:335
output residual component w
#define FFALIGN(x, a)
Definition: common.h:63
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
static void compute_ref_coefs(const LPC_TYPE *autoc, int max_order, LPC_TYPE *ref, LPC_TYPE *error)
Schur recursion.
Definition: lpc.h:120
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
enum FFLPCType lpc_type
Definition: lpc.h:53
#define av_cold
Definition: attributes.h:78
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:63
window constants for m
double coeff[MAX_VARS][MAX_VARS]
Definition: lls.h:37
double * windowed_buffer
Definition: lpc.h:54
#define lrintf(x)
Definition: libm_mips.h:70
integer sqrt
Definition: avutil.txt:2
int ff_lpc_calc_ref_coefs(LPCContext *s, const int32_t *samples, int order, double *ref)
Definition: lpc.c:152
int max_order
Definition: lpc.h:52
#define ARCH_X86
Definition: config.h:35
int blocksize
Definition: lpc.h:51
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:65
Spectrum Plot time data
simple assert() macros that are a bit more flexible than ISO C assert().
#define FFMAX(a, b)
Definition: common.h:56
static int estimate_best_order(double *ref, int min_order, int max_order)
Definition: lpc.c:138
av_cold void ff_lpc_end(LPCContext *s)
Uninitialize LPCContext.
Definition: lpc.c:284
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
eval(cmd)
int32_t
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:80
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:89
NULL
Definition: eval.c:55
void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order)
Definition: lls.c:52
static int 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:151
#define MIN_LPC_ORDER
Definition: lpc.h:35
Levinson-Durbin recursion.
Definition: lpc.h:45
#define ORDER_METHOD_EST
Definition: lpc.h:28
for lag
synthesis window for stochastic i
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
double * windowed_samples
Definition: lpc.h:55
av_cold int ff_lpc_init(LPCContext *s, int blocksize, int max_order, enum FFLPCType lpc_type)
Initialize LPCContext.
Definition: lpc.c:258
static int weight(int i, int blen, int offset)
FFLPCType
LPC analysis type.
Definition: lpc.h:41
Cholesky factorization.
Definition: lpc.h:46
common internal and external API header
static double c[64]
Same thing on a dB scale
fixed LPC coefficients
Definition: lpc.h:44
int len
#define av_uninit(x)
Definition: attributes.h:137
Filter the word “frame” indicates either a video frame or a group of audio samples
double avpriv_evaluate_lls(LLSModel *m, double *param, int order)
Definition: lls.c:109
void avpriv_update_lls(LLSModel *m, double *var, double decay)
Definition: lls.c:40
void ff_lpc_init_x86(LPCContext *s)
Definition: x86/lpc.c:144