All Downloads are FREE. Search and download functionalities are using the official Maven repository.

marytts.tools.voiceimport.F0PolynomialTreeTrainer Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 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 .
 *
 */
package marytts.tools.voiceimport;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

import marytts.cart.CART;
import marytts.cart.DirectedGraph;
import marytts.cart.io.DirectedGraphWriter;
import marytts.exceptions.MaryConfigurationException;
import marytts.features.FeatureDefinition;
import marytts.features.FeatureVector;
import marytts.tools.voiceimport.traintrees.AgglomerativeClusterer;
import marytts.tools.voiceimport.traintrees.F0ContourPolynomialDistanceMeasure;
import marytts.tools.voiceimport.traintrees.Wagon;
import marytts.unitselection.data.FeatureFileReader;
import marytts.util.math.ArrayUtils;

public class F0PolynomialTreeTrainer extends VoiceImportComponent {
	protected File maryDir;
	protected FeatureFileReader features;
	protected FeatureDefinition featureDefinition;
	protected FeatureFileReader contours;
	protected DatabaseLayout db = null;

	public final String FEATUREFILE = "F0PolynomialTreeTrainer.featureFile";
	public final String F0FEATUREFILE = "F0PolynomialTreeTrainer.f0FeatureFile";
	public final String F0TREE = "F0PolynomialTreeTrainer.treeFile";
	public final String MAXDATA = "F0PolynomialTreeTrainer.maxData";
	public final String PROPORTIONTESTDATA = "F0PolynomialTreeTrainer.propTestData";

	public final String WAGONDIR = "F0PolynomialTreeTrainer.wagonDir";
	public final String WAGONEXECUTABLE = "F0PolynomialTreeTrainer.wagonExecutable";
	public final String BALANCE = "F0PolynomialTreeTrainer.wagonBalance";
	public final String STOP = "F0PolynomialTreeTrainer.wagonStop";

	public String getName() {
		return "F0PolynomialTreeTrainer";
	}

	public SortedMap getDefaultProps(DatabaseLayout theDb) {
		this.db = theDb;
		if (props == null) {
			props = new TreeMap();
			String fileDir = db.getProp(db.FILEDIR);
			String maryExt = db.getProp(db.MARYEXT);
			props.put(FEATUREFILE, fileDir + "halfphoneFeatures" + maryExt);
			props.put(F0FEATUREFILE, fileDir + "syllableF0Polynomials" + maryExt);
			props.put(F0TREE, fileDir + "f0contourtree.mry");
			props.put(MAXDATA, "0");
			props.put(PROPORTIONTESTDATA, "0.1");

			props.put(WAGONDIR, "f0contours");
			props.put(WAGONEXECUTABLE, System.getenv("ESTDIR") + "/bin/wagon");
			props.put(BALANCE, "0");
			props.put(STOP, "50");
		}
		return props;
	}

	protected void setupHelp() {
		if (props2Help == null) {
			props2Help = new TreeMap();
			props2Help.put(FEATUREFILE, "file containing all halfphone units and their target cost features");
			props2Help.put(F0FEATUREFILE, "file containing syllable-based polynom coefficients on vowels");
			props2Help.put(F0TREE, "the path for saving the resulting f0 contour tree");
			props2Help.put(MAXDATA, "if >0, gives the maximum number of syllables to use for training the tree");
			props2Help.put(PROPORTIONTESTDATA,
					"the proportion of the data to use as test data (choose so that 1/value is an integer)");

			props2Help.put(WAGONDIR, "directory in which to store the wagon files");
			props2Help.put(WAGONEXECUTABLE, "full path of the wagon executable from the Edinburgh speech tools");
			props2Help.put(BALANCE, "the wagon balance value");
			props2Help.put(STOP, "the wagon stop criterion (min number of items in leaf)");
		}
	}

	@Override
	public boolean compute() throws IOException, MaryConfigurationException {
		logger.info("F0 polynomial tree trainer started.");

		features = new FeatureFileReader(getProp(FEATUREFILE));
		featureDefinition = features.getFeatureDefinition();
		contours = new FeatureFileReader(getProp(F0FEATUREFILE));
		if (features.getNumberOfUnits() != contours.getNumberOfUnits()) {
			throw new IllegalArgumentException(
					"Number of units differs between feature file and contour file -- they are out of sync");
		}

		int maxData = Integer.parseInt(getProp(MAXDATA));

		// 1. Extract the feature vectors for which there are contours
		List relevantFVList = new ArrayList();
		for (int i = 0, numUnits = contours.getNumberOfUnits(); i < numUnits; i++) {
			FeatureVector fv = contours.getFeatureVector(i);
			float[] floats = fv.getContinuousFeatures();
			boolean isZero = ArrayUtils.isZero(floats);
			if (!isZero) {
				relevantFVList.add(features.getFeatureVector(i));
				if (maxData > 0 && relevantFVList.size() >= maxData)
					break;
			}
		}
		FeatureVector[] relevantFV = relevantFVList.toArray(new FeatureVector[0]);
		logger.debug("Read " + relevantFV.length + " f0 contours and corresponding feature vectors");

		// 2. Grow a tree
		// CART cart = trainWagon(relevantFV);
		DirectedGraph graph = trainAgglomerativeCluster(relevantFV);

		// 3. Save resulting tree in MARY format.
		if (graph != null) {
			DirectedGraphWriter writer = new DirectedGraphWriter();
			writer.saveGraph(graph, getProp(F0TREE));
			return true;
		}
		return false;
	}

	private CART trainWagon(FeatureVector[] relevantFV) throws IOException {
		// 2. Call wagon with these feature vectors
		// and a distance measure based on contour distances
		Wagon.setWagonExecutable(new File(getProp(WAGONEXECUTABLE)));
		File wagonDir = new File(getProp(WAGONDIR));
		if (!wagonDir.exists()) {
			wagonDir.mkdirs();
		}
		Wagon w = new Wagon("f0contours", featureDefinition, relevantFV, new F0ContourPolynomialDistanceMeasure(contours),
				wagonDir, Integer.parseInt(getProp(BALANCE)), Integer.parseInt(getProp(STOP)));
		w.run();
		if (w.success())
			return w.getCART();
		return null;
	}

	private DirectedGraph trainAgglomerativeCluster(FeatureVector[] relevantFV) throws IOException {
		List featuresToUse = new ArrayList();
		for (int i = 0, numByteFeatures = featureDefinition.getNumberOfByteFeatures(); i < numByteFeatures; i++) {
			String f = featureDefinition.getFeatureName(i);
			if (!f.contains("phone") && !f.contains("halfphone") && !f.contains("vc") && !f.contains("ctype")
					&& !f.contains("cvox") && !f.contains("edge") && !f.contains("vfront") && !f.contains("vlng")
					&& !f.contains("vheight") && !f.contains("cplace") && !f.contains("vrnd")
					&& !f.contains("selection_next_phone_class")) {
				featuresToUse.add(f);
				// System.out.println("adding feature "+f);
			} else {
				// System.err.println("ignoring feature "+f);
			}
		}

		AgglomerativeClusterer clusterer = new AgglomerativeClusterer(relevantFV, featureDefinition, featuresToUse,
				new F0ContourPolynomialDistanceMeasure(contours));
		DirectedGraphWriter writer = new DirectedGraphWriter();
		DirectedGraph graph;
		int iteration = 0;
		do {
			graph = clusterer.cluster();
			iteration++;
			if (graph != null) {
				writer.saveGraph(graph, getProp(F0TREE) + ".level" + iteration);
			}
		} while (clusterer.canClusterMore());
		return graph;
	}

	/**
	 * Provide the progress of computation, in percent, or -1 if that feature is not implemented.
	 * 
	 * @return -1 if not implemented, or an integer between 0 and 100.
	 */
	public int getProgress() {
		return -1;
	}

	/**
	 * @param args
	 *            args
	 * @throws Exception
	 *             Exception
	 */
	public static void main(String[] args) throws Exception {
		F0PolynomialTreeTrainer acfeatsWriter = new F0PolynomialTreeTrainer();
		DatabaseLayout db = new DatabaseLayout(acfeatsWriter);
		acfeatsWriter.compute();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy