Browse Source

lpc: use levinson for the first pass of multipass cholesky

Levinson is faster, and cholesky is only needed if we want to apply different
weights to different samples, which doesn't happen on the first pass.

Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
tags/n2.0
Loren Merritt Luca Barbato 12 years ago
parent
commit
c93ccf5a4c
1 changed files with 16 additions and 13 deletions
  1. +16
    -13
      libavcodec/lpc.c

+ 16
- 13
libavcodec/lpc.c View File

@@ -176,7 +176,7 @@ int ff_lpc_calc_coefs(LPCContext *s,
double autoc[MAX_LPC_ORDER+1];
double ref[MAX_LPC_ORDER];
double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER];
int i, j, pass;
int i, j, pass = 0;
int opt_order;

assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER &&
@@ -189,7 +189,7 @@ int ff_lpc_calc_coefs(LPCContext *s,
ff_lpc_init(s, blocksize, max_order, lpc_type);
}

if (lpc_type == FF_LPC_TYPE_LEVINSON) {
if (lpc_type == FF_LPC_TYPE_LEVINSON || (lpc_type == FF_LPC_TYPE_CHOLESKY && lpc_passes > 1)) {
s->lpc_apply_welch_window(samples, blocksize, s->windowed_samples);

s->lpc_compute_autocorr(s->windowed_samples, blocksize, max_order, autoc);
@@ -198,13 +198,20 @@ int ff_lpc_calc_coefs(LPCContext *s,

for(i=0; i<max_order; i++)
ref[i] = fabs(lpc[i][i]);
} else if (lpc_type == FF_LPC_TYPE_CHOLESKY) {

pass++;
}

if (lpc_type == FF_LPC_TYPE_CHOLESKY) {
LLSModel m[2];
LOCAL_ALIGNED(32, double, var, [FFALIGN(MAX_LPC_ORDER+1,4)]);
double av_uninit(weight);
memset(var, 0, FFALIGN(MAX_LPC_ORDER+1,4)*sizeof(*var));

for(pass=0; pass<lpc_passes; pass++){
for(j=0; j<max_order; j++)
m[0].coeff[max_order-1][j] = -lpc[max_order-1][j];

for(; pass<lpc_passes; pass++){
avpriv_init_lls(&m[pass&1], max_order);

weight=0;
@@ -259,15 +266,11 @@ av_cold int ff_lpc_init(LPCContext *s, int blocksize, int max_order,
s->max_order = max_order;
s->lpc_type = lpc_type;

if (lpc_type == FF_LPC_TYPE_LEVINSON) {
s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) *
sizeof(*s->windowed_samples));
if (!s->windowed_buffer)
return AVERROR(ENOMEM);
s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4);
} else {
s->windowed_samples = NULL;
}
s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) *
sizeof(*s->windowed_samples));
if (!s->windowed_buffer)
return AVERROR(ENOMEM);
s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4);

s->lpc_apply_welch_window = lpc_apply_welch_window_c;
s->lpc_compute_autocorr = lpc_compute_autocorr_c;


Loading…
Cancel
Save