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 * "general", "time", or 033 * "weather". 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