/* * 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 "utils.h" #include "LP2LSPConversion.h" /* local functions and codebook */ word32_t ChebyshevPolynomial(word16_t x, word32_t f[]); /* return value in Q24 */ static const word16_t cosW0pi[NB_COMPUTED_VALUES_CHEBYSHEV_POLYNOMIAL]; /* cos(w) from 0 to Pi in 50 steps */ /*****************************************************************************/ /* LP2LSPConversion : Compute polynomials, find their roots as in spec A3.2.3*/ /* parameters: */ /* -(i) LPCoefficients[] : 10 coefficients in Q12 */ /* -(o) LSPCoefficients[] : 10 coefficients in Q15 */ /* */ /* return value : */ /* - boolean: 1 if all roots found, 0 if unable to compute 10 roots */ /* */ /*****************************************************************************/ int LP2LSPConversion(word16_t LPCoefficients[], word16_t LSPCoefficients[]) { uint8_t i; word32_t f1[6]; word32_t f2[6]; /* coefficients for polynomials F1 anf F2 in Q12 for computation, then converted in Q15 for the Chebyshev Polynomial function */ uint8_t numberOfRootFound = 0; /* used to check the final number of roots found and exit the loop on each polynomial computation when we have 10 roots */ word32_t *polynomialCoefficients; word32_t previousCx; word32_t Cx; /* value of Chebyshev Polynomial at current point in Q15 */ /*** Compute the polynomials coefficients according to spec 3.2.3 eq15 ***/ f1[0] = ONE_IN_Q12; /* values 0 are not part of the output, they are just used for computation purpose */ f2[0] = ONE_IN_Q12; /* for (i = 0; i< 5; i++) { */ /* f1[i+1] = a[i+1] + a[10-i] - f1[i]; */ /* f2[i+1] = a[i+1] - a[10-i] + f2[i]; */ /* } */ for (i=0; i<5; i++) { f1[i+1] = ADD32(LPCoefficients[i], SUB32(LPCoefficients[9-i], f1[i])); /* note: index on LPCoefficients are -1 respect to spec because the unused value 0 is not stored */ f2[i+1] = ADD32(f2[i], SUB32(LPCoefficients[i], LPCoefficients[9-i])); /* note: index on LPCoefficients are -1 respect to spec because the unused value 0 is not stored */ } /* convert the coefficients from Q12 to Q15 to be used by the Chebyshev Polynomial function (f1/2[0] aren't used so they are not converted) */ for (i=1; i<6; i++) { f1[i] = SHL(f1[i], 3); f2[i] = SHL(f2[i], 3); } /*** Compute at each step(50 steps for the AnnexA version) the Chebyshev polynomial to find the 10 roots ***/ /* start using f1 polynomials coefficients and altern with f2 after founding each root (spec 3.2.3 eq13 and eq14) */ polynomialCoefficients = f1; /* start with f1 coefficients */ previousCx = ChebyshevPolynomial(cosW0pi[0], polynomialCoefficients); /* compute the first point and store it as the previous value for polynomial */ for (i=1; i0; k--) { /* at the end of loop execution we have b1 in bk1 and b2 in bk2 */ bk = SUB32(ADD32(SHL(MULT16_32_Q15(x,bk1), 1), f[5-k]), bk2); /* bk = 2*x*bk1 − bk2 + f(5-k) all in Q15*/ bk2 = bk1; bk1 = bk; } return SUB32(ADD32(MULT16_32_Q15(x,bk1), SHR(f[5],1)), bk2); /* C(x) = x*b1 - b2 + f(5)/2 */ } /*****************************************************************************/ /* */ /* Codebook: */ /* */ /* x = cos(w) with w in [0,Pi] in 50 steps */ /* */ /*****************************************************************************/ static const word16_t cosW0pi[NB_COMPUTED_VALUES_CHEBYSHEV_POLYNOMIAL] = { /* in Q15 */ 32760, 32703, 32509, 32187, 31738, 31164, 30466, 29649, 28714, 27666, 26509, 25248, 23886, 22431, 20887, 19260, 17557, 15786, 13951, 12062, 10125, 8149, 6140, 4106, 2057, 0, -2057, -4106, -6140, -8149, -10125, -12062, -13951, -15786, -17557, -19260, -20887, -22431, -23886, -25248, -26509, -27666, -28714, -29649, -30466, -31164, -31738, -32187, -32509, -32703, -32760};