/**
* 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.adaptation;
import java.io.IOException;
import javax.sound.sampled.UnsupportedAudioFileException;
import marytts.signalproc.adaptation.codebook.WeightedCodebookTrainerParams;
import marytts.signalproc.adaptation.codebook.WeightedCodebookTransformerParams;
import marytts.signalproc.adaptation.gmm.jointgmm.JointGMMTransformerParams;
import marytts.signalproc.analysis.EnergyContourRms;
import marytts.signalproc.analysis.EnergyFileHeader;
import marytts.signalproc.analysis.F0TrackerAutocorrelationHeuristic;
import marytts.signalproc.analysis.LsfAnalyser;
import marytts.signalproc.analysis.LsfFileHeader;
import marytts.signalproc.analysis.MfccFileHeader;
import marytts.signalproc.analysis.PitchFileHeader;
import marytts.util.io.FileUtils;
import marytts.util.string.StringUtils;
/**
*
* Baseline class for acoustic feature analysis for voice conversion
*
* @author Oytun Türk
*/
public class BaselineFeatureExtractor {
// Add more as necessary & make sure you can discriminate each using AND(&) operator
// from a single integer that represents desired analyses (See the function run())
public static final int NOT_DEFINED = Integer.parseInt("00000000", 2);
public static final int LSF_FEATURES = Integer.parseInt("00000001", 2);
public static final int F0_FEATURES = Integer.parseInt("00000010", 2);
public static final int ENERGY_FEATURES = Integer.parseInt("00000100", 2);
public static final int DURATION_FEATURES = Integer.parseInt("00001000", 2);
public static final int MFCC_FEATURES_FROM_FILES = Integer.parseInt("00010000", 2);
public BaselineFeatureExtractor() {
this(null);
}
public BaselineFeatureExtractor(BaselineFeatureExtractor existing) {
if (existing != null) {
// Copy class members if you add any
} else {
// Set default class member values
}
}
public void run(BaselineAdaptationSet fileSet, BaselineParams params, int desiredFeatures) throws IOException,
UnsupportedAudioFileException {
LsfFileHeader lsfParams = null;
if (params instanceof WeightedCodebookTrainerParams)
lsfParams = new LsfFileHeader(((WeightedCodebookTrainerParams) params).codebookHeader.lsfParams);
else if (params instanceof WeightedCodebookTransformerParams)
lsfParams = new LsfFileHeader(((WeightedCodebookTransformerParams) params).lsfParams);
else if (params instanceof JointGMMTransformerParams)
lsfParams = new LsfFileHeader(((JointGMMTransformerParams) params).lsfParams);
PitchFileHeader ptcParams = null;
if (params instanceof WeightedCodebookTrainerParams)
ptcParams = new PitchFileHeader(((WeightedCodebookTrainerParams) params).codebookHeader.ptcParams);
else if (params instanceof WeightedCodebookTransformerParams)
ptcParams = new PitchFileHeader(((WeightedCodebookTransformerParams) params).ptcParams);
else if (params instanceof JointGMMTransformerParams)
ptcParams = new PitchFileHeader(((JointGMMTransformerParams) params).ptcParams);
EnergyFileHeader energyParams = null;
if (params instanceof WeightedCodebookTrainerParams)
energyParams = new EnergyFileHeader(((WeightedCodebookTrainerParams) params).codebookHeader.energyParams);
else if (params instanceof WeightedCodebookTransformerParams)
energyParams = new EnergyFileHeader(((WeightedCodebookTransformerParams) params).energyParams);
else if (params instanceof JointGMMTransformerParams)
energyParams = new EnergyFileHeader(((JointGMMTransformerParams) params).energyParams);
MfccFileHeader mfccParams = null;
if (params instanceof WeightedCodebookTrainerParams)
mfccParams = new MfccFileHeader(((WeightedCodebookTrainerParams) params).codebookHeader.mfccParams);
else if (params instanceof WeightedCodebookTransformerParams)
mfccParams = new MfccFileHeader(((WeightedCodebookTransformerParams) params).mfccParams);
else if (params instanceof JointGMMTransformerParams)
mfccParams = new MfccFileHeader(((JointGMMTransformerParams) params).mfccParams);
boolean isForcedAnalysis = false;
if (params instanceof WeightedCodebookTrainerParams)
isForcedAnalysis = ((WeightedCodebookTrainerParams) params).isForcedAnalysis;
else if (params instanceof WeightedCodebookTransformerParams)
isForcedAnalysis = ((WeightedCodebookTransformerParams) params).isForcedAnalysis;
else if (params instanceof JointGMMTransformerParams)
isForcedAnalysis = ((JointGMMTransformerParams) params).isForcedAnalysis;
// ADD more analyses as necessary
if (StringUtils.isDesired(LSF_FEATURES, desiredFeatures))
lsfAnalysis(fileSet, lsfParams, isForcedAnalysis);
if (StringUtils.isDesired(F0_FEATURES, desiredFeatures))
f0Analysis(fileSet, ptcParams, isForcedAnalysis);
if (StringUtils.isDesired(ENERGY_FEATURES, desiredFeatures))
energyAnalysis(fileSet, energyParams, isForcedAnalysis);
if (StringUtils.isDesired(MFCC_FEATURES_FROM_FILES, desiredFeatures))
checkMfccFiles(fileSet, mfccParams, isForcedAnalysis);
//
}
public static void lsfAnalysis(BaselineAdaptationItem item, LsfFileHeader lsfParams, boolean isForcedAnalysis)
throws IOException {
BaselineAdaptationSet fileSet = new BaselineAdaptationSet(1);
fileSet.items[0] = new BaselineAdaptationItem(item);
lsfAnalysis(fileSet, lsfParams, isForcedAnalysis);
}
public static void lsfAnalysis(BaselineAdaptationSet fileSet, LsfFileHeader lsfParams, boolean isForcedAnalysis)
throws IOException {
System.err.println("Starting LSF analysis...");
boolean bAnalyze;
for (int i = 0; i < fileSet.items.length; i++) {
bAnalyze = true;
if (!isForcedAnalysis && FileUtils.exists(fileSet.items[i].lsfFile)) {
LsfFileHeader tmpParams = new LsfFileHeader(fileSet.items[i].lsfFile);
if (tmpParams.isIdenticalAnalysisParams(lsfParams))
bAnalyze = false;
}
if (bAnalyze) {
LsfAnalyser.lsfAnalyzeWavFile(fileSet.items[i].audioFile, fileSet.items[i].lsfFile, lsfParams);
System.err.println("Extracted LSFs: " + fileSet.items[i].lsfFile);
} else
System.err.println("LSF file found with identical analysis parameters: " + fileSet.items[i].lsfFile);
}
System.err.println("LSF analysis completed...");
}
public static void f0Analysis(BaselineAdaptationSet fileSet, PitchFileHeader ptcParams, boolean isForcedAnalysis)
throws UnsupportedAudioFileException, IOException {
System.err.println("Starting f0 analysis...");
boolean bAnalyze;
F0TrackerAutocorrelationHeuristic p = new F0TrackerAutocorrelationHeuristic(ptcParams);
for (int i = 0; i < fileSet.items.length; i++) {
bAnalyze = true;
if (!isForcedAnalysis && FileUtils.exists(fileSet.items[i].pitchFile)) // No f0 detection if ptc file already exists
bAnalyze = false;
if (bAnalyze) {
p.pitchAnalyzeWavFile(fileSet.items[i].audioFile, fileSet.items[i].pitchFile);
System.err.println("Extracted f0 contour: " + fileSet.items[i].pitchFile);
} else
System.err.println("F0 file found with identical analysis parameters: " + fileSet.items[i].pitchFile);
}
System.err.println("f0 analysis completed...");
}
public static void energyAnalysis(BaselineAdaptationSet fileSet, EnergyFileHeader energyParams, boolean isForcedAnalysis)
throws UnsupportedAudioFileException, IOException {
System.err.println("Starting energy analysis...");
boolean bAnalyze;
EnergyContourRms e = null;
for (int i = 0; i < fileSet.items.length; i++) {
bAnalyze = true;
if (!isForcedAnalysis && FileUtils.exists(fileSet.items[i].energyFile)) // No f0 detection if ptc file already exists
bAnalyze = false;
if (bAnalyze) {
e = new EnergyContourRms(fileSet.items[i].audioFile, fileSet.items[i].energyFile,
energyParams.windowSizeInSeconds, energyParams.skipSizeInSeconds);
System.err.println("Extracted energy contour: " + fileSet.items[i].energyFile);
} else
System.err.println("Energy file found with identical analysis parameters: " + fileSet.items[i].energyFile);
}
System.err.println("Energy analysis completed...");
}
public static void checkMfccFiles(BaselineAdaptationSet fileSet, MfccFileHeader mfccParams, boolean isForcedAnalysis)
throws IOException {
System.err.println("Attempting to read MFCC parameters from files...");
for (int i = 0; i < fileSet.items.length; i++) {
if (!FileUtils.exists(fileSet.items[i].mfccFile))
System.err.println("MFCC files not found!Please use SPTK generated raw MFCC file named as "
+ fileSet.items[i].mfccFile);
}
System.err.println("MFCC files verified...");
}
}