/** * LPC utility code * Copyright (c) 2006 Justin Ruggles * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libavutil/lls.h" #include "dsputil.h" #define LPC_USE_DOUBLE #include "lpc.h" /** * Quantize LPC coefficients */ static void quantize_lpc_coefs(double *lpc_in, int order, int precision, int32_t *lpc_out, int *shift, int max_shift, int zero_shift) { int i; double cmax, error; int32_t qmax; int sh; /* define maximum levels */ qmax = (1 << (precision - 1)) - 1; /* find maximum coefficient value */ cmax = 0.0; for(i=0; i qmax) && (sh > 0)) { sh--; } /* since negative shift values are unsupported in decoder, scale down coefficients instead */ if(sh == 0 && cmax > qmax) { double scale = ((double)qmax) / cmax; for(i=0; i=min_order-1; i--) { if(ref[i] > 0.10) { est = i+1; break; } } return est; } /** * Calculate LPC coefficients for multiple orders * * @param use_lpc LPC method for determining coefficients * 0 = LPC with fixed pre-defined coeffs * 1 = LPC with coeffs determined by Levinson-Durbin recursion * 2+ = LPC with coeffs determined by Cholesky factorization using (use_lpc-1) passes. */ int ff_lpc_calc_coefs(DSPContext *s, const int32_t *samples, int blocksize, int min_order, int max_order, int precision, int32_t coefs[][MAX_LPC_ORDER], int *shift, int use_lpc, int omethod, int max_shift, int zero_shift) { double autoc[MAX_LPC_ORDER+1]; double ref[MAX_LPC_ORDER]; double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER]; int i, j, pass; int opt_order; assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER && use_lpc > 0); if(use_lpc == 1){ s->flac_compute_autocorr(samples, blocksize, max_order, autoc); compute_lpc_coefs(autoc, max_order, &lpc[0][0], MAX_LPC_ORDER, 0, 1); for(i=0; i>pass) + fabs(eval - var[0]); inv = 1/eval; rinv = sqrt(inv); for(j=0; j<=max_order; j++) var[j] *= rinv; weight += inv; }else weight++; av_update_lls(&m[pass&1], var, 1.0); } av_solve_lls(&m[pass&1], 0.001, 0); } for(i=0; i0; i--) ref[i] = ref[i-1] - ref[i]; } opt_order = max_order; if(omethod == ORDER_METHOD_EST) { opt_order = estimate_best_order(ref, min_order, max_order); i = opt_order-1; quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift); } else { for(i=min_order-1; i