001/** 002 * Copyright 2002 DFKI GmbH. 003 * Portions Copyright 2002 Sun Microsystems, Inc. 004 * All Rights Reserved. Use is subject to license terms. 005 * 006 * See the file "license.terms" for information on usage and 007 * redistribution of this file, and for a DISCLAIMER OF ALL 008 * WARRANTIES. 009 */ 010 011package de.dfki.lt.freetts.en.us; 012 013import java.io.File; 014import java.io.IOException; 015import java.net.URL; 016import java.util.Locale; 017 018import com.sun.speech.freetts.Age; 019import com.sun.speech.freetts.Gender; 020import com.sun.speech.freetts.UtteranceProcessor; 021import com.sun.speech.freetts.en.us.CMULexicon; 022import com.sun.speech.freetts.en.us.CMUVoice; 023import com.sun.speech.freetts.util.Utilities; 024 025import de.dfki.lt.freetts.mbrola.MbrolaAudioOutput; 026import de.dfki.lt.freetts.mbrola.MbrolaCaller; 027import de.dfki.lt.freetts.mbrola.ParametersToMbrolaConverter; 028 029/** 030 * Defines an unlimited-domain diphone synthesis based voice using 031 * the MBROLA synthesis. 032 */ 033public class MbrolaVoice extends CMUVoice { 034 035 private String databaseDirectory; // where the voice database is 036 private String database; // name of the voice database 037 038 private static final String MRPA_TO_SAMPA_RENAME_LIST = 039 "V ah i iy I ih U uh { ae @ ax r= er A aa O ao u uw E eh EI ey AI ay OI oy aU aw @U ow j y h hh N ng S sh T th Z zh D dh tS ch dZ jh _ pau"; 040 041 /** 042 * Creates an MbrolaVoice. 043 * 044 * @param databaseDirectory the directory within the MBROLA directory 045 * where the voice database of this voice is located 046 * @param database the name of the voice database of this voice 047 * @param rate the rate of the voice 048 * @param pitch the pitch of the voice 049 * @param range the range of the voice 050 * @param name the name of the voice 051 * @param gender the gender of the voice 052 * @param age the age of the voice 053 * @param description a human-readable string providing a 054 * description that can be displayed for the users. 055 * @param locale the locale of the voice 056 * @param domain the domain of this voice. For example, 057 * @param organization the organization which created the voice 058 * @param lexicon the lexicon to use 059 */ 060 public MbrolaVoice(String databaseDirectory, 061 String database, float rate, float pitch, float range, 062 String name, Gender gender, Age age, 063 String description, Locale locale, String domain, 064 String organization, CMULexicon lexicon) { 065 super(name, gender, age, description, locale, 066 domain, organization, lexicon); 067 setRate(rate); 068 setPitch(pitch); 069 setPitchRange(range); 070 this.databaseDirectory = databaseDirectory; 071 this.database = database; 072 } 073 074 //[[Providing the Mbrola classes via getUnitSelector() and 075 // getUnitConcatenator() is just a hack allowing us to use 076 // the current CMUVoice.java framework. It only means that 077 // after the Durator and the ContourGenerator, the classes 078 // process the utterance (Selector before Concatenator).]] 079 /** 080 * Returns the unit selector to be used by this voice. 081 * Derived voices typically override this to customize behaviors. 082 * 083 * @return the unit selector 084 * 085 * @throws IOException if an IO error occurs while getting 086 * processor 087 */ 088 protected UtteranceProcessor getUnitSelector() throws IOException { 089 return new ParametersToMbrolaConverter(); 090 } 091 092 /** 093 * Returns the command line that invokes the MBROLA executable. 094 * The command will be in the form of: 095 * 096 * <pre> {mbrolaExecutable} -e -R {mbrolaRenameList} {mbrolaVoiceDB} 097 * - -.raw </pre> 098 */ 099 protected String[] getMbrolaCommand() { 100 101 // Construct the mbrola command in such a way that 102 // mbrola reads from stdin and writes raw, headerless audio data 103 // to stdout; translates CMU us radio to sampa phonetic symbols; 104 // and only complains, but does not abort, when encountering an 105 // unknown diphone: 106 String[] cmd = 107 {getMbrolaBinary(), "-e", "-R", getRenameList(), 108 getDatabase(), "-", "-.raw"}; 109 110 if (false) { 111 for (int i = 0; i < cmd.length; i++) { 112 System.out.println(cmd[i]); 113 } 114 } 115 116 return cmd; 117 } 118 119 /** 120 * Returns the absolute name of the MBROLA directory. 121 * 122 * @return the absolute name of the MBROLA directory 123 */ 124 public String getMbrolaBase() { 125 return Utilities.getProperty("mbrola.base", "."); 126 } 127 128 /** 129 * Returns the absolute file name of the MBROLA binary. 130 * 131 * @return the absolute file name of the MBROLA binary 132 */ 133 public String getMbrolaBinary() { 134 // In windows environments, executables typically end with exe, so 135 // we add this suffix if we are running under windows. 136 StringBuffer executable = new StringBuffer(); 137 executable.append("mbrola"); 138 String os = System.getProperty("os.name"); 139 if (os.indexOf("Windows") >= 0) { 140 executable.append(".exe"); 141 } 142 return getMbrolaBase() + File.separator + executable.toString(); 143 } 144 145 /** 146 * Returns the absolute file name of the MBROLA phonetic symbols 147 * rename table. 148 * 149 * @return the absolute file name of the rename table 150 */ 151 public String getRenameList() { 152 return MRPA_TO_SAMPA_RENAME_LIST; 153 } 154 155 /** 156 * Returns the absolute file name of the Voice database 157 * this MbrolaVoice uses. 158 * 159 * @return the absolute file name of the Voice database 160 */ 161 public String getDatabase() { 162 return getMbrolaBase() + File.separator + 163 databaseDirectory + File.separator + database; 164 } 165 166// /** 167// * Returns the unit concatenator to be used by this voice. 168// * Derived voices typically override this to customize behaviors. 169// * 170// * @return the unit conatenator 171// * 172// * @throws IOException if an IO error occurs while getting 173// * processor 174// */ 175// protected UtteranceProcessor getUnitConcatenator() throws IOException { 176// return null; 177// } 178 179 //[[Providing the Mbrola classes via getUnitSelector() and 180 // getUnitConcatenator() is just a hack allowing us to use 181 // the current CMUVoice.java framework. It only means that 182 // after the Durator and the ContourGenerator, the classes 183 // process the utterance (Selector before Concatenator).]] 184 /** 185 * Returns the unit concatenator to be used by this voice. 186 * This method constructs the command line with which the 187 * MBROLA binary will be called, and initialises the 188 * MbrolaCaller accordingly. 189 * 190 * @return the unit conatenator 191 * 192 * @throws IOException if an IO error occurs while getting 193 * processor 194 */ 195 protected UtteranceProcessor getUnitConcatenator() throws IOException { 196 return new MbrolaCaller(getMbrolaCommand()); 197 } 198 199 /** 200 * Returns the audio output used by this voice. 201 * 202 * @return the audio output used by this voice 203 * 204 * @throws IOException if an I/O error occurs 205 */ 206 protected UtteranceProcessor getAudioOutput() throws IOException { 207 return new MbrolaAudioOutput(); 208 } 209 210 /** 211 * Get a resource for this voice. Resources for this voice are located in 212 * the package <code>com.sun.speech.freetts.en.us</code>. 213 */ 214 protected URL getResource(String resource) { 215 return com.sun.speech.freetts.en.us.CMUVoice.class. 216 getResource(resource); 217 } 218 219 /** 220 * Converts this object to a string 221 * 222 * @return a string representation of this object 223 */ 224 public String toString() { 225 return "MbrolaVoice"; 226 } 227} 228