/* * Copyright (c) 2011-2019 Belledonne Communications SARL. * * This file is part of bcg729. * * 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 3 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, see . */ #include "typedef.h" #include "codecParameters.h" #include "basicOperationsMacros.h" #include "codebooks.h" #include "utils.h" #include "computeLP.h" /*****************************************************************************/ /* autoCorrelation2LP: convert autocorrelation coefficients to LP using */ /* Levinson-Durbin algo described in spec 3.2.2 */ /* parameters : */ /* -(i) autoCorrelationCoefficients : 11 values in variable scale */ /* scale is not needed here as a division cancel it */ /* -(o) LPCoefficientsQ12: 10 LP coefficients in Q12 */ /* -(o) reflectionCoefficient: 10 values Q31, k generated during Levinson */ /* Durbin LP coefficient generation and needed for VAD and RFC3389 */ /* -(o) residualEnergy : with the same scale factor as input */ /* autoCorrelationCoefficients, needed by DTX */ /* */ /*****************************************************************************/ void autoCorrelation2LP(word32_t autoCorrelationCoefficients[], word16_t LPCoefficientsQ12[], word32_t reflectionCoefficients[], word32_t *residualEnergy) { /*********************************************************************************/ /* Compute the LP Coefficient using Levinson-Durbin algo spec 3.2.2 */ /*********************************************************************************/ /* start a iteration i=2, init values as after iteration i=1 : */ /* a[0] = 1 */ /* a[1] = -r1/r0 */ /* E = r0(1 - a[1]^2) */ /* */ /* iterations i = 2..10 */ /* sum = r[i] + ∑ a[j]*r[i-j] with j = 1..i-1 (a[0] is always 1) */ /* a[i] = -sum/E */ /* iterations j = 1..i-1 */ /* a[j] += a[i]*a{i-1}[i-j] use a{i-1}: from previous iteration */ /* E *=(1-a[i]^2) */ /* */ /* r in Q31 (normalised) stored in array autoCorrelationCoefficients */ /* E in Q31 (can't be > 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 */ /* */ /*********************************************************************************/ word32_t previousIterationLPCoefficients[NB_LSP_COEFF+1]; /* to compute a[]*/ word32_t LPCoefficients[NB_LSP_COEFF+1]; /* in Q4.27 */ word32_t E = 0; /* in Q31 */ word32_t sum = 0; /* in Q27 */ int i,j; /* init */ LPCoefficients[0] = ONE_IN_Q27; LPCoefficients[1] = -DIV32_32_Q27(autoCorrelationCoefficients[1], autoCorrelationCoefficients[0]); /* result in Q27(but<1) */ reflectionCoefficients[0] = SHL(LPCoefficients[1],4); /* k[0] is -r1/r0 in Q31 */ /* E = r0(1 - a[1]^2) in Q31 */ E = MULT32_32_Q31(autoCorrelationCoefficients[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), autoCorrelationCoefficients[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 */ reflectionCoefficients[i-1] = LPCoefficients[i]; /* k[1] is needed by VAD others by RFC3389 RTP payload for Comfort Noise spectral information encoding */ /* iterations j = 1..i-1 */ /* a[j] += a[i]*a[i-j] */ for (j=1; jMAXINT32) { do { acc64 = SHR(acc64,1); rightShiftToNormalise++; } while (acc64>MAXINT32); autoCorrelationCoefficients[0] = acc64; } else { rightShiftToNormalise = -countLeadingZeros((word32_t)acc64); autoCorrelationCoefficients[0] = SHL((word32_t)acc64, -rightShiftToNormalise); } /* give current autoCorrelation coefficients scale to the output */ *autoCorrelationCoefficientsScale = -rightShiftToNormalise; /* compute autoCorrelationCoefficients 1 to requested number (10 - no VAD - or 12 if VAD is enabled */ if (rightShiftToNormalise>0) { /* acc64 was not fitting on 32 bits so compute the other sum on 64 bits too */ for (i=1; iNB_LSP_COEFF+3) { autoCorrelationCoefficientsNumber = NB_LSP_COEFF+3; } for (i=1; i