001/** 002 * Portions Copyright 2001 Sun Microsystems, Inc. 003 * Portions Copyright 1999-2001 Language Technologies Institute, 004 * Carnegie Mellon University. 005 * All Rights Reserved. Use is subject to license terms. 006 * 007 * See the file "license.terms" for information on usage and 008 * redistribution of this file, and for a DISCLAIMER OF ALL 009 * WARRANTIES. 010 */ 011package com.sun.speech.freetts.cart; 012 013import com.sun.speech.freetts.Item; 014import com.sun.speech.freetts.PathExtractor; 015import com.sun.speech.freetts.PathExtractorImpl; 016import com.sun.speech.freetts.PhoneDuration; 017import com.sun.speech.freetts.PhoneDurations; 018import com.sun.speech.freetts.ProcessException; 019import com.sun.speech.freetts.Relation; 020import com.sun.speech.freetts.Utterance; 021import com.sun.speech.freetts.UtteranceProcessor; 022 023/** 024 * Determines duration timing for <code>Relation.SEGMENT</code> relations in an 025 * utterance. Annotates the <code>Relation.SEGMENT</code> relation with an "end" 026 * time feature. 027 * 028 * <p> 029 * [[[TODO: The mean words-per-minute rate should become part of the CART data. 030 * For now, it is passed into the constructor.]]] 031 * 032 * @see Relation#SEGMENT 033 */ 034public class Durator implements UtteranceProcessor { 035 /** 036 * The CART used for this duration UtteranceProcessor. It is passed into the 037 * constructor. 038 */ 039 protected final CART cart; 040 041 /** 042 * The PhoneDurations used for this duration UtteranceProcessor. It is 043 * passed into the constructor. 044 */ 045 protected final PhoneDurations durations; 046 047 private static final PathExtractor DURATION_STRETCH_PATH = new PathExtractorImpl( 048 "R:SylStructure.parent.parent.R:Token.parent.local_duration_stretch", 049 true); 050 051 /** 052 * Creates a new duration UtteranceProcessor with the given CART and phone 053 * durations. 054 * 055 * @param cart 056 * contains zscore duration data 057 * @param durations 058 * contains mean and standard deviation phone durations 059 */ 060 public Durator(CART cart, PhoneDurations durations) { 061 this.cart = cart; 062 this.durations = durations; 063 } 064 065 /** 066 * Annotates the <code>Relation.SEGMENT</code> relations with cumulative 067 * "end" time features based on phone durations. Expects the CART to return 068 * a zscore for each phone, which specifies the number of standard 069 * deviations from the mean. This is coupled with a phone durations table 070 * that returns the mean and standard deviation for phones. 071 * 072 * @param utterance 073 * the utterance to process 074 * 075 * @throws ProcessException 076 * if a problem is encountered during the processing of the 077 * utterance 078 */ 079 public void processUtterance(Utterance utterance) throws ProcessException { 080 PhoneDuration durStat; 081 float durationStretch = utterance.getVoice().getDurationStretch(); 082 float zdur; 083 float dur; 084 float end = 0.0f; 085 float localDurationStretch; 086 087 // Go through each of the segments and calculate a duration 088 // for it. Store the cumulative end time for the duration in 089 // the "end" feature of the segment. 090 // 091 for (Item segment = utterance.getRelation(Relation.SEGMENT).getHead(); segment != null; segment = segment 092 .getNext()) { 093 zdur = ((Float) cart.interpret(segment)).floatValue(); 094 durStat = durations.getPhoneDuration(segment.getFeatures() 095 .getString("name")); 096 097 Object tval = DURATION_STRETCH_PATH.findFeature(segment); 098 localDurationStretch = Float.parseFloat(tval.toString()); 099 100 if (localDurationStretch == 0.0) { 101 localDurationStretch = durationStretch; 102 } else { 103 localDurationStretch *= durationStretch; 104 } 105 106 dur = localDurationStretch 107 * ((zdur * durStat.getStandardDeviation()) + durStat 108 .getMean()); 109 end += dur; 110 segment.getFeatures().setFloat("end", end); 111 } 112 } 113 114 // inherited from Object 115 public String toString() { 116 return "CARTDurator"; 117 } 118}