/**
* Portions Copyright 2001 Sun Microsystems, Inc.
* Portions Copyright 1999-2001 Language Technologies Institute,
* Carnegie Mellon University.
* All Rights Reserved. Use is subject to license terms.
*
* See the file "license.terms" for information on usage and
* redistribution of this file, and for a DISCLAIMER OF ALL
* WARRANTIES.
*/
package com.sun.speech.freetts.cart;
import com.sun.speech.freetts.Item;
import com.sun.speech.freetts.PathExtractor;
import com.sun.speech.freetts.PathExtractorImpl;
import com.sun.speech.freetts.PhoneDuration;
import com.sun.speech.freetts.PhoneDurations;
import com.sun.speech.freetts.ProcessException;
import com.sun.speech.freetts.Relation;
import com.sun.speech.freetts.Utterance;
import com.sun.speech.freetts.UtteranceProcessor;
/**
* Determines duration timing for
* <code>Relation.SEGMENT</code> relations in an utterance.
* Annotates the <code>Relation.SEGMENT</code> relation with an
* "end" time feature.
*
* <p>[[[TODO: The mean words-per-minute rate should become part
* of the CART data. For now, it is passed into the constructor.]]]
*
* @see Relation#SEGMENT
*/
public class Durator implements UtteranceProcessor {
/**
* The nominal speaking rate in words per minute. Set in the
* constructor.
*/
private final float meanRate;
/**
* The CART used for this duration UtteranceProcessor. It is
* passed into the constructor.
*/
protected final CART cart;
/**
* The PhoneDurations used for this duration UtteranceProcessor.
* It is passed into the constructor.
*/
protected final PhoneDurations durations;
private static final PathExtractor DURATION_STRETCH_PATH =
new PathExtractorImpl(
"R:SylStructure.parent.parent.R:Token.parent.local_duration_stretch",
true);
/**
* Creates a new duration UtteranceProcessor with the given
* CART and phone durations.
*
* @param cart contains zscore duration data
* @param meanRate the mean words per minute rate of the CART data
* @param durations contains mean and standard deviation phone durations
*/
public Durator(CART cart, float meanRate, PhoneDurations durations) {
this.cart = cart;
this.meanRate = meanRate;
this.durations = durations;
}
/**
* Annotates the <code>Relation.SEGMENT</code> relations with
* cumulative "end" time
* features based on phone durations. Expects the CART to return
* a zscore for each phone, which specifies the number of standard
* deviations from the mean. This is coupled with a phone
* durations table that returns the mean and standard deviation
* for phones.
*
* @param utterance the utterance to process
*
* @throws ProcessException if a problem is encountered during the
* processing of the utterance
*/
public void processUtterance(Utterance utterance) throws ProcessException {
float durStretch;
PhoneDuration durStat;
float durationStretch = utterance.getVoice().getDurationStretch();
float zdur;
float dur;
float end = 0.0f;
float localDurationStretch;
// Figure out how far to stretch the durations (speed things
// up or slow them down.
//
durStretch = meanRate / utterance.getVoice().getRate();
// Go through each of the segments and calculate a duration
// for it. Store the cumulative end time for the duration in
// the "end" feature of the segment.
//
for (Item segment =
utterance.getRelation(Relation.SEGMENT).getHead();
segment != null; segment = segment.getNext()) {
zdur = ((Float) cart.interpret(segment)).floatValue();
durStat = durations.getPhoneDuration(
segment.getFeatures().getString("name"));
Object tval = DURATION_STRETCH_PATH.findFeature(segment);
localDurationStretch = Float.parseFloat(tval.toString());
if (localDurationStretch == 0.0) {
localDurationStretch = durationStretch;
} else {
localDurationStretch *= durationStretch;
}
dur = localDurationStretch * ((zdur*durStat.getStandardDeviation())
+ durStat.getMean());
end += dur;
segment.getFeatures().setFloat("end", end);
}
}
// inherited from Object
public String toString() {
return "CARTDurator";
}
}