TextToSpeech.java revision dc871fd870972bd704d720fae45bcbbcc5905173
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.annotation.SdkConstant; 22import android.annotation.SdkConstant.SdkConstantType; 23import android.content.ComponentName; 24import android.content.Context; 25import android.content.Intent; 26import android.content.ServiceConnection; 27import android.media.AudioManager; 28import android.os.IBinder; 29import android.os.RemoteException; 30import android.util.Log; 31 32import java.util.HashMap; 33import java.util.Locale; 34 35/** 36 * 37 * Synthesizes speech from text for immediate playback or to create a sound file. 38 * <p>A TextToSpeech instance can only be used to synthesize text once it has completed its 39 * initialization. Implement the {@link TextToSpeech.OnInitListener} to be 40 * notified of the completion of the initialization.<br> 41 * When you are done using the TextToSpeech instance, call the {@link #shutdown()} method 42 * to release the native resources used by the TextToSpeech engine. 43 * 44 */ 45public class TextToSpeech { 46 47 /** 48 * Denotes a successful operation. 49 */ 50 public static final int SUCCESS = 0; 51 /** 52 * Denotes a generic operation failure. 53 */ 54 public static final int ERROR = -1; 55 56 /** 57 * Queue mode where all entries in the playback queue (media to be played 58 * and text to be synthesized) are dropped and replaced by the new entry. 59 */ 60 public static final int QUEUE_FLUSH = 0; 61 /** 62 * Queue mode where the new entry is added at the end of the playback queue. 63 */ 64 public static final int QUEUE_ADD = 1; 65 66 67 /** 68 * Denotes the language is available exactly as specified by the locale. 69 */ 70 public static final int LANG_COUNTRY_VAR_AVAILABLE = 2; 71 72 73 /** 74 * Denotes the language is available for the language and country specified 75 * by the locale, but not the variant. 76 */ 77 public static final int LANG_COUNTRY_AVAILABLE = 1; 78 79 80 /** 81 * Denotes the language is available for the language by the locale, 82 * but not the country and variant. 83 */ 84 public static final int LANG_AVAILABLE = 0; 85 86 /** 87 * Denotes the language data is missing. 88 */ 89 public static final int LANG_MISSING_DATA = -1; 90 91 /** 92 * Denotes the language is not supported. 93 */ 94 public static final int LANG_NOT_SUPPORTED = -2; 95 96 97 /** 98 * Broadcast Action: The TextToSpeech synthesizer has completed processing 99 * of all the text in the speech queue. 100 */ 101 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 102 public static final String ACTION_TTS_QUEUE_PROCESSING_COMPLETED = 103 "android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED"; 104 105 106 /** 107 * Interface definition of a callback to be invoked indicating the completion of the 108 * TextToSpeech engine initialization. 109 */ 110 public interface OnInitListener { 111 /** 112 * Called to signal the completion of the TextToSpeech engine initialization. 113 * @param status {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}. 114 */ 115 public void onInit(int status); 116 } 117 118 /** 119 * Interface definition of a callback to be invoked indicating the TextToSpeech engine has 120 * completed synthesizing an utterance with an utterance ID set. 121 * 122 */ 123 public interface OnUtteranceCompletedListener { 124 /** 125 * Called to signal the completion of the synthesis of the utterance that was identified 126 * with the string parameter. This identifier is the one originally passed in the 127 * parameter hashmap of the synthesis request in 128 * {@link TextToSpeech#speak(String, int, HashMap)} or 129 * {@link TextToSpeech#synthesizeToFile(String, HashMap, String)} with the 130 * {@link TextToSpeech.Engine#KEY_PARAM_UTTERANCE_ID} key. 131 * @param utteranceId the identifier of the utterance. 132 */ 133 public void onUtteranceCompleted(String utteranceId); 134 } 135 136 137 /** 138 * Internal constants for the TextToSpeech functionality 139 * 140 */ 141 public class Engine { 142 // default values for a TTS engine when settings are not found in the provider 143 /** 144 * {@hide} 145 */ 146 public static final int DEFAULT_RATE = 100; // 1x 147 /** 148 * {@hide} 149 */ 150 public static final int DEFAULT_PITCH = 100;// 1x 151 /** 152 * {@hide} 153 */ 154 public static final float DEFAULT_VOLUME = 1.0f; 155 /** 156 * {@hide} 157 */ 158 protected static final String DEFAULT_VOLUME_STRING = "1.0"; 159 /** 160 * {@hide} 161 */ 162 public static final float DEFAULT_PAN = 0.0f; 163 /** 164 * {@hide} 165 */ 166 protected static final String DEFAULT_PAN_STRING = "0.0"; 167 168 /** 169 * {@hide} 170 */ 171 public static final int USE_DEFAULTS = 0; // false 172 /** 173 * {@hide} 174 */ 175 public static final String DEFAULT_SYNTH = "com.svox.pico"; 176 177 // default values for rendering 178 /** 179 * Default audio stream used when playing synthesized speech. 180 */ 181 public static final int DEFAULT_STREAM = AudioManager.STREAM_MUSIC; 182 183 // return codes for a TTS engine's check data activity 184 /** 185 * Indicates success when checking the installation status of the resources used by the 186 * TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. 187 */ 188 public static final int CHECK_VOICE_DATA_PASS = 1; 189 /** 190 * Indicates failure when checking the installation status of the resources used by the 191 * TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. 192 */ 193 public static final int CHECK_VOICE_DATA_FAIL = 0; 194 /** 195 * Indicates erroneous data when checking the installation status of the resources used by 196 * the TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. 197 */ 198 public static final int CHECK_VOICE_DATA_BAD_DATA = -1; 199 /** 200 * Indicates missing resources when checking the installation status of the resources used 201 * by the TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. 202 */ 203 public static final int CHECK_VOICE_DATA_MISSING_DATA = -2; 204 /** 205 * Indicates missing storage volume when checking the installation status of the resources 206 * used by the TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent. 207 */ 208 public static final int CHECK_VOICE_DATA_MISSING_VOLUME = -3; 209 210 // intents to ask engine to install data or check its data 211 /** 212 * Activity Action: Triggers the platform TextToSpeech engine to 213 * start the activity that installs the resource files on the device 214 * that are required for TTS to be operational. Since the installation 215 * of the data can be interrupted or declined by the user, the application 216 * shouldn't expect successful installation upon return from that intent, 217 * and if need be, should check installation status with 218 * {@link #ACTION_CHECK_TTS_DATA}. 219 */ 220 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 221 public static final String ACTION_INSTALL_TTS_DATA = 222 "android.speech.tts.engine.INSTALL_TTS_DATA"; 223 224 /** 225 * Broadcast Action: broadcast to signal the completion of the installation of 226 * the data files used by the synthesis engine. Success or failure is indicated in the 227 * {@link #EXTRA_TTS_DATA_INSTALLED} extra. 228 */ 229 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 230 public static final String ACTION_TTS_DATA_INSTALLED = 231 "android.speech.tts.engine.TTS_DATA_INSTALLED"; 232 /** 233 * Activity Action: Starts the activity from the platform TextToSpeech 234 * engine to verify the proper installation and availability of the 235 * resource files on the system. Upon completion, the activity will 236 * return one of the following codes: 237 * {@link #CHECK_VOICE_DATA_PASS}, 238 * {@link #CHECK_VOICE_DATA_FAIL}, 239 * {@link #CHECK_VOICE_DATA_BAD_DATA}, 240 * {@link #CHECK_VOICE_DATA_MISSING_DATA}, or 241 * {@link #CHECK_VOICE_DATA_MISSING_VOLUME}. 242 * <p> Moreover, the data received in the activity result will contain the following 243 * fields: 244 * <ul> 245 * <li>{@link #EXTRA_VOICE_DATA_ROOT_DIRECTORY} which 246 * indicates the path to the location of the resource files,</li> 247 * <li>{@link #EXTRA_VOICE_DATA_FILES} which contains 248 * the list of all the resource files,</li> 249 * <li>and {@link #EXTRA_VOICE_DATA_FILES_INFO} which 250 * contains, for each resource file, the description of the language covered by 251 * the file in the xxx-YYY format, where xxx is the 3-letter ISO language code, 252 * and YYY is the 3-letter ISO country code.</li> 253 * </ul> 254 */ 255 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 256 public static final String ACTION_CHECK_TTS_DATA = 257 "android.speech.tts.engine.CHECK_TTS_DATA"; 258 259 // extras for a TTS engine's check data activity 260 /** 261 * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where 262 * the TextToSpeech engine specifies the path to its resources. 263 */ 264 public static final String EXTRA_VOICE_DATA_ROOT_DIRECTORY = "dataRoot"; 265 /** 266 * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where 267 * the TextToSpeech engine specifies the file names of its resources under the 268 * resource path. 269 */ 270 public static final String EXTRA_VOICE_DATA_FILES = "dataFiles"; 271 /** 272 * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where 273 * the TextToSpeech engine specifies the locale associated with each resource file. 274 */ 275 public static final String EXTRA_VOICE_DATA_FILES_INFO = "dataFilesInfo"; 276 /** 277 * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where 278 * the TextToSpeech engine returns an ArrayList<String> of all the available voices. 279 * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are 280 * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE"). 281 */ 282 public static final String EXTRA_AVAILABLE_VOICES = "availableVoices"; 283 /** 284 * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where 285 * the TextToSpeech engine returns an ArrayList<String> of all the unavailable voices. 286 * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are 287 * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE"). 288 */ 289 public static final String EXTRA_UNAVAILABLE_VOICES = "unavailableVoices"; 290 /** 291 * Extra information sent with the {@link #ACTION_CHECK_TTS_DATA} intent where the 292 * caller indicates to the TextToSpeech engine which specific sets of voice data to 293 * check for by sending an ArrayList<String> of the voices that are of interest. 294 * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are 295 * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE"). 296 */ 297 public static final String EXTRA_CHECK_VOICE_DATA_FOR = "checkVoiceDataFor"; 298 299 // extras for a TTS engine's data installation 300 /** 301 * Extra information received with the {@link #ACTION_TTS_DATA_INSTALLED} intent. 302 * It indicates whether the data files for the synthesis engine were successfully 303 * installed. The installation was initiated with the {@link #ACTION_INSTALL_TTS_DATA} 304 * intent. The possible values for this extra are 305 * {@link TextToSpeech#SUCCESS} and {@link TextToSpeech#ERROR}. 306 */ 307 public static final String EXTRA_TTS_DATA_INSTALLED = "dataInstalled"; 308 309 // keys for the parameters passed with speak commands. Hidden keys are used internally 310 // to maintain engine state for each TextToSpeech instance. 311 /** 312 * {@hide} 313 */ 314 public static final String KEY_PARAM_RATE = "rate"; 315 /** 316 * {@hide} 317 */ 318 public static final String KEY_PARAM_LANGUAGE = "language"; 319 /** 320 * {@hide} 321 */ 322 public static final String KEY_PARAM_COUNTRY = "country"; 323 /** 324 * {@hide} 325 */ 326 public static final String KEY_PARAM_VARIANT = "variant"; 327 /** 328 * {@hide} 329 */ 330 public static final String KEY_PARAM_ENGINE = "engine"; 331 /** 332 * {@hide} 333 */ 334 public static final String KEY_PARAM_PITCH = "pitch"; 335 /** 336 * Parameter key to specify the audio stream type to be used when speaking text 337 * or playing back a file. 338 * @see TextToSpeech#speak(String, int, HashMap) 339 * @see TextToSpeech#playEarcon(String, int, HashMap) 340 */ 341 public static final String KEY_PARAM_STREAM = "streamType"; 342 /** 343 * Parameter key to identify an utterance in the 344 * {@link TextToSpeech.OnUtteranceCompletedListener} after text has been 345 * spoken, a file has been played back or a silence duration has elapsed. 346 * @see TextToSpeech#speak(String, int, HashMap) 347 * @see TextToSpeech#playEarcon(String, int, HashMap) 348 * @see TextToSpeech#synthesizeToFile(String, HashMap, String) 349 */ 350 public static final String KEY_PARAM_UTTERANCE_ID = "utteranceId"; 351 /** 352 * Parameter key to specify the speech volume relative to the current stream type 353 * volume used when speaking text. Volume is specified as a float ranging from 0 to 1 354 * where 0 is silence, and 1 is the maximum volume (the default behavior). 355 * @see TextToSpeech#speak(String, int, HashMap) 356 * @see TextToSpeech#playEarcon(String, int, HashMap) 357 */ 358 public static final String KEY_PARAM_VOLUME = "volume"; 359 /** 360 * Parameter key to specify how the speech is panned from left to right when speaking text. 361 * Pan is specified as a float ranging from -1 to +1 where -1 maps to a hard-left pan, 362 * 0 to center (the default behavior), and +1 to hard-right. 363 * @see TextToSpeech#speak(String, int, HashMap) 364 * @see TextToSpeech#playEarcon(String, int, HashMap) 365 */ 366 public static final String KEY_PARAM_PAN = "pan"; 367 368 // key positions in the array of cached parameters 369 /** 370 * {@hide} 371 */ 372 protected static final int PARAM_POSITION_RATE = 0; 373 /** 374 * {@hide} 375 */ 376 protected static final int PARAM_POSITION_LANGUAGE = 2; 377 /** 378 * {@hide} 379 */ 380 protected static final int PARAM_POSITION_COUNTRY = 4; 381 /** 382 * {@hide} 383 */ 384 protected static final int PARAM_POSITION_VARIANT = 6; 385 /** 386 * {@hide} 387 */ 388 protected static final int PARAM_POSITION_STREAM = 8; 389 /** 390 * {@hide} 391 */ 392 protected static final int PARAM_POSITION_UTTERANCE_ID = 10; 393 394 /** 395 * {@hide} 396 */ 397 protected static final int PARAM_POSITION_ENGINE = 12; 398 399 /** 400 * {@hide} 401 */ 402 protected static final int PARAM_POSITION_PITCH = 14; 403 404 /** 405 * {@hide} 406 */ 407 protected static final int PARAM_POSITION_VOLUME = 16; 408 409 /** 410 * {@hide} 411 */ 412 protected static final int PARAM_POSITION_PAN = 18; 413 414 415 /** 416 * {@hide} 417 */ 418 protected static final int NB_CACHED_PARAMS = 20; 419 } 420 421 /** 422 * Connection needed for the TTS. 423 */ 424 private ServiceConnection mServiceConnection; 425 426 private ITts mITts = null; 427 private ITtsCallback mITtscallback = null; 428 private Context mContext = null; 429 private String mPackageName = ""; 430 private OnInitListener mInitListener = null; 431 private boolean mStarted = false; 432 private final Object mStartLock = new Object(); 433 /** 434 * Used to store the cached parameters sent along with each synthesis request to the 435 * TTS service. 436 */ 437 private String[] mCachedParams; 438 439 /** 440 * The constructor for the TextToSpeech class. 441 * This will also initialize the associated TextToSpeech engine if it isn't already running. 442 * 443 * @param context 444 * The context this instance is running in. 445 * @param listener 446 * The {@link TextToSpeech.OnInitListener} that will be called when the 447 * TextToSpeech engine has initialized. 448 */ 449 public TextToSpeech(Context context, OnInitListener listener) { 450 mContext = context; 451 mPackageName = mContext.getPackageName(); 452 mInitListener = listener; 453 454 mCachedParams = new String[2*Engine.NB_CACHED_PARAMS]; // store key and value 455 mCachedParams[Engine.PARAM_POSITION_RATE] = Engine.KEY_PARAM_RATE; 456 mCachedParams[Engine.PARAM_POSITION_LANGUAGE] = Engine.KEY_PARAM_LANGUAGE; 457 mCachedParams[Engine.PARAM_POSITION_COUNTRY] = Engine.KEY_PARAM_COUNTRY; 458 mCachedParams[Engine.PARAM_POSITION_VARIANT] = Engine.KEY_PARAM_VARIANT; 459 mCachedParams[Engine.PARAM_POSITION_STREAM] = Engine.KEY_PARAM_STREAM; 460 mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID] = Engine.KEY_PARAM_UTTERANCE_ID; 461 mCachedParams[Engine.PARAM_POSITION_ENGINE] = Engine.KEY_PARAM_ENGINE; 462 mCachedParams[Engine.PARAM_POSITION_PITCH] = Engine.KEY_PARAM_PITCH; 463 mCachedParams[Engine.PARAM_POSITION_VOLUME] = Engine.KEY_PARAM_VOLUME; 464 mCachedParams[Engine.PARAM_POSITION_PAN] = Engine.KEY_PARAM_PAN; 465 466 // Leave all defaults that are shown in Settings uninitialized/at the default 467 // so that the values set in Settings will take effect if the application does 468 // not try to change these settings itself. 469 mCachedParams[Engine.PARAM_POSITION_RATE + 1] = ""; 470 mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = ""; 471 mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = ""; 472 mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = ""; 473 mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = 474 String.valueOf(Engine.DEFAULT_STREAM); 475 mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = ""; 476 mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = ""; 477 mCachedParams[Engine.PARAM_POSITION_PITCH + 1] = "100"; 478 mCachedParams[Engine.PARAM_POSITION_VOLUME + 1] = Engine.DEFAULT_VOLUME_STRING; 479 mCachedParams[Engine.PARAM_POSITION_PAN + 1] = Engine.DEFAULT_PAN_STRING; 480 481 initTts(); 482 } 483 484 485 private void initTts() { 486 mStarted = false; 487 488 // Initialize the TTS, run the callback after the binding is successful 489 mServiceConnection = new ServiceConnection() { 490 public void onServiceConnected(ComponentName name, IBinder service) { 491 synchronized(mStartLock) { 492 mITts = ITts.Stub.asInterface(service); 493 mStarted = true; 494 // Cache the default engine and current language 495 setEngineByPackageName(getDefaultEngine()); 496 setLanguage(getLanguage()); 497 if (mInitListener != null) { 498 // TODO manage failures and missing resources 499 mInitListener.onInit(SUCCESS); 500 } 501 } 502 } 503 504 public void onServiceDisconnected(ComponentName name) { 505 synchronized(mStartLock) { 506 mITts = null; 507 mInitListener = null; 508 mStarted = false; 509 } 510 } 511 }; 512 513 Intent intent = new Intent("android.intent.action.START_TTS_SERVICE"); 514 intent.addCategory("android.intent.category.TTS"); 515 boolean bound = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); 516 if (!bound) { 517 Log.e("TextToSpeech.java", "initTts() failed to bind to service"); 518 if (mInitListener != null) { 519 mInitListener.onInit(ERROR); 520 } 521 } else { 522 // initialization listener will be called inside ServiceConnection 523 Log.i("TextToSpeech.java", "initTts() successfully bound to service"); 524 } 525 // TODO handle plugin failures 526 } 527 528 529 /** 530 * Releases the resources used by the TextToSpeech engine. 531 * It is good practice for instance to call this method in the onDestroy() method of an Activity 532 * so the TextToSpeech engine can be cleanly stopped. 533 */ 534 public void shutdown() { 535 try { 536 mContext.unbindService(mServiceConnection); 537 } catch (IllegalArgumentException e) { 538 // Do nothing and fail silently since an error here indicates that 539 // binding never succeeded in the first place. 540 } 541 } 542 543 544 /** 545 * Adds a mapping between a string of text and a sound resource in a 546 * package. After a call to this method, subsequent calls to 547 * {@link #speak(String, int, HashMap)} will play the specified sound resource 548 * if it is available, or synthesize the text it is missing. 549 * 550 * @param text 551 * The string of text. Example: <code>"south_south_east"</code> 552 * 553 * @param packagename 554 * Pass the packagename of the application that contains the 555 * resource. If the resource is in your own application (this is 556 * the most common case), then put the packagename of your 557 * application here.<br/> 558 * Example: <b>"com.google.marvin.compass"</b><br/> 559 * The packagename can be found in the AndroidManifest.xml of 560 * your application. 561 * <p> 562 * <code><manifest xmlns:android="..." 563 * package="<b>com.google.marvin.compass</b>"></code> 564 * </p> 565 * 566 * @param resourceId 567 * Example: <code>R.raw.south_south_east</code> 568 * 569 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 570 */ 571 public int addSpeech(String text, String packagename, int resourceId) { 572 synchronized(mStartLock) { 573 if (!mStarted) { 574 return ERROR; 575 } 576 try { 577 mITts.addSpeech(mPackageName, text, packagename, resourceId); 578 return SUCCESS; 579 } catch (RemoteException e) { 580 // TTS died; restart it. 581 Log.e("TextToSpeech.java - addSpeech", "RemoteException"); 582 e.printStackTrace(); 583 mStarted = false; 584 initTts(); 585 } catch (NullPointerException e) { 586 // TTS died; restart it. 587 Log.e("TextToSpeech.java - addSpeech", "NullPointerException"); 588 e.printStackTrace(); 589 mStarted = false; 590 initTts(); 591 } catch (IllegalStateException e) { 592 // TTS died; restart it. 593 Log.e("TextToSpeech.java - addSpeech", "IllegalStateException"); 594 e.printStackTrace(); 595 mStarted = false; 596 initTts(); 597 } 598 return ERROR; 599 } 600 } 601 602 603 /** 604 * Adds a mapping between a string of text and a sound file. Using this, it 605 * is possible to add custom pronounciations for a string of text. 606 * After a call to this method, subsequent calls to {@link #speak(String, int, HashMap)} 607 * will play the specified sound resource if it is available, or synthesize the text it is 608 * missing. 609 * 610 * @param text 611 * The string of text. Example: <code>"south_south_east"</code> 612 * @param filename 613 * The full path to the sound file (for example: 614 * "/sdcard/mysounds/hello.wav") 615 * 616 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 617 */ 618 public int addSpeech(String text, String filename) { 619 synchronized (mStartLock) { 620 if (!mStarted) { 621 return ERROR; 622 } 623 try { 624 mITts.addSpeechFile(mPackageName, text, filename); 625 return SUCCESS; 626 } catch (RemoteException e) { 627 // TTS died; restart it. 628 Log.e("TextToSpeech.java - addSpeech", "RemoteException"); 629 e.printStackTrace(); 630 mStarted = false; 631 initTts(); 632 } catch (NullPointerException e) { 633 // TTS died; restart it. 634 Log.e("TextToSpeech.java - addSpeech", "NullPointerException"); 635 e.printStackTrace(); 636 mStarted = false; 637 initTts(); 638 } catch (IllegalStateException e) { 639 // TTS died; restart it. 640 Log.e("TextToSpeech.java - addSpeech", "IllegalStateException"); 641 e.printStackTrace(); 642 mStarted = false; 643 initTts(); 644 } 645 return ERROR; 646 } 647 } 648 649 650 /** 651 * Adds a mapping between a string of text and a sound resource in a 652 * package. Use this to add custom earcons. 653 * 654 * @see #playEarcon(String, int, HashMap) 655 * 656 * @param earcon The name of the earcon. 657 * Example: <code>"[tick]"</code><br/> 658 * 659 * @param packagename 660 * the package name of the application that contains the 661 * resource. This can for instance be the package name of your own application. 662 * Example: <b>"com.google.marvin.compass"</b><br/> 663 * The package name can be found in the AndroidManifest.xml of 664 * the application containing the resource. 665 * <p> 666 * <code><manifest xmlns:android="..." 667 * package="<b>com.google.marvin.compass</b>"></code> 668 * </p> 669 * 670 * @param resourceId 671 * Example: <code>R.raw.tick_snd</code> 672 * 673 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 674 */ 675 public int addEarcon(String earcon, String packagename, int resourceId) { 676 synchronized(mStartLock) { 677 if (!mStarted) { 678 return ERROR; 679 } 680 try { 681 mITts.addEarcon(mPackageName, earcon, packagename, resourceId); 682 return SUCCESS; 683 } catch (RemoteException e) { 684 // TTS died; restart it. 685 Log.e("TextToSpeech.java - addEarcon", "RemoteException"); 686 e.printStackTrace(); 687 mStarted = false; 688 initTts(); 689 } catch (NullPointerException e) { 690 // TTS died; restart it. 691 Log.e("TextToSpeech.java - addEarcon", "NullPointerException"); 692 e.printStackTrace(); 693 mStarted = false; 694 initTts(); 695 } catch (IllegalStateException e) { 696 // TTS died; restart it. 697 Log.e("TextToSpeech.java - addEarcon", "IllegalStateException"); 698 e.printStackTrace(); 699 mStarted = false; 700 initTts(); 701 } 702 return ERROR; 703 } 704 } 705 706 707 /** 708 * Adds a mapping between a string of text and a sound file. 709 * Use this to add custom earcons. 710 * 711 * @see #playEarcon(String, int, HashMap) 712 * 713 * @param earcon 714 * The name of the earcon. 715 * Example: <code>"[tick]"</code> 716 * @param filename 717 * The full path to the sound file (for example: 718 * "/sdcard/mysounds/tick.wav") 719 * 720 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 721 */ 722 public int addEarcon(String earcon, String filename) { 723 synchronized (mStartLock) { 724 if (!mStarted) { 725 return ERROR; 726 } 727 try { 728 mITts.addEarconFile(mPackageName, earcon, filename); 729 return SUCCESS; 730 } catch (RemoteException e) { 731 // TTS died; restart it. 732 Log.e("TextToSpeech.java - addEarcon", "RemoteException"); 733 e.printStackTrace(); 734 mStarted = false; 735 initTts(); 736 } catch (NullPointerException e) { 737 // TTS died; restart it. 738 Log.e("TextToSpeech.java - addEarcon", "NullPointerException"); 739 e.printStackTrace(); 740 mStarted = false; 741 initTts(); 742 } catch (IllegalStateException e) { 743 // TTS died; restart it. 744 Log.e("TextToSpeech.java - addEarcon", "IllegalStateException"); 745 e.printStackTrace(); 746 mStarted = false; 747 initTts(); 748 } 749 return ERROR; 750 } 751 } 752 753 754 /** 755 * Speaks the string using the specified queuing strategy and speech 756 * parameters. 757 * 758 * @param text 759 * The string of text to be spoken. 760 * @param queueMode 761 * The queuing strategy to use. 762 * {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}. 763 * @param params 764 * The list of parameters to be used. Can be null if no parameters are given. 765 * They are specified using a (key, value) pair, where the key can be 766 * {@link Engine#KEY_PARAM_STREAM} or 767 * {@link Engine#KEY_PARAM_UTTERANCE_ID}. 768 * 769 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 770 */ 771 public int speak(String text, int queueMode, HashMap<String,String> params) 772 { 773 synchronized (mStartLock) { 774 int result = ERROR; 775 Log.i("TextToSpeech.java - speak", "speak text of length " + text.length()); 776 if (!mStarted) { 777 Log.e("TextToSpeech.java - speak", "service isn't started"); 778 return result; 779 } 780 try { 781 if ((params != null) && (!params.isEmpty())) { 782 setCachedParam(params, Engine.KEY_PARAM_STREAM, Engine.PARAM_POSITION_STREAM); 783 setCachedParam(params, Engine.KEY_PARAM_UTTERANCE_ID, 784 Engine.PARAM_POSITION_UTTERANCE_ID); 785 setCachedParam(params, Engine.KEY_PARAM_ENGINE, Engine.PARAM_POSITION_ENGINE); 786 setCachedParam(params, Engine.KEY_PARAM_VOLUME, Engine.PARAM_POSITION_VOLUME); 787 setCachedParam(params, Engine.KEY_PARAM_PAN, Engine.PARAM_POSITION_PAN); 788 } 789 result = mITts.speak(mPackageName, text, queueMode, mCachedParams); 790 } catch (RemoteException e) { 791 // TTS died; restart it. 792 Log.e("TextToSpeech.java - speak", "RemoteException"); 793 e.printStackTrace(); 794 mStarted = false; 795 initTts(); 796 } catch (NullPointerException e) { 797 // TTS died; restart it. 798 Log.e("TextToSpeech.java - speak", "NullPointerException"); 799 e.printStackTrace(); 800 mStarted = false; 801 initTts(); 802 } catch (IllegalStateException e) { 803 // TTS died; restart it. 804 Log.e("TextToSpeech.java - speak", "IllegalStateException"); 805 e.printStackTrace(); 806 mStarted = false; 807 initTts(); 808 } finally { 809 resetCachedParams(); 810 return result; 811 } 812 } 813 } 814 815 816 /** 817 * Plays the earcon using the specified queueing mode and parameters. 818 * 819 * @param earcon 820 * The earcon that should be played 821 * @param queueMode 822 * {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}. 823 * @param params 824 * The list of parameters to be used. Can be null if no parameters are given. 825 * They are specified using a (key, value) pair, where the key can be 826 * {@link Engine#KEY_PARAM_STREAM} or 827 * {@link Engine#KEY_PARAM_UTTERANCE_ID}. 828 * 829 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 830 */ 831 public int playEarcon(String earcon, int queueMode, 832 HashMap<String,String> params) { 833 synchronized (mStartLock) { 834 int result = ERROR; 835 if (!mStarted) { 836 return result; 837 } 838 try { 839 if ((params != null) && (!params.isEmpty())) { 840 String extra = params.get(Engine.KEY_PARAM_STREAM); 841 if (extra != null) { 842 mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra; 843 } 844 setCachedParam(params, Engine.KEY_PARAM_STREAM, Engine.PARAM_POSITION_STREAM); 845 setCachedParam(params, Engine.KEY_PARAM_UTTERANCE_ID, 846 Engine.PARAM_POSITION_UTTERANCE_ID); 847 } 848 result = mITts.playEarcon(mPackageName, earcon, queueMode, null); 849 } catch (RemoteException e) { 850 // TTS died; restart it. 851 Log.e("TextToSpeech.java - playEarcon", "RemoteException"); 852 e.printStackTrace(); 853 mStarted = false; 854 initTts(); 855 } catch (NullPointerException e) { 856 // TTS died; restart it. 857 Log.e("TextToSpeech.java - playEarcon", "NullPointerException"); 858 e.printStackTrace(); 859 mStarted = false; 860 initTts(); 861 } catch (IllegalStateException e) { 862 // TTS died; restart it. 863 Log.e("TextToSpeech.java - playEarcon", "IllegalStateException"); 864 e.printStackTrace(); 865 mStarted = false; 866 initTts(); 867 } finally { 868 resetCachedParams(); 869 return result; 870 } 871 } 872 } 873 874 /** 875 * Plays silence for the specified amount of time using the specified 876 * queue mode. 877 * 878 * @param durationInMs 879 * A long that indicates how long the silence should last. 880 * @param queueMode 881 * {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}. 882 * @param params 883 * The list of parameters to be used. Can be null if no parameters are given. 884 * They are specified using a (key, value) pair, where the key can be 885 * {@link Engine#KEY_PARAM_UTTERANCE_ID}. 886 * 887 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 888 */ 889 public int playSilence(long durationInMs, int queueMode, HashMap<String,String> params) { 890 synchronized (mStartLock) { 891 int result = ERROR; 892 if (!mStarted) { 893 return result; 894 } 895 try { 896 if ((params != null) && (!params.isEmpty())) { 897 setCachedParam(params, Engine.KEY_PARAM_UTTERANCE_ID, 898 Engine.PARAM_POSITION_UTTERANCE_ID); 899 } 900 result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams); 901 } catch (RemoteException e) { 902 // TTS died; restart it. 903 Log.e("TextToSpeech.java - playSilence", "RemoteException"); 904 e.printStackTrace(); 905 mStarted = false; 906 initTts(); 907 } catch (NullPointerException e) { 908 // TTS died; restart it. 909 Log.e("TextToSpeech.java - playSilence", "NullPointerException"); 910 e.printStackTrace(); 911 mStarted = false; 912 initTts(); 913 } catch (IllegalStateException e) { 914 // TTS died; restart it. 915 Log.e("TextToSpeech.java - playSilence", "IllegalStateException"); 916 e.printStackTrace(); 917 mStarted = false; 918 initTts(); 919 } finally { 920 resetCachedParams(); 921 return result; 922 } 923 } 924 } 925 926 927 /** 928 * Returns whether or not the TextToSpeech engine is busy speaking. 929 * 930 * @return Whether or not the TextToSpeech engine is busy speaking. 931 */ 932 public boolean isSpeaking() { 933 synchronized (mStartLock) { 934 if (!mStarted) { 935 return false; 936 } 937 try { 938 return mITts.isSpeaking(); 939 } catch (RemoteException e) { 940 // TTS died; restart it. 941 Log.e("TextToSpeech.java - isSpeaking", "RemoteException"); 942 e.printStackTrace(); 943 mStarted = false; 944 initTts(); 945 } catch (NullPointerException e) { 946 // TTS died; restart it. 947 Log.e("TextToSpeech.java - isSpeaking", "NullPointerException"); 948 e.printStackTrace(); 949 mStarted = false; 950 initTts(); 951 } catch (IllegalStateException e) { 952 // TTS died; restart it. 953 Log.e("TextToSpeech.java - isSpeaking", "IllegalStateException"); 954 e.printStackTrace(); 955 mStarted = false; 956 initTts(); 957 } 958 return false; 959 } 960 } 961 962 963 /** 964 * Interrupts the current utterance (whether played or rendered to file) and discards other 965 * utterances in the queue. 966 * 967 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 968 */ 969 public int stop() { 970 synchronized (mStartLock) { 971 int result = ERROR; 972 if (!mStarted) { 973 return result; 974 } 975 try { 976 result = mITts.stop(mPackageName); 977 } catch (RemoteException e) { 978 // TTS died; restart it. 979 Log.e("TextToSpeech.java - stop", "RemoteException"); 980 e.printStackTrace(); 981 mStarted = false; 982 initTts(); 983 } catch (NullPointerException e) { 984 // TTS died; restart it. 985 Log.e("TextToSpeech.java - stop", "NullPointerException"); 986 e.printStackTrace(); 987 mStarted = false; 988 initTts(); 989 } catch (IllegalStateException e) { 990 // TTS died; restart it. 991 Log.e("TextToSpeech.java - stop", "IllegalStateException"); 992 e.printStackTrace(); 993 mStarted = false; 994 initTts(); 995 } finally { 996 return result; 997 } 998 } 999 } 1000 1001 1002 /** 1003 * Sets the speech rate for the TextToSpeech engine. 1004 * 1005 * This has no effect on any pre-recorded speech. 1006 * 1007 * @param speechRate 1008 * The speech rate for the TextToSpeech engine. 1 is the normal speed, 1009 * lower values slow down the speech (0.5 is half the normal speech rate), 1010 * greater values accelerate it (2 is twice the normal speech rate). 1011 * 1012 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 1013 */ 1014 public int setSpeechRate(float speechRate) { 1015 synchronized (mStartLock) { 1016 int result = ERROR; 1017 if (!mStarted) { 1018 return result; 1019 } 1020 try { 1021 if (speechRate > 0) { 1022 int rate = (int)(speechRate*100); 1023 mCachedParams[Engine.PARAM_POSITION_RATE + 1] = String.valueOf(rate); 1024 // the rate is not set here, instead it is cached so it will be associated 1025 // with all upcoming utterances. 1026 if (speechRate > 0.0f) { 1027 result = SUCCESS; 1028 } else { 1029 result = ERROR; 1030 } 1031 } 1032 } catch (NullPointerException e) { 1033 // TTS died; restart it. 1034 Log.e("TextToSpeech.java - setSpeechRate", "NullPointerException"); 1035 e.printStackTrace(); 1036 mStarted = false; 1037 initTts(); 1038 } catch (IllegalStateException e) { 1039 // TTS died; restart it. 1040 Log.e("TextToSpeech.java - setSpeechRate", "IllegalStateException"); 1041 e.printStackTrace(); 1042 mStarted = false; 1043 initTts(); 1044 } finally { 1045 return result; 1046 } 1047 } 1048 } 1049 1050 1051 /** 1052 * Sets the speech pitch for the TextToSpeech engine. 1053 * 1054 * This has no effect on any pre-recorded speech. 1055 * 1056 * @param pitch 1057 * The pitch for the TextToSpeech engine. 1 is the normal pitch, 1058 * lower values lower the tone of the synthesized voice, 1059 * greater values increase it. 1060 * 1061 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 1062 */ 1063 public int setPitch(float pitch) { 1064 synchronized (mStartLock) { 1065 int result = ERROR; 1066 if (!mStarted) { 1067 return result; 1068 } 1069 try { 1070 // the pitch is not set here, instead it is cached so it will be associated 1071 // with all upcoming utterances. 1072 if (pitch > 0) { 1073 int p = (int)(pitch*100); 1074 mCachedParams[Engine.PARAM_POSITION_PITCH + 1] = String.valueOf(p); 1075 result = SUCCESS; 1076 } 1077 } catch (NullPointerException e) { 1078 // TTS died; restart it. 1079 Log.e("TextToSpeech.java - setPitch", "NullPointerException"); 1080 e.printStackTrace(); 1081 mStarted = false; 1082 initTts(); 1083 } catch (IllegalStateException e) { 1084 // TTS died; restart it. 1085 Log.e("TextToSpeech.java - setPitch", "IllegalStateException"); 1086 e.printStackTrace(); 1087 mStarted = false; 1088 initTts(); 1089 } finally { 1090 return result; 1091 } 1092 } 1093 } 1094 1095 1096 /** 1097 * Sets the language for the TextToSpeech engine. 1098 * The TextToSpeech engine will try to use the closest match to the specified 1099 * language as represented by the Locale, but there is no guarantee that the exact same Locale 1100 * will be used. Use {@link #isLanguageAvailable(Locale)} to check the level of support 1101 * before choosing the language to use for the next utterances. 1102 * 1103 * @param loc 1104 * The locale describing the language to be used. 1105 * 1106 * @return code indicating the support status for the locale. See {@link #LANG_AVAILABLE}, 1107 * {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE}, 1108 * {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}. 1109 */ 1110 public int setLanguage(Locale loc) { 1111 synchronized (mStartLock) { 1112 int result = LANG_NOT_SUPPORTED; 1113 if (!mStarted) { 1114 return result; 1115 } 1116 if (loc == null) { 1117 return result; 1118 } 1119 try { 1120 String language = loc.getISO3Language(); 1121 String country = loc.getISO3Country(); 1122 String variant = loc.getVariant(); 1123 // Check if the language, country, variant are available, and cache 1124 // the available parts. 1125 // Note that the language is not actually set here, instead it is cached so it 1126 // will be associated with all upcoming utterances. 1127 result = mITts.isLanguageAvailable(language, country, variant, mCachedParams); 1128 if (result >= LANG_AVAILABLE){ 1129 mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = language; 1130 if (result >= LANG_COUNTRY_AVAILABLE){ 1131 mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = country; 1132 } else { 1133 mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = ""; 1134 } 1135 if (result >= LANG_COUNTRY_VAR_AVAILABLE){ 1136 mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = variant; 1137 } else { 1138 mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = ""; 1139 } 1140 } 1141 } catch (RemoteException e) { 1142 // TTS died; restart it. 1143 Log.e("TextToSpeech.java - setLanguage", "RemoteException"); 1144 e.printStackTrace(); 1145 mStarted = false; 1146 initTts(); 1147 } catch (NullPointerException e) { 1148 // TTS died; restart it. 1149 Log.e("TextToSpeech.java - setLanguage", "NullPointerException"); 1150 e.printStackTrace(); 1151 mStarted = false; 1152 initTts(); 1153 } catch (IllegalStateException e) { 1154 // TTS died; restart it. 1155 Log.e("TextToSpeech.java - setLanguage", "IllegalStateException"); 1156 e.printStackTrace(); 1157 mStarted = false; 1158 initTts(); 1159 } finally { 1160 return result; 1161 } 1162 } 1163 } 1164 1165 1166 /** 1167 * Returns a Locale instance describing the language currently being used by the TextToSpeech 1168 * engine. 1169 * @return language, country (if any) and variant (if any) used by the engine stored in a Locale 1170 * instance, or null is the TextToSpeech engine has failed. 1171 */ 1172 public Locale getLanguage() { 1173 synchronized (mStartLock) { 1174 if (!mStarted) { 1175 return null; 1176 } 1177 try { 1178 // Only do a call to the native synth if there is nothing in the cached params 1179 if (mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1].length() < 1){ 1180 String[] locStrings = mITts.getLanguage(); 1181 if ((locStrings != null) && (locStrings.length == 3)) { 1182 return new Locale(locStrings[0], locStrings[1], locStrings[2]); 1183 } else { 1184 return null; 1185 } 1186 } else { 1187 return new Locale(mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1], 1188 mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1], 1189 mCachedParams[Engine.PARAM_POSITION_VARIANT + 1]); 1190 } 1191 } catch (RemoteException e) { 1192 // TTS died; restart it. 1193 Log.e("TextToSpeech.java - getLanguage", "RemoteException"); 1194 e.printStackTrace(); 1195 mStarted = false; 1196 initTts(); 1197 } catch (NullPointerException e) { 1198 // TTS died; restart it. 1199 Log.e("TextToSpeech.java - getLanguage", "NullPointerException"); 1200 e.printStackTrace(); 1201 mStarted = false; 1202 initTts(); 1203 } catch (IllegalStateException e) { 1204 // TTS died; restart it. 1205 Log.e("TextToSpeech.java - getLanguage", "IllegalStateException"); 1206 e.printStackTrace(); 1207 mStarted = false; 1208 initTts(); 1209 } 1210 return null; 1211 } 1212 } 1213 1214 /** 1215 * Checks if the specified language as represented by the Locale is available and supported. 1216 * 1217 * @param loc 1218 * The Locale describing the language to be used. 1219 * 1220 * @return code indicating the support status for the locale. See {@link #LANG_AVAILABLE}, 1221 * {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE}, 1222 * {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}. 1223 */ 1224 public int isLanguageAvailable(Locale loc) { 1225 synchronized (mStartLock) { 1226 int result = LANG_NOT_SUPPORTED; 1227 if (!mStarted) { 1228 return result; 1229 } 1230 try { 1231 result = mITts.isLanguageAvailable(loc.getISO3Language(), 1232 loc.getISO3Country(), loc.getVariant(), mCachedParams); 1233 } catch (RemoteException e) { 1234 // TTS died; restart it. 1235 Log.e("TextToSpeech.java - isLanguageAvailable", "RemoteException"); 1236 e.printStackTrace(); 1237 mStarted = false; 1238 initTts(); 1239 } catch (NullPointerException e) { 1240 // TTS died; restart it. 1241 Log.e("TextToSpeech.java - isLanguageAvailable", "NullPointerException"); 1242 e.printStackTrace(); 1243 mStarted = false; 1244 initTts(); 1245 } catch (IllegalStateException e) { 1246 // TTS died; restart it. 1247 Log.e("TextToSpeech.java - isLanguageAvailable", "IllegalStateException"); 1248 e.printStackTrace(); 1249 mStarted = false; 1250 initTts(); 1251 } finally { 1252 return result; 1253 } 1254 } 1255 } 1256 1257 1258 /** 1259 * Synthesizes the given text to a file using the specified parameters. 1260 * 1261 * @param text 1262 * The String of text that should be synthesized 1263 * @param params 1264 * The list of parameters to be used. Can be null if no parameters are given. 1265 * They are specified using a (key, value) pair, where the key can be 1266 * {@link Engine#KEY_PARAM_UTTERANCE_ID}. 1267 * @param filename 1268 * The string that gives the full output filename; it should be 1269 * something like "/sdcard/myappsounds/mysound.wav". 1270 * 1271 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 1272 */ 1273 public int synthesizeToFile(String text, HashMap<String,String> params, 1274 String filename) { 1275 Log.i("TextToSpeech.java", "synthesizeToFile()"); 1276 synchronized (mStartLock) { 1277 int result = ERROR; 1278 Log.i("TextToSpeech.java - synthesizeToFile", "synthesizeToFile text of length " 1279 + text.length()); 1280 if (!mStarted) { 1281 Log.e("TextToSpeech.java - synthesizeToFile", "service isn't started"); 1282 return result; 1283 } 1284 try { 1285 if ((params != null) && (!params.isEmpty())) { 1286 // no need to read the stream type here 1287 setCachedParam(params, Engine.KEY_PARAM_UTTERANCE_ID, 1288 Engine.PARAM_POSITION_UTTERANCE_ID); 1289 setCachedParam(params, Engine.KEY_PARAM_ENGINE, Engine.PARAM_POSITION_ENGINE); 1290 } 1291 result = mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename) ? 1292 SUCCESS : ERROR; 1293 } catch (RemoteException e) { 1294 // TTS died; restart it. 1295 Log.e("TextToSpeech.java - synthesizeToFile", "RemoteException"); 1296 e.printStackTrace(); 1297 mStarted = false; 1298 initTts(); 1299 } catch (NullPointerException e) { 1300 // TTS died; restart it. 1301 Log.e("TextToSpeech.java - synthesizeToFile", "NullPointerException"); 1302 e.printStackTrace(); 1303 mStarted = false; 1304 initTts(); 1305 } catch (IllegalStateException e) { 1306 // TTS died; restart it. 1307 Log.e("TextToSpeech.java - synthesizeToFile", "IllegalStateException"); 1308 e.printStackTrace(); 1309 mStarted = false; 1310 initTts(); 1311 } finally { 1312 resetCachedParams(); 1313 return result; 1314 } 1315 } 1316 } 1317 1318 1319 /** 1320 * Convenience method to reset the cached parameters to the current default values 1321 * if they are not persistent between calls to the service. 1322 */ 1323 private void resetCachedParams() { 1324 mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = 1325 String.valueOf(Engine.DEFAULT_STREAM); 1326 mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID+ 1] = ""; 1327 mCachedParams[Engine.PARAM_POSITION_VOLUME + 1] = Engine.DEFAULT_VOLUME_STRING; 1328 mCachedParams[Engine.PARAM_POSITION_PAN + 1] = Engine.DEFAULT_PAN_STRING; 1329 } 1330 1331 /** 1332 * Convenience method to save a parameter in the cached parameter array, at the given index, 1333 * for a property saved in the given hashmap. 1334 */ 1335 private void setCachedParam(HashMap<String,String> params, String key, int keyIndex) { 1336 String extra = params.get(key); 1337 if (extra != null) { 1338 mCachedParams[keyIndex+1] = extra; 1339 } 1340 } 1341 1342 /** 1343 * Sets the OnUtteranceCompletedListener that will fire when an utterance completes. 1344 * 1345 * @param listener 1346 * The OnUtteranceCompletedListener 1347 * 1348 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 1349 */ 1350 public int setOnUtteranceCompletedListener( 1351 final OnUtteranceCompletedListener listener) { 1352 synchronized (mStartLock) { 1353 int result = ERROR; 1354 if (!mStarted) { 1355 return result; 1356 } 1357 mITtscallback = new ITtsCallback.Stub() { 1358 public void utteranceCompleted(String utteranceId) throws RemoteException { 1359 if (listener != null) { 1360 listener.onUtteranceCompleted(utteranceId); 1361 } 1362 } 1363 }; 1364 try { 1365 result = mITts.registerCallback(mPackageName, mITtscallback); 1366 } catch (RemoteException e) { 1367 // TTS died; restart it. 1368 Log.e("TextToSpeech.java - registerCallback", "RemoteException"); 1369 e.printStackTrace(); 1370 mStarted = false; 1371 initTts(); 1372 } catch (NullPointerException e) { 1373 // TTS died; restart it. 1374 Log.e("TextToSpeech.java - registerCallback", "NullPointerException"); 1375 e.printStackTrace(); 1376 mStarted = false; 1377 initTts(); 1378 } catch (IllegalStateException e) { 1379 // TTS died; restart it. 1380 Log.e("TextToSpeech.java - registerCallback", "IllegalStateException"); 1381 e.printStackTrace(); 1382 mStarted = false; 1383 initTts(); 1384 } finally { 1385 return result; 1386 } 1387 } 1388 } 1389 1390 /** 1391 * Sets the speech synthesis engine to be used by its packagename. 1392 * 1393 * @param enginePackageName 1394 * The packagename for the synthesis engine (ie, "com.svox.pico") 1395 * 1396 * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}. 1397 */ 1398 public int setEngineByPackageName(String enginePackageName) { 1399 synchronized (mStartLock) { 1400 int result = TextToSpeech.ERROR; 1401 if (!mStarted) { 1402 return result; 1403 } 1404 try { 1405 result = mITts.setEngineByPackageName(enginePackageName); 1406 if (result == TextToSpeech.SUCCESS){ 1407 mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = enginePackageName; 1408 } 1409 } catch (RemoteException e) { 1410 // TTS died; restart it. 1411 Log.e("TextToSpeech.java - setEngineByPackageName", "RemoteException"); 1412 e.printStackTrace(); 1413 mStarted = false; 1414 initTts(); 1415 } catch (NullPointerException e) { 1416 // TTS died; restart it. 1417 Log.e("TextToSpeech.java - setEngineByPackageName", "NullPointerException"); 1418 e.printStackTrace(); 1419 mStarted = false; 1420 initTts(); 1421 } catch (IllegalStateException e) { 1422 // TTS died; restart it. 1423 Log.e("TextToSpeech.java - setEngineByPackageName", "IllegalStateException"); 1424 e.printStackTrace(); 1425 mStarted = false; 1426 initTts(); 1427 } finally { 1428 return result; 1429 } 1430 } 1431 } 1432 1433 1434 /** 1435 * Gets the packagename of the default speech synthesis engine. 1436 * 1437 * @return Packagename of the TTS engine that the user has chosen as their default. 1438 */ 1439 public String getDefaultEngine() { 1440 synchronized (mStartLock) { 1441 String engineName = ""; 1442 if (!mStarted) { 1443 return engineName; 1444 } 1445 try { 1446 engineName = mITts.getDefaultEngine(); 1447 } catch (RemoteException e) { 1448 // TTS died; restart it. 1449 Log.e("TextToSpeech.java - setEngineByPackageName", "RemoteException"); 1450 e.printStackTrace(); 1451 mStarted = false; 1452 initTts(); 1453 } catch (NullPointerException e) { 1454 // TTS died; restart it. 1455 Log.e("TextToSpeech.java - setEngineByPackageName", "NullPointerException"); 1456 e.printStackTrace(); 1457 mStarted = false; 1458 initTts(); 1459 } catch (IllegalStateException e) { 1460 // TTS died; restart it. 1461 Log.e("TextToSpeech.java - setEngineByPackageName", "IllegalStateException"); 1462 e.printStackTrace(); 1463 mStarted = false; 1464 initTts(); 1465 } finally { 1466 return engineName; 1467 } 1468 } 1469 } 1470 1471 1472 /** 1473 * Returns whether or not the user is forcing their defaults to override the 1474 * Text-To-Speech settings set by applications. 1475 * 1476 * @return Whether or not defaults are enforced. 1477 */ 1478 public boolean areDefaultsEnforced() { 1479 synchronized (mStartLock) { 1480 boolean defaultsEnforced = false; 1481 if (!mStarted) { 1482 return defaultsEnforced; 1483 } 1484 try { 1485 defaultsEnforced = mITts.areDefaultsEnforced(); 1486 } catch (RemoteException e) { 1487 // TTS died; restart it. 1488 Log.e("TextToSpeech.java - areDefaultsEnforced", "RemoteException"); 1489 e.printStackTrace(); 1490 mStarted = false; 1491 initTts(); 1492 } catch (NullPointerException e) { 1493 // TTS died; restart it. 1494 Log.e("TextToSpeech.java - areDefaultsEnforced", "NullPointerException"); 1495 e.printStackTrace(); 1496 mStarted = false; 1497 initTts(); 1498 } catch (IllegalStateException e) { 1499 // TTS died; restart it. 1500 Log.e("TextToSpeech.java - areDefaultsEnforced", "IllegalStateException"); 1501 e.printStackTrace(); 1502 mStarted = false; 1503 initTts(); 1504 } finally { 1505 return defaultsEnforced; 1506 } 1507 } 1508 } 1509} 1510