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

marytts.unitselection.data.UnitDatabase 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.unitselection.data;

import java.util.ArrayList;
import java.util.List;

import marytts.cart.CART;
import marytts.unitselection.select.JoinCostFunction;
import marytts.unitselection.select.StatisticalCostFunction;
import marytts.unitselection.select.Target;
import marytts.unitselection.select.TargetCostFunction;
import marytts.unitselection.select.viterbi.ViterbiCandidate;
import marytts.util.MaryUtils;
import marytts.util.data.Datagram;
import marytts.util.dom.DomUtils;

import org.apache.log4j.Logger;
import org.w3c.dom.Element;

/**
 * The unit database of a voice
 * 
 * @author Marc Schröder
 *
 */
public class UnitDatabase {
	protected TargetCostFunction targetCostFunction;
	protected JoinCostFunction joinCostFunction;
	protected StatisticalCostFunction sCostFunction = null;
	protected UnitFileReader unitReader;
	protected int numUnits;
	protected CART preselectionCART;
	protected TimelineReader audioTimeline;
	protected TimelineReader basenameTimeline;
	protected int backtrace;
	protected Logger logger = MaryUtils.getLogger("UnitDatabase");

	public UnitDatabase() {
	}

	public void load(TargetCostFunction aTargetCostFunction, JoinCostFunction aJoinCostFunction, UnitFileReader aUnitReader,
			CART aPreselectionCART, TimelineReader anAudioTimeline, TimelineReader aBasenameTimeline, int backtraceLeafSize) {
		this.targetCostFunction = aTargetCostFunction;
		this.joinCostFunction = aJoinCostFunction;
		this.unitReader = aUnitReader;
		this.numUnits = (unitReader != null ? unitReader.getNumberOfUnits() : 0);
		this.preselectionCART = aPreselectionCART;
		this.audioTimeline = anAudioTimeline;
		this.basenameTimeline = aBasenameTimeline;
		this.backtrace = backtraceLeafSize;
	}

	public void load(TargetCostFunction aTargetCostFunction, JoinCostFunction aJoinCostFunction,
			StatisticalCostFunction asCostFunction, UnitFileReader aUnitReader, CART aPreselectionCART,
			TimelineReader anAudioTimeline, TimelineReader aBasenameTimeline, int backtraceLeafSize) {
		this.targetCostFunction = aTargetCostFunction;
		this.joinCostFunction = aJoinCostFunction;
		this.sCostFunction = asCostFunction;
		this.unitReader = aUnitReader;
		this.numUnits = (unitReader != null ? unitReader.getNumberOfUnits() : 0);
		this.preselectionCART = aPreselectionCART;
		this.audioTimeline = anAudioTimeline;
		this.basenameTimeline = aBasenameTimeline;
		this.backtrace = backtraceLeafSize;
	}

	public TargetCostFunction getTargetCostFunction() {
		return targetCostFunction;
	}

	public JoinCostFunction getJoinCostFunction() {
		return joinCostFunction;
	}

	public UnitFileReader getUnitFileReader() {
		return unitReader;
	}

	public TimelineReader getAudioTimeline() {
		return audioTimeline;
	}

	public StatisticalCostFunction getSCostFunction() {
		return sCostFunction;
	}

	/**
	 * Preselect a set of candidates that could be used to realise the given target.
	 * 
	 * @param target
	 *            a Target object representing an optimal unit
	 * @return an unsorted ArrayList of ViterbiCandidates, each containing the (same) target and a
	 *         (different) Unit object
	 */
	public List getCandidates(Target target) {
		// BEGIN blacklisting
		// The point of this is to get the value of the "blacklist" attribute in the first child element of the MaryXML
		// and store it in the blacklist String variable.
		// This code seems rather inelegant; perhaps there is a better way to access the MaryXML from this method?
		String blacklist = "";
		String unitBasename = "This must never be null or the empty string!"; // otherwise candidate selection fails!
		Element targetElement = target.getMaryxmlElement();
		blacklist = DomUtils.getAttributeFromClosestAncestorOfAnyKind(targetElement, "blacklist");
		// END blacklisting

		// logger.debug("Looking for candidates in cart "+target.getName());
		// get the cart tree and extract the candidates
		int[] clist = (int[]) preselectionCART.interpret(target, backtrace);
		logger.debug("For target " + target + ", selected " + clist.length + " units");

		// Now, clist is an array of unit indexes.
		List candidates = new ArrayList();
		for (int i = 0; i < clist.length; i++) {
			// The target is the same for all these candidates in the queue
			// remember the actual unit:
			Unit unit = unitReader.getUnit(clist[i]);
			candidates.add(new ViterbiCandidate(target, unit, targetCostFunction));
		}

		// Blacklisting without crazy performance drop:
		// just remove candidates again if their basenames are blacklisted
		java.util.Iterator candIt = candidates.iterator();
		while (candIt.hasNext()) {
			ViterbiCandidate candidate = candIt.next();
			unitBasename = getFilename(candidate.getUnit());
			if (blacklist.contains(unitBasename)) {
				candIt.remove();
			}
		}

		return candidates;
	}

	/**
	 * For debugging, return the basename of the original audio file from which the unit is coming, as well as the start time in
	 * that file.
	 * 
	 * @param unit
	 *            unit
	 * @return a String containing basename followed by a space and the unit's start time, in seconds, from the beginning of the
	 *         file. If no basenameTimeline was specified for this voice, returns the string "unknown origin".
	 */
	public String getFilenameAndTime(Unit unit) {
		if (basenameTimeline == null)
			return "unknown origin";
		long[] offset = new long[1];
		try {
			Datagram[] datagrams = basenameTimeline.getDatagrams(unit.startTime, 1, unitReader.getSampleRate(), offset);
			Datagram filenameData = datagrams[0];
			float time = (float) offset[0] / basenameTimeline.getSampleRate();
			String filename = new String(filenameData.getData(), "UTF-8");
			return filename + " " + time;
		} catch (Exception e) {
			logger.warn("Problem getting filename and time for unit " + unit.index + " at time " + unit.startTime, e);
			return "unknown origin";
		}
	}

	/**
	 * For debugging, return the basename of the original audio file from which the unit is coming.
	 * 
	 * @param unit
	 *            unit
	 * @return a String containing basename. If no basenameTimeline was specified for this voice, returns the string
	 *         "unknown origin".
	 */
	public String getFilename(Unit unit) {
		// if (basenameTimeline == null) return "unknown origin";
		try {
			Datagram filenameData = basenameTimeline.getDatagram(unit.startTime);
			String filename = new String(filenameData.getData(), "UTF-8");
			return filename;
		} catch (Exception e) {
			logger.warn("Problem getting filename for unit " + unit.index, e);
			return "unknown origin";
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy