[258991] support TTS engines that do not support multiple instances
diff --git a/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/Jaws.java b/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/Jaws.java
index 25ed274..6740f4f 100644
--- a/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/Jaws.java
+++ b/plugins/org.eclipse.actf.ai.screenreader.jaws/src/org/eclipse/actf/ai/screenreader/jaws/Jaws.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and Others
+ * Copyright (c) 2007, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* Daisuke SATO - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.screenreader.jaws;
@@ -39,6 +40,11 @@
public void dispose() {
// not supported
}
+
+ public boolean isDisposed() {
+ return false;
+ }
+
/*
* (non-Javadoc)
@@ -161,4 +167,5 @@
return false;
return jaws.isAvailable();
}
+
}
diff --git a/plugins/org.eclipse.actf.ai.screenreader.windoweyes/src/org/eclipse/actf/ai/screenreader/windoweyes/engine/GWSpeak.java b/plugins/org.eclipse.actf.ai.screenreader.windoweyes/src/org/eclipse/actf/ai/screenreader/windoweyes/engine/GWSpeak.java
index 595da36..8a863d9 100644
--- a/plugins/org.eclipse.actf.ai.screenreader.windoweyes/src/org/eclipse/actf/ai/screenreader/windoweyes/engine/GWSpeak.java
+++ b/plugins/org.eclipse.actf.ai.screenreader.windoweyes/src/org/eclipse/actf/ai/screenreader/windoweyes/engine/GWSpeak.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and Others
+ * Copyright (c) 2007, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* Takashi ITOH - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.screenreader.windoweyes.engine;
@@ -27,19 +28,21 @@
private IGWSpeak dispGWSpeak = null; // Instanceof GWSpeak.Speak ActiveX
private IVoiceEventListener eventListener = null;
private boolean notifyEndOfSpeech = false; // Invoke indexReceived() if
- // true
+ // true
private long lastNotificationTime = 0; // Last time of indexReceived()
// Constants
private static final int DELAY_FIRST = 500; // Delay on the first
- // indexReceived()
+ // indexReceived()
private static final int DELAY_NEXT = 1000; // Delay on the subsequent
- // indexReceived()
+ // indexReceived()
private static final TCHAR GWM_WINDOW_CLASS = new TCHAR(0,
"GWMExternalControl", true); //$NON-NLS-1$
private static final TCHAR GWM_WINDOW_NAME = new TCHAR(0,
"External Control", true); //$NON-NLS-1$
+ private boolean isDisposed = false;
+
/**
* Constructor
*/
@@ -65,6 +68,7 @@
* @see org.eclipse.actf.ai.tts.ITTSEngine#dispose()
*/
public void dispose() {
+ isDisposed = true;
if (null != dispGWSpeak) {
eventListener = null;
stop();
@@ -195,4 +199,8 @@
public void setSpeed(int speed) {
}
+ public boolean isDisposed() {
+ return isDisposed;
+ }
+
}
diff --git a/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/engine/ProTalker.java b/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/engine/ProTalker.java
index 2d23530..843ed25 100644
--- a/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/engine/ProTalker.java
+++ b/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/engine/ProTalker.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and Others
+ * Copyright (c) 2007, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* Daisuke SATO - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.tts.protalker.engine;
@@ -27,6 +28,8 @@
private ProTalkerBridge engine;
+ private boolean isDisposed = false;
+
public ProTalker() {
engine = new ProTalkerBridge(Display.getDefault());
setVoice();
@@ -145,6 +148,16 @@
* @see org.eclipse.actf.ai.tts.ITTSEngine#dispose()
*/
public void dispose() {
+ if (!isDisposed) {
+ isDisposed = true;
+ engine.dispose();
+ if (ProTalkerPlugin.getDefault() != null) {
+ ProTalkerPlugin.getDefault().removePropertyChangeListener(this);
+ }
+ }
+ }
+ public boolean isDisposed() {
+ return isDisposed;
}
}
diff --git a/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/engine/ProTalkerBridge.java b/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/engine/ProTalkerBridge.java
index 55759de..0b0e4f5 100644
--- a/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/engine/ProTalkerBridge.java
+++ b/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/engine/ProTalkerBridge.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and Others
+ * Copyright (c) 2007, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* Daisuke SATO - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.tts.protalker.engine;
@@ -77,9 +78,11 @@
private OleFrame frame = null;
private Vector<IVoiceEventListener> indexListener = new Vector<IVoiceEventListener>();
+
+ private Shell parent;
ProTalkerBridge(Display display) {
- Shell parent = new Shell();
+ parent = new Shell();
parent.setLayout(new FillLayout());
frame = new OleFrame(parent, SWT.NONE);
try {
@@ -95,6 +98,11 @@
}
setVoice(VOICE_MALE);
}
+
+ public void dispose(){
+ auto.dispose();
+ parent.dispose();
+ }
private Variant getProperty(String name) {
int id = auto.getIDsOfNames(new String[] { name })[0];
diff --git a/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/preferences/ProTalkerFieldEditor.java b/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/preferences/ProTalkerFieldEditor.java
index 29c34c0..dfd3732 100644
--- a/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/preferences/ProTalkerFieldEditor.java
+++ b/plugins/org.eclipse.actf.ai.tts.protalker/src/org/eclipse/actf/ai/tts/protalker/preferences/ProTalkerFieldEditor.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Daisuke SATO - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.tts.protalker.preferences;
@@ -62,5 +63,11 @@
proTalker = null;
}
}
+
+ @Override
+ public void dispose() {
+ proTalker.dispose();
+ super.dispose();
+ }
}
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 bc48fe5..d3a333f 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and Others
+ * Copyright (c) 2007, 2008 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
@@ -7,10 +7,11 @@
*
* Contributors:
* Takashi ITOH - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.tts.sapi.engine;
-import org.eclipse.actf.ai.tts.ITTSEngine;
+import org.eclipse.actf.ai.tts.ISAPIEngine;
import org.eclipse.actf.ai.tts.sapi.SAPIPlugin;
import org.eclipse.actf.ai.voice.IVoiceEventListener;
import org.eclipse.actf.util.win32.COMUtil;
@@ -26,16 +27,12 @@
/**
* The implementation of ITTSEngine to use Microsoft Speech API.
*/
-public class SapiVoice implements ITTSEngine, IPropertyChangeListener {
+public class SapiVoice implements ISAPIEngine, IPropertyChangeListener {
public static final String ID = "org.eclipse.actf.ai.tts.sapi.engine.SapiVoice"; //$NON-NLS-1$
public static final String AUDIO_OUTPUT = "org.eclipse.actf.ai.tts.SapiVoice.audioOutput"; //$NON-NLS-1$
- public static final int SVSFDefault = 0, SVSFlagsAsync = 1,
- SVSFPurgeBeforeSpeak = 2, SVSFIsFilename = 4, SVSFIsXML = 8,
- SVSFIsNotXML = 16, SVSFPersistXML = 32;
-
- private ISpVoice dispSpVoice;
+ public ISpVoice dispSpVoice;
private Variant varSapiVoice;
private OleAutomation automation;
private int idGetVoices;
@@ -43,6 +40,7 @@
private ISpNotifySource spNotifySource = null;
private static IPreferenceStore preferenceStore = SAPIPlugin.getDefault()
.getPreferenceStore();
+ private boolean isDisposed = false;
public SapiVoice() {
int pv = COMUtil.createDispatch(ISpVoice.IID);
@@ -55,8 +53,16 @@
idGetVoices = getIDsOfNames("GetVoices"); //$NON-NLS-1$
idGetAudioOutputs = getIDsOfNames("GetAudioOutputs"); //$NON-NLS-1$
- setVoiceName();
+ // init by using default engine to avoid init error of some TTS engines
+ String orgID = preferenceStore.getString(ID);
+ preferenceStore.setValue(ID, preferenceStore.getDefaultString(ID));
setAudioOutputName();
+ // switch to actual engine
+ preferenceStore.setValue(ID, orgID);
+ // setVoiceName();
+
+ // to avoid access violation error at application shutdown
+ stop();
}
/*
@@ -103,7 +109,7 @@
}
}
- private void speak(String text, int sapiFlags) {
+ public void speak(String text, int sapiFlags) {
char[] data = (text + "\0").toCharArray(); //$NON-NLS-1$
int bstrText = MemoryUtil.SysAllocString(data);
try {
@@ -192,6 +198,30 @@
}
varVoices.dispose();
}
+ if (!success) {
+ int index = voiceName.indexOf("name=");
+ varVoices = getVoices(null, null);
+ if (null != varVoices && index > -1) {
+ String name = voiceName.substring(index + 5);
+ SpeechObjectTokens voiceTokens = SpeechObjectTokens
+ .getTokens(varVoices);
+ if (null != voiceTokens) {
+ 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
+ && name.equals(token.getDescription(0))) {
+ success = setVoice(varVoice);
+ }
+ }
+ }
+ }
+ }
+ varVoices.dispose();
+ }
return success;
}
@@ -282,7 +312,15 @@
* @see org.eclipse.actf.ai.tts.ITTSEngine#dispose()
*/
public void dispose() {
- varSapiVoice.dispose();
+ if (!isDisposed) {
+ isDisposed = true;
+
+ varSapiVoice.dispose();
+
+ if (SAPIPlugin.getDefault() != null) {
+ SAPIPlugin.getDefault().removePropertyChangeListener(this);
+ }
+ }
}
/*
@@ -338,4 +376,8 @@
public boolean isAvailable() {
return automation != null;
}
+
+ public boolean isDisposed() {
+ return isDisposed;
+ }
}
diff --git a/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiAudioOutputFieldEditor.java b/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiAudioOutputFieldEditor.java
index e1574bd..7c0a260 100644
--- a/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiAudioOutputFieldEditor.java
+++ b/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiAudioOutputFieldEditor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and Others
+ * Copyright (c) 2007, 2008 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
@@ -7,23 +7,37 @@
*
* Contributors:
* Takashi ITOH - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.tts.sapi.preferences;
+import org.eclipse.actf.ai.tts.sapi.SAPIPlugin;
import org.eclipse.actf.ai.tts.sapi.engine.SapiVoice;
import org.eclipse.actf.ai.voice.preferences.util.ComboFieldEditor;
+import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Composite;
-
-
public class SapiAudioOutputFieldEditor extends ComboFieldEditor {
- public SapiAudioOutputFieldEditor(String labelText, Composite parent) {
- super(SapiVoice.AUDIO_OUTPUT, labelText, null, parent);
- }
-
- protected void initLabelsAndValues(String[][] labelsAndValues) {
- super.initLabelsAndValues(SapiTestManager.getInstance().getAudioOutputNames());
- }
+ private static IPreferenceStore preferenceStore = SAPIPlugin.getDefault()
+ .getPreferenceStore();
+
+ public SapiAudioOutputFieldEditor(String labelText, Composite parent) {
+ super(SapiVoice.AUDIO_OUTPUT, labelText, null, parent);
+ }
+
+ protected void initLabelsAndValues(String[][] labelsAndValues) {
+ super.initLabelsAndValues(SapiTestManager.getInstance()
+ .getAudioOutputNames());
+ }
+
+ @Override
+ protected void fireValueChanged(String property, Object oldValue,
+ Object newValue) {
+
+ preferenceStore.setValue(SapiVoice.AUDIO_OUTPUT, newValue.toString());
+
+ super.fireValueChanged(property, oldValue, newValue);
+ }
}
diff --git a/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiPreferencePage.java b/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiPreferencePage.java
index 635d5af..148d5b8 100644
--- a/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiPreferencePage.java
+++ b/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiPreferencePage.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Takashi ITOH - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.tts.sapi.preferences;
@@ -26,10 +27,12 @@
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
-
public class SapiPreferencePage extends GroupFieldEditorVoicePreferencePage
implements IWorkbenchPreferencePage {
+ private String orgVoice;
+ private String orgAudio;
+
public SapiPreferencePage() {
super();
setDescription(Messages.getString("tts.sapi.description")); //$NON-NLS-1$
@@ -37,38 +40,53 @@
}
public void createFieldEditors() {
- if(!TTSRegistry.isAvailable(SapiVoice.ID)){
- setMessage(Messages.getString("tts.sapi.notAvailable"));
- return;
- }
- final ComboFieldEditor voiceEditor, audioEditor;
- addField(voiceEditor = new SapiVoiceFieldEditor(Messages.getString("tts.sapi.voicename"), getFieldEditorParent())); //$NON-NLS-1$
- addField(audioEditor = new SapiAudioOutputFieldEditor(Messages.getString("tts.sapi.audiooutput"), getFieldEditorParent())); //$NON-NLS-1$
-
- Composite comp = new Composite(getFieldEditorParent(),SWT.NONE);
- GridLayout layout = new GridLayout();
- layout.marginHeight = layout.marginWidth = 0;
- comp.setLayout(layout);
- GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
- gd.horizontalSpan = voiceEditor.getNumberOfControls();
- comp.setLayoutData(gd);
-
- Button testButton = new Button(comp,SWT.NONE);
- testButton.setText(Messages.getString("tts.sapi.test"));
- testButton.addSelectionListener(new SelectionAdapter(){
- public void widgetSelected(SelectionEvent e) {
- int voiceIndex = voiceEditor.getComboControl().getSelectionIndex();
- int audioIndex = audioEditor.getComboControl().getSelectionIndex();
- SapiTestManager.getInstance().speakTest(voiceIndex,audioIndex);
- }
- });
+ if (!TTSRegistry.isAvailable(SapiVoice.ID)) {
+ setMessage(Messages.getString("tts.sapi.notAvailable"));
+ return;
+ }
+
+ orgVoice = getPreferenceStore().getString(SapiVoice.ID);
+ orgAudio = getPreferenceStore().getString(SapiVoice.AUDIO_OUTPUT);
+
+ final ComboFieldEditor voiceEditor, audioEditor;
+ addField(voiceEditor = new SapiVoiceFieldEditor(Messages
+ .getString("tts.sapi.voicename"), getFieldEditorParent())); //$NON-NLS-1$
+ addField(audioEditor = new SapiAudioOutputFieldEditor(Messages
+ .getString("tts.sapi.audiooutput"), getFieldEditorParent())); //$NON-NLS-1$
+
+ Composite comp = new Composite(getFieldEditorParent(), SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = layout.marginWidth = 0;
+ comp.setLayout(layout);
+ GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ gd.horizontalSpan = voiceEditor.getNumberOfControls();
+ comp.setLayoutData(gd);
+
+ Button testButton = new Button(comp, SWT.NONE);
+ testButton.setText(Messages.getString("tts.sapi.test"));
+ testButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ SapiTestManager.getInstance().speakTest();
+ }
+ });
}
- public void init(IWorkbench workbench) {
+ public void init(IWorkbench workbench) {
}
- public void dispose() {
- super.dispose();
- SapiTestManager.freeInstance();
- }
+ @Override
+ public boolean performCancel() {
+ getPreferenceStore().setValue(SapiVoice.ID, orgVoice);
+ getPreferenceStore().setValue(SapiVoice.AUDIO_OUTPUT, orgAudio);
+ return super.performCancel();
+ }
+
+ @Override
+ protected void performApply() {
+ super.performApply();
+
+ orgVoice = getPreferenceStore().getString(SapiVoice.ID);
+ orgAudio = getPreferenceStore().getString(SapiVoice.AUDIO_OUTPUT);
+ }
+
}
diff --git a/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiTestManager.java b/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiTestManager.java
index 73150be..a535b40 100644
--- a/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiTestManager.java
+++ b/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiTestManager.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Takashi ITOH - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.tts.sapi.preferences;
@@ -14,136 +15,109 @@
import java.util.ArrayList;
import java.util.List;
-import org.eclipse.actf.ai.tts.ITTSEngine;
+import org.eclipse.actf.ai.tts.ISAPIEngine;
+import org.eclipse.actf.ai.tts.TTSRegistry;
import org.eclipse.actf.ai.tts.sapi.SAPIPlugin;
import org.eclipse.actf.ai.tts.sapi.engine.SapiVoice;
import org.eclipse.actf.ai.tts.sapi.engine.SpObjectToken;
import org.eclipse.actf.ai.tts.sapi.engine.SpeechObjectTokens;
-import org.eclipse.actf.ai.voice.VoiceUtil;
import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.ole.win32.Variant;
-
-
-
public class SapiTestManager {
- private static SapiTestManager instance;
+ private static SapiTestManager instance;
- private SapiVoice sapiVoice;
- private String[][] voiceNames;
- private String[][] audioOutputNames;
+ private SapiVoice sapiVoice;
+ private String[][] voiceNames;
+ private String[][] audioOutputNames;
- private static final String SAMPLE_TEXT = "Hello. This is test."; //$NON-NLS-1$
-
- public SapiTestManager() {
- sapiVoice = new SapiVoice();
- Variant varVoices = sapiVoice.getVoices(null, null);
- if (null != varVoices) {
- SpeechObjectTokens voiceTokens = SpeechObjectTokens.getTokens(varVoices);
- if( null != voiceTokens ) {
- String exclude = Platform.getResourceString(SAPIPlugin.getDefault().getBundle(), "%voice.exclude"); //$NON-NLS-1$
- List<String[]> voiceList = new ArrayList<String[]>();
- 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);
- if( null==exclude || !exclude.equals(voiceName) ) {
- voiceList.add(new String[]{voiceName,voiceName});
- }
- }
- }
- }
- voiceNames = voiceList.toArray(new String[voiceList.size()][]);
- }
- varVoices.dispose();
- }
- Variant varAudioOutputs = sapiVoice.getAudioOutputs(null, null);
- if (null != varAudioOutputs) {
- SpeechObjectTokens audioOutputTokens = SpeechObjectTokens.getTokens(varAudioOutputs);
- if (null != audioOutputTokens) {
- List<String[]> audioOutputList = new ArrayList<String[]>();
- int count = audioOutputTokens.getCount();
- for (int i = 0; i < count; i++) {
- Variant varAudioOutput = audioOutputTokens.getItem(i);
- if (null != varAudioOutput) {
- SpObjectToken token = SpObjectToken.getToken(varAudioOutput);
- if (null != token) {
- String audioOutputName = token.getDescription(0);
- audioOutputList.add(new String[]{audioOutputName,audioOutputName});
- }
- }
- }
- audioOutputNames= audioOutputList.toArray(new String[audioOutputList.size()][]);
- }
- varAudioOutputs.dispose();
- }
- }
-
- public static SapiTestManager getInstance() {
- if( null == instance ) {
- instance = new SapiTestManager();
- }
- return instance;
- }
-
- public static void freeInstance() {
- if( null != instance ) {
- instance.dispose();
- instance = null;
- }
- }
-
- public void dispose() {
- if( null != sapiVoice ) {
- sapiVoice.dispose();
- sapiVoice = null;
- }
- }
-
- public SapiVoice getVoice() {
- return sapiVoice;
- }
-
- public String[][] getVoiceNames() {
- return voiceNames;
- }
-
- public String getVoiceName(int index) {
- if (null != voiceNames && index<voiceNames.length ) {
- return voiceNames[index][1];
- }
- return null;
- }
-
- public String[][] getAudioOutputNames() {
- return audioOutputNames;
- }
-
- public String getAudioOutputName(int index) {
- if (null != audioOutputNames && index<audioOutputNames.length) {
- return audioOutputNames[index][1];
- }
- return null;
- }
-
- public void speakTest(int voiceIndex, int audioIndex) {
- if( voiceIndex>=0 ) {
- String voiceName = getVoiceName(voiceIndex);
- if( null != voiceName ) {
- sapiVoice.setVoiceName("name="+voiceName);
- }
- }
- if( audioIndex>=0 ) {
- String audioOutputName = getAudioOutputName(audioIndex);
- if( null != audioOutputName ) {
- sapiVoice.setAudioOutputName(audioOutputName);
- }
- }
- sapiVoice.setSpeed(VoiceUtil.getDefaultSpeed());
- sapiVoice.speak(SAMPLE_TEXT, ITTSEngine.TTSFLAG_FLUSH, -1);
- }
+ private static final String SAMPLE_TEXT = "Hello. This is test."; //$NON-NLS-1$
+
+ public SapiTestManager() {
+ sapiVoice = (SapiVoice) TTSRegistry.createTTSEngine(SapiVoice.ID);
+ Variant varVoices = sapiVoice.getVoices(null, null);
+ if (null != varVoices) {
+ SpeechObjectTokens voiceTokens = SpeechObjectTokens
+ .getTokens(varVoices);
+ if (null != voiceTokens) {
+ String exclude = Platform.getResourceString(SAPIPlugin
+ .getDefault().getBundle(), "%voice.exclude"); //$NON-NLS-1$
+ List<String[]> voiceList = new ArrayList<String[]>();
+ 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);
+ if (null == exclude || !exclude.equals(voiceName)) {
+ voiceList.add(new String[] { voiceName,
+ voiceName });
+ }
+ }
+ }
+ }
+ voiceNames = voiceList.toArray(new String[voiceList.size()][]);
+ }
+ varVoices.dispose();
+ }
+ Variant varAudioOutputs = sapiVoice.getAudioOutputs(null, null);
+ if (null != varAudioOutputs) {
+ SpeechObjectTokens audioOutputTokens = SpeechObjectTokens
+ .getTokens(varAudioOutputs);
+ if (null != audioOutputTokens) {
+ List<String[]> audioOutputList = new ArrayList<String[]>();
+ int count = audioOutputTokens.getCount();
+ for (int i = 0; i < count; i++) {
+ Variant varAudioOutput = audioOutputTokens.getItem(i);
+ if (null != varAudioOutput) {
+ SpObjectToken token = SpObjectToken
+ .getToken(varAudioOutput);
+ if (null != token) {
+ String audioOutputName = token.getDescription(0);
+ audioOutputList.add(new String[] { audioOutputName,
+ audioOutputName });
+ }
+ }
+ }
+ audioOutputNames = audioOutputList
+ .toArray(new String[audioOutputList.size()][]);
+ }
+ varAudioOutputs.dispose();
+ }
+ }
+
+ public static SapiTestManager getInstance() {
+ if (null == instance) {
+ instance = new SapiTestManager();
+ }
+ return instance;
+ }
+
+ public String[][] getVoiceNames() {
+ return voiceNames;
+ }
+
+ public String getVoiceName(int index) {
+ if (null != voiceNames && index < voiceNames.length) {
+ return voiceNames[index][1];
+ }
+ return null;
+ }
+
+ public String[][] getAudioOutputNames() {
+ return audioOutputNames;
+ }
+
+ public String getAudioOutputName(int index) {
+ if (null != audioOutputNames && index < audioOutputNames.length) {
+ return audioOutputNames[index][1];
+ }
+ return null;
+ }
+
+ public void speakTest() {
+ sapiVoice.speak(SAMPLE_TEXT, ISAPIEngine.SVSFDefault);
+ }
}
diff --git a/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiVoiceFieldEditor.java b/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiVoiceFieldEditor.java
index c61c4be..70b7d91 100644
--- a/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiVoiceFieldEditor.java
+++ b/plugins/org.eclipse.actf.ai.tts.sapi/src/org/eclipse/actf/ai/tts/sapi/preferences/SapiVoiceFieldEditor.java
@@ -7,23 +7,39 @@
*
* Contributors:
* Takashi ITOH - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.tts.sapi.preferences;
+import org.eclipse.actf.ai.tts.sapi.SAPIPlugin;
import org.eclipse.actf.ai.tts.sapi.engine.SapiVoice;
import org.eclipse.actf.ai.voice.preferences.util.ComboFieldEditor;
+import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Composite;
-
-
public class SapiVoiceFieldEditor extends ComboFieldEditor {
+ private static IPreferenceStore preferenceStore = SAPIPlugin.getDefault()
+ .getPreferenceStore();
+
public SapiVoiceFieldEditor(String labelText, Composite parent) {
super(SapiVoice.ID, labelText, null, parent);
}
protected void initLabelsAndValues(String[][] labelsAndValues) {
- super.initLabelsAndValues(SapiTestManager.getInstance().getVoiceNames());
+ super
+ .initLabelsAndValues(SapiTestManager.getInstance()
+ .getVoiceNames());
}
+
+ @Override
+ protected void fireValueChanged(String property, Object oldValue,
+ Object newValue) {
+
+ preferenceStore.setValue(SapiVoice.ID, newValue.toString());
+
+ super.fireValueChanged(property, oldValue, newValue);
+ }
+
}
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
new file mode 100644
index 0000000..73ba5d4
--- /dev/null
+++ b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ISAPIEngine.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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 - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.actf.ai.tts;
+
+
+public interface ISAPIEngine extends ITTSEngine {
+
+ public static final int SVSFDefault = 0, SVSFlagsAsync = 1,
+ SVSFPurgeBeforeSpeak = 2, SVSFIsFilename = 4, SVSFIsXML = 8,
+ SVSFIsNotXML = 16, SVSFPersistXML = 32;
+
+ /**
+ * @param rate
+ * The rate property to be set.
+ * @return The invocation is succeeded then it returns true.
+ */
+ public boolean setRate(int rate);
+
+ /**
+ * @return The rate property of the voice engine.
+ */
+ public int getRate();
+
+ public void speak(String text, int sapiFlags);
+
+
+}
diff --git a/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ITTSEngine.java b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ITTSEngine.java
index a0a1667..2bf6688 100644
--- a/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ITTSEngine.java
+++ b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/ITTSEngine.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and Others
+ * Copyright (c) 2007, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* Takashi ITOH - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.tts;
@@ -74,6 +75,15 @@
public void dispose();
/**
+ * Returns <code>true</code> if the TTSEngine has been disposed, and
+ * <code>false</code> otherwise.
+ *
+ * @return <code>true</code> when the TTSEngine is disposed and
+ * <code>false</code> otherwise
+ */
+ public boolean isDisposed();
+
+ /**
* Get current speaking speed
*
* @see IVoice#getSpeed()
diff --git a/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/TTSRegistry.java b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/TTSRegistry.java
index 8efb6c1..3c143b6 100644
--- a/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/TTSRegistry.java
+++ b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/tts/TTSRegistry.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and Others
+ * Copyright (c) 2007, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* Takashi ITOH - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.tts;
@@ -29,6 +30,8 @@
private static boolean[] availables;
+ private static ITTSEngine[] INSTANCES;
+
static {
initialize();
}
@@ -55,14 +58,18 @@
}
});
availables = new boolean[ttsElements.length];
+ INSTANCES = new ITTSEngine[ttsElements.length];
for (int i = 0; i < ttsElements.length; i++) {
try {
- if (((ITTSEngine) ttsElements[i]
- .createExecutableExtension("class")).isAvailable()) {
+ ITTSEngine test = (ITTSEngine) ttsElements[i]
+ .createExecutableExtension("class");
+ if (test.isAvailable()) {
availables[i] = true;
+ INSTANCES[i] = test;
}
} catch (Exception e) {
availables[i] = false;
+ INSTANCES[i] = null;
}
}
}
@@ -126,8 +133,11 @@
try {
for (int i = 0; i < ttsElements.length; i++) {
if (id.equals(ttsElements[i].getAttribute("id"))) { //$NON-NLS-1$
- return (ITTSEngine) ttsElements[i]
- .createExecutableExtension("class"); //$NON-NLS-1$
+ if (INSTANCES[i] == null || INSTANCES[i].isDisposed()) {
+ INSTANCES[i] = (ITTSEngine) ttsElements[i]
+ .createExecutableExtension("class"); //$NON-NLS-1$
+ }
+ return INSTANCES[i];
}
}
} catch (Exception e) {
diff --git a/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/voice/internal/Voice.java b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/voice/internal/Voice.java
index 0f284fc..0218ea0 100644
--- a/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/voice/internal/Voice.java
+++ b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/voice/internal/Voice.java
@@ -134,6 +134,7 @@
*/
public void dispose() {
if( null != ttsEngine ) {
+ stop();
ttsEngine.dispose();
ttsEngine = null;
}
diff --git a/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/voice/preferences/VoicePreferencePage.java b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/voice/preferences/VoicePreferencePage.java
index 8570ad8..644a5cb 100644
--- a/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/voice/preferences/VoicePreferencePage.java
+++ b/plugins/org.eclipse.actf.ai.voice/src/org/eclipse/actf/ai/voice/preferences/VoicePreferencePage.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Takashi ITOH - initial API and implementation
+ * Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.ai.voice.preferences;
@@ -29,14 +30,13 @@
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
-
public class VoicePreferencePage extends GroupFieldEditorVoicePreferencePage
implements IWorkbenchPreferencePage {
- private static final String SAMPLE_TEXT = "Hello. This is test."; //$NON-NLS-1$
+ private static final String SAMPLE_TEXT = "Hello. This is test."; //$NON-NLS-1$
- private static IVoice voice = VoiceUtil.getVoice();
-
+ private static IVoice voice = VoiceUtil.getVoice();
+
public VoicePreferencePage() {
super();
setPreferenceStore(VoicePlugin.getDefault().getPreferenceStore());
@@ -44,46 +44,54 @@
}
public void createFieldEditors() {
- RadioGroupFieldEditor rgfe;
- String[][] labelAndIds = TTSRegistry.getLabelAndIds();
- addField(rgfe = new RadioGroupFieldEditor(IVoice.PREF_ENGINE,
- Messages.getString("voice.engine"), 1, labelAndIds, //$NON-NLS-1$
+
+ final RadioGroupFieldEditor rgfe;
+ String[][] labelAndIds = TTSRegistry.getLabelAndIds();
+ addField(rgfe = new RadioGroupFieldEditor(IVoice.PREF_ENGINE, Messages
+ .getString("voice.engine"), 1, labelAndIds, //$NON-NLS-1$
getFieldEditorParent()));
- Composite c = rgfe.getRadioBoxControl(getFieldEditorParent());
- for(int i=0; i<labelAndIds.length; i++){
- if(labelAndIds[i][1].length() == 0){
- c.getChildren()[i].setEnabled(false);
- }
- }
-
- final ScaleFieldEditor speedEditor;
- addField(speedEditor = new ScaleFieldEditor(IVoice.PREF_SPEED, Messages.getString("voice.speed"), //$NON-NLS-1$
+ Composite c = rgfe.getRadioBoxControl(getFieldEditorParent());
+ for (int i = 0; i < labelAndIds.length; i++) {
+ if (labelAndIds[i][1].length() == 0) {
+ c.getChildren()[i].setEnabled(false);
+ }
+ }
+
+ final ScaleFieldEditor speedEditor;
+ addField(speedEditor = new ScaleFieldEditor(IVoice.PREF_SPEED,
+ Messages.getString("voice.speed"), //$NON-NLS-1$
getFieldEditorParent(), IVoice.SPEED_MIN, IVoice.SPEED_MAX, 5,
25));
-
- Composite comp = new Composite(getFieldEditorParent(),SWT.NONE);
- GridLayout layout = new GridLayout();
- layout.marginHeight = layout.marginWidth = 0;
- comp.setLayout(layout);
- GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
- gd.horizontalSpan = speedEditor.getNumberOfControls();
- comp.setLayoutData(gd);
- Button testButton = new Button(comp,SWT.NONE);
- testButton.setText(Messages.getString("voice.test"));
- testButton.addSelectionListener(new SelectionAdapter(){
- public void widgetSelected(SelectionEvent e) {
- voice.setSpeed(speedEditor.getScaleControl().getSelection());
- voice.speak(SAMPLE_TEXT,true);
- }
- });
+ Composite comp = new Composite(getFieldEditorParent(), SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = layout.marginWidth = 0;
+ comp.setLayout(layout);
+ GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ gd.horizontalSpan = speedEditor.getNumberOfControls();
+ comp.setLayoutData(gd);
+
+ Button testButton = new Button(comp, SWT.NONE);
+ testButton.setText(Messages.getString("voice.test"));
+ testButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+
+ voice.setSpeed(speedEditor.getScaleControl().getSelection());
+ voice.speak(SAMPLE_TEXT, false);
+ }
+ });
}
+ @Override
+ public boolean performCancel() {
+ return super.performCancel();
+ }
+
public void init(IWorkbench workbench) {
}
public void dispose() {
super.dispose();
- ((Voice)voice).setSpeed();
+ ((Voice) voice).setSpeed();
}
}