001package com.sun.speech.freetts.en.us;
002
003import java.io.IOException;
004import java.net.URL;
005import java.util.Locale;
006
007import com.sun.speech.freetts.Age;
008import com.sun.speech.freetts.Gender;
009import com.sun.speech.freetts.Item;
010import com.sun.speech.freetts.UtteranceProcessor;
011import com.sun.speech.freetts.clunits.ClusterUnitSelector;
012
013import de.dfki.lt.freetts.ClusterUnitNamer;
014
015/**
016 * Experimental class that selects units for the
017 * <a href="http://festvox.org/cmu_arctic/">CMU ARCTIC voices</a>.
018 */
019public class CMUArcticVoice extends CMUClusterUnitVoice {
020    
021    /**
022     * Creates a simple cluster unit voice for the ARCTIC voices
023     *
024     * @param name the name of the voice
025     * @param gender the gender of the voice
026     * @param age the age of the voice
027     * @param description a human-readable string providing a
028     * description that can be displayed for the users.
029     * @param locale the locale of the voice
030     * @param domain the domain of this voice.  For example,
031     * @param organization the organization which created the voice
032     * &quot;general&quot;, &quot;time&quot;, or
033     * &quot;weather&quot;.
034     * @param lexicon the lexicon to load
035     * @param database the url to the database containing unit data
036     * for this voice.
037     */
038    public CMUArcticVoice(String name, Gender gender, Age age,
039            String description, Locale locale, String domain,
040            String organization, CMULexicon lexicon, URL database) {
041        super(name, gender, age, description, locale,
042                domain, organization, lexicon, database);
043    }
044
045    /**
046     * Returns the unit selector to be used by this voice.
047     * Derived voices typically override this to customize behaviors.
048     * This voice uses  a cluster unit selector as the unit selector.
049     * 
050     * @return the post lexical processor
051     * 
052     * @throws IOException if an IO error occurs while getting
053     *     processor
054     */
055    public UtteranceProcessor getUnitSelector() throws IOException {
056        ClusterUnitNamer unitNamer = new ClusterUnitNamer() {
057            public void setUnitName(Item seg) {
058                String VOWELS = "aeiou";
059                String cname = null;
060                
061                String segName = seg.getFeatures().getString("name");
062                
063                /*
064                 * If we have a vowel, then the unit name is the segment name
065                 * plus a 0 or 1, depending upon the stress of the parent.
066                 * Otherwise, the unit name is the segment name plus "coda" or
067                 * "onset" based upon the seg_onsetcoda feature processor.
068                 */
069                if (segName.equals("pau")) {
070                    cname = segName;
071                } else if (VOWELS.indexOf(segName.charAt(0)) >= 0) {
072                    cname = segName + seg.findFeature("R:SylStructure.parent.stress");
073                } else {
074                    cname = segName + seg.findFeature("seg_onsetcoda");
075                }
076                
077                seg.getFeatures().setString("clunit_name", cname);
078            }
079            
080        };
081        return new ClusterUnitSelector(getDatabase(), unitNamer);
082    }
083}
084