/** * Copyright 2007 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.sinusoidal.hntm.analysis; import java.io.DataInputStream; import java.io.DataOutput; import java.io.IOException; import java.nio.ByteBuffer; import marytts.signalproc.analysis.RegularizedCepstrumEstimator; import marytts.signalproc.analysis.RegularizedPostWarpedCepstrumEstimator; import marytts.signalproc.analysis.RegularizedPreWarpedCepstrumEstimator; import marytts.signalproc.window.GaussWindow; import marytts.util.math.ArrayUtils; import marytts.util.math.ComplexNumber; import marytts.util.math.MathUtils; /** * @author Oytun Türk * */ public class FrameHarmonicPart { public ComplexNumber[] complexAmps; // Keep complex amplitudes of harmonics public FrameHarmonicPart() { complexAmps = null; } public FrameHarmonicPart(FrameHarmonicPart existing) { this(); if (existing != null) { complexAmps = ArrayUtils.copy(existing.complexAmps); } } public FrameHarmonicPart(DataInputStream dis, int numHarmonics) { complexAmps = null; if (numHarmonics > 0) { complexAmps = new ComplexNumber[numHarmonics]; for (int i = 0; i < complexAmps.length; i++) { try { complexAmps[i] = new ComplexNumber(dis.readFloat(), dis.readFloat()); } catch (IOException e) { complexAmps[i] = null; } } } } public FrameHarmonicPart(ByteBuffer bb, int numHarmonics) { complexAmps = null; if (numHarmonics > 0) { complexAmps = new ComplexNumber[numHarmonics]; for (int i = 0; i < complexAmps.length; i++) { try { complexAmps[i] = new ComplexNumber(bb.getFloat(), bb.getFloat()); } catch (Exception e) { complexAmps[i] = null; } } } } public boolean equals(FrameHarmonicPart other) { if (complexAmps != null || other.complexAmps != null) { if (complexAmps != null && other.complexAmps == null) return false; if (complexAmps == null && other.complexAmps != null) return false; if (complexAmps.length != other.complexAmps.length) return false; for (int i = 0; i < complexAmps.length; i++) if (!complexAmps[i].equals(other.complexAmps[i])) return false; } return true; } public int getLength() { int len = 0; if (complexAmps != null && complexAmps.length > 0) len = complexAmps.length; return 4 * 2 * len; } public void write(DataOutput out) throws IOException { int numHarmonics = 0; if (complexAmps != null && complexAmps.length > 0) numHarmonics = complexAmps.length; if (numHarmonics > 0) { for (int i = 0; i < complexAmps.length; i++) { out.writeFloat(complexAmps[i].real); out.writeFloat(complexAmps[i].imag); } } } public float[] getCeps(double f0InHz, int samplingRateInHz, HntmAnalyzerParams params) { float[] ceps = null; if (complexAmps != null) { double[] linearAmps = new double[complexAmps.length]; double[] freqsInHz = new double[complexAmps.length]; int j; for (j = 0; j < complexAmps.length; j++) { freqsInHz[j] = (j + 1) * f0InHz; linearAmps[j] = MathUtils.magnitudeComplex(complexAmps[j]); } // double[] harmonicWeights = null; if (params.useWeightingInRegularizedCepstrumEstimationHarmonic) { GaussWindow g = new GaussWindow(2 * linearAmps.length); g.normalizeRange(0.1f, 1.0f); harmonicWeights = g.getCoeffsRightHalf(); } if (params.regularizedCepstrumWarpingMethod == RegularizedCepstrumEstimator.REGULARIZED_CEPSTRUM_WITH_PRE_BARK_WARPING) ceps = RegularizedPreWarpedCepstrumEstimator.freqsLinearAmps2cepstrum(linearAmps, freqsInHz, samplingRateInHz, params.harmonicPartCepstrumOrder, harmonicWeights, params.regularizedCepstrumLambdaHarmonic); else if (params.regularizedCepstrumWarpingMethod == RegularizedCepstrumEstimator.REGULARIZED_CEPSTRUM_WITH_POST_MEL_WARPING) ceps = RegularizedPostWarpedCepstrumEstimator.freqsLinearAmps2cepstrum(linearAmps, freqsInHz, samplingRateInHz, params.harmonicPartCepstrumOrderPreMel, params.harmonicPartCepstrumOrder, harmonicWeights, params.regularizedCepstrumLambdaHarmonic); } return ceps; } public double[] getLinearAmps() { if (complexAmps != null) return MathUtils.magnitudeComplex(complexAmps); else return null; } public double[] getDBAmps() { return MathUtils.amp2db(getLinearAmps()); } public double[] getPhasesInRadians() { double[] phasesInRadians = null; if (complexAmps != null) { phasesInRadians = new double[complexAmps.length]; for (int k = 0; k < complexAmps.length; k++) phasesInRadians[k] = MathUtils.phaseInRadians(complexAmps[k]); } return phasesInRadians; } }