diff options
author | kfukuda | 2012-09-19 12:29:48 +0000 |
---|---|---|
committer | kfukuda | 2012-09-19 12:29:48 +0000 |
commit | 5fa7a8167aa62e8b83d6d36d80d5c267a699887f (patch) | |
tree | 2e2fbb1b0409035512f9798f87a21f313b14e048 | |
parent | aec0bf71c182b93d2ce83955787fa469a742df17 (diff) | |
download | org.eclipse.actf.ai-5fa7a8167aa62e8b83d6d36d80d5c267a699887f.tar.gz org.eclipse.actf.ai-5fa7a8167aa62e8b83d6d36d80d5c267a699887f.tar.xz org.eclipse.actf.ai-5fa7a8167aa62e8b83d6d36d80d5c267a699887f.zip |
[389790] multiple language id support
4 files changed, 240 insertions, 62 deletions
diff --git a/plugins/org.eclipse.actf.ai.tts.msp/src/org/eclipse/actf/ai/tts/msp/engine/MspVoice.java b/plugins/org.eclipse.actf.ai.tts.msp/src/org/eclipse/actf/ai/tts/msp/engine/MspVoice.java index 5415010..9129ade 100644 --- a/plugins/org.eclipse.actf.ai.tts.msp/src/org/eclipse/actf/ai/tts/msp/engine/MspVoice.java +++ b/plugins/org.eclipse.actf.ai.tts.msp/src/org/eclipse/actf/ai/tts/msp/engine/MspVoice.java @@ -12,13 +12,20 @@ package org.eclipse.actf.ai.tts.msp.engine; import java.io.File; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import org.eclipse.actf.ai.tts.ISAPIEngine; +import org.eclipse.actf.ai.tts.ITTSEngineInfo; import org.eclipse.actf.ai.tts.msp.MspPlugin; import org.eclipse.actf.ai.voice.IVoiceEventListener; import org.eclipse.actf.util.win32.COMUtil; import org.eclipse.actf.util.win32.MemoryUtil; import org.eclipse.actf.util.win32.NativeIntAccess; +import org.eclipse.core.runtime.Platform; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; @@ -51,6 +58,42 @@ public class MspVoice implements ISAPIEngine, IPropertyChangeListener { private SpObjectToken curVoiceToken = null; + private class EngineInfo implements ITTSEngineInfo { + String name; + String lang; + String langId; + String gender; + + public EngineInfo(String name, String lang, String langId, String gender) { + this.name = name; + this.lang = lang; + this.langId = langId; + this.gender = gender; + } + + public String getName() { + return name; + } + + public String getLanguage() { + return lang; + } + + public String getGender() { + return gender; + } + + } + + private Map<String, TreeSet<EngineInfo>> langId2EngineMap = new HashMap<String, TreeSet<EngineInfo>>(); + private Set<ITTSEngineInfo> ttsEngineInfoSet = new TreeSet<ITTSEngineInfo>( + new Comparator<ITTSEngineInfo>() { + public int compare(ITTSEngineInfo o1, ITTSEngineInfo o2) { + // TODO null, lang/gender check + return o1.getName().compareTo(o2.getName()); + } + }); + public MspVoice() { int pv = COMUtil.createDispatch(ISpVoice.IID); dispSpVoice = new ISpVoice(pv); @@ -68,7 +111,57 @@ public class MspVoice implements ISAPIEngine, IPropertyChangeListener { setAudioOutputName(); // switch to actual engine preferenceStore.setValue(ID, orgID); - setVoiceName(); //for init curVoiceToken + setVoiceName(); // for init curVoiceToken + + Variant varVoices = getVoices(null, null); + if (null != varVoices) { + SpeechObjectTokens voiceTokens = SpeechObjectTokens + .getTokens(varVoices); + if (null != voiceTokens) { + String exclude = Platform.getResourceString(MspPlugin + .getDefault().getBundle(), "%voice.exclude"); //$NON-NLS-1$ + int count = voiceTokens.getCount(); + for (int i = 0; i < count; i++) { + Variant varVoice = voiceTokens.getItem(i); + if (null != varVoice) { + SpObjectToken token = SpObjectToken.getToken(varVoice); + if (null != token) { + String voiceName = token.getDescription(0); + String langId = token.getAttribute("language"); //$NON-NLS-1$ + int index = langId.indexOf(";"); + // use primary lang ID + if (index > 0) { + langId = langId.substring(0, index); + } + String gender = token.getAttribute("gender"); //$NON-NLS-1$ + if (null == exclude || !exclude.equals(voiceName)) { + TreeSet<EngineInfo> set = langId2EngineMap + .get(langId); + if (set == null) { + set = new TreeSet<EngineInfo>( + new Comparator<EngineInfo>() { + public int compare( + EngineInfo o1, + EngineInfo o2) { + // TODO priority + return -o1.name + .compareTo(o2.name); + } + }); + langId2EngineMap.put(langId, set); + } + String lang = LANGID_REVERSE_MAP.get(langId); + EngineInfo engineInfo = new EngineInfo( + voiceName, lang, langId, gender); + set.add(engineInfo); + ttsEngineInfoSet.add(engineInfo); + } + } + } + } + } + varVoices.dispose(); + } // to avoid access violation error at application shutdown stop(); @@ -415,6 +508,9 @@ public class MspVoice implements ISAPIEngine, IPropertyChangeListener { * @see org.eclipse.actf.ai.tts.ITTSEngine#setGender(java.lang.String) */ public void setGender(String gender) { + if (gender == null) { + return; + } String langId = null; if (curVoiceToken != null) { langId = curVoiceToken.getAttribute("language"); @@ -485,7 +581,7 @@ public class MspVoice implements ISAPIEngine, IPropertyChangeListener { // open 100 close 101 String tmpS = file.toURI().toString(); if (tmpS.startsWith("file:/")) { - tmpS = tmpS.substring(6).replaceAll("%20"," ");; + tmpS = tmpS.substring(6).replaceAll("%20", " "); } autoSpFileStream.invoke(100, new Variant[] { new Variant(tmpS), @@ -516,4 +612,9 @@ public class MspVoice implements ISAPIEngine, IPropertyChangeListener { setAudioOutputName(); // reset output return speakToFileResult; } + + public Set<ITTSEngineInfo> getTTSEngineInfoSet() { + return ttsEngineInfoSet; + } + } diff --git a/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/engine/SapiVoice.java b/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/engine/SapiVoice.java index 38635a8..7ead32b 100644 --- a/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/engine/SapiVoice.java +++ b/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/engine/SapiVoice.java @@ -15,9 +15,11 @@ import java.io.File; import java.util.Comparator; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.TreeSet; import org.eclipse.actf.ai.tts.ISAPIEngine; +import org.eclipse.actf.ai.tts.ITTSEngineInfo; import org.eclipse.actf.ai.tts.sapi.SAPIPlugin; import org.eclipse.actf.ai.voice.IVoiceEventListener; import org.eclipse.actf.util.win32.COMUtil; @@ -56,19 +58,41 @@ public class SapiVoice implements ISAPIEngine, IPropertyChangeListener { private SpObjectToken curVoiceToken = null; - private class EngineInfo { + private class EngineInfo implements ITTSEngineInfo { String name; + String lang; String langId; String gender; - public EngineInfo(String name, String langId, String gender) { + public EngineInfo(String name, String lang, String langId, String gender) { this.name = name; + this.lang = lang; this.langId = langId; this.gender = gender; } + + public String getName() { + return name; + } + + public String getLanguage() { + return lang; + } + + public String getGender() { + return gender; + } + } private Map<String, TreeSet<EngineInfo>> langId2EngineMap = new HashMap<String, TreeSet<EngineInfo>>(); + private Set<ITTSEngineInfo> ttsEngineInfoSet = new TreeSet<ITTSEngineInfo>( + new Comparator<ITTSEngineInfo>() { + public int compare(ITTSEngineInfo o1, ITTSEngineInfo o2) { + // TODO null, lang/gender check + return o1.getName().compareTo(o2.getName()); + } + }); public SapiVoice() { int pv = COMUtil.createDispatch(ISpVoice.IID); @@ -105,8 +129,8 @@ public class SapiVoice implements ISAPIEngine, IPropertyChangeListener { String voiceName = token.getDescription(0); String langId = token.getAttribute("language"); //$NON-NLS-1$ int index = langId.indexOf(";"); - //use primary lang ID - if (index > 0){ + // use primary lang ID + if (index > 0) { langId = langId.substring(0, index); } String gender = token.getAttribute("gender"); //$NON-NLS-1$ @@ -126,8 +150,11 @@ public class SapiVoice implements ISAPIEngine, IPropertyChangeListener { }); langId2EngineMap.put(langId, set); } - set.add(new EngineInfo(voiceName, langId, - gender)); + String lang = LANGID_REVERSE_MAP.get(langId); + EngineInfo engineInfo = new EngineInfo( + voiceName, lang, langId, gender); + set.add(engineInfo); + ttsEngineInfoSet.add(engineInfo); } } } @@ -497,7 +524,6 @@ public class SapiVoice implements ISAPIEngine, IPropertyChangeListener { } } } - } /* @@ -540,7 +566,7 @@ public class SapiVoice implements ISAPIEngine, IPropertyChangeListener { // open 100 close 101 String tmpS = file.toURI().toString(); if (tmpS.startsWith("file:/")) { - tmpS = tmpS.substring(6).replaceAll("%20"," "); + tmpS = tmpS.substring(6).replaceAll("%20", " "); } autoSpFileStream.invoke(100, new Variant[] { new Variant(tmpS), @@ -572,4 +598,8 @@ public class SapiVoice implements ISAPIEngine, IPropertyChangeListener { return speakToFileResult; } + public Set<ITTSEngineInfo> getTTSEngineInfoSet() { + return ttsEngineInfoSet; + } + } diff --git a/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ISAPIEngine.java b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ISAPIEngine.java index 3dc51fc..f4ed427 100644 --- a/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ISAPIEngine.java +++ b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ISAPIEngine.java @@ -12,11 +12,12 @@ package org.eclipse.actf.ai.tts; import java.util.HashMap; import java.util.Map; - +import java.util.Set; /** - * ISAPIEngine interface defines text synthesis interface to be - * implemented by SAPI5 and MSP text-to-speech engine + * ISAPIEngine interface defines text synthesis interface to be implemented by + * SAPI5 and MSP text-to-speech engine + * * @see ITTSEngine */ public interface ISAPIEngine extends ITTSEngine { @@ -25,7 +26,6 @@ public interface ISAPIEngine extends ITTSEngine { SVSFPurgeBeforeSpeak = 2, SVSFIsFilename = 4, SVSFIsXML = 8, SVSFIsNotXML = 16, SVSFPersistXML = 32; - /** * Map to get LangId from "Language"-"Country" code (e.g., en-US). */ @@ -78,60 +78,60 @@ public interface ISAPIEngine extends ITTSEngine { put("zh-HK", "C04"); } }; - + /** * Map to get "Language"-"Country" code (e.g., en-US) from LangId. */ public static final Map<String, String> LANGID_REVERSE_MAP = new HashMap<String, String>() { private static final long serialVersionUID = -4065510530588377900L; { - put("401","ar-SA"); - put("402","bg-BG"); - put("403","ca-ES"); - put("404","zh-TW"); - put("405","cs-CZ"); - put("406","da-DK"); - put("407","de-DE"); - put("408","el-GR"); - put("409","en-US"); - put("40B","fi-FI"); - put("40C","fr-FR"); - put("40D","he-IL"); - put("40E","hu-HU"); - put("410","it-IT"); - put("411","ja-JP"); - put("412","ko-KR"); - put("413","nl-NL"); - put("414","nb-NO"); - put("415","pl-PL"); - put("416","pt-BR"); - put("418","ro-RO"); - put("419","ru-RU"); - put("41A","hr-HR"); - put("41B","sk-SK"); - put("41D","sv-SE"); - put("41E","th-TH"); - put("41F","tr-TR"); - put("422","uk-UA"); - put("424","sl-SI"); - put("425","et-EE"); - put("426","lv-LV"); - put("427","lt-LT"); - put("42A","vi-VN"); - put("42D","eu-ES"); - put("804","zh-CN"); - put("816","pt-PT"); - put("81A","sr-CS"); - put("C0A","es-ES"); - put("C09","en-AU"); - put("1009","en-CA"); - put("809","en-GB"); - put("4009","en-IN"); - put("C0C","fr-CA"); - put("C04","zh-HK"); + put("401", "ar-SA"); + put("402", "bg-BG"); + put("403", "ca-ES"); + put("404", "zh-TW"); + put("405", "cs-CZ"); + put("406", "da-DK"); + put("407", "de-DE"); + put("408", "el-GR"); + put("409", "en-US"); + put("40B", "fi-FI"); + put("40C", "fr-FR"); + put("40D", "he-IL"); + put("40E", "hu-HU"); + put("410", "it-IT"); + put("411", "ja-JP"); + put("412", "ko-KR"); + put("413", "nl-NL"); + put("414", "nb-NO"); + put("415", "pl-PL"); + put("416", "pt-BR"); + put("418", "ro-RO"); + put("419", "ru-RU"); + put("41A", "hr-HR"); + put("41B", "sk-SK"); + put("41D", "sv-SE"); + put("41E", "th-TH"); + put("41F", "tr-TR"); + put("422", "uk-UA"); + put("424", "sl-SI"); + put("425", "et-EE"); + put("426", "lv-LV"); + put("427", "lt-LT"); + put("42A", "vi-VN"); + put("42D", "eu-ES"); + put("804", "zh-CN"); + put("816", "pt-PT"); + put("81A", "sr-CS"); + put("C0A", "es-ES"); + put("C09", "en-AU"); + put("1009", "en-CA"); + put("809", "en-GB"); + put("4009", "en-IN"); + put("C0C", "fr-CA"); + put("C04", "zh-HK"); } }; - + /** * @param rate * The rate property to be set. @@ -143,8 +143,20 @@ public interface ISAPIEngine extends ITTSEngine { * @return The rate property of the voice engine. */ public int getRate(); - + + /** + * Speak text by using specified SAPI flag + * + * @param text + * text string to be spoken + * @param sapiFlags + * SAPI flags + */ public void speak(String text, int sapiFlags); - + + /** + * @return set of TTS engine information that supported in the environment. + */ + public Set<ITTSEngineInfo> getTTSEngineInfoSet(); } diff --git a/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ITTSEngineInfo.java b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ITTSEngineInfo.java new file mode 100644 index 0000000..6816c11 --- /dev/null +++ b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ITTSEngineInfo.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2012 IBM Corporation and Others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Kentarou FUKUDA - initial API and implementation + *******************************************************************************/ + +package org.eclipse.actf.ai.tts; + +/** + * ITTSEngineInfo enables to store information of text synthesis engines (name, language and gender). + * + * @see ITTSEngine + */ +public interface ITTSEngineInfo { + + /** + * @return name of TTS engine + */ + String getName(); + + /** + * @return language of TTS engine + */ + String getLanguage(); + + /** + * @return gender of TTS engine + */ + String getGender(); +} |