TextToSpeech.java revision 62253a319d6359ce71c547d0b0aa36ba17789ab4
1e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi/*
2e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * Copyright (C) 2009 Google Inc.
3e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi *
4e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * use this file except in compliance with the License. You may obtain a copy of
6e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * the License at
7e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi *
8e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0
9e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi *
10e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * License for the specific language governing permissions and limitations under
14e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * the License.
15e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi */
1621a6a6d26baf32593d63226f9728ddd66f0bd571Jean-Michel Trivipackage android.speech.tts;
1721a6a6d26baf32593d63226f9728ddd66f0bd571Jean-Michel Trivi
18f85aa5a4d4e6f1ef7e07638568e27d709b8085c6Charles Chenimport android.speech.tts.ITts;
19f85aa5a4d4e6f1ef7e07638568e27d709b8085c6Charles Chenimport android.speech.tts.ITtsCallback;
20e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
21e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.content.ComponentName;
22e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.content.Context;
23e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.content.Intent;
24e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.content.ServiceConnection;
25a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Triviimport android.media.AudioManager;
26e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.os.IBinder;
27e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.os.RemoteException;
28e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.util.Log;
29e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
30a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Triviimport java.util.HashMap;
31679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Triviimport java.util.Locale;
32a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi
33e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi/**
34e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi *
3562788e9b48f884a35b89c88911b581daa6a14e08Jean-Michel Trivi * Synthesizes speech from text for immediate playback or to create a sound file.
36e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi *
37e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi */
3862788e9b48f884a35b89c88911b581daa6a14e08Jean-Michel Trivi//TODO complete javadoc + add links to constants
39a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivipublic class TextToSpeech {
40e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
4191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    /**
4291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * Denotes a successful operation.
4391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     */
4491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    public static final int TTS_SUCCESS                = 0;
4591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    /**
4691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * Denotes a generic operation failure.
4791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     */
4891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    public static final int TTS_ERROR                  = -1;
4991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi
50679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    /**
51679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * Queue mode where all entries in the playback queue (media to be played
52679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * and text to be synthesized) are dropped and replaced by the new entry.
53679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     */
54679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    public static final int TTS_QUEUE_FLUSH = 0;
55679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    /**
56679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * Queue mode where the new entry is added at the end of the playback queue.
57679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     */
58679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    public static final int TTS_QUEUE_ADD = 1;
59e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
60aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
61aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
62aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     * Denotes the language is available exactly as specified by the locale
63aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
64aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    public static final int TTS_LANG_COUNTRY_VAR_AVAILABLE = 2;
65aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
66aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
67aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
68aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     * Denotes the language is available for the language and country specified
69aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     * by the locale, but not the variant.
70aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
71aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    public static final int TTS_LANG_COUNTRY_AVAILABLE = 1;
72aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
73aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
74aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
75aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     * Denotes the language is available for the language by the locale,
76aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     * but not the country and variant.
77aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
78aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    public static final int TTS_LANG_AVAILABLE = 0;
79aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
80aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
81aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     * Denotes the language data is missing.
82aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
83aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    public static final int TTS_LANG_MISSING_DATA = -1;
84aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
85aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
86aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     * Denotes the language is not supported by the current TTS engine.
87aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
88aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    public static final int TTS_LANG_NOT_SUPPORTED = -2;
89aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
90aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
91e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
92679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * Called when the TTS has initialized.
93e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
9491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * The InitListener must implement the onInit function. onInit is passed a
9591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * status code indicating the result of the TTS initialization.
96e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
97e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public interface OnInitListener {
9891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        public void onInit(int status);
99e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
100e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
101e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
10278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     * Called when the TTS has completed saying something that has an utterance ID set.
10378c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     *
10478c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     * The OnUtteranceCompletedListener must implement the onUtteranceCompleted function.
10578c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     * onUtteranceCompleted is passed a String that is the utteranceId given in
10678c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     * the original speak call.
10778c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     */
10878c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    public interface OnUtteranceCompletedListener {
10978c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen        public void onUtteranceCompleted(String utteranceId);
11078c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    }
11178c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen
11278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen
11378c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    /**
114d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi     * Internal constants for the TTS functionality
115d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi     *
116d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi     */
117d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi    public class Engine {
118d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        // default values for a TTS engine when settings are not found in the provider
11962253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
12062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
12162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
122d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int FALLBACK_TTS_DEFAULT_RATE = 100; // 1x
12362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
12462253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
12562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
126d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int FALLBACK_TTS_DEFAULT_PITCH = 100;// 1x
12762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
12862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
12962253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
130d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int FALLBACK_TTS_USE_DEFAULTS = 0; // false
13162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
13262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
13362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
134e28aced7bb96b086b16df82ff9c75b08671eb7dfJean-Michel Trivi        public static final String FALLBACK_TTS_DEFAULT_SYNTH = "com.svox.pico";
135d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi
136a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        // default values for rendering
137a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        public static final int TTS_DEFAULT_STREAM = AudioManager.STREAM_MUSIC;
138a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi
139d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        // return codes for a TTS engine's check data activity
14062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
14162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Indicates success when checking the installation status of the resources used by the
14262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
14362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
144d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_PASS = 1;
14562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
14662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Indicates failure when checking the installation status of the resources used by the
14762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
14862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
149d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_FAIL = 0;
15062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
15162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Indicates erroneous data when checking the installation status of the resources used by
15262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
15362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
154d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_BAD_DATA = -1;
15562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
15662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Indicates missing resources when checking the installation status of the resources used
15762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * by the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
15862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
159d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_MISSING_DATA = -2;
16062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
16162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Indicates missing storage volume when checking the installation status of the resources
16262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * used by the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
16362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
16462253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_MISSING_VOLUME = -3;
16599a0feecd0f0aad314d7a4637d329b8a9e8c1150Charles Chen
16699a0feecd0f0aad314d7a4637d329b8a9e8c1150Charles Chen        // return codes for a TTS engine's check data activity
16762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
16862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
16962253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * the text-to-speech engine specifies the path to its resources.
17062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
17199a0feecd0f0aad314d7a4637d329b8a9e8c1150Charles Chen        public static final String VOICE_DATA_ROOT_DIRECTORY = "dataRoot";
17262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
17362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
17462253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * the text-to-speech engine specifies the file names of its resources under the
17562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * resource path.
17662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
17799a0feecd0f0aad314d7a4637d329b8a9e8c1150Charles Chen        public static final String VOICE_DATA_FILES = "dataFiles";
17862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
17962253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
18062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * the text-to-speech engine specifies the locale associated with each resource file.
18162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
18299a0feecd0f0aad314d7a4637d329b8a9e8c1150Charles Chen        public static final String VOICE_DATA_FILES_INFO = "dataFilesInfo";
18399a0feecd0f0aad314d7a4637d329b8a9e8c1150Charles Chen
18462253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        // keys for the parameters passed with speak commands. Hidden keys are used internally
18562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        // to maintain engine state for each TextToSpeech instance.
18662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
18762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
18862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
18987c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi        public static final String TTS_KEY_PARAM_RATE = "rate";
19062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
19162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
19262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
19387c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi        public static final String TTS_KEY_PARAM_LANGUAGE = "language";
19462253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
19562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
19662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
19787c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi        public static final String TTS_KEY_PARAM_COUNTRY = "country";
19862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
19962253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
20062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
20187c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi        public static final String TTS_KEY_PARAM_VARIANT = "variant";
20262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
20362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Parameter key to specify the audio stream type to be used when speaking text
20462253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * or playing back a file.
20562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
206a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        public static final String TTS_KEY_PARAM_STREAM = "streamType";
20762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
20862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Parameter key to identify an utterance in the completion listener after text has been
20962253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * spoken, a file has been played back or a silence duration has elapsed.
21062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
211a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        public static final String TTS_KEY_PARAM_UTTERANCE_ID = "utteranceId";
21262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi
21362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        // key positions in the array of cached parameters
21462253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
21562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
21662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
217a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        protected static final int TTS_PARAM_POSITION_RATE = 0;
21862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
21962253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
22062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
221a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        protected static final int TTS_PARAM_POSITION_LANGUAGE = 2;
22262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
22362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
22462253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
225a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        protected static final int TTS_PARAM_POSITION_COUNTRY = 4;
22662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
22762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
22862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
229a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        protected static final int TTS_PARAM_POSITION_VARIANT = 6;
23062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
23162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
23262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
233a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        protected static final int TTS_PARAM_POSITION_STREAM = 8;
23462253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
23562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
23662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
237a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        protected static final int TTS_PARAM_POSITION_UTTERANCE_ID = 10;
23862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
23962253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * {@hide}
24062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
241a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        protected static final int TTS_NB_CACHED_PARAMS = 6;
242d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi    }
243d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi
244d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi    /**
245679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * Connection needed for the TTS.
246e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
247679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    private ServiceConnection mServiceConnection;
248e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
24991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private ITts mITts = null;
25078c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    private ITtsCallback mITtscallback = null;
25191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private Context mContext = null;
252a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen    private String mPackageName = "";
25391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private OnInitListener mInitListener = null;
25491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private boolean mStarted = false;
25591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private final Object mStartLock = new Object();
256da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi    /**
257da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi     * Used to store the cached parameters sent along with each synthesis request to the
258da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi     * TTS service.
259da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi     */
26087c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi    private String[] mCachedParams;
261e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
262e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
263e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * The constructor for the TTS.
264e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
265e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param context
266e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The context
26791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * @param listener
26891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     *            The InitListener that will be called when the TTS has
269e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            initialized successfully.
270e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
27191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    public TextToSpeech(Context context, OnInitListener listener) {
27291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        mContext = context;
273a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen        mPackageName = mContext.getPackageName();
27491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        mInitListener = listener;
27587c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi
276a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        mCachedParams = new String[2*Engine.TTS_NB_CACHED_PARAMS]; // store key and value
27787c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_RATE] = Engine.TTS_KEY_PARAM_RATE;
27887c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE] = Engine.TTS_KEY_PARAM_LANGUAGE;
27987c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY] = Engine.TTS_KEY_PARAM_COUNTRY;
28087c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT] = Engine.TTS_KEY_PARAM_VARIANT;
281a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_STREAM] = Engine.TTS_KEY_PARAM_STREAM;
28278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID] = Engine.TTS_KEY_PARAM_UTTERANCE_ID;
28387c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi
284da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] =
285da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi                String.valueOf(Engine.FALLBACK_TTS_DEFAULT_RATE);
286da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi        // initialize the language cached parameters with the current Locale
287da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi        Locale defaultLoc = Locale.getDefault();
288da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = defaultLoc.getISO3Language();
289da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = defaultLoc.getISO3Country();
290da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = defaultLoc.getVariant();
291e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
292a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] =
293a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                String.valueOf(Engine.TTS_DEFAULT_STREAM);
29478c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = "";
295a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi
296da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi        initTts();
297e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
298e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
299e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
300e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    private void initTts() {
30191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        mStarted = false;
302e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
303e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        // Initialize the TTS, run the callback after the binding is successful
304679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi        mServiceConnection = new ServiceConnection() {
305e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            public void onServiceConnected(ComponentName name, IBinder service) {
30691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                synchronized(mStartLock) {
30791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    mITts = ITts.Stub.asInterface(service);
30891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    mStarted = true;
30991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    if (mInitListener != null) {
31091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                        // TODO manage failures and missing resources
31191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                        mInitListener.onInit(TTS_SUCCESS);
312e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                    }
313e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                }
314e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
315e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
316e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            public void onServiceDisconnected(ComponentName name) {
31791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                synchronized(mStartLock) {
31891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    mITts = null;
31991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    mInitListener = null;
32091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    mStarted = false;
321e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                }
322e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
323e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        };
324e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
32552ae06521a8d4c48757b126cff233f037d0a16baCharles Chen        Intent intent = new Intent("android.intent.action.START_TTS_SERVICE");
326e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        intent.addCategory("android.intent.category.TTS");
327679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi        mContext.bindService(intent, mServiceConnection,
32891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                Context.BIND_AUTO_CREATE);
329a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi        // TODO handle case where the binding works (should always work) but
330a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi        //      the plugin fails
331e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
332e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
333e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
334e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
335e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Shuts down the TTS. It is good practice to call this in the onDestroy
336e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * method of the Activity that is using the TTS so that the TTS is stopped
337e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * cleanly.
338e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
339e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public void shutdown() {
340e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        try {
341679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi            mContext.unbindService(mServiceConnection);
342e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        } catch (IllegalArgumentException e) {
343e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            // Do nothing and fail silently since an error here indicates that
344e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            // binding never succeeded in the first place.
345e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
346e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
347e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
348e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
349e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
350e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Adds a mapping between a string of text and a sound resource in a
351e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * package.
352e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
353e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @see #TTS.speak(String text, int queueMode, String[] params)
354e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
355e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param text
356e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            Example: <b><code>"south_south_east"</code></b><br/>
357e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
358e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param packagename
359e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            Pass the packagename of the application that contains the
360e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            resource. If the resource is in your own application (this is
361e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            the most common case), then put the packagename of your
362e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            application here.<br/>
363e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            Example: <b>"com.google.marvin.compass"</b><br/>
364e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The packagename can be found in the AndroidManifest.xml of
365e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            your application.
366e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            <p>
367e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            <code>&lt;manifest xmlns:android=&quot;...&quot;
368e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *      package=&quot;<b>com.google.marvin.compass</b>&quot;&gt;</code>
369e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            </p>
370e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
371e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param resourceId
372e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            Example: <b><code>R.raw.south_south_east</code></b>
3735c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
3745c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
375e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
3765c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int addSpeech(String text, String packagename, int resourceId) {
37791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized(mStartLock) {
37891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
3795c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen                return TTS_ERROR;
380e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
381e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
382a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen                mITts.addSpeech(mPackageName, text, packagename, resourceId);
3835c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen                return TTS_SUCCESS;
384e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
385e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
386630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - addSpeech", "RemoteException");
387630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
38891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
389e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
390e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
391e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
392630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - addSpeech", "NullPointerException");
393630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
39491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
395e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
396e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
397e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
398630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - addSpeech", "IllegalStateException");
399630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
40091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
401e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
402e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
4035c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen            return TTS_ERROR;
404e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
405e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
406e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
407e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
408e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
409e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Adds a mapping between a string of text and a sound file. Using this, it
410e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * is possible to add custom pronounciations for text.
411e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
412e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param text
413e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The string of text
414e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param filename
415e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The full path to the sound file (for example:
416e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            "/sdcard/mysounds/hello.wav")
4175c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
4185c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
419e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
4205c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int addSpeech(String text, String filename) {
42191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
42291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
4235c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen                return TTS_ERROR;
424e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
425e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
426a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen                mITts.addSpeechFile(mPackageName, text, filename);
4275c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen                return TTS_SUCCESS;
428e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
429e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
430630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - addSpeech", "RemoteException");
431630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
43291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
433e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
434e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
435e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
436630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - addSpeech", "NullPointerException");
437630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
43891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
439e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
440e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
441e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
442630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - addSpeech", "IllegalStateException");
443630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
44491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
445e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
446e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
4475c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen            return TTS_ERROR;
448e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
449e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
450e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
451e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
452e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
453e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Speaks the string using the specified queuing strategy and speech
454e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * parameters. Note that the speech parameters are not universally supported
455e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * by all engines and will be treated as a hint. The TTS library will try to
456e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * fulfill these parameters as much as possible, but there is no guarantee
457e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * that the voice used will have the properties specified.
458e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
459e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param text
460e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The string of text to be spoken.
461e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param queueMode
462679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            The queuing strategy to use.
463679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
464e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param params
465a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi     *            The hashmap of speech parameters to be used.
4665c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
4675c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
468e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
4695c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int speak(String text, int queueMode, HashMap<String,String> params)
470a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi    {
47191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
472c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            int result = TTS_ERROR;
473e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            Log.i("TTS received: ", text);
47491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
475c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                return result;
476e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
477e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
478630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                if ((params != null) && (!params.isEmpty())) {
479630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                    String extra = params.get(Engine.TTS_KEY_PARAM_STREAM);
480630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                    if (extra != null) {
481630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                        mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = extra;
482630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                    }
483630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                    extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
484630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                    if (extra != null) {
48578c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
486630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                    }
487a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                }
488a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen                result = mITts.speak(mPackageName, text, queueMode, mCachedParams);
489e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
490e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
491630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - speak", "RemoteException");
492630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
49391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
494e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
495e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
496e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
497630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - speak", "NullPointerException");
498630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
49991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
500e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
501e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
502e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
503630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - speak", "IllegalStateException");
504630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
50591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
506e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
507c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            } finally {
508a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                resetCachedParams();
509a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                return result;
510e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
511e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
512e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
513e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
514e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
515e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
516e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Plays the earcon using the specified queueing mode and parameters.
517e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
518e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param earcon
519e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The earcon that should be played
520e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param queueMode
521679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
522e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param params
523a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi     *            The hashmap of parameters to be used.
5245c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
5255c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
526e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
5275c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int playEarcon(String earcon, int queueMode,
528a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi            HashMap<String,String> params) {
52991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
530c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            int result = TTS_ERROR;
53191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
532c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                return result;
533e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
534e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
535a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                if ((params != null) && (!params.isEmpty())) {
536a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                    String extra = params.get(Engine.TTS_KEY_PARAM_STREAM);
537a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                    if (extra != null) {
538a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                        mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = extra;
539a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                    }
540a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                    extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
541a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                    if (extra != null) {
54278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
543a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                    }
544a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                }
545a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen                result = mITts.playEarcon(mPackageName, earcon, queueMode, null);
546e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
547e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
548630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - playEarcon", "RemoteException");
549630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
55091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
551e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
552e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
553e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
554630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - playEarcon", "NullPointerException");
555630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
55691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
557e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
558e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
559e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
560630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - playEarcon", "IllegalStateException");
561630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
56291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
563e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
564c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            } finally {
565a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                resetCachedParams();
566a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                return result;
567e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
568e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
569e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
570679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi
5715c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    /**
5725c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * Plays silence for the specified amount of time using the specified
5735c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * queue mode.
5745c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
5755c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * @param durationInMs
5765c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *            A long that indicates how long the silence should last.
5775c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * @param queueMode
5785c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
5795c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
5805c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
5815c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     */
58278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    public int playSilence(long durationInMs, int queueMode, HashMap<String,String> params) {
583f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen        synchronized (mStartLock) {
584c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            int result = TTS_ERROR;
585f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen            if (!mStarted) {
586c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                return result;
587f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen            }
588f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen            try {
58978c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                if ((params != null) && (!params.isEmpty())) {
59078c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                    String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
59178c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                    if (extra != null) {
59278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
59378c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                    }
59478c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                }
595a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen                result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams);
596f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen            } catch (RemoteException e) {
597f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen                // TTS died; restart it.
598630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - playSilence", "RemoteException");
599630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
600f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen                mStarted = false;
601f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen                initTts();
602f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen            } catch (NullPointerException e) {
603f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen                // TTS died; restart it.
604630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - playSilence", "NullPointerException");
605630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
606f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen                mStarted = false;
607f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen                initTts();
608f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen            } catch (IllegalStateException e) {
609f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen                // TTS died; restart it.
610630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - playSilence", "IllegalStateException");
611630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
612f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen                mStarted = false;
613f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen                initTts();
614c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            } finally {
615c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen              return result;
616f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen            }
617f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen        }
618a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi    }
619e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
620e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
621e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
622e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Returns whether or not the TTS is busy speaking.
623e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
624e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @return Whether or not the TTS is busy speaking.
625e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
626e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public boolean isSpeaking() {
62791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
62891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
629e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                return false;
630e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
631e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
63291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                return mITts.isSpeaking();
633e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
634e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
635630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - isSpeaking", "RemoteException");
636630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
63791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
638e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
639e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
640e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
641630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - isSpeaking", "NullPointerException");
642630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
64391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
644e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
645e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
646e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
647630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - isSpeaking", "IllegalStateException");
648630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
64991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
650e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
651e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
652e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            return false;
653e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
654e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
655e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
656e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
657e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
658e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Stops speech from the TTS.
6595c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
6605c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
661e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
6625c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int stop() {
66391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
664c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            int result = TTS_ERROR;
66591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
666c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                return result;
667e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
668e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
669a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen                result = mITts.stop(mPackageName);
670e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
671e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
672630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - stop", "RemoteException");
673630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
67491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
675e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
676e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
677e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
678630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - stop", "NullPointerException");
679630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
68091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
681e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
682e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
683e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
684630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - stop", "IllegalStateException");
685630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
68691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
687e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
688c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            } finally {
689c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen              return result;
690e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
691e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
692e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
693e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
694e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
695e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
696e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Sets the speech rate for the TTS engine.
697e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
698e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Note that the speech rate is not universally supported by all engines and
699e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * will be treated as a hint. The TTS library will try to use the specified
700e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * speech rate, but there is no guarantee.
701679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * This has no effect on any pre-recorded speech.
702e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
703e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param speechRate
704679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            The speech rate for the TTS engine. 1 is the normal speed,
705679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            lower values slow down the speech (0.5 is half the normal speech rate),
706679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            greater values accelerate it (2 is twice the normal speech rate).
7075c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
7085c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
709e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
7105c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int setSpeechRate(float speechRate) {
71191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
712c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            int result = TTS_ERROR;
71391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
714c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                return result;
715e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
716e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
717679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi                if (speechRate > 0) {
718da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi                    int rate = (int)(speechRate*100);
719da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi                    mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] = String.valueOf(rate);
720a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen                    result = mITts.setSpeechRate(mPackageName, rate);
721679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi                }
722e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
723e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
724630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - setSpeechRate", "RemoteException");
725630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
726630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                mStarted = false;
727630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                initTts();
728630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen            } catch (NullPointerException e) {
729630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                // TTS died; restart it.
730630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - setSpeechRate", "NullPointerException");
731630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
732630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                mStarted = false;
733630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                initTts();
734630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen            } catch (IllegalStateException e) {
735630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                // TTS died; restart it.
736630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - setSpeechRate", "IllegalStateException");
737630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
73891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
739e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
740c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            } finally {
741c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen              return result;
742e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
743e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
744e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
745e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
746e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
747e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
7482ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     * Sets the speech pitch for the TTS engine.
7492ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     *
7502ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     * Note that the pitch is not universally supported by all engines and
7512ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     * will be treated as a hint. The TTS library will try to use the specified
7522ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     * pitch, but there is no guarantee.
7532ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     * This has no effect on any pre-recorded speech.
7542ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     *
7552ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     * @param pitch
7562ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     *            The pitch for the TTS engine. 1 is the normal pitch,
7572ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     *            lower values lower the tone of the synthesized voice,
7582ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     *            greater values increase it.
7595c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
7605c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
7612ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     */
7625c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int setPitch(float pitch) {
7632ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi        synchronized (mStartLock) {
764c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            int result = TTS_ERROR;
7652ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi            if (!mStarted) {
766c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                return result;
7672ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi            }
7682ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi            try {
7692ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi                if (pitch > 0) {
770a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen                    result = mITts.setPitch(mPackageName, (int)(pitch*100));
7712ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi                }
7722ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi            } catch (RemoteException e) {
7732ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi                // TTS died; restart it.
774630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - setPitch", "RemoteException");
775630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
776630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                mStarted = false;
777630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                initTts();
778630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen            } catch (NullPointerException e) {
779630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                // TTS died; restart it.
780630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - setPitch", "NullPointerException");
781630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
782630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                mStarted = false;
783630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                initTts();
784630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen            } catch (IllegalStateException e) {
785630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                // TTS died; restart it.
786630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - setPitch", "IllegalStateException");
787630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
7882ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi                mStarted = false;
7892ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi                initTts();
790c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            } finally {
791c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen              return result;
7922ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi            }
7932ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi        }
7942ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi    }
7952ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi
7962ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi
7972ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi    /**
798e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Sets the language for the TTS engine.
799e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
800e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Note that the language is not universally supported by all engines and
801e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * will be treated as a hint. The TTS library will try to use the specified
802679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * language as represented by the Locale, but there is no guarantee.
803e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
804679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * @param loc
805679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            The locale describing the language to be used.
8065c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
807c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen     * @return Code indicating the support status for the locale. See the TTS_LANG_ codes.
808e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
8095c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int setLanguage(Locale loc) {
81091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
811c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            int result = TTS_LANG_NOT_SUPPORTED;
81291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
813c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                return result;
814e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
815e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
816da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi                mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language();
817da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi                mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country();
818da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi                mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = loc.getVariant();
819a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen                result = mITts.setLanguage(mPackageName,
820a9c5e4bf2639f8f09be8bace4230613b7b689f0eCharles Chen                        mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1],
821da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi                        mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1],
822da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi                        mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] );
823748efcc3fb1b369690ab4617a04f452b1832edf4Charles Chen            } catch (RemoteException e) {
824e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
825630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - setLanguage", "RemoteException");
826630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
827630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                mStarted = false;
828630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                initTts();
829630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen            } catch (NullPointerException e) {
830630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                // TTS died; restart it.
831630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - setLanguage", "NullPointerException");
832630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
833630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                mStarted = false;
834630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                initTts();
835630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen            } catch (IllegalStateException e) {
836630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                // TTS died; restart it.
837630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - setLanguage", "IllegalStateException");
838630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
83991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
840e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
841c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            } finally {
842c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen              return result;
843e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
844e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
845e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
846e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
8475c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen
848aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
849ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi     * Returns a Locale instance describing the language currently being used by the TTS engine.
850ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi     * @return language, country (if any) and variant (if any) used by the engine stored in a Locale
851ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi     *     instance, or null is the TTS engine has failed.
852ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi     */
853ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi    public Locale getLanguage() {
854ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi        synchronized (mStartLock) {
855ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            if (!mStarted) {
856ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                return null;
857ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            }
858ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            try {
859ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                String[] locStrings =  mITts.getLanguage();
860ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                if (locStrings.length == 3) {
861ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                    return new Locale(locStrings[0], locStrings[1], locStrings[2]);
862ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                } else {
863ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                    return null;
864ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                }
865ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            } catch (RemoteException e) {
866ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                // TTS died; restart it.
867630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - getLanguage", "RemoteException");
868630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
869630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                mStarted = false;
870630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                initTts();
871630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen            } catch (NullPointerException e) {
872630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                // TTS died; restart it.
873630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - getLanguage", "NullPointerException");
874630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
875630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                mStarted = false;
876630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                initTts();
877630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen            } catch (IllegalStateException e) {
878630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                // TTS died; restart it.
879630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - getLanguage", "IllegalStateException");
880630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
881ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                mStarted = false;
882ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                initTts();
883ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            }
884ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            return null;
885ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi        }
886ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi    }
887ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi
888ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi    /**
889ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi     * Checks if the specified language as represented by the Locale is available.
890aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     *
891aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     * @param loc
892ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi     *            The Locale describing the language to be used.
8935c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
89487c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi     * @return one of TTS_LANG_NOT_SUPPORTED, TTS_LANG_MISSING_DATA, TTS_LANG_AVAILABLE,
8955c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *         TTS_LANG_COUNTRY_AVAILABLE, TTS_LANG_COUNTRY_VAR_AVAILABLE.
896aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
897aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    public int isLanguageAvailable(Locale loc) {
898ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi        synchronized (mStartLock) {
899c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            int result = TTS_LANG_NOT_SUPPORTED;
900ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            if (!mStarted) {
901c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                return result;
902ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            }
903ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            try {
904c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                result = mITts.isLanguageAvailable(loc.getISO3Language(),
905c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                        loc.getISO3Country(), loc.getVariant());
906ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            } catch (RemoteException e) {
907ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                // TTS died; restart it.
908630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - isLanguageAvailable", "RemoteException");
909630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
910630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                mStarted = false;
911630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                initTts();
912630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen            } catch (NullPointerException e) {
913630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                // TTS died; restart it.
914630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - isLanguageAvailable", "NullPointerException");
915630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
916630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                mStarted = false;
917630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                initTts();
918630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen            } catch (IllegalStateException e) {
919630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                // TTS died; restart it.
920630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - isLanguageAvailable", "IllegalStateException");
921630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
922ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                mStarted = false;
923ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi                initTts();
924c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            } finally {
925c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen              return result;
926ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            }
927ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi        }
928aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    }
929aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
930aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
931e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
932d4989093ed708ddf9c799655ea0af7afda726426Charles Chen     * Synthesizes the given text to a file using the specified parameters.
933e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
934e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param text
935e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The String of text that should be synthesized
936e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param params
937a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi     *            A hashmap of parameters.
938e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param filename
939e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The string that gives the full output filename; it should be
940e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            something like "/sdcard/myappsounds/mysound.wav".
9415c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
9425c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
943e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
9445c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int synthesizeToFile(String text, HashMap<String,String> params,
945e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            String filename) {
94691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
947c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            int result = TTS_ERROR;
94891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
949c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                return result;
950e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
951e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
952630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                if ((params != null) && (!params.isEmpty())) {
953630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                    // no need to read the stream type here
954630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                    String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
955630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                    if (extra != null) {
95678c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
957630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                    }
958a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                }
959a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                if (mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename)){
960c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen                    result = TTS_SUCCESS;
9615c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen                }
962e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
963e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
964630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - synthesizeToFile", "RemoteException");
965630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
96691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
967e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
968e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
969e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
970630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - synthesizeToFile", "NullPointerException");
971630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
97291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
973e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
974e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
975e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
976630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                Log.e("TextToSpeech.java - synthesizeToFile", "IllegalStateException");
977630a8de44fa0ca855c4a87d939432f831e8ed531Charles Chen                e.printStackTrace();
97891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
979e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
980c8ba3b560ce0ce5944939a50d61f639fdcaa0015Charles Chen            } finally {
981a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                resetCachedParams();
982a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                return result;
983e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
984e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
985e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
986e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
987a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi
988a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi    /**
989a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi     * Convenience method to reset the cached parameters to the current default values
990a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi     * if they are not persistent between calls to the service.
991a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi     */
992a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi    private void resetCachedParams() {
993a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] =
994a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                String.valueOf(Engine.TTS_DEFAULT_STREAM);
995a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID+ 1] = "";
996a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi    }
997a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi
99878c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    /**
99978c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     * Sets the OnUtteranceCompletedListener that will fire when an utterance completes.
100078c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     *
100178c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     * @param listener
100278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     *            The OnUtteranceCompletedListener
100378c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     *
100478c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
100578c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     */
100678c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    public int setOnUtteranceCompletedListener(
100778c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            final OnUtteranceCompletedListener listener) {
100878c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen        synchronized (mStartLock) {
100978c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            int result = TTS_ERROR;
101078c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            if (!mStarted) {
101178c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                return result;
101278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            }
101378c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            mITtscallback = new ITtsCallback.Stub() {
101478c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                public void utteranceCompleted(String utteranceId) throws RemoteException {
101578c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                    if (listener != null) {
101678c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                        listener.onUtteranceCompleted(utteranceId);
101778c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                    }
101878c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                }
101978c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            };
102078c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            try {
102178c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                result = mITts.registerCallback(mPackageName, mITtscallback);
102278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            } catch (RemoteException e) {
102378c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                // TTS died; restart it.
102478c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                Log.e("TextToSpeech.java - registerCallback", "RemoteException");
102578c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                e.printStackTrace();
102678c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                mStarted = false;
102778c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                initTts();
102878c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            } catch (NullPointerException e) {
102978c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                // TTS died; restart it.
103078c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                Log.e("TextToSpeech.java - registerCallback", "NullPointerException");
103178c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                e.printStackTrace();
103278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                mStarted = false;
103378c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                initTts();
103478c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            } catch (IllegalStateException e) {
103578c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                // TTS died; restart it.
103678c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                Log.e("TextToSpeech.java - registerCallback", "IllegalStateException");
103778c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                e.printStackTrace();
103878c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                mStarted = false;
103978c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                initTts();
104078c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            } finally {
104178c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen                return result;
104278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen            }
104378c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen        }
104478c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    }
104578c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen
1046e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi}
1047