From 60dd360640a400d9b4a602160733281d284aaee5 Mon Sep 17 00:00:00 2001 From: Charles Chen Date: Thu, 7 Jan 2010 18:56:24 -0800 Subject: [PATCH] Enabling multiple apps to use different speech synthesis engines and not interfere with one another. --- .../java/android/speech/tts/TextToSpeech.java | 120 +++++++++++------- .../src/android/tts/TtsService.java | 12 ++ 2 files changed, 83 insertions(+), 49 deletions(-) diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java index bd19f9e9c3580..bbbeb3f00a561 100755 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -129,8 +129,8 @@ public class TextToSpeech { * {@link TextToSpeech#synthesizeToFile(String, HashMap, String)} with the * {@link TextToSpeech.Engine#KEY_PARAM_UTTERANCE_ID} key. * @param utteranceId the identifier of the utterance. - */ - public void onUtteranceCompleted(String utteranceId); + */ + public void onUtteranceCompleted(String utteranceId); } @@ -285,6 +285,10 @@ public class TextToSpeech { * {@hide} */ public static final String KEY_PARAM_VARIANT = "variant"; + /** + * {@hide} + */ + public static final String KEY_PARAM_ENGINE = "engine"; /** * Parameter key to specify the audio stream type to be used when speaking text * or playing back a file. @@ -327,10 +331,16 @@ public class TextToSpeech { * {@hide} */ protected static final int PARAM_POSITION_UTTERANCE_ID = 10; + /** * {@hide} */ - protected static final int NB_CACHED_PARAMS = 6; + protected static final int PARAM_POSITION_ENGINE = 12; + + /** + * {@hide} + */ + protected static final int NB_CACHED_PARAMS = 7; } /** @@ -373,6 +383,7 @@ public class TextToSpeech { mCachedParams[Engine.PARAM_POSITION_VARIANT] = Engine.KEY_PARAM_VARIANT; mCachedParams[Engine.PARAM_POSITION_STREAM] = Engine.KEY_PARAM_STREAM; mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID] = Engine.KEY_PARAM_UTTERANCE_ID; + mCachedParams[Engine.PARAM_POSITION_ENGINE] = Engine.KEY_PARAM_ENGINE; mCachedParams[Engine.PARAM_POSITION_RATE + 1] = String.valueOf(Engine.DEFAULT_RATE); @@ -381,10 +392,10 @@ public class TextToSpeech { mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = defaultLoc.getISO3Language(); mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = defaultLoc.getISO3Country(); mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = defaultLoc.getVariant(); - mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = String.valueOf(Engine.DEFAULT_STREAM); mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = ""; + mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = Engine.DEFAULT_SYNTH; initTts(); } @@ -684,6 +695,10 @@ public class TextToSpeech { if (extra != null) { mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra; } + extra = params.get(Engine.KEY_PARAM_ENGINE); + if (extra != null) { + mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = extra; + } } result = mITts.speak(mPackageName, text, queueMode, mCachedParams); } catch (RemoteException e) { @@ -819,7 +834,7 @@ public class TextToSpeech { mStarted = false; initTts(); } finally { - return result; + return result; } } } @@ -894,7 +909,7 @@ public class TextToSpeech { mStarted = false; initTts(); } finally { - return result; + return result; } } } @@ -943,7 +958,7 @@ public class TextToSpeech { mStarted = false; initTts(); } finally { - return result; + return result; } } } @@ -990,7 +1005,7 @@ public class TextToSpeech { mStarted = false; initTts(); } finally { - return result; + return result; } } } @@ -1046,7 +1061,7 @@ public class TextToSpeech { mStarted = false; initTts(); } finally { - return result; + return result; } } } @@ -1064,7 +1079,7 @@ public class TextToSpeech { return null; } try { - String[] locStrings = mITts.getLanguage(); + String[] locStrings = mITts.getLanguage(); if ((locStrings != null) && (locStrings.length == 3)) { return new Locale(locStrings[0], locStrings[1], locStrings[2]); } else { @@ -1131,7 +1146,7 @@ public class TextToSpeech { mStarted = false; initTts(); } finally { - return result; + return result; } } } @@ -1166,6 +1181,10 @@ public class TextToSpeech { if (extra != null) { mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra; } + extra = params.get(Engine.KEY_PARAM_ENGINE); + if (extra != null) { + mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = extra; + } } if (mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename)){ result = SUCCESS; @@ -1214,19 +1233,19 @@ public class TextToSpeech { * * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ - public int setOnUtteranceCompletedListener( - final OnUtteranceCompletedListener listener) { + public int setOnUtteranceCompletedListener( + final OnUtteranceCompletedListener listener) { synchronized (mStartLock) { int result = ERROR; if (!mStarted) { return result; } mITtscallback = new ITtsCallback.Stub() { - public void utteranceCompleted(String utteranceId) throws RemoteException { - if (listener != null) { - listener.onUtteranceCompleted(utteranceId); - } - } + public void utteranceCompleted(String utteranceId) throws RemoteException { + if (listener != null) { + listener.onUtteranceCompleted(utteranceId); + } + } }; try { result = mITts.registerCallback(mPackageName, mITtscallback); @@ -1251,7 +1270,7 @@ public class TextToSpeech { } finally { return result; } - } + } } /** @@ -1262,36 +1281,39 @@ public class TextToSpeech { * * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. */ - public int setEngineByPackageName(String enginePackageName) { - synchronized (mStartLock) { - int result = TextToSpeech.ERROR; - if (!mStarted) { - return result; - } - try { - result = mITts.setEngineByPackageName(enginePackageName); - } catch (RemoteException e) { - // TTS died; restart it. - Log.e("TextToSpeech.java - setEngineByPackageName", "RemoteException"); - e.printStackTrace(); - mStarted = false; - initTts(); - } catch (NullPointerException e) { - // TTS died; restart it. - Log.e("TextToSpeech.java - setEngineByPackageName", "NullPointerException"); - e.printStackTrace(); - mStarted = false; - initTts(); - } catch (IllegalStateException e) { - // TTS died; restart it. - Log.e("TextToSpeech.java - setEngineByPackageName", "IllegalStateException"); - e.printStackTrace(); - mStarted = false; - initTts(); - } finally { - return result; - } - } + public int setEngineByPackageName(String enginePackageName) { + synchronized (mStartLock) { + int result = TextToSpeech.ERROR; + if (!mStarted) { + return result; + } + try { + result = mITts.setEngineByPackageName(enginePackageName); + if (result == TextToSpeech.SUCCESS){ + mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = enginePackageName; + } + } catch (RemoteException e) { + // TTS died; restart it. + Log.e("TextToSpeech.java - setEngineByPackageName", "RemoteException"); + e.printStackTrace(); + mStarted = false; + initTts(); + } catch (NullPointerException e) { + // TTS died; restart it. + Log.e("TextToSpeech.java - setEngineByPackageName", "NullPointerException"); + e.printStackTrace(); + mStarted = false; + initTts(); + } catch (IllegalStateException e) { + // TTS died; restart it. + Log.e("TextToSpeech.java - setEngineByPackageName", "IllegalStateException"); + e.printStackTrace(); + mStarted = false; + initTts(); + } finally { + return result; + } + } } } diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java index 23365c91c8875..1efa5a3e51798 100755 --- a/packages/TtsService/src/android/tts/TtsService.java +++ b/packages/TtsService/src/android/tts/TtsService.java @@ -744,6 +744,7 @@ public class TtsService extends Service implements OnCompletionListener { String country = ""; String variant = ""; String speechRate = ""; + String engine = ""; if (speechItem.mParams != null){ for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){ String param = speechItem.mParams.get(i); @@ -765,12 +766,17 @@ public class TtsService extends Service implements OnCompletionListener { } catch (NumberFormatException e) { streamType = DEFAULT_STREAM_TYPE; } + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_ENGINE)) { + engine = speechItem.mParams.get(i + 1); } } } } // Only do the synthesis if it has not been killed by a subsequent utterance. if (mKillList.get(speechItem) == null) { + if (engine.length() > 0) { + setEngine(engine); + } if (language.length() > 0){ setLanguage("", language, country, variant); } @@ -825,6 +831,7 @@ public class TtsService extends Service implements OnCompletionListener { String country = ""; String variant = ""; String speechRate = ""; + String engine = ""; if (speechItem.mParams != null){ for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){ String param = speechItem.mParams.get(i); @@ -839,12 +846,17 @@ public class TtsService extends Service implements OnCompletionListener { variant = speechItem.mParams.get(i+1); } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)){ utteranceId = speechItem.mParams.get(i+1); + } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_ENGINE)) { + engine = speechItem.mParams.get(i + 1); } } } } // Only do the synthesis if it has not been killed by a subsequent utterance. if (mKillList.get(speechItem) == null){ + if (engine.length() > 0) { + setEngine(engine); + } if (language.length() > 0){ setLanguage("", language, country, variant); }