/* computeLP.c Copyright (C) 2011 Belledonne Communications, Grenoble, France Author : Johan Pascal This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "typedef.h" #include "codecParameters.h" #include "basicOperationsMacros.h" #include "codebooks.h" #include "utils.h" #include "computeLP.h" /*****************************************************************************/ /* computeLP : As described in spec 3.2.1 and 3.2.2 : Windowing, */ /* Autocorrelation and Levinson-Durbin algorithm */ /* parameters: */ /* -(i) signal: 240 samples in Q0, the last 40 are from next frame */ /* -(o) LPCoefficientsQ12: 10 LP coefficients in Q12 */ /* */ /*****************************************************************************/ void computeLP(word16_t signal[], word16_t LPCoefficientsQ12[]) { int i,j; word16_t windowedSignal[L_LP_ANALYSIS_WINDOW]; word32_t autoCorrelationCoefficient[NB_LSP_COEFF+1]; word64_t acc64=0; /* acc on 64 bits */ int rightShiftToNormalise=0; word32_t previousIterationLPCoefficients[NB_LSP_COEFF+1]; /* to compute a[]*/ word32_t LPCoefficients[NB_LSP_COEFF+1]; /* in Q4.27 */ word32_t sum = 0; /* in Q27 */ word32_t E = 0; /* in Q31 */ /*********************************************************************/ /* Compute the windowed signal according to spec 3.2.1 eq4 */ /*********************************************************************/ for (i=0; iMAXINT32) { do { acc64 = SHR(acc64,1); rightShiftToNormalise++; } while (acc64>MAXINT32); autoCorrelationCoefficient[0] = acc64; } else { rightShiftToNormalise = -countLeadingZeros((word32_t)acc64); autoCorrelationCoefficient[0] = SHL((word32_t)acc64, -rightShiftToNormalise); } /* compute autoCorrelationCoefficient 1 to 10 */ if (rightShiftToNormalise>0) { /* acc64 was not fitting on 32 bits so compute the other sum on 64 bits too */ for (i=1; i 1) */ /* sum in Q27 (sum can't be > 1 but intermediate accumulation can) */ /* a in Q4.27 with full range possible */ /* Note: during iteration, current a[i] is in Q31 (can't be >1) and is */ /* set to Q27 at the end of current iteration */ /* */ /*********************************************************************************/ /* init */ LPCoefficients[0] = ONE_IN_Q27; LPCoefficients[1] = -DIV32_32_Q27(autoCorrelationCoefficient[1], autoCorrelationCoefficient[0]); /* result in Q27(but<1) */ /* E = r0(1 - a[1]^2) in Q31 */ E = MULT32_32_Q31(autoCorrelationCoefficient[0], SUB32(ONE_IN_Q31, MULT32_32_Q23(LPCoefficients[1], LPCoefficients[1]))); /* LPCoefficient[1] is in Q27, using a Q23 operation will result in a Q31 variable */ for (i=2; i result in Q27 -> sum in Q27 */ } sum = ADD32(SHL(sum, 4), autoCorrelationCoefficient[i]); /* set sum in Q31 and add r[0] */ /* a[i] = -sum/E */ LPCoefficients[i] = -DIV32_32_Q31(sum,E); /* LPCoefficient of current iteration is in Q31 for now, it will be set to Q27 at the end of this iteration */ /* iterations j = 1..i-1 */ /* a[j] += a[i]*a[i-j] */ for (j=1; j