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.util;
012
013import com.sun.speech.freetts.FeatureSet;
014import com.sun.speech.freetts.Item;
015import com.sun.speech.freetts.Relation;
016
017
018/**
019 * Provides a set of utilities for the SegmentRelation. A 
020 * SegmentRelation is a Relation, but has
021 * features specific to Segments.
022 */
023public class SegmentRelationUtils {
024
025    /**
026     * Returns the Item in the Segment Relation that corresponds to the given
027     * time.
028     *
029     * @param segmentRelation the segmentRelation of interest
030     * @param time the time
031     */
032    public static Item getItem(Relation segmentRelation, float time) {
033
034        Item lastSegment = segmentRelation.getTail();
035        
036        // if given time is closer to the front than the end, search from
037        // the front; otherwise, start search from end
038        // this might not be the best strategy though
039
040        float lastSegmentEndTime = SegmentRelationUtils.getSegmentEnd
041            (lastSegment);
042        
043        if (time < 0 || lastSegmentEndTime < time) {
044            return null;
045        } else if (lastSegmentEndTime - time > time) {
046            return SegmentRelationUtils.findFromFront(segmentRelation, time);
047        } else {
048            return SegmentRelationUtils.findFromEnd(segmentRelation, time);
049        }
050    }
051
052    /**
053     * Returns the value of the feature <code>end</code> of
054     * the given Segment Item.
055     *
056     * @param segment the Segment Item
057     *
058     * @return the <code>end</code> feature of the Segment
059     */
060    public static float getSegmentEnd(Item segment) {
061        FeatureSet segmentFeatureSet = segment.getFeatures();
062        return segmentFeatureSet.getFloat("end");
063    }
064    
065    /**
066     * Starting from the front of the given Segment Relation, finds the Item
067     * that corresponds to the given time.
068     *
069     * @param segmentRelation the Segment Relation to search
070     * @param time the time of the Segment Item
071     *
072     * @return the Segment Item
073     */
074    public static Item findFromFront(Relation segmentRelation, float time) {
075        Item item = segmentRelation.getHead();
076
077        while (item != null &&
078               time > SegmentRelationUtils.getSegmentEnd(item)) {
079            item = item.getNext();
080        }
081
082        return item;
083    }
084    
085    /**
086     * Starting from the end of the given Segment Relation, go backwards
087     * to find the Item that corresponds to the given time.
088     *
089     * @param segmentRelation the Segment Relation to search
090     * @param time the time of the Segment Item
091     *
092     * @return the Segment Item
093     */
094    public static Item findFromEnd(Relation segmentRelation, float time) {
095        Item item = segmentRelation.getTail();
096                
097        while (item != null &&
098               SegmentRelationUtils.getSegmentEnd(item) > time) {
099            item = item.getPrevious();
100        }
101
102        if (item != segmentRelation.getTail()) {
103            item = item.getNext();
104        }
105
106        return item;
107    }
108}