PageRenderTime 163ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/marytts-runtime/src/main/java/marytts/modules/synthesis/FreeTTSVoices.java

https://bitbucket.org/marytts/marytts
Java | 248 lines | 136 code | 19 blank | 93 comment | 43 complexity | 54cb173355330213bf5dbdff6717be4a MD5 | raw file
  1. /**
  2. * Copyright 2000-2006 DFKI GmbH.
  3. * All Rights Reserved. Use is subject to license terms.
  4. *
  5. * This file is part of MARY TTS.
  6. *
  7. * MARY TTS is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation, version 3 of the License.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. package marytts.modules.synthesis;
  21. import java.util.Collection;
  22. import java.util.HashMap;
  23. import java.util.Iterator;
  24. import java.util.Locale;
  25. import java.util.Map;
  26. import marytts.exceptions.NoSuchPropertyException;
  27. import marytts.modules.DummyFreeTTSVoice;
  28. import marytts.server.MaryProperties;
  29. import marytts.unitselection.UnitSelectionVoice;
  30. import marytts.util.MaryUtils;
  31. import org.apache.log4j.Logger;
  32. import com.sun.speech.freetts.en.us.CMULexicon;
  33. import com.sun.speech.freetts.lexicon.Lexicon;
  34. import de.dfki.lt.freetts.de.GermanLexicon;
  35. /**
  36. * Instantiate and manage FreeTTS voices.
  37. *
  38. * @author Marc Schr&ouml;der
  39. */
  40. public class FreeTTSVoices
  41. {
  42. private FreeTTSVoices() {} // no instances of this class
  43. /**
  44. * The keys in this map are instances of
  45. * <code>marytts.modules.synthesis.Voice</code>; the values are
  46. * instances of <code>com.sun.speech.freetts.Voice</code>.
  47. */
  48. private static Map<marytts.modules.synthesis.Voice, com.sun.speech.freetts.Voice> mary2freettsVoices = null;
  49. /**
  50. * The keys in this map are instances of
  51. * <code>com.sun.speech.freetts.Voice</code>;
  52. * the values are instances of
  53. * <code>marytts.modules.synthesis.Voice</code>.
  54. */
  55. private static Map<com.sun.speech.freetts.Voice, marytts.modules.synthesis.Voice> freetts2maryVoices = null;
  56. private static Lexicon usenLexicon = null;
  57. private static Lexicon deLexicon = null;
  58. protected static Logger logger = MaryUtils.getLogger("FreeTTSVoices");
  59. /**
  60. * Ascertain that the FreeTTS voices are loaded.
  61. * Whether the resources for them will also be allocated
  62. * depends on the mary property "freetts.lexicon.preload" setting --
  63. * if that results to false, no resources will be loaded; if the setting is missing,
  64. * a NoSuchPropertyException will be thrown.
  65. * This method can safely be called more than once; any subsequent calls
  66. * will have no effect.
  67. */
  68. public static void load() throws NoSuchPropertyException
  69. {
  70. if (mary2freettsVoices == null) {
  71. logger.info("Loading US English FreeTTS voices...");
  72. // create all voices at startup time
  73. Collection maryVoices = marytts.modules.synthesis.Voice.
  74. getAvailableVoices(Locale.US);
  75. Iterator it = maryVoices.iterator();
  76. while (it.hasNext()) {
  77. marytts.modules.synthesis.Voice maryVoice =
  78. (marytts.modules.synthesis.Voice) it.next();
  79. load(maryVoice);
  80. }
  81. logger.info("done.");
  82. }
  83. }
  84. /**
  85. * Add a freetts voice for a given mary voice.
  86. * This is used by load(), but can also be called separately. Repeated
  87. * registration of the same voice will be ignored, so it is safe to call
  88. * this several times with the same maryVoice.
  89. * This depends on the mary property "freetts.lexicon.preload" setting --
  90. * if that results to false, nothing will be loaded; if the setting is missing,
  91. * a NoSuchPropertyException will be thrown.
  92. * @param maryVoice the maryVoice object to register a freetts voice for.
  93. */
  94. public static void load(marytts.modules.synthesis.Voice maryVoice)
  95. throws NoSuchPropertyException
  96. {
  97. if (mary2freettsVoices == null) mary2freettsVoices = new HashMap<marytts.modules.synthesis.Voice, com.sun.speech.freetts.Voice>();
  98. if (freetts2maryVoices == null) freetts2maryVoices = new HashMap<com.sun.speech.freetts.Voice, marytts.modules.synthesis.Voice>();
  99. if (mary2freettsVoices.containsKey(maryVoice)) return; // already known
  100. load(maryVoice, createFreeTTSVoice(maryVoice));
  101. }
  102. /**
  103. * Depending on the locale of the mary voice, create a suitable FreeTTS dummy voice.
  104. * @param maryVoice
  105. * @return a newly created FreeTTS dummy voice
  106. */
  107. private static DummyFreeTTSVoice createFreeTTSVoice(Voice maryVoice)
  108. {
  109. DummyFreeTTSVoice freeTTSVoice;
  110. if (maryVoice.getLocale() != null && maryVoice.getLocale().equals(Locale.US)) {
  111. try {
  112. freeTTSVoice = (DummyFreeTTSVoice) Class.forName("marytts.language.en.DummyFreeTTSVoice").newInstance();
  113. } catch (InstantiationException e) {
  114. throw new RuntimeException(e);
  115. } catch (IllegalAccessException e) {
  116. throw new RuntimeException(e);
  117. } catch (ClassNotFoundException e) {
  118. throw new RuntimeException(e);
  119. }
  120. freeTTSVoice.initialise(maryVoice, null);
  121. } else {
  122. freeTTSVoice = new DummyFreeTTSVoice(maryVoice, null);
  123. }
  124. return freeTTSVoice;
  125. }
  126. /**
  127. * Depending on the maryVoice and its locale, associate an existing
  128. * or create a new lexicon.
  129. * @param maryVoice
  130. * @return a Lexicon; if it was freshly created, it is not yet loaded.
  131. */
  132. @Deprecated
  133. private static Lexicon getLexicon(Voice maryVoice)
  134. {
  135. if (maryVoice instanceof UnitSelectionVoice) {
  136. return ((UnitSelectionVoice)maryVoice).getLexicon();
  137. }
  138. if (maryVoice.getLocale() == null) {
  139. return null;
  140. } else if (maryVoice.getLocale().equals(Locale.US)) {
  141. if (usenLexicon == null) usenLexicon = new CMULexicon("cmudict04");
  142. return usenLexicon;
  143. } else if (maryVoice.getLocale().equals(Locale.GERMAN)) {
  144. if (deLexicon == null) deLexicon = new GermanLexicon();
  145. return deLexicon;
  146. }
  147. return null;
  148. }
  149. /**
  150. * Add a given freetts voice for a given mary voice.
  151. * Repeated
  152. * registration of the same voice will be ignored, so it is safe to call
  153. * this several times with the same maryVoice/freettsVoice pair.
  154. * This depends on the mary property "freetts.lexicon.preload" setting --
  155. * if that results to false, nothing will be loaded; if the setting is missing,
  156. * a NoSuchPropertyException will be thrown.
  157. * @param maryVoice the maryVoice object to register the freetts voice for.
  158. * @param freeTTSVoice the freettsVoice object to register.
  159. */
  160. public static void load(marytts.modules.synthesis.Voice maryVoice, com.sun.speech.freetts.Voice freeTTSVoice)
  161. throws NoSuchPropertyException
  162. {
  163. if (mary2freettsVoices == null) mary2freettsVoices = new HashMap<marytts.modules.synthesis.Voice, com.sun.speech.freetts.Voice>();
  164. if (freetts2maryVoices == null) freetts2maryVoices = new HashMap<com.sun.speech.freetts.Voice, marytts.modules.synthesis.Voice>();
  165. if (mary2freettsVoices.containsKey(maryVoice)) return; // already known
  166. if (freeTTSVoice.getLexicon() == null) {
  167. Lexicon lex = maryVoice.getLexicon();
  168. freeTTSVoice.setLexicon(lex);
  169. }
  170. if (MaryProperties.needAutoBoolean("freetts.lexicon.preload") && !freeTTSVoice.isLoaded()) {
  171. logger.debug("Allocating resources for voice "+freeTTSVoice.getName()+"...");
  172. freeTTSVoice.allocate();
  173. logger.debug("... done.");
  174. }
  175. mary2freettsVoices.put(maryVoice, freeTTSVoice);
  176. freetts2maryVoices.put(freeTTSVoice, maryVoice);
  177. logger.debug("added freetts voice for mary voice " + maryVoice.toString());
  178. }
  179. /**
  180. * For a given MARY voice, get the corresponding FreeTTS voice.
  181. * This method will load/allocate a voice if it had not been loaded before.
  182. * @throws NoSuchPropertyException if the property <code>freetts.lexicon.preload</code>
  183. * is not defined in the MARY properties file.
  184. */
  185. public static com.sun.speech.freetts.Voice getFreeTTSVoice
  186. (marytts.modules.synthesis.Voice maryVoice)
  187. throws NoSuchPropertyException
  188. {
  189. if (maryVoice == null) {
  190. maryVoice = marytts.modules.synthesis.Voice.getDefaultVoice(Locale.US);
  191. }
  192. assert mary2freettsVoices != null; // called before startup()?
  193. com.sun.speech.freetts.Voice freeTTSVoice = (com.sun.speech.freetts.Voice) mary2freettsVoices.get(maryVoice);
  194. if (freeTTSVoice == null) {
  195. // need to create dummy freetts voice for mary voice
  196. load(maryVoice);
  197. freeTTSVoice = (com.sun.speech.freetts.Voice) mary2freettsVoices.get(maryVoice);
  198. }
  199. assert freeTTSVoice != null;
  200. // At this stage, make sure the voice is loaded:
  201. if (!freeTTSVoice.isLoaded()) {
  202. logger.debug("Allocating resources for voice "+freeTTSVoice.getName()+"...");
  203. freeTTSVoice.allocate();
  204. logger.debug("... done.");
  205. }
  206. return freeTTSVoice;
  207. }
  208. /**
  209. * For a given MARY voice, get the corresponding FreeTTS voice.
  210. * @throws NoSuchPropertyException if the property <code>freetts.lexicon.preload</code>
  211. * is not defined in the MARY properties file.
  212. */
  213. public static marytts.modules.synthesis.Voice getMaryVoice
  214. (com.sun.speech.freetts.Voice freeTTSVoice)
  215. throws NoSuchPropertyException
  216. {
  217. if (freeTTSVoice == null) {
  218. throw new NullPointerException("Received null voice");
  219. }
  220. if (freetts2maryVoices != null) {
  221. marytts.modules.synthesis.Voice maryVoice = (marytts.modules.synthesis.Voice) freetts2maryVoices.get(freeTTSVoice);
  222. /*if (maryVoice == null) {
  223. throw new NoSuchPropertyException("No Mary voice available for the FreeTTS voice \"" + freeTTSVoice + "\"");
  224. }*/
  225. return maryVoice;
  226. }
  227. return null;
  228. }
  229. }