/**
* Copyright 2004-2006 DFKI GmbH.
* All Rights Reserved. Use is subject to license terms.
*
* This file is part of MARY TTS.
*
* MARY TTS 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, version 3 of the License.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package marytts.signalproc.analysis;
/**
*
* @author sacha
*
* Implements the conversion between the Linear Prediction Coefficients (LPC) and the corresponding Linear Prediction
* Cepstrum Coefficients.
*
*/
public class CepstrumLPCAnalyser {
/**
* Converts from LPC coefficients to LPCC coefficients.
*
* @param oneMinusA
* A(z) = a0 - sum { ai * z^-i } . a0 = 1.
* @param gain
* The LPC gain factor.
* @param cepstrumOrder
* Cepstrum order (equal to the index of the last cepstrum coefficient).
*
* @return The LPCC coefficents. c[0] is set to log(gain).
*
*/
public static double[] lpc2lpcc(double[] oneMinusA, double gain, int cepstrumOrder) {
// Check the cepstrum order
if (cepstrumOrder <= 0) {
throw new RuntimeException("The cepstrum order [" + cepstrumOrder + "] must be a positive integer.");
}
// Declare misc. useful variables
int k, m;
double acc;
double[] c = new double[cepstrumOrder + 1];
int lpcOrder = oneMinusA.length - 1;
/* First cepstral coeff */
c[0] = Math.log(gain);
/* Other coeffs: */
for (m = 1; m <= cepstrumOrder; m++) {
/* Coeffs within the LPC order: */
if (m <= lpcOrder) {
acc = 0.0;
for (k = 1; k < m; k++)
acc += ((double) (m - k) * oneMinusA[k] * c[m - k]);
c[m] = acc / (double) (m) + oneMinusA[m];
}
/* Coeffs above the LPC order: */
else {
acc = 0.0;
for (k = 1; k <= lpcOrder; k++)
acc += ((double) (m - k) * oneMinusA[k] * c[m - k]);
c[m] = acc / (double) (m);
}
}
return (c);
}
/**
* Converts from LPCC coefficients to LPC coefficients.
*
* @param c
* the vector of cepstral coefficients. Note: c[0] = log(gain).
* @param lpcOrder
* The original LPC order (equal to the index of the last LPC coefficient).
*
* @return The LPC coefficents [1 -a_1 -a_2 ... -a_p].
*
* The gain is not returned, but it can be recovered as exp(c[0]).
*
*/
public static double[] lpcc2lpc(double[] c, int lpcOrder) {
// Check the LPC order
if (lpcOrder <= 0) {
throw new RuntimeException("The LPC order [" + lpcOrder + "] must be a positive integer.");
}
// Declare misc. useful variables
int k, m;
double acc;
double[] a = new double[lpcOrder + 1];
int cepstrumOrder = c.length - 1;
/* First lpc coeff */
a[0] = 1.0;
/* Other coeffs: */
for (m = 1; m <= lpcOrder; m++) {
/* Coeffs within the Cepstrum order: */
if (m <= cepstrumOrder) {
acc = 0.0;
for (k = 1; k < m; k++)
acc += ((double) (k) * a[m - k] * c[k]);
a[m] = c[m] - acc / (double) (m);
}
/* Coeffs above the Cepstrum order: */
else {
acc = 0.0;
for (k = 1; k <= cepstrumOrder; k++)
acc += ((double) (k) * a[m - k] * c[k]);
a[m] = -acc / (double) (m);
}
}
return (a);
}
}