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