TextToSpeech.java revision 99a0feecd0f0aad314d7a4637d329b8a9e8c1150
1/*
2 * Copyright (C) 2009 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16package android.speech.tts;
17
18import android.speech.tts.ITts;
19import android.speech.tts.ITtsCallback;
20
21import android.content.ComponentName;
22import android.content.Context;
23import android.content.Intent;
24import android.content.ServiceConnection;
25import android.os.IBinder;
26import android.os.RemoteException;
27import android.util.Log;
28
29import java.util.HashMap;
30import java.util.Locale;
31
32/**
33 *
34 * Synthesizes speech from text.
35 *
36 * {@hide}
37 */
38//TODO #TTS# review + complete javadoc + add links to constants
39public class TextToSpeech {
40
41    /**
42     * Denotes a successful operation.
43     */
44    public static final int TTS_SUCCESS                = 0;
45    /**
46     * Denotes a generic operation failure.
47     */
48    public static final int TTS_ERROR                  = -1;
49
50    /**
51     * Queue mode where all entries in the playback queue (media to be played
52     * and text to be synthesized) are dropped and replaced by the new entry.
53     */
54    public static final int TTS_QUEUE_FLUSH = 0;
55    /**
56     * Queue mode where the new entry is added at the end of the playback queue.
57     */
58    public static final int TTS_QUEUE_ADD = 1;
59
60
61    /**
62     * Denotes the language is available exactly as specified by the locale
63     */
64    public static final int TTS_LANG_COUNTRY_VAR_AVAILABLE = 2;
65
66
67    /**
68     * Denotes the language is available for the language and country specified
69     * by the locale, but not the variant.
70     */
71    public static final int TTS_LANG_COUNTRY_AVAILABLE = 1;
72
73
74    /**
75     * Denotes the language is available for the language by the locale,
76     * but not the country and variant.
77     */
78    public static final int TTS_LANG_AVAILABLE = 0;
79
80    /**
81     * Denotes the language data is missing.
82     */
83    public static final int TTS_LANG_MISSING_DATA = -1;
84
85    /**
86     * Denotes the language is not supported by the current TTS engine.
87     */
88    public static final int TTS_LANG_NOT_SUPPORTED = -2;
89
90
91    /**
92     * Called when the TTS has initialized.
93     *
94     * The InitListener must implement the onInit function. onInit is passed a
95     * status code indicating the result of the TTS initialization.
96     */
97    public interface OnInitListener {
98        public void onInit(int status);
99    }
100
101    /**
102     * Internal constants for the TTS functionality
103     *
104     * {@hide}
105     */
106    public class Engine {
107        // default values for a TTS engine when settings are not found in the provider
108        public static final int FALLBACK_TTS_DEFAULT_RATE = 100; // 1x
109        public static final int FALLBACK_TTS_DEFAULT_PITCH = 100;// 1x
110        public static final int FALLBACK_TTS_USE_DEFAULTS = 0; // false
111        public static final String FALLBACK_TTS_DEFAULT_LANG = "eng";
112        public static final String FALLBACK_TTS_DEFAULT_COUNTRY = "";
113        public static final String FALLBACK_TTS_DEFAULT_VARIANT = "";
114
115        // return codes for a TTS engine's check data activity
116        public static final int CHECK_VOICE_DATA_PASS = 1;
117        public static final int CHECK_VOICE_DATA_FAIL = 0;
118        public static final int CHECK_VOICE_DATA_BAD_DATA = -1;
119        public static final int CHECK_VOICE_DATA_MISSING_DATA = -2;
120        public static final int CHECK_VOICE_DATA_MISSING_DATA_NO_SDCARD = -3;
121
122        // return codes for a TTS engine's check data activity
123        public static final String VOICE_DATA_ROOT_DIRECTORY = "dataRoot";
124        public static final String VOICE_DATA_FILES = "dataFiles";
125        public static final String VOICE_DATA_FILES_INFO = "dataFilesInfo";
126
127        // keys for the parameters passed with speak commands
128        public static final String TTS_KEY_PARAM_RATE = "rate";
129        public static final String TTS_KEY_PARAM_LANGUAGE = "language";
130        public static final String TTS_KEY_PARAM_COUNTRY = "country";
131        public static final String TTS_KEY_PARAM_VARIANT = "variant";
132        public static final int TTS_PARAM_POSITION_RATE = 0;
133        public static final int TTS_PARAM_POSITION_LANGUAGE = 2;
134        public static final int TTS_PARAM_POSITION_COUNTRY = 4;
135        public static final int TTS_PARAM_POSITION_VARIANT = 6;
136    }
137
138    /**
139     * Connection needed for the TTS.
140     */
141    private ServiceConnection mServiceConnection;
142
143    private ITts mITts = null;
144    private Context mContext = null;
145    private OnInitListener mInitListener = null;
146    private boolean mStarted = false;
147    private final Object mStartLock = new Object();
148    private int mCachedRate = Engine.FALLBACK_TTS_DEFAULT_RATE;
149    private String mCachedLang = Engine.FALLBACK_TTS_DEFAULT_LANG;
150    private String mCachedCountry = Engine.FALLBACK_TTS_DEFAULT_COUNTRY;
151    private String mCachedVariant = Engine.FALLBACK_TTS_DEFAULT_VARIANT;
152    private String[] mCachedParams;
153
154    /**
155     * The constructor for the TTS.
156     *
157     * @param context
158     *            The context
159     * @param listener
160     *            The InitListener that will be called when the TTS has
161     *            initialized successfully.
162     */
163    public TextToSpeech(Context context, OnInitListener listener) {
164        mContext = context;
165        mInitListener = listener;
166
167        mCachedParams = new String[2*4]; //4 parameters, store key and value
168        mCachedParams[Engine.TTS_PARAM_POSITION_RATE] = Engine.TTS_KEY_PARAM_RATE;
169        mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE] = Engine.TTS_KEY_PARAM_LANGUAGE;
170        mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY] = Engine.TTS_KEY_PARAM_COUNTRY;
171        mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT] = Engine.TTS_KEY_PARAM_VARIANT;
172        updateCachedParamArray();
173
174        initTts();
175    }
176
177
178    private void updateCachedParamArray() {
179        mCachedParams[Engine.TTS_PARAM_POSITION_RATE+1] = String.valueOf(mCachedRate);
180        mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE+1] = mCachedLang;
181        mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY+1] = mCachedCountry;
182        mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT+1] = mCachedVariant;
183    }
184
185
186    private void initTts() {
187        mStarted = false;
188
189        // Initialize the TTS, run the callback after the binding is successful
190        mServiceConnection = new ServiceConnection() {
191            public void onServiceConnected(ComponentName name, IBinder service) {
192                synchronized(mStartLock) {
193                    mITts = ITts.Stub.asInterface(service);
194                    mStarted = true;
195                    if (mInitListener != null) {
196                        // TODO manage failures and missing resources
197                        mInitListener.onInit(TTS_SUCCESS);
198                    }
199                }
200            }
201
202            public void onServiceDisconnected(ComponentName name) {
203                synchronized(mStartLock) {
204                    mITts = null;
205                    mInitListener = null;
206                    mStarted = false;
207                }
208            }
209        };
210
211        Intent intent = new Intent("android.intent.action.USE_TTS");
212        intent.addCategory("android.intent.category.TTS");
213        mContext.bindService(intent, mServiceConnection,
214                Context.BIND_AUTO_CREATE);
215        // TODO handle case where the binding works (should always work) but
216        //      the plugin fails
217    }
218
219
220    /**
221     * Shuts down the TTS. It is good practice to call this in the onDestroy
222     * method of the Activity that is using the TTS so that the TTS is stopped
223     * cleanly.
224     */
225    public void shutdown() {
226        try {
227            mContext.unbindService(mServiceConnection);
228        } catch (IllegalArgumentException e) {
229            // Do nothing and fail silently since an error here indicates that
230            // binding never succeeded in the first place.
231        }
232    }
233
234
235    /**
236     * Adds a mapping between a string of text and a sound resource in a
237     * package.
238     *
239     * @see #TTS.speak(String text, int queueMode, String[] params)
240     *
241     * @param text
242     *            Example: <b><code>"south_south_east"</code></b><br/>
243     *
244     * @param packagename
245     *            Pass the packagename of the application that contains the
246     *            resource. If the resource is in your own application (this is
247     *            the most common case), then put the packagename of your
248     *            application here.<br/>
249     *            Example: <b>"com.google.marvin.compass"</b><br/>
250     *            The packagename can be found in the AndroidManifest.xml of
251     *            your application.
252     *            <p>
253     *            <code>&lt;manifest xmlns:android=&quot;...&quot;
254     *      package=&quot;<b>com.google.marvin.compass</b>&quot;&gt;</code>
255     *            </p>
256     *
257     * @param resourceId
258     *            Example: <b><code>R.raw.south_south_east</code></b>
259     *
260     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
261     */
262    public int addSpeech(String text, String packagename, int resourceId) {
263        synchronized(mStartLock) {
264            if (!mStarted) {
265                return TTS_ERROR;
266            }
267            try {
268                mITts.addSpeech(text, packagename, resourceId);
269                return TTS_SUCCESS;
270            } catch (RemoteException e) {
271                // TTS died; restart it.
272                mStarted = false;
273                initTts();
274            } catch (NullPointerException e) {
275                // TTS died; restart it.
276                mStarted = false;
277                initTts();
278            } catch (IllegalStateException e) {
279                // TTS died; restart it.
280                mStarted = false;
281                initTts();
282            }
283            return TTS_ERROR;
284        }
285    }
286
287
288    /**
289     * Adds a mapping between a string of text and a sound file. Using this, it
290     * is possible to add custom pronounciations for text.
291     *
292     * @param text
293     *            The string of text
294     * @param filename
295     *            The full path to the sound file (for example:
296     *            "/sdcard/mysounds/hello.wav")
297     *
298     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
299     */
300    public int addSpeech(String text, String filename) {
301        synchronized (mStartLock) {
302            if (!mStarted) {
303                return TTS_ERROR;
304            }
305            try {
306                mITts.addSpeechFile(text, filename);
307                return TTS_SUCCESS;
308            } catch (RemoteException e) {
309                // TTS died; restart it.
310                mStarted = false;
311                initTts();
312            } catch (NullPointerException e) {
313                // TTS died; restart it.
314                mStarted = false;
315                initTts();
316            } catch (IllegalStateException e) {
317                // TTS died; restart it.
318                mStarted = false;
319                initTts();
320            }
321            return TTS_ERROR;
322        }
323    }
324
325
326    /**
327     * Speaks the string using the specified queuing strategy and speech
328     * parameters. Note that the speech parameters are not universally supported
329     * by all engines and will be treated as a hint. The TTS library will try to
330     * fulfill these parameters as much as possible, but there is no guarantee
331     * that the voice used will have the properties specified.
332     *
333     * @param text
334     *            The string of text to be spoken.
335     * @param queueMode
336     *            The queuing strategy to use.
337     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
338     * @param params
339     *            The hashmap of speech parameters to be used.
340     *
341     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
342     */
343    public int speak(String text, int queueMode, HashMap<String,String> params)
344    {
345        synchronized (mStartLock) {
346            Log.i("TTS received: ", text);
347            if (!mStarted) {
348                return TTS_ERROR;
349            }
350            try {
351                // TODO support extra parameters, passing cache of current parameters for the moment
352                mITts.speak(text, queueMode, mCachedParams);
353                return TTS_SUCCESS;
354            } catch (RemoteException e) {
355                // TTS died; restart it.
356                mStarted = false;
357                initTts();
358            } catch (NullPointerException e) {
359                // TTS died; restart it.
360                mStarted = false;
361                initTts();
362            } catch (IllegalStateException e) {
363                // TTS died; restart it.
364                mStarted = false;
365                initTts();
366            }
367            return TTS_ERROR;
368        }
369    }
370
371
372    /**
373     * Speaks the IPA string using the specified queuing strategy and speech
374     * parameters. Note that the speech parameters are not universally supported
375     * by all engines and will be treated as a hint. The TTS library will try to
376     * fulfill these parameters as much as possible, but there is no guarantee
377     * that the voice used will have the properties specified.
378     *
379     * @param ipaText
380     *            The string of IPA text to be spoken.
381     * @param queueMode
382     *            The queuing strategy to use.
383     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
384     * @param params
385     *            The hashmap of speech parameters to be used.
386     *
387     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
388     *
389     * {@hide}
390     */
391    public int speakIpa(String ipaText, int queueMode, HashMap<String,String> params)
392    {
393        synchronized (mStartLock) {
394            Log.i("TTS received: ", ipaText);
395            if (!mStarted) {
396                return TTS_ERROR;
397            }
398            try {
399                // TODO support extra parameters, passing cache of current parameters for the moment
400                mITts.speakIpa(ipaText, queueMode, mCachedParams);
401                return TTS_SUCCESS;
402            } catch (RemoteException e) {
403                // TTS died; restart it.
404                mStarted = false;
405                initTts();
406            } catch (NullPointerException e) {
407                // TTS died; restart it.
408                mStarted = false;
409                initTts();
410            } catch (IllegalStateException e) {
411                // TTS died; restart it.
412                mStarted = false;
413                initTts();
414            }
415            return TTS_ERROR;
416        }
417    }
418
419
420    /**
421     * Plays the earcon using the specified queueing mode and parameters.
422     *
423     * @param earcon
424     *            The earcon that should be played
425     * @param queueMode
426     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
427     * @param params
428     *            The hashmap of parameters to be used.
429     *
430     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
431     */
432    public int playEarcon(String earcon, int queueMode,
433            HashMap<String,String> params) {
434        synchronized (mStartLock) {
435            if (!mStarted) {
436                return TTS_ERROR;
437            }
438            try {
439                // TODO support extra parameters, passing null for the moment
440                mITts.playEarcon(earcon, queueMode, null);
441                return TTS_SUCCESS;
442            } catch (RemoteException e) {
443                // TTS died; restart it.
444                mStarted = false;
445                initTts();
446            } catch (NullPointerException e) {
447                // TTS died; restart it.
448                mStarted = false;
449                initTts();
450            } catch (IllegalStateException e) {
451                // TTS died; restart it.
452                mStarted = false;
453                initTts();
454            }
455            return TTS_ERROR;
456        }
457    }
458
459    /**
460     * Plays silence for the specified amount of time using the specified
461     * queue mode.
462     *
463     * @param durationInMs
464     *            A long that indicates how long the silence should last.
465     * @param queueMode
466     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
467     *
468     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
469     */
470    public int playSilence(long durationInMs, int queueMode) {
471        synchronized (mStartLock) {
472            if (!mStarted) {
473                return TTS_ERROR;
474            }
475            try {
476                // TODO support extra parameters, passing cache of current parameters for the moment
477                mITts.playSilence(durationInMs, queueMode, mCachedParams);
478                return TTS_SUCCESS;
479            } catch (RemoteException e) {
480                // TTS died; restart it.
481                mStarted = false;
482                initTts();
483            } catch (NullPointerException e) {
484                // TTS died; restart it.
485                mStarted = false;
486                initTts();
487            } catch (IllegalStateException e) {
488                // TTS died; restart it.
489                mStarted = false;
490                initTts();
491            }
492            return TTS_ERROR;
493        }
494    }
495
496
497    /**
498     * Returns whether or not the TTS is busy speaking.
499     *
500     * @return Whether or not the TTS is busy speaking.
501     */
502    public boolean isSpeaking() {
503        synchronized (mStartLock) {
504            if (!mStarted) {
505                return false;
506            }
507            try {
508                return mITts.isSpeaking();
509            } catch (RemoteException e) {
510                // TTS died; restart it.
511                mStarted = false;
512                initTts();
513            } catch (NullPointerException e) {
514                // TTS died; restart it.
515                mStarted = false;
516                initTts();
517            } catch (IllegalStateException e) {
518                // TTS died; restart it.
519                mStarted = false;
520                initTts();
521            }
522            return false;
523        }
524    }
525
526
527    /**
528     * Stops speech from the TTS.
529     *
530     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
531     */
532    public int stop() {
533        synchronized (mStartLock) {
534            if (!mStarted) {
535                return TTS_ERROR;
536            }
537            try {
538                mITts.stop();
539                return TTS_SUCCESS;
540            } catch (RemoteException e) {
541                // TTS died; restart it.
542                mStarted = false;
543                initTts();
544            } catch (NullPointerException e) {
545                // TTS died; restart it.
546                mStarted = false;
547                initTts();
548            } catch (IllegalStateException e) {
549                // TTS died; restart it.
550                mStarted = false;
551                initTts();
552            }
553            return TTS_ERROR;
554        }
555    }
556
557
558    /**
559     * Sets the speech rate for the TTS engine.
560     *
561     * Note that the speech rate is not universally supported by all engines and
562     * will be treated as a hint. The TTS library will try to use the specified
563     * speech rate, but there is no guarantee.
564     * This has no effect on any pre-recorded speech.
565     *
566     * @param speechRate
567     *            The speech rate for the TTS engine. 1 is the normal speed,
568     *            lower values slow down the speech (0.5 is half the normal speech rate),
569     *            greater values accelerate it (2 is twice the normal speech rate).
570     *
571     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
572     */
573    public int setSpeechRate(float speechRate) {
574        synchronized (mStartLock) {
575            if (!mStarted) {
576                return TTS_SUCCESS;
577            }
578            try {
579                if (speechRate > 0) {
580                    mCachedRate = (int)(speechRate*100);
581                    updateCachedParamArray();
582                    mITts.setSpeechRate(mCachedRate);
583                    return TTS_SUCCESS;
584                }
585            } catch (RemoteException e) {
586                // TTS died; restart it.
587                mStarted = false;
588                initTts();
589            }
590            return TTS_ERROR;
591        }
592    }
593
594
595    /**
596     * Sets the speech pitch for the TTS engine.
597     *
598     * Note that the pitch is not universally supported by all engines and
599     * will be treated as a hint. The TTS library will try to use the specified
600     * pitch, but there is no guarantee.
601     * This has no effect on any pre-recorded speech.
602     *
603     * @param pitch
604     *            The pitch for the TTS engine. 1 is the normal pitch,
605     *            lower values lower the tone of the synthesized voice,
606     *            greater values increase it.
607     *
608     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
609     */
610    public int setPitch(float pitch) {
611        synchronized (mStartLock) {
612            if (!mStarted) {
613                return TTS_ERROR;
614            }
615            try {
616                if (pitch > 0) {
617                    mITts.setPitch((int)(pitch*100));
618                    return TTS_SUCCESS;
619                }
620            } catch (RemoteException e) {
621                // TTS died; restart it.
622                mStarted = false;
623                initTts();
624            }
625            return TTS_ERROR;
626        }
627    }
628
629
630    /**
631     * Sets the language for the TTS engine.
632     *
633     * Note that the language is not universally supported by all engines and
634     * will be treated as a hint. The TTS library will try to use the specified
635     * language as represented by the Locale, but there is no guarantee.
636     *
637     * @param loc
638     *            The locale describing the language to be used.
639     *
640     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
641     */
642    public int setLanguage(Locale loc) {
643        synchronized (mStartLock) {
644            if (!mStarted) {
645                return TTS_ERROR;
646            }
647            try {
648                mCachedLang = loc.getISO3Language();
649                mCachedCountry = loc.getISO3Country();
650                mCachedVariant = loc.getVariant();
651                updateCachedParamArray();
652                mITts.setLanguage(mCachedLang, mCachedCountry, mCachedVariant);
653                return TTS_SUCCESS;
654            } catch (RemoteException e) {
655                // TTS died; restart it.
656                mStarted = false;
657                initTts();
658            }
659            return TTS_ERROR;
660        }
661    }
662
663
664    /**
665     * Returns a Locale instance describing the language currently being used by the TTS engine.
666     * @return language, country (if any) and variant (if any) used by the engine stored in a Locale
667     *     instance, or null is the TTS engine has failed.
668     */
669    public Locale getLanguage() {
670        synchronized (mStartLock) {
671            if (!mStarted) {
672                return null;
673            }
674            try {
675                String[] locStrings =  mITts.getLanguage();
676                if (locStrings.length == 3) {
677                    return new Locale(locStrings[0], locStrings[1], locStrings[2]);
678                } else {
679                    return null;
680                }
681            } catch (RemoteException e) {
682                // TTS died; restart it.
683                mStarted = false;
684                initTts();
685            }
686            return null;
687        }
688    }
689
690    /**
691     * Checks if the specified language as represented by the Locale is available.
692     *
693     * @param loc
694     *            The Locale describing the language to be used.
695     *
696     * @return one of TTS_LANG_NOT_SUPPORTED, TTS_LANG_MISSING_DATA, TTS_LANG_AVAILABLE,
697     *         TTS_LANG_COUNTRY_AVAILABLE, TTS_LANG_COUNTRY_VAR_AVAILABLE.
698     */
699    public int isLanguageAvailable(Locale loc) {
700        synchronized (mStartLock) {
701            if (!mStarted) {
702                return TTS_LANG_NOT_SUPPORTED;
703            }
704            try {
705                return mITts.isLanguageAvailable(loc.getISO3Language(), loc.getISO3Country(),
706                        loc.getVariant());
707            } catch (RemoteException e) {
708                // TTS died; restart it.
709                mStarted = false;
710                initTts();
711            }
712            return TTS_LANG_NOT_SUPPORTED;
713        }
714    }
715
716
717    /**
718     * Synthesizes the given text to a file using the specified parameters.
719     *
720     * @param text
721     *            The String of text that should be synthesized
722     * @param params
723     *            A hashmap of parameters.
724     * @param filename
725     *            The string that gives the full output filename; it should be
726     *            something like "/sdcard/myappsounds/mysound.wav".
727     *
728     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
729     */
730    public int synthesizeToFile(String text, HashMap<String,String> params,
731            String filename) {
732        synchronized (mStartLock) {
733            if (!mStarted) {
734                return TTS_ERROR;
735            }
736            try {
737                // TODO support extra parameters, passing null for the moment
738                if (mITts.synthesizeToFile(text, null, filename)){
739                    return TTS_SUCCESS;
740                }
741            } catch (RemoteException e) {
742                // TTS died; restart it.
743                mStarted = false;
744                initTts();
745            } catch (NullPointerException e) {
746                // TTS died; restart it.
747                mStarted = false;
748                initTts();
749            } catch (IllegalStateException e) {
750                // TTS died; restart it.
751                mStarted = false;
752                initTts();
753            }
754            return TTS_ERROR;
755        }
756    }
757
758
759    /**
760     * Synthesizes the given IPA text to a file using the specified parameters.
761     *
762     * @param text
763     *            The String of text that should be synthesized
764     * @param params
765     *            A hashmap of parameters.
766     * @param filename
767     *            The string that gives the full output filename; it should be
768     *            something like "/sdcard/myappsounds/mysound.wav".
769     *
770     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
771     *
772     * {@hide}
773     */
774    public int synthesizeIpaToFile(String ipaText,
775            HashMap<String,String> params, String filename) {
776        synchronized (mStartLock) {
777            if (!mStarted) {
778                return TTS_ERROR;
779            }
780            try {
781                // TODO support extra parameters, passing null for the moment
782                if (mITts.synthesizeIpaToFile(ipaText, null, filename)){
783                    return TTS_SUCCESS;
784                }
785            } catch (RemoteException e) {
786                // TTS died; restart it.
787                mStarted = false;
788                initTts();
789            } catch (NullPointerException e) {
790                // TTS died; restart it.
791                mStarted = false;
792                initTts();
793            } catch (IllegalStateException e) {
794                // TTS died; restart it.
795                mStarted = false;
796                initTts();
797            }
798            return TTS_ERROR;
799        }
800    }
801
802}
803