TextToSpeech.java revision d146874d7341bc9602c93719582b4209e7b81f01
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;
25e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.os.IBinder;
26e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.os.RemoteException;
27e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.util.Log;
28e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
29a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Triviimport java.util.HashMap;
30679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Triviimport java.util.Locale;
31a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi
32e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi/**
33e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi *
34a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi * Synthesizes speech from text.
35e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi *
36f85aa5a4d4e6f1ef7e07638568e27d709b8085c6Charles Chen * {@hide}
37e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi */
38679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi//TODO #TTS# review + 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    /**
5091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * Denotes a failure due to a missing resource.
5191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     */
5291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    public static final int TTS_ERROR_MISSING_RESOURCE = -2;
5391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi
54679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    /**
55679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * Queue mode where all entries in the playback queue (media to be played
56679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * and text to be synthesized) are dropped and replaced by the new entry.
57679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     */
58679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    public static final int TTS_QUEUE_FLUSH = 0;
59679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    /**
60679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * Queue mode where the new entry is added at the end of the playback queue.
61679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     */
62679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    public static final int TTS_QUEUE_ADD = 1;
63e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
64e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
65679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * Called when the TTS has initialized.
66e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
6791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * The InitListener must implement the onInit function. onInit is passed a
6891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * status code indicating the result of the TTS initialization.
69e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
70e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public interface OnInitListener {
7191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        public void onInit(int status);
72e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
73e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
74e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
75e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Called when the TTS has finished speaking by itself (speaking
76e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * finished without being canceled).
77e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
78e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
79e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public interface OnSpeechCompletedListener {
80e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        public void onSpeechCompleted();
81e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
82e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
83e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
84d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi     * Internal constants for the TTS functionality
85d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi     *
86d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi     * {@hide}
87d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi     */
88d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi    public class Engine {
89d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        // default values for a TTS engine when settings are not found in the provider
90d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int FALLBACK_TTS_DEFAULT_RATE = 100; // 1x
91d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int FALLBACK_TTS_DEFAULT_PITCH = 100;// 1x
92d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int FALLBACK_TTS_USE_DEFAULTS = 0; // false
93d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final String FALLBACK_TTS_DEFAULT_LANG = "eng";
94d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final String FALLBACK_TTS_DEFAULT_COUNTRY = "";
95d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final String FALLBACK_TTS_DEFAULT_VARIANT = "";
96d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi
97d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        // return codes for a TTS engine's check data activity
98d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_PASS = 1;
99d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_FAIL = 0;
100d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_BAD_DATA = -1;
101d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_MISSING_DATA = -2;
102d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_MISSING_DATA_NO_SDCARD = -3;
103d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi    }
104d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi
105d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi    /**
106679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * Connection needed for the TTS.
107e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
108679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    private ServiceConnection mServiceConnection;
109e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
11091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private ITts mITts = null;
11191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private Context mContext = null;
11291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private OnInitListener mInitListener = null;
11391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private boolean mStarted = false;
11491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private final Object mStartLock = new Object();
11591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private ITtsCallback mITtsCallback;
11691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private OnSpeechCompletedListener mSpeechCompListener = null;
11791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private final Object mSpeechCompListenerLock = new Object();
118e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
119e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
120e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
121e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
122e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * The constructor for the TTS.
123e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
124e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param context
125e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The context
12691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * @param listener
12791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     *            The InitListener that will be called when the TTS has
128e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            initialized successfully.
129e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
13091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    public TextToSpeech(Context context, OnInitListener listener) {
13191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        mContext = context;
13291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        mInitListener = listener;
133a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi        initTts();
134e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
135e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
136e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
137679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    public void setOnSpeechCompletedListener(final OnSpeechCompletedListener listener) {
13891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized(mSpeechCompListenerLock) {
13991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            mSpeechCompListener = listener;
14091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        }
141e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
142e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
143e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
144e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    private boolean dataFilesCheck() {
145a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi        // TODO #TTS# config manager will be in settings
146e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        Log.i("TTS_FIXME", "FIXME in Tts: config manager will be in settings");
147a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi        // TODO #TTS# implement checking of the correct installation of
148e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        //             the data files.
149e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
150e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        return true;
151e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
152e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
153e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
154e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    private void initTts() {
15591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        mStarted = false;
156e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
157e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        // Initialize the TTS, run the callback after the binding is successful
158679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi        mServiceConnection = new ServiceConnection() {
159e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            public void onServiceConnected(ComponentName name, IBinder service) {
16091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                synchronized(mStartLock) {
16191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    mITts = ITts.Stub.asInterface(service);
162e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                    try {
16391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                        mITtsCallback = new ITtsCallback.Stub() {
164e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                            public void markReached(String mark)
165e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                            throws RemoteException {
16691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                                // call the listener of that event, but not
16791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                                // while locked.
16891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                                OnSpeechCompletedListener listener = null;
16991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                                synchronized(mSpeechCompListenerLock) {
17091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                                    listener = mSpeechCompListener;
17191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                                }
17291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                                if (listener != null) {
17391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                                    listener.onSpeechCompleted();
174e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                                }
175e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                            }
176e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                        };
17791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                        mITts.registerCallback(mITtsCallback);
178e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
179e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                    } catch (RemoteException e) {
180e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                        initTts();
181e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                        return;
182e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                    }
183e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
18491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    mStarted = true;
185e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                    // The callback can become null if the Android OS decides to
186e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                    // restart the TTS process as well as whatever is using it.
187e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                    // In such cases, do nothing - the error handling from the
188e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                    // speaking calls will kick in and force a proper restart of
189e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                    // the TTS.
19091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    if (mInitListener != null) {
19191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                        // TODO manage failures and missing resources
19291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                        mInitListener.onInit(TTS_SUCCESS);
193e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                    }
194e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                }
195e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
196e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
197e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            public void onServiceDisconnected(ComponentName name) {
19891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                synchronized(mStartLock) {
19991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    mITts = null;
20091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    mInitListener = null;
20191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                    mStarted = false;
202e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                }
203e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
204e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        };
205e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
206e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        Intent intent = new Intent("android.intent.action.USE_TTS");
207e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        intent.addCategory("android.intent.category.TTS");
208679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi        mContext.bindService(intent, mServiceConnection,
20991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                Context.BIND_AUTO_CREATE);
210a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi        // TODO handle case where the binding works (should always work) but
211a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi        //      the plugin fails
212e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
213e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
214e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
215e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
216e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Shuts down the TTS. It is good practice to call this in the onDestroy
217e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * method of the Activity that is using the TTS so that the TTS is stopped
218e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * cleanly.
219e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
220e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public void shutdown() {
221e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        try {
222679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi            mContext.unbindService(mServiceConnection);
223e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        } catch (IllegalArgumentException e) {
224e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            // Do nothing and fail silently since an error here indicates that
225e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            // binding never succeeded in the first place.
226e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
227e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
228e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
229e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
230e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
231e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Adds a mapping between a string of text and a sound resource in a
232e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * package.
233e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
234e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @see #TTS.speak(String text, int queueMode, String[] params)
235e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
236e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param text
237e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            Example: <b><code>"south_south_east"</code></b><br/>
238e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
239e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param packagename
240e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            Pass the packagename of the application that contains the
241e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            resource. If the resource is in your own application (this is
242e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            the most common case), then put the packagename of your
243e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            application here.<br/>
244e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            Example: <b>"com.google.marvin.compass"</b><br/>
245e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The packagename can be found in the AndroidManifest.xml of
246e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            your application.
247e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            <p>
248e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            <code>&lt;manifest xmlns:android=&quot;...&quot;
249e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *      package=&quot;<b>com.google.marvin.compass</b>&quot;&gt;</code>
250e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            </p>
251e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
252e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param resourceId
253e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            Example: <b><code>R.raw.south_south_east</code></b>
254e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
255e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public void addSpeech(String text, String packagename, int resourceId) {
25691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized(mStartLock) {
25791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
258e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                return;
259e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
260e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
26191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mITts.addSpeech(text, packagename, resourceId);
262e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
263e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
26491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
265e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
266e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
267e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
26891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
269e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
270e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
271e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
27291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
273e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
274e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
275e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
276e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
277e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
278e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
279e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
280e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Adds a mapping between a string of text and a sound file. Using this, it
281e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * is possible to add custom pronounciations for text.
282e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
283e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param text
284e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The string of text
285e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param filename
286e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The full path to the sound file (for example:
287e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            "/sdcard/mysounds/hello.wav")
288e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
289e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public void addSpeech(String text, String filename) {
29091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
29191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
292e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                return;
293e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
294e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
29591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mITts.addSpeechFile(text, filename);
296e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
297e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
29891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
299e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
300e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
301e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
30291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
303e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
304e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
305e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
30691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
307e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
308e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
309e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
310e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
311e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
312e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
313e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
314e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Speaks the string using the specified queuing strategy and speech
315e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * parameters. Note that the speech parameters are not universally supported
316e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * by all engines and will be treated as a hint. The TTS library will try to
317e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * fulfill these parameters as much as possible, but there is no guarantee
318e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * that the voice used will have the properties specified.
319e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
320e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param text
321e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The string of text to be spoken.
322e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param queueMode
323679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            The queuing strategy to use.
324679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
325e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param params
326a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi     *            The hashmap of speech parameters to be used.
327e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
328a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi    public void speak(String text, int queueMode, HashMap<String,String> params)
329a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi    {
33091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
331e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            Log.i("TTS received: ", text);
33291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
333e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                return;
334e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
335e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
336a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi                // TODO support extra parameters, passing null for the moment
33791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mITts.speak(text, queueMode, null);
338e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
339e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
34091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
341e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
342e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
343e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
34491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
345e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
346e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
347e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
34891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
349e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
350e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
351e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
352e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
353e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
354e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
355e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
356e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Plays the earcon using the specified queueing mode and parameters.
357e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
358e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param earcon
359e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The earcon that should be played
360e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param queueMode
361679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
362e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param params
363a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi     *            The hashmap of parameters to be used.
364e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
365679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    public void playEarcon(String earcon, int queueMode,
366a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi            HashMap<String,String> params) {
36791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
36891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
369e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                return;
370e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
371e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
372a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi                // TODO support extra parameters, passing null for the moment
37391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mITts.playEarcon(earcon, queueMode, null);
374e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
375e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
37691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
377e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
378e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
379e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
38091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
381e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
382e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
383e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
38491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
385e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
386e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
387e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
388e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
389679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi
390679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi
391a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi    public void playSilence(long durationInMs, int queueMode) {
392a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi        // TODO implement, already present in TTS service
393a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi    }
394e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
395e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
396e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
397e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Returns whether or not the TTS is busy speaking.
398e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
399e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @return Whether or not the TTS is busy speaking.
400e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
401e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public boolean isSpeaking() {
40291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
40391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
404e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                return false;
405e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
406e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
40791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                return mITts.isSpeaking();
408e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
409e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
41091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
411e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
412e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
413e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
41491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
415e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
416e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
417e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
41891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
419e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
420e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
421e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            return false;
422e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
423e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
424e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
425e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
426e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
427e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Stops speech from the TTS.
428e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
429e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public void stop() {
43091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
43191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
432e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                return;
433e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
434e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
43591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mITts.stop();
436e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
437e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
43891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
439e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
440e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
441e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
44291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
443e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
444e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
445e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
44691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
447e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
448e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
449e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
450e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
451e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
452e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
453e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
454e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
455e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Sets the speech rate for the TTS engine.
456e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
457e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Note that the speech rate is not universally supported by all engines and
458e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * will be treated as a hint. The TTS library will try to use the specified
459e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * speech rate, but there is no guarantee.
460679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * This has no effect on any pre-recorded speech.
461e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
462e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param speechRate
463679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            The speech rate for the TTS engine. 1 is the normal speed,
464679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            lower values slow down the speech (0.5 is half the normal speech rate),
465679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            greater values accelerate it (2 is twice the normal speech rate).
466e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
467679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    public void setSpeechRate(float speechRate) {
46891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
46991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
470e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                return;
471e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
472e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
473679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi                if (speechRate > 0) {
474679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi                    mITts.setSpeechRate((int)(speechRate*100));
475679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi                }
476e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
477e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
47891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
479e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
480e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
481e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
482e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
483e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
484e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
485e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
486e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Sets the language for the TTS engine.
487e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
488e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Note that the language is not universally supported by all engines and
489e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * will be treated as a hint. The TTS library will try to use the specified
490679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * language as represented by the Locale, but there is no guarantee.
491e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
492679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * @param loc
493679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     *            The locale describing the language to be used.
494e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
495679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    public void setLanguage(Locale loc) {
49691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
49791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
498e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                return;
499e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
500e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
501679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi                mITts.setLanguage(loc.getISO3Language(), loc.getISO3Country(), loc.getVariant());
502e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
503e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
50491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
505e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
506e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
507e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
508e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
509e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
510e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
511e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
512e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Speaks the given text using the specified queueing mode and parameters.
513e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
514e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param text
515e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The String of text that should be synthesized
516e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param params
517a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi     *            A hashmap of parameters.
518e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param filename
519e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The string that gives the full output filename; it should be
520e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            something like "/sdcard/myappsounds/mysound.wav".
521e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @return A boolean that indicates if the synthesis succeeded
522e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
523a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi    public boolean synthesizeToFile(String text, HashMap<String,String> params,
524e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            String filename) {
52591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
52691bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi            if (!mStarted) {
527e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                return false;
528e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
529e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            try {
530a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi                // TODO support extra parameters, passing null for the moment
53191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                return mITts.synthesizeToFile(text, null, filename);
532e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (RemoteException e) {
533e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
53491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
535e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
536e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (NullPointerException e) {
537e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
53891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
539e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
540e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            } catch (IllegalStateException e) {
541e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                // TTS died; restart it.
54291bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi                mStarted = false;
543e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi                initTts();
544e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
545e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            return false;
546e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
547e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
548e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
549e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
550e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi}
551