TextToSpeech.java revision a981013aa7315e13c6c5f6aad489813c419031ea
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.media.AudioManager; 26import android.os.IBinder; 27import android.os.RemoteException; 28import android.util.Log; 29 30import java.util.HashMap; 31import java.util.Locale; 32 33/** 34 * 35 * Synthesizes speech from text for immediate playback or to create a sound file. 36 * 37 */ 38//TODO 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_SYNTH = "com.svox.pico"; 112 113 // default values for rendering 114 public static final int TTS_DEFAULT_STREAM = AudioManager.STREAM_MUSIC; 115 116 // return codes for a TTS engine's check data activity 117 public static final int CHECK_VOICE_DATA_PASS = 1; 118 public static final int CHECK_VOICE_DATA_FAIL = 0; 119 public static final int CHECK_VOICE_DATA_BAD_DATA = -1; 120 public static final int CHECK_VOICE_DATA_MISSING_DATA = -2; 121 public static final int CHECK_VOICE_DATA_MISSING_DATA_NO_SDCARD = -3; 122 123 // return codes for a TTS engine's check data activity 124 public static final String VOICE_DATA_ROOT_DIRECTORY = "dataRoot"; 125 public static final String VOICE_DATA_FILES = "dataFiles"; 126 public static final String VOICE_DATA_FILES_INFO = "dataFilesInfo"; 127 128 // keys for the parameters passed with speak commands 129 public static final String TTS_KEY_PARAM_RATE = "rate"; 130 public static final String TTS_KEY_PARAM_LANGUAGE = "language"; 131 public static final String TTS_KEY_PARAM_COUNTRY = "country"; 132 public static final String TTS_KEY_PARAM_VARIANT = "variant"; 133 public static final String TTS_KEY_PARAM_STREAM = "streamType"; 134 public static final String TTS_KEY_PARAM_UTTERANCE_ID = "utteranceId"; 135 protected static final int TTS_PARAM_POSITION_RATE = 0; 136 protected static final int TTS_PARAM_POSITION_LANGUAGE = 2; 137 protected static final int TTS_PARAM_POSITION_COUNTRY = 4; 138 protected static final int TTS_PARAM_POSITION_VARIANT = 6; 139 protected static final int TTS_PARAM_POSITION_STREAM = 8; 140 protected static final int TTS_PARAM_POSITION_UTTERANCE_ID = 10; 141 protected static final int TTS_NB_CACHED_PARAMS = 6; 142 } 143 144 /** 145 * Connection needed for the TTS. 146 */ 147 private ServiceConnection mServiceConnection; 148 149 private ITts mITts = null; 150 private Context mContext = null; 151 private String mPackageName = ""; 152 private OnInitListener mInitListener = null; 153 private boolean mStarted = false; 154 private final Object mStartLock = new Object(); 155 /** 156 * Used to store the cached parameters sent along with each synthesis request to the 157 * TTS service. 158 */ 159 private String[] mCachedParams; 160 161 /** 162 * The constructor for the TTS. 163 * 164 * @param context 165 * The context 166 * @param listener 167 * The InitListener that will be called when the TTS has 168 * initialized successfully. 169 */ 170 public TextToSpeech(Context context, OnInitListener listener) { 171 mContext = context; 172 mPackageName = mContext.getPackageName(); 173 mInitListener = listener; 174 175 mCachedParams = new String[2*Engine.TTS_NB_CACHED_PARAMS]; // store key and value 176 mCachedParams[Engine.TTS_PARAM_POSITION_RATE] = Engine.TTS_KEY_PARAM_RATE; 177 mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE] = Engine.TTS_KEY_PARAM_LANGUAGE; 178 mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY] = Engine.TTS_KEY_PARAM_COUNTRY; 179 mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT] = Engine.TTS_KEY_PARAM_VARIANT; 180 mCachedParams[Engine.TTS_PARAM_POSITION_STREAM] = Engine.TTS_KEY_PARAM_STREAM; 181 182 mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] = 183 String.valueOf(Engine.FALLBACK_TTS_DEFAULT_RATE); 184 // initialize the language cached parameters with the current Locale 185 Locale defaultLoc = Locale.getDefault(); 186 mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = defaultLoc.getISO3Language(); 187 mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = defaultLoc.getISO3Country(); 188 mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = defaultLoc.getVariant(); 189 190 mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = 191 String.valueOf(Engine.TTS_DEFAULT_STREAM); 192 mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID+ 1] = ""; 193 194 initTts(); 195 } 196 197 198 private void initTts() { 199 mStarted = false; 200 201 // Initialize the TTS, run the callback after the binding is successful 202 mServiceConnection = new ServiceConnection() { 203 public void onServiceConnected(ComponentName name, IBinder service) { 204 synchronized(mStartLock) { 205 mITts = ITts.Stub.asInterface(service); 206 mStarted = true; 207 if (mInitListener != null) { 208 // TODO manage failures and missing resources 209 mInitListener.onInit(TTS_SUCCESS); 210 } 211 } 212 } 213 214 public void onServiceDisconnected(ComponentName name) { 215 synchronized(mStartLock) { 216 mITts = null; 217 mInitListener = null; 218 mStarted = false; 219 } 220 } 221 }; 222 223 Intent intent = new Intent("android.intent.action.START_TTS_SERVICE"); 224 intent.addCategory("android.intent.category.TTS"); 225 mContext.bindService(intent, mServiceConnection, 226 Context.BIND_AUTO_CREATE); 227 // TODO handle case where the binding works (should always work) but 228 // the plugin fails 229 } 230 231 232 /** 233 * Shuts down the TTS. It is good practice to call this in the onDestroy 234 * method of the Activity that is using the TTS so that the TTS is stopped 235 * cleanly. 236 */ 237 public void shutdown() { 238 try { 239 mContext.unbindService(mServiceConnection); 240 } catch (IllegalArgumentException e) { 241 // Do nothing and fail silently since an error here indicates that 242 // binding never succeeded in the first place. 243 } 244 } 245 246 247 /** 248 * Adds a mapping between a string of text and a sound resource in a 249 * package. 250 * 251 * @see #TTS.speak(String text, int queueMode, String[] params) 252 * 253 * @param text 254 * Example: <b><code>"south_south_east"</code></b><br/> 255 * 256 * @param packagename 257 * Pass the packagename of the application that contains the 258 * resource. If the resource is in your own application (this is 259 * the most common case), then put the packagename of your 260 * application here.<br/> 261 * Example: <b>"com.google.marvin.compass"</b><br/> 262 * The packagename can be found in the AndroidManifest.xml of 263 * your application. 264 * <p> 265 * <code><manifest xmlns:android="..." 266 * package="<b>com.google.marvin.compass</b>"></code> 267 * </p> 268 * 269 * @param resourceId 270 * Example: <b><code>R.raw.south_south_east</code></b> 271 * 272 * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. 273 */ 274 public int addSpeech(String text, String packagename, int resourceId) { 275 synchronized(mStartLock) { 276 if (!mStarted) { 277 return TTS_ERROR; 278 } 279 try { 280 mITts.addSpeech(mPackageName, text, packagename, resourceId); 281 return TTS_SUCCESS; 282 } catch (RemoteException e) { 283 // TTS died; restart it. 284 mStarted = false; 285 initTts(); 286 } catch (NullPointerException e) { 287 // TTS died; restart it. 288 mStarted = false; 289 initTts(); 290 } catch (IllegalStateException e) { 291 // TTS died; restart it. 292 mStarted = false; 293 initTts(); 294 } 295 return TTS_ERROR; 296 } 297 } 298 299 300 /** 301 * Adds a mapping between a string of text and a sound file. Using this, it 302 * is possible to add custom pronounciations for text. 303 * 304 * @param text 305 * The string of text 306 * @param filename 307 * The full path to the sound file (for example: 308 * "/sdcard/mysounds/hello.wav") 309 * 310 * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. 311 */ 312 public int addSpeech(String text, String filename) { 313 synchronized (mStartLock) { 314 if (!mStarted) { 315 return TTS_ERROR; 316 } 317 try { 318 mITts.addSpeechFile(mPackageName, text, filename); 319 return TTS_SUCCESS; 320 } catch (RemoteException e) { 321 // TTS died; restart it. 322 mStarted = false; 323 initTts(); 324 } catch (NullPointerException e) { 325 // TTS died; restart it. 326 mStarted = false; 327 initTts(); 328 } catch (IllegalStateException e) { 329 // TTS died; restart it. 330 mStarted = false; 331 initTts(); 332 } 333 return TTS_ERROR; 334 } 335 } 336 337 338 /** 339 * Speaks the string using the specified queuing strategy and speech 340 * parameters. Note that the speech parameters are not universally supported 341 * by all engines and will be treated as a hint. The TTS library will try to 342 * fulfill these parameters as much as possible, but there is no guarantee 343 * that the voice used will have the properties specified. 344 * 345 * @param text 346 * The string of text to be spoken. 347 * @param queueMode 348 * The queuing strategy to use. 349 * See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH. 350 * @param params 351 * The hashmap of speech parameters to be used. 352 * 353 * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. 354 */ 355 public int speak(String text, int queueMode, HashMap<String,String> params) 356 { 357 synchronized (mStartLock) { 358 int result = TTS_ERROR; 359 Log.i("TTS received: ", text); 360 if (!mStarted) { 361 return result; 362 } 363 try { 364 String extra = params.get(Engine.TTS_KEY_PARAM_STREAM); 365 if (extra != null) { 366 mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = extra; 367 } 368 extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); 369 if (extra != null) { 370 mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID] = extra; 371 } 372 result = mITts.speak(mPackageName, text, queueMode, mCachedParams); 373 } catch (RemoteException e) { 374 // TTS died; restart it. 375 mStarted = false; 376 initTts(); 377 } catch (NullPointerException e) { 378 // TTS died; restart it. 379 mStarted = false; 380 initTts(); 381 } catch (IllegalStateException e) { 382 // TTS died; restart it. 383 mStarted = false; 384 initTts(); 385 } finally { 386 resetCachedParams(); 387 return result; 388 } 389 } 390 } 391 392 393 /** 394 * Plays the earcon using the specified queueing mode and parameters. 395 * 396 * @param earcon 397 * The earcon that should be played 398 * @param queueMode 399 * See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH. 400 * @param params 401 * The hashmap of parameters to be used. 402 * 403 * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. 404 */ 405 public int playEarcon(String earcon, int queueMode, 406 HashMap<String,String> params) { 407 synchronized (mStartLock) { 408 int result = TTS_ERROR; 409 if (!mStarted) { 410 return result; 411 } 412 try { 413 if ((params != null) && (!params.isEmpty())) { 414 String extra = params.get(Engine.TTS_KEY_PARAM_STREAM); 415 if (extra != null) { 416 mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = extra; 417 } 418 extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); 419 if (extra != null) { 420 mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID] = extra; 421 } 422 } 423 result = mITts.playEarcon(mPackageName, earcon, queueMode, null); 424 } catch (RemoteException e) { 425 // TTS died; restart it. 426 mStarted = false; 427 initTts(); 428 } catch (NullPointerException e) { 429 // TTS died; restart it. 430 mStarted = false; 431 initTts(); 432 } catch (IllegalStateException e) { 433 // TTS died; restart it. 434 mStarted = false; 435 initTts(); 436 } finally { 437 resetCachedParams(); 438 return result; 439 } 440 } 441 } 442 443 /** 444 * Plays silence for the specified amount of time using the specified 445 * queue mode. 446 * 447 * @param durationInMs 448 * A long that indicates how long the silence should last. 449 * @param queueMode 450 * See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH. 451 * 452 * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. 453 */ 454 public int playSilence(long durationInMs, int queueMode) { 455 synchronized (mStartLock) { 456 int result = TTS_ERROR; 457 if (!mStarted) { 458 return result; 459 } 460 try { 461 result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams); 462 } catch (RemoteException e) { 463 // TTS died; restart it. 464 mStarted = false; 465 initTts(); 466 } catch (NullPointerException e) { 467 // TTS died; restart it. 468 mStarted = false; 469 initTts(); 470 } catch (IllegalStateException e) { 471 // TTS died; restart it. 472 mStarted = false; 473 initTts(); 474 } finally { 475 return result; 476 } 477 } 478 } 479 480 481 /** 482 * Returns whether or not the TTS is busy speaking. 483 * 484 * @return Whether or not the TTS is busy speaking. 485 */ 486 public boolean isSpeaking() { 487 synchronized (mStartLock) { 488 if (!mStarted) { 489 return false; 490 } 491 try { 492 return mITts.isSpeaking(); 493 } catch (RemoteException e) { 494 // TTS died; restart it. 495 mStarted = false; 496 initTts(); 497 } catch (NullPointerException e) { 498 // TTS died; restart it. 499 mStarted = false; 500 initTts(); 501 } catch (IllegalStateException e) { 502 // TTS died; restart it. 503 mStarted = false; 504 initTts(); 505 } 506 return false; 507 } 508 } 509 510 511 /** 512 * Stops speech from the TTS. 513 * 514 * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. 515 */ 516 public int stop() { 517 synchronized (mStartLock) { 518 int result = TTS_ERROR; 519 if (!mStarted) { 520 return result; 521 } 522 try { 523 result = mITts.stop(mPackageName); 524 } catch (RemoteException e) { 525 // TTS died; restart it. 526 mStarted = false; 527 initTts(); 528 } catch (NullPointerException e) { 529 // TTS died; restart it. 530 mStarted = false; 531 initTts(); 532 } catch (IllegalStateException e) { 533 // TTS died; restart it. 534 mStarted = false; 535 initTts(); 536 } finally { 537 return result; 538 } 539 } 540 } 541 542 543 /** 544 * Sets the speech rate for the TTS engine. 545 * 546 * Note that the speech rate is not universally supported by all engines and 547 * will be treated as a hint. The TTS library will try to use the specified 548 * speech rate, but there is no guarantee. 549 * This has no effect on any pre-recorded speech. 550 * 551 * @param speechRate 552 * The speech rate for the TTS engine. 1 is the normal speed, 553 * lower values slow down the speech (0.5 is half the normal speech rate), 554 * greater values accelerate it (2 is twice the normal speech rate). 555 * 556 * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. 557 */ 558 public int setSpeechRate(float speechRate) { 559 synchronized (mStartLock) { 560 int result = TTS_ERROR; 561 if (!mStarted) { 562 return result; 563 } 564 try { 565 if (speechRate > 0) { 566 int rate = (int)(speechRate*100); 567 mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] = String.valueOf(rate); 568 result = mITts.setSpeechRate(mPackageName, rate); 569 } 570 } catch (RemoteException e) { 571 // TTS died; restart it. 572 mStarted = false; 573 initTts(); 574 } finally { 575 return result; 576 } 577 } 578 } 579 580 581 /** 582 * Sets the speech pitch for the TTS engine. 583 * 584 * Note that the pitch is not universally supported by all engines and 585 * will be treated as a hint. The TTS library will try to use the specified 586 * pitch, but there is no guarantee. 587 * This has no effect on any pre-recorded speech. 588 * 589 * @param pitch 590 * The pitch for the TTS engine. 1 is the normal pitch, 591 * lower values lower the tone of the synthesized voice, 592 * greater values increase it. 593 * 594 * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. 595 */ 596 public int setPitch(float pitch) { 597 synchronized (mStartLock) { 598 int result = TTS_ERROR; 599 if (!mStarted) { 600 return result; 601 } 602 try { 603 if (pitch > 0) { 604 result = mITts.setPitch(mPackageName, (int)(pitch*100)); 605 } 606 } catch (RemoteException e) { 607 // TTS died; restart it. 608 mStarted = false; 609 initTts(); 610 } finally { 611 return result; 612 } 613 } 614 } 615 616 617 /** 618 * Sets the language for the TTS engine. 619 * 620 * Note that the language is not universally supported by all engines and 621 * will be treated as a hint. The TTS library will try to use the specified 622 * language as represented by the Locale, but there is no guarantee. 623 * 624 * @param loc 625 * The locale describing the language to be used. 626 * 627 * @return Code indicating the support status for the locale. See the TTS_LANG_ codes. 628 */ 629 public int setLanguage(Locale loc) { 630 synchronized (mStartLock) { 631 int result = TTS_LANG_NOT_SUPPORTED; 632 if (!mStarted) { 633 return result; 634 } 635 try { 636 mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language(); 637 mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country(); 638 mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = loc.getVariant(); 639 result = mITts.setLanguage(mPackageName, 640 mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1], 641 mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1], 642 mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] ); 643 } catch (RemoteException e) { 644 // TTS died; restart it. 645 mStarted = false; 646 initTts(); 647 } finally { 648 return result; 649 } 650 } 651 } 652 653 654 /** 655 * Returns a Locale instance describing the language currently being used by the TTS engine. 656 * @return language, country (if any) and variant (if any) used by the engine stored in a Locale 657 * instance, or null is the TTS engine has failed. 658 */ 659 public Locale getLanguage() { 660 synchronized (mStartLock) { 661 if (!mStarted) { 662 return null; 663 } 664 try { 665 String[] locStrings = mITts.getLanguage(); 666 if (locStrings.length == 3) { 667 return new Locale(locStrings[0], locStrings[1], locStrings[2]); 668 } else { 669 return null; 670 } 671 } catch (RemoteException e) { 672 // TTS died; restart it. 673 mStarted = false; 674 initTts(); 675 } 676 return null; 677 } 678 } 679 680 /** 681 * Checks if the specified language as represented by the Locale is available. 682 * 683 * @param loc 684 * The Locale describing the language to be used. 685 * 686 * @return one of TTS_LANG_NOT_SUPPORTED, TTS_LANG_MISSING_DATA, TTS_LANG_AVAILABLE, 687 * TTS_LANG_COUNTRY_AVAILABLE, TTS_LANG_COUNTRY_VAR_AVAILABLE. 688 */ 689 public int isLanguageAvailable(Locale loc) { 690 synchronized (mStartLock) { 691 int result = TTS_LANG_NOT_SUPPORTED; 692 if (!mStarted) { 693 return result; 694 } 695 try { 696 result = mITts.isLanguageAvailable(loc.getISO3Language(), 697 loc.getISO3Country(), loc.getVariant()); 698 } catch (RemoteException e) { 699 // TTS died; restart it. 700 mStarted = false; 701 initTts(); 702 } finally { 703 return result; 704 } 705 } 706 } 707 708 709 /** 710 * Synthesizes the given text to a file using the specified parameters. 711 * 712 * @param text 713 * The String of text that should be synthesized 714 * @param params 715 * A hashmap of parameters. 716 * @param filename 717 * The string that gives the full output filename; it should be 718 * something like "/sdcard/myappsounds/mysound.wav". 719 * 720 * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. 721 */ 722 public int synthesizeToFile(String text, HashMap<String,String> params, 723 String filename) { 724 synchronized (mStartLock) { 725 int result = TTS_ERROR; 726 if (!mStarted) { 727 return result; 728 } 729 try { 730 // no need to read the stream type here 731 String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); 732 if (extra != null) { 733 mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID] = extra; 734 } 735 if (mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename)){ 736 result = TTS_SUCCESS; 737 } 738 } catch (RemoteException e) { 739 // TTS died; restart it. 740 mStarted = false; 741 initTts(); 742 } catch (NullPointerException e) { 743 // TTS died; restart it. 744 mStarted = false; 745 initTts(); 746 } catch (IllegalStateException e) { 747 // TTS died; restart it. 748 mStarted = false; 749 initTts(); 750 } finally { 751 resetCachedParams(); 752 return result; 753 } 754 } 755 } 756 757 758 /** 759 * Convenience method to reset the cached parameters to the current default values 760 * if they are not persistent between calls to the service. 761 */ 762 private void resetCachedParams() { 763 mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = 764 String.valueOf(Engine.TTS_DEFAULT_STREAM); 765 mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID+ 1] = ""; 766 } 767 768} 769