PageRenderTime 103ms CodeModel.GetById 21ms app.highlight 73ms RepoModel.GetById 1ms app.codeStats 1ms

/tts/src/com/google/tts/TextToSpeechBeta.java

http://eyes-free.googlecode.com/
Java | 1604 lines | 913 code | 103 blank | 588 comment | 88 complexity | e4fafd3ff35c6897b03ad1b069b79b9c MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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 */
  16
  17package com.google.tts;
  18
  19import com.google.tts.ITtsBeta;
  20import com.google.tts.ITtsCallbackBeta;
  21
  22// import android.annotation.SdkConstant;
  23// import android.annotation.SdkConstant.SdkConstantType;
  24import android.content.ComponentName;
  25import android.content.Context;
  26import android.content.Intent;
  27import android.content.ServiceConnection;
  28import android.content.pm.PackageInfo;
  29import android.content.pm.PackageManager;
  30import android.content.pm.ResolveInfo;
  31import android.content.pm.PackageManager.NameNotFoundException;
  32import android.media.AudioManager;
  33import android.os.IBinder;
  34import android.os.RemoteException;
  35import android.speech.tts.TextToSpeech;
  36import android.util.Log;
  37import android.view.MotionEvent;
  38
  39import java.lang.reflect.InvocationTargetException;
  40import java.lang.reflect.Method;
  41import java.util.HashMap;
  42import java.util.Locale;
  43
  44/**
  45 * Synthesizes speech from text for immediate playback or to create a sound
  46 * file.
  47 * <p>
  48 * A TextToSpeech instance can only be used to synthesize text once it has
  49 * completed its initialization. Implement the
  50 * {@link TextToSpeechBeta.OnInitListener} to be notified of the completion of
  51 * the initialization.<br>
  52 * When you are done using the TextToSpeech instance, call the
  53 * {@link #shutdown()} method to release the native resources used by the
  54 * TextToSpeech engine.
  55 */
  56public class TextToSpeechBeta extends TextToSpeech {
  57    // BEGINNING OF WORKAROUND FOR PRE-FROYO COMPATIBILITY
  58    private static Method Platform_areDefaultsEnforced;
  59
  60    private static Method Platform_getDefaultEngine;
  61
  62    private static Method Platform_setEngineByPackageName;
  63    static {
  64        initCompatibility();
  65    }
  66
  67    private static void initCompatibility() {
  68        try {
  69            Platform_areDefaultsEnforced = TextToSpeech.class.getMethod("areDefaultsEnforced",
  70                    new Class[] {});
  71            Platform_getDefaultEngine = TextToSpeech.class.getMethod("getDefaultEngine",
  72                    new Class[] {});
  73            Platform_setEngineByPackageName = TextToSpeech.class.getMethod(
  74                    "setEngineByPackageName", new Class[] {
  75                        String.class
  76                    });
  77            /* success, this is a newer device */
  78        } catch (NoSuchMethodException nsme) {
  79            /* failure, must be older device */
  80        }
  81    }
  82
  83    private static boolean usePlatform_areDefaultsEnforced(TextToSpeech ttsObj) {
  84        try {
  85            Object retobj = Platform_areDefaultsEnforced.invoke(ttsObj);
  86            return (Boolean) retobj;
  87        } catch (IllegalAccessException ie) {
  88            System.err.println("unexpected " + ie);
  89        } catch (IllegalArgumentException e) {
  90            // TODO Auto-generated catch block
  91            e.printStackTrace();
  92        } catch (InvocationTargetException e) {
  93            // TODO Auto-generated catch block
  94            e.printStackTrace();
  95        }
  96        return false;
  97    }
  98
  99    private static String usePlatform_getDefaultEngine(TextToSpeech ttsObj) {
 100        try {
 101            Object retobj = Platform_getDefaultEngine.invoke(ttsObj);
 102            return (String) retobj;
 103        } catch (IllegalAccessException ie) {
 104            System.err.println("unexpected " + ie);
 105        } catch (IllegalArgumentException e) {
 106            // TODO Auto-generated catch block
 107            e.printStackTrace();
 108        } catch (InvocationTargetException e) {
 109            // TODO Auto-generated catch block
 110            e.printStackTrace();
 111        }
 112        return "com.svox.pico";
 113    }
 114
 115    private static int usePlatform_setEngineByPackageName(TextToSpeech ttsObj, String enginePackageName) {
 116        try {
 117            Object retobj = Platform_setEngineByPackageName.invoke(ttsObj, enginePackageName);
 118            return (Integer) retobj;
 119        } catch (IllegalAccessException ie) {
 120            System.err.println("unexpected " + ie);
 121        } catch (IllegalArgumentException e) {
 122            // TODO Auto-generated catch block
 123            e.printStackTrace();
 124        } catch (InvocationTargetException e) {
 125            // TODO Auto-generated catch block
 126            e.printStackTrace();
 127        }
 128        return ERROR;
 129    }
 130
 131    // END OF WORKAROUND FOR PRE-FROYO COMPATIBILITY
 132
 133    public static final String USING_PLATFORM_TTS = "TextToSpeechBeta not installed - defaulting to basic platform TextToSpeech for ";
 134
 135    public static final String NOT_ON_PLATFORM_TTS = "TextToSpeechBeta not installed - basic platform TextToSpeech does not support ";
 136
 137    /**
 138     * Denotes a successful operation.
 139     */
 140    public static final int SUCCESS = 0;
 141
 142    /**
 143     * Denotes a generic operation failure.
 144     */
 145    public static final int ERROR = -1;
 146
 147    /**
 148     * Queue mode where all entries in the playback queue (media to be played
 149     * and text to be synthesized) are dropped and replaced by the new entry.
 150     */
 151    public static final int QUEUE_FLUSH = 0;
 152
 153    /**
 154     * Queue mode where the new entry is added at the end of the playback queue.
 155     */
 156    public static final int QUEUE_ADD = 1;
 157
 158    /**
 159     * Denotes the language is available exactly as specified by the locale.
 160     */
 161    public static final int LANG_COUNTRY_VAR_AVAILABLE = 2;
 162
 163    /**
 164     * Denotes the language is available for the language and country specified
 165     * by the locale, but not the variant.
 166     */
 167    public static final int LANG_COUNTRY_AVAILABLE = 1;
 168
 169    /**
 170     * Denotes the language is available for the language by the locale, but not
 171     * the country and variant.
 172     */
 173    public static final int LANG_AVAILABLE = 0;
 174
 175    /**
 176     * Denotes the language data is missing.
 177     */
 178    public static final int LANG_MISSING_DATA = -1;
 179
 180    /**
 181     * Denotes the language is not supported.
 182     */
 183    public static final int LANG_NOT_SUPPORTED = -2;
 184
 185    /**
 186     * Broadcast Action: The TextToSpeech synthesizer has completed processing
 187     * of all the text in the speech queue.
 188     */
 189    // @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
 190    public static final String ACTION_TTS_QUEUE_PROCESSING_COMPLETED = "android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED";
 191
 192    /**
 193     * Interface definition of a callback to be invoked indicating the
 194     * completion of the TextToSpeech engine initialization.
 195     */
 196    public interface OnInitListener {
 197        /**
 198         * Called to signal the completion of the TextToSpeech engine
 199         * initialization.
 200         * 
 201         * @param status {@link TextToSpeechBeta#SUCCESS} or
 202         *            {@link TextToSpeechBeta#ERROR}.
 203         * @param version The version of TextToSpeechBeta Service that the user
 204         *            has installed, or -1 if the user does not have it
 205         *            installed.
 206         */
 207        public void onInit(int status, int version);
 208    }
 209
 210    /**
 211     * Interface definition of a callback to be invoked indicating the
 212     * TextToSpeech engine has completed synthesizing an utterance with an
 213     * utterance ID set.
 214     */
 215    public interface OnUtteranceCompletedListener {
 216        /**
 217         * Called to signal the completion of the synthesis of the utterance
 218         * that was identified with the string parameter. This identifier is the
 219         * one originally passed in the parameter hashmap of the synthesis
 220         * request in {@link TextToSpeechBeta#speak(String, int, HashMap)} or
 221         * {@link TextToSpeechBeta#synthesizeToFile(String, HashMap, String)}
 222         * with the {@link TextToSpeechBeta.Engine#KEY_PARAM_UTTERANCE_ID} key.
 223         * 
 224         * @param utteranceId the identifier of the utterance.
 225         */
 226        public void onUtteranceCompleted(String utteranceId);
 227    }
 228
 229    /**
 230     * Internal constants for the TextToSpeech functionality
 231     */
 232    public class Engine {
 233        // default values for a TTS engine when settings are not found in the
 234        // provider
 235        /**
 236         * {@hide}
 237         */
 238        public static final int DEFAULT_RATE = 100; // 1x
 239
 240        /**
 241         * {@hide}
 242         */
 243        public static final int DEFAULT_PITCH = 100;// 1x
 244
 245        /**
 246         * {@hide}
 247         */
 248        public static final int USE_DEFAULTS = 0; // false
 249
 250        /**
 251         * {@hide}
 252         */
 253        public static final String DEFAULT_SYNTH = "com.svox.pico";
 254
 255        // default values for rendering
 256        /**
 257         * Default audio stream used when playing synthesized speech.
 258         */
 259        public static final int DEFAULT_STREAM = AudioManager.STREAM_MUSIC;
 260
 261        // return codes for a TTS engine's check data activity
 262        /**
 263         * Indicates success when checking the installation status of the
 264         * resources used by the TextToSpeech engine with the
 265         * {@link #ACTION_CHECK_TTS_DATA} intent.
 266         */
 267        public static final int CHECK_VOICE_DATA_PASS = 1;
 268
 269        /**
 270         * Indicates failure when checking the installation status of the
 271         * resources used by the TextToSpeech engine with the
 272         * {@link #ACTION_CHECK_TTS_DATA} intent.
 273         */
 274        public static final int CHECK_VOICE_DATA_FAIL = 0;
 275
 276        /**
 277         * Indicates erroneous data when checking the installation status of the
 278         * resources used by the TextToSpeech engine with the
 279         * {@link #ACTION_CHECK_TTS_DATA} intent.
 280         */
 281        public static final int CHECK_VOICE_DATA_BAD_DATA = -1;
 282
 283        /**
 284         * Indicates missing resources when checking the installation status of
 285         * the resources used by the TextToSpeech engine with the
 286         * {@link #ACTION_CHECK_TTS_DATA} intent.
 287         */
 288        public static final int CHECK_VOICE_DATA_MISSING_DATA = -2;
 289
 290        /**
 291         * Indicates missing storage volume when checking the installation
 292         * status of the resources used by the TextToSpeech engine with the
 293         * {@link #ACTION_CHECK_TTS_DATA} intent.
 294         */
 295        public static final int CHECK_VOICE_DATA_MISSING_VOLUME = -3;
 296
 297        // intents to ask engine to install data or check its data
 298        /**
 299         * Activity Action: Triggers the platform TextToSpeech engine to start
 300         * the activity that installs the resource files on the device that are
 301         * required for TTS to be operational. Since the installation of the
 302         * data can be interrupted or declined by the user, the application
 303         * shouldn't expect successful installation upon return from that
 304         * intent, and if need be, should check installation status with
 305         * {@link #ACTION_CHECK_TTS_DATA}.
 306         */
 307        // @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
 308        public static final String ACTION_INSTALL_TTS_DATA = "android.speech.tts.engine.INSTALL_TTS_DATA";
 309
 310        /**
 311         * Broadcast Action: broadcast to signal the completion of the
 312         * installation of the data files used by the synthesis engine. Success
 313         * or failure is indicated in the {@link #EXTRA_TTS_DATA_INSTALLED}
 314         * extra.
 315         */
 316        // @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
 317        public static final String ACTION_TTS_DATA_INSTALLED = "android.speech.tts.engine.TTS_DATA_INSTALLED";
 318
 319        /**
 320         * Activity Action: Starts the activity from the platform TextToSpeech
 321         * engine to verify the proper installation and availability of the
 322         * resource files on the system. Upon completion, the activity will
 323         * return one of the following codes: {@link #CHECK_VOICE_DATA_PASS},
 324         * {@link #CHECK_VOICE_DATA_FAIL}, {@link #CHECK_VOICE_DATA_BAD_DATA},
 325         * {@link #CHECK_VOICE_DATA_MISSING_DATA}, or
 326         * {@link #CHECK_VOICE_DATA_MISSING_VOLUME}.
 327         * <p>
 328         * Moreover, the data received in the activity result will contain the
 329         * following fields:
 330         * <ul>
 331         * <li>{@link #EXTRA_VOICE_DATA_ROOT_DIRECTORY} which indicates the path
 332         * to the location of the resource files,</li>
 333         * <li>{@link #EXTRA_VOICE_DATA_FILES} which contains the list of all
 334         * the resource files,</li>
 335         * <li>and {@link #EXTRA_VOICE_DATA_FILES_INFO} which contains, for each
 336         * resource file, the description of the language covered by the file in
 337         * the xxx-YYY format, where xxx is the 3-letter ISO language code, and
 338         * YYY is the 3-letter ISO country code.</li>
 339         * </ul>
 340         */
 341        // @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
 342        public static final String ACTION_CHECK_TTS_DATA = "android.speech.tts.engine.CHECK_TTS_DATA";
 343
 344        // extras for a TTS engine's check data activity
 345        /**
 346         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA}
 347         * intent where the TextToSpeech engine specifies the path to its
 348         * resources.
 349         */
 350        public static final String EXTRA_VOICE_DATA_ROOT_DIRECTORY = "dataRoot";
 351
 352        /**
 353         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA}
 354         * intent where the TextToSpeech engine specifies the file names of its
 355         * resources under the resource path.
 356         */
 357        public static final String EXTRA_VOICE_DATA_FILES = "dataFiles";
 358
 359        /**
 360         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA}
 361         * intent where the TextToSpeech engine specifies the locale associated
 362         * with each resource file.
 363         */
 364        public static final String EXTRA_VOICE_DATA_FILES_INFO = "dataFilesInfo";
 365
 366        // extras for a TTS engine's data installation
 367        /**
 368         * Extra information received with the
 369         * {@link #ACTION_TTS_DATA_INSTALLED} intent. It indicates whether the
 370         * data files for the synthesis engine were successfully installed. The
 371         * installation was initiated with the {@link #ACTION_INSTALL_TTS_DATA}
 372         * intent. The possible values for this extra are
 373         * {@link TextToSpeechBeta#SUCCESS} and {@link TextToSpeechBeta#ERROR}.
 374         */
 375        public static final String EXTRA_TTS_DATA_INSTALLED = "dataInstalled";
 376
 377        // keys for the parameters passed with speak commands. Hidden keys are
 378        // used
 379        // internally
 380        // to maintain engine state for each TextToSpeech instance.
 381        /**
 382         * {@hide}
 383         */
 384        public static final String KEY_PARAM_RATE = "rate";
 385
 386        /**
 387         * {@hide}
 388         */
 389        public static final String KEY_PARAM_LANGUAGE = "language";
 390
 391        /**
 392         * {@hide}
 393         */
 394        public static final String KEY_PARAM_COUNTRY = "country";
 395
 396        /**
 397         * {@hide}
 398         */
 399        public static final String KEY_PARAM_VARIANT = "variant";
 400
 401        /**
 402         * Parameter key to specify the audio stream type to be used when
 403         * speaking text or playing back a file.
 404         * 
 405         * @see TextToSpeechBeta#speak(String, int, HashMap)
 406         * @see TextToSpeechBeta#playEarcon(String, int, HashMap)
 407         */
 408        public static final String KEY_PARAM_STREAM = "streamType";
 409
 410        /**
 411         * Parameter key to identify an utterance in the
 412         * {@link TextToSpeechBeta.OnUtteranceCompletedListener} after text has
 413         * been spoken, a file has been played back or a silence duration has
 414         * elapsed.
 415         * 
 416         * @see TextToSpeechBeta#speak(String, int, HashMap)
 417         * @see TextToSpeechBeta#playEarcon(String, int, HashMap)
 418         * @see TextToSpeechBeta#synthesizeToFile(String, HashMap, String)
 419         */
 420        public static final String KEY_PARAM_UTTERANCE_ID = "utteranceId";
 421
 422        /**
 423         * Parameter key to specify the synthesis engine
 424         * 
 425         * @see TextToSpeechBeta#setEngineByPackageName(String)
 426         */
 427        public static final String KEY_PARAM_ENGINE = "engine";
 428
 429        public static final String KEY_PARAM_PITCH = "pitch";
 430
 431        // key positions in the array of cached parameters
 432        /**
 433         * {@hide}
 434         */
 435        protected static final int PARAM_POSITION_RATE = 0;
 436
 437        /**
 438         * {@hide}
 439         */
 440        protected static final int PARAM_POSITION_LANGUAGE = 2;
 441
 442        /**
 443         * {@hide}
 444         */
 445        protected static final int PARAM_POSITION_COUNTRY = 4;
 446
 447        /**
 448         * {@hide}
 449         */
 450        protected static final int PARAM_POSITION_VARIANT = 6;
 451
 452        /**
 453         * {@hide}
 454         */
 455        protected static final int PARAM_POSITION_STREAM = 8;
 456
 457        /**
 458         * {@hide}
 459         */
 460        protected static final int PARAM_POSITION_UTTERANCE_ID = 10;
 461
 462        /**
 463         * {@hide}
 464         */
 465        protected static final int PARAM_POSITION_ENGINE = 12;
 466
 467        /**
 468         * {@hide}
 469         */
 470        protected static final int NB_CACHED_PARAMS = 7;
 471    }
 472
 473    /**
 474     * Connection needed for the TTS.
 475     */
 476    private ServiceConnection mServiceConnection;
 477
 478    private ITtsBeta mITts = null;
 479
 480    private ITtsCallbackBeta mITtscallback = null;
 481
 482    private Context mContext = null;
 483
 484    private String mPackageName = "";
 485
 486    private static OnInitListener mInitListener = null;
 487
 488    private boolean mStarted = false;
 489
 490    private final Object mStartLock = new Object();
 491
 492    /**
 493     * Used to store the cached parameters sent along with each synthesis
 494     * request to the TTS service.
 495     */
 496    private String[] mCachedParams;
 497
 498    static boolean ttsBetaInstalled = false;
 499
 500    static TextToSpeech.OnInitListener platformOnInitListener = new TextToSpeech.OnInitListener() {
 501        public void onInit(int status) {
 502            if (!ttsBetaInstalled) {
 503                if (mInitListener != null) {
 504                    mInitListener.onInit(status, -1);
 505                }
 506            }
 507        }
 508    };
 509
 510    /**
 511     * The constructor for the TextToSpeech class. This will also initialize the
 512     * associated TextToSpeech engine if it isn't already running.
 513     * 
 514     * @param context The context this instance is running in.
 515     * @param listener The {@link TextToSpeechBeta.OnInitListener} that will be
 516     *            called when the TextToSpeech engine has initialized.
 517     */
 518    public TextToSpeechBeta(Context context, OnInitListener listener) {
 519        super(context, platformOnInitListener);
 520        ttsBetaInstalled = isInstalled(context);
 521        mInitListener = listener;
 522        if (ttsBetaInstalled) {
 523            super.shutdown();
 524            mContext = context;
 525            mPackageName = mContext.getPackageName();
 526
 527            mCachedParams = new String[2 * Engine.NB_CACHED_PARAMS]; // store
 528            // key and
 529            // value
 530            mCachedParams[Engine.PARAM_POSITION_RATE] = Engine.KEY_PARAM_RATE;
 531            mCachedParams[Engine.PARAM_POSITION_LANGUAGE] = Engine.KEY_PARAM_LANGUAGE;
 532            mCachedParams[Engine.PARAM_POSITION_COUNTRY] = Engine.KEY_PARAM_COUNTRY;
 533            mCachedParams[Engine.PARAM_POSITION_VARIANT] = Engine.KEY_PARAM_VARIANT;
 534            mCachedParams[Engine.PARAM_POSITION_STREAM] = Engine.KEY_PARAM_STREAM;
 535            mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID] = Engine.KEY_PARAM_UTTERANCE_ID;
 536            mCachedParams[Engine.PARAM_POSITION_ENGINE] = Engine.KEY_PARAM_ENGINE;
 537
 538            mCachedParams[Engine.PARAM_POSITION_RATE + 1] = String.valueOf(Engine.DEFAULT_RATE);
 539            // initialize the language cached parameters with the current Locale
 540            Locale defaultLoc = Locale.getDefault();
 541            mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = defaultLoc.getISO3Language();
 542            mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = defaultLoc.getISO3Country();
 543            mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = defaultLoc.getVariant();
 544
 545            mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = String.valueOf(Engine.DEFAULT_STREAM);
 546            mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = "";
 547
 548            mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = "";
 549
 550            initTts();
 551        }
 552    }
 553
 554    private void initTts() {
 555        mStarted = false;
 556
 557        // Initialize the TTS, run the callback after the binding is successful
 558        mServiceConnection = new ServiceConnection() {
 559            public void onServiceConnected(ComponentName name, IBinder service) {
 560                synchronized (mStartLock) {
 561                    mITts = ITtsBeta.Stub.asInterface(service);
 562                    mStarted = true;
 563                    // Cache the default engine and current language
 564                    setEngineByPackageNameExtended(getDefaultEngineExtended());
 565                    setLanguage(getLanguage());
 566                    if (mInitListener != null) {
 567                        try {
 568                            PackageManager pm = mContext.getPackageManager();
 569                            PackageInfo info = pm.getPackageInfo("com.google.tts", 0);
 570                            mInitListener.onInit(SUCCESS, info.versionCode);
 571                        } catch (NameNotFoundException e) {
 572                            e.printStackTrace();
 573                        }
 574                    }
 575                }
 576            }
 577
 578            public void onServiceDisconnected(ComponentName name) {
 579                synchronized (mStartLock) {
 580                    mITts = null;
 581                    mInitListener = null;
 582                    mStarted = false;
 583                }
 584            }
 585        };
 586
 587        // Remove "_BETA" tags when in framework
 588        Intent intent = new Intent("com.google.intent.action.START_TTS_SERVICE_BETA");
 589        intent.addCategory("com.google.intent.category.TTS_BETA");
 590        mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
 591        // TODO handle case where the binding works (should always work) but
 592        // the plugin fails
 593    }
 594
 595    /**
 596     * Releases the resources used by the TextToSpeech engine. It is good
 597     * practice for instance to call this method in the onDestroy() method of an
 598     * Activity so the TextToSpeech engine can be cleanly stopped.
 599     */
 600    public void shutdown() {
 601        if (!ttsBetaInstalled) {
 602            Log.d("TextToSpeechBeta", USING_PLATFORM_TTS + "shutdown");
 603            super.shutdown();
 604            return;
 605        }
 606        try {
 607            mContext.unbindService(mServiceConnection);
 608        } catch (IllegalArgumentException e) {
 609            // Do nothing and fail silently since an error here indicates that
 610            // binding never succeeded in the first place.
 611        }
 612    }
 613
 614    /**
 615     * Adds a mapping between a string of text and a sound resource in a
 616     * package. After a call to this method, subsequent calls to
 617     * {@link #speak(String, int, HashMap)} will play the specified sound
 618     * resource if it is available, or synthesize the text it is missing.
 619     * 
 620     * @param text The string of text. Example: <code>"south_south_east"</code>
 621     * @param packagename Pass the packagename of the application that contains
 622     *            the resource. If the resource is in your own application (this
 623     *            is the most common case), then put the packagename of your
 624     *            application here.<br/>
 625     *            Example: <b>"com.google.marvin.compass"</b><br/>
 626     *            The packagename can be found in the AndroidManifest.xml of
 627     *            your application.
 628     *            <p>
 629     *            <code>&lt;manifest xmlns:android=&quot;...&quot;
 630     *      package=&quot;<b>com.google.marvin.compass</b>&quot;&gt;</code>
 631     *            </p>
 632     * @param resourceId Example: <code>R.raw.south_south_east</code>
 633     * @return Code indicating success or failure. See {@link #ERROR} and
 634     *         {@link #SUCCESS}.
 635     */
 636    public int addSpeech(String text, String packagename, int resourceId) {
 637        if (!ttsBetaInstalled) {
 638            Log.d("TextToSpeechBeta", USING_PLATFORM_TTS + "addSpeech");
 639            return super.addSpeech(text, packagename, resourceId);
 640        }
 641        synchronized (mStartLock) {
 642            if (!mStarted) {
 643                return ERROR;
 644            }
 645            try {
 646                mITts.addSpeech(mPackageName, text, packagename, resourceId);
 647                return SUCCESS;
 648            } catch (RemoteException e) {
 649                // TTS died; restart it.
 650                Log.e("TextToSpeech.java - addSpeech", "RemoteException");
 651                e.printStackTrace();
 652                mStarted = false;
 653                initTts();
 654            } catch (NullPointerException e) {
 655                // TTS died; restart it.
 656                Log.e("TextToSpeech.java - addSpeech", "NullPointerException");
 657                e.printStackTrace();
 658                mStarted = false;
 659                initTts();
 660            } catch (IllegalStateException e) {
 661                // TTS died; restart it.
 662                Log.e("TextToSpeech.java - addSpeech", "IllegalStateException");
 663                e.printStackTrace();
 664                mStarted = false;
 665                initTts();
 666            }
 667            return ERROR;
 668        }
 669    }
 670
 671    /**
 672     * Adds a mapping between a string of text and a sound file. Using this, it
 673     * is possible to add custom pronounciations for a string of text. After a
 674     * call to this method, subsequent calls to
 675     * {@link #speak(String, int, HashMap)} will play the specified sound
 676     * resource if it is available, or synthesize the text it is missing.
 677     * 
 678     * @param text The string of text. Example: <code>"south_south_east"</code>
 679     * @param filename The full path to the sound file (for example:
 680     *            "/sdcard/mysounds/hello.wav")
 681     * @return Code indicating success or failure. See {@link #ERROR} and
 682     *         {@link #SUCCESS}.
 683     */
 684    public int addSpeech(String text, String filename) {
 685        if (!ttsBetaInstalled) {
 686            Log.d("TextToSpeechBeta", USING_PLATFORM_TTS + "addSpeech");
 687            return super.addSpeech(text, filename);
 688        }
 689        synchronized (mStartLock) {
 690            if (!mStarted) {
 691                return ERROR;
 692            }
 693            try {
 694                mITts.addSpeechFile(mPackageName, text, filename);
 695                return SUCCESS;
 696            } catch (RemoteException e) {
 697                // TTS died; restart it.
 698                Log.e("TextToSpeech.java - addSpeech", "RemoteException");
 699                e.printStackTrace();
 700                mStarted = false;
 701                initTts();
 702            } catch (NullPointerException e) {
 703                // TTS died; restart it.
 704                Log.e("TextToSpeech.java - addSpeech", "NullPointerException");
 705                e.printStackTrace();
 706                mStarted = false;
 707                initTts();
 708            } catch (IllegalStateException e) {
 709                // TTS died; restart it.
 710                Log.e("TextToSpeech.java - addSpeech", "IllegalStateException");
 711                e.printStackTrace();
 712                mStarted = false;
 713                initTts();
 714            }
 715            return ERROR;
 716        }
 717    }
 718
 719    /**
 720     * Adds a mapping between a string of text and a sound resource in a
 721     * package. Use this to add custom earcons.
 722     * 
 723     * @see #playEarcon(String, int, HashMap)
 724     * @param earcon The name of the earcon. Example: <code>"[tick]"</code><br/>
 725     * @param packagename the package name of the application that contains the
 726     *            resource. This can for instance be the package name of your
 727     *            own application. Example: <b>"com.google.marvin.compass"</b><br/>
 728     *            The package name can be found in the AndroidManifest.xml of
 729     *            the application containing the resource.
 730     *            <p>
 731     *            <code>&lt;manifest xmlns:android=&quot;...&quot;
 732     *      package=&quot;<b>com.google.marvin.compass</b>&quot;&gt;</code>
 733     *            </p>
 734     * @param resourceId Example: <code>R.raw.tick_snd</code>
 735     * @return Code indicating success or failure. See {@link #ERROR} and
 736     *         {@link #SUCCESS}.
 737     */
 738    public int addEarcon(String earcon, String packagename, int resourceId) {
 739        if (!ttsBetaInstalled) {
 740            Log.d("TextToSpeechBeta", USING_PLATFORM_TTS + "addEarcon");
 741            return super.addEarcon(earcon, packagename, resourceId);
 742        }
 743        synchronized (mStartLock) {
 744            if (!mStarted) {
 745                return ERROR;
 746            }
 747            try {
 748                mITts.addEarcon(mPackageName, earcon, packagename, resourceId);
 749                return SUCCESS;
 750            } catch (RemoteException e) {
 751                // TTS died; restart it.
 752                Log.e("TextToSpeech.java - addEarcon", "RemoteException");
 753                e.printStackTrace();
 754                mStarted = false;
 755                initTts();
 756            } catch (NullPointerException e) {
 757                // TTS died; restart it.
 758                Log.e("TextToSpeech.java - addEarcon", "NullPointerException");
 759                e.printStackTrace();
 760                mStarted = false;
 761                initTts();
 762            } catch (IllegalStateException e) {
 763                // TTS died; restart it.
 764                Log.e("TextToSpeech.java - addEarcon", "IllegalStateException");
 765                e.printStackTrace();
 766                mStarted = false;
 767                initTts();
 768            }
 769            return ERROR;
 770        }
 771    }
 772
 773    /**
 774     * Adds a mapping between a string of text and a sound file. Use this to add
 775     * custom earcons.
 776     * 
 777     * @see #playEarcon(String, int, HashMap)
 778     * @param earcon The name of the earcon. Example: <code>"[tick]"</code>
 779     * @param filename The full path to the sound file (for example:
 780     *            "/sdcard/mysounds/tick.wav")
 781     * @return Code indicating success or failure. See {@link #ERROR} and
 782     *         {@link #SUCCESS}.
 783     */
 784    public int addEarcon(String earcon, String filename) {
 785        if (!ttsBetaInstalled) {
 786            Log.d("TextToSpeechBeta", USING_PLATFORM_TTS + "addEarcon");
 787            return super.addEarcon(earcon, filename);
 788        }
 789        synchronized (mStartLock) {
 790            if (!mStarted) {
 791                return ERROR;
 792            }
 793            try {
 794                mITts.addEarconFile(mPackageName, earcon, filename);
 795                return SUCCESS;
 796            } catch (RemoteException e) {
 797                // TTS died; restart it.
 798                Log.e("TextToSpeech.java - addEarcon", "RemoteException");
 799                e.printStackTrace();
 800                mStarted = false;
 801                initTts();
 802            } catch (NullPointerException e) {
 803                // TTS died; restart it.
 804                Log.e("TextToSpeech.java - addEarcon", "NullPointerException");
 805                e.printStackTrace();
 806                mStarted = false;
 807                initTts();
 808            } catch (IllegalStateException e) {
 809                // TTS died; restart it.
 810                Log.e("TextToSpeech.java - addEarcon", "IllegalStateException");
 811                e.printStackTrace();
 812                mStarted = false;
 813                initTts();
 814            }
 815            return ERROR;
 816        }
 817    }
 818
 819    /**
 820     * Speaks the string using the specified queuing strategy and speech
 821     * parameters.
 822     * 
 823     * @param text The string of text to be spoken.
 824     * @param queueMode The queuing strategy to use. {@link #QUEUE_ADD} or
 825     *            {@link #QUEUE_FLUSH}.
 826     * @param params The list of parameters to be used. Can be null if no
 827     *            parameters are given. They are specified using a (key, value)
 828     *            pair, where the key can be {@link Engine#KEY_PARAM_STREAM} or
 829     *            {@link Engine#KEY_PARAM_UTTERANCE_ID}.
 830     * @return Code indicating success or failure. See {@link #ERROR} and
 831     *         {@link #SUCCESS}.
 832     */
 833    public int speak(String text, int queueMode, HashMap<String, String> params) {
 834        if (!ttsBetaInstalled) {
 835            Log.d("TextToSpeechBeta", USING_PLATFORM_TTS + "speak");
 836            return super.speak(text, queueMode, params);
 837        }
 838        synchronized (mStartLock) {
 839            int result = ERROR;
 840            Log.i("TTS received: ", text);
 841            if (!mStarted) {
 842                return result;
 843            }
 844            try {
 845                if ((params != null) && (!params.isEmpty())) {
 846                    String extra = params.get(Engine.KEY_PARAM_STREAM);
 847                    if (extra != null) {
 848                        mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra;
 849                    }
 850                    extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
 851                    if (extra != null) {
 852                        mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
 853                    }
 854                    extra = params.get(Engine.KEY_PARAM_ENGINE);
 855                    if (extra != null) {
 856                        mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = extra;
 857                    }
 858                }
 859                result = mITts.speak(mPackageName, text, queueMode, mCachedParams);
 860            } catch (RemoteException e) {
 861                // TTS died; restart it.
 862                Log.e("TextToSpeech.java - speak", "RemoteException");
 863                e.printStackTrace();
 864                mStarted = false;
 865                initTts();
 866            } catch (NullPointerException e) {
 867                // TTS died; restart it.
 868                Log.e("TextToSpeech.java - speak", "NullPointerException");
 869                e.printStackTrace();
 870                mStarted = false;
 871                initTts();
 872            } catch (IllegalStateException e) {
 873                // TTS died; restart it.
 874                Log.e("TextToSpeech.java - speak", "IllegalStateException");
 875                e.printStackTrace();
 876                mStarted = false;
 877                initTts();
 878            } finally {
 879                resetCachedParams();
 880                return result;
 881            }
 882        }
 883    }
 884
 885    /**
 886     * Plays the earcon using the specified queueing mode and parameters.
 887     * 
 888     * @param earcon The earcon that should be played
 889     * @param queueMode {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
 890     * @param params The list of parameters to be used. Can be null if no
 891     *            parameters are given. They are specified using a (key, value)
 892     *            pair, where the key can be {@link Engine#KEY_PARAM_STREAM} or
 893     *            {@link Engine#KEY_PARAM_UTTERANCE_ID}.
 894     * @return Code indicating success or failure. See {@link #ERROR} and
 895     *         {@link #SUCCESS}.
 896     */
 897    public int playEarcon(String earcon, int queueMode, HashMap<String, String> params) {
 898        if (!ttsBetaInstalled) {
 899            Log.d("TextToSpeechBeta", USING_PLATFORM_TTS + "playEarcon");
 900            return super.playEarcon(earcon, queueMode, params);
 901        }
 902        synchronized (mStartLock) {
 903            int result = ERROR;
 904            if (!mStarted) {
 905                return result;
 906            }
 907            try {
 908                if ((params != null) && (!params.isEmpty())) {
 909                    String extra = params.get(Engine.KEY_PARAM_STREAM);
 910                    if (extra != null) {
 911                        mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra;
 912                    }
 913                    extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
 914                    if (extra != null) {
 915                        mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
 916                    }
 917                }
 918                result = mITts.playEarcon(mPackageName, earcon, queueMode, null);
 919            } catch (RemoteException e) {
 920                // TTS died; restart it.
 921                Log.e("TextToSpeech.java - playEarcon", "RemoteException");
 922                e.printStackTrace();
 923                mStarted = false;
 924                initTts();
 925            } catch (NullPointerException e) {
 926                // TTS died; restart it.
 927                Log.e("TextToSpeech.java - playEarcon", "NullPointerException");
 928                e.printStackTrace();
 929                mStarted = false;
 930                initTts();
 931            } catch (IllegalStateException e) {
 932                // TTS died; restart it.
 933                Log.e("TextToSpeech.java - playEarcon", "IllegalStateException");
 934                e.printStackTrace();
 935                mStarted = false;
 936                initTts();
 937            } finally {
 938                resetCachedParams();
 939                return result;
 940            }
 941        }
 942    }
 943
 944    /**
 945     * Plays silence for the specified amount of time using the specified queue
 946     * mode.
 947     * 
 948     * @param durationInMs A long that indicates how long the silence should
 949     *            last.
 950     * @param queueMode {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
 951     * @param params The list of parameters to be used. Can be null if no
 952     *            parameters are given. They are specified using a (key, value)
 953     *            pair, where the key can be
 954     *            {@link Engine#KEY_PARAM_UTTERANCE_ID}.
 955     * @return Code indicating success or failure. See {@link #ERROR} and
 956     *         {@link #SUCCESS}.
 957     */
 958    public int playSilence(long durationInMs, int queueMode, HashMap<String, String> params) {
 959        if (!ttsBetaInstalled) {
 960            Log.d("TextToSpeechBeta", USING_PLATFORM_TTS + "playSilence");
 961            return super.playSilence(durationInMs, queueMode, params);
 962        }
 963        synchronized (mStartLock) {
 964            int result = ERROR;
 965            if (!mStarted) {
 966                return result;
 967            }
 968            try {
 969                if ((params != null) && (!params.isEmpty())) {
 970                    String extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
 971                    if (extra != null) {
 972                        mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
 973                    }
 974                }
 975                result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams);
 976            } catch (RemoteException e) {
 977                // TTS died; restart it.
 978                Log.e("TextToSpeech.java - playSilence", "RemoteException");
 979                e.printStackTrace();
 980                mStarted = false;
 981                initTts();
 982            } catch (NullPointerException e) {
 983                // TTS died; restart it.
 984                Log.e("TextToSpeech.java - playSilence", "NullPointerException");
 985                e.printStackTrace();
 986                mStarted = false;
 987                initTts();
 988            } catch (IllegalStateException e) {
 989                // TTS died; restart it.
 990                Log.e("TextToSpeech.java - playSilence", "IllegalStateException");
 991                e.printStackTrace();
 992                mStarted = false;
 993                initTts();
 994            } finally {
 995                return result;
 996            }
 997        }
 998    }
 999
1000    /**
1001     * Returns whether or not the TextToSpeech engine is busy speaking.
1002     * 
1003     * @return Whether or not the TextToSpeech engine is busy speaking.
1004     */
1005    public boolean isSpeaking() {
1006        if (!ttsBetaInstalled) {
1007            Log.d("TextToSpeechBeta", USING_PLATFORM_TTS + "isSpeaking");
1008            return super.isSpeaking();
1009        }
1010        synchronized (mStartLock) {
1011            if (!mStarted) {
1012                return false;
1013            }
1014            try {
1015                return mITts.isSpeaking();
1016            } catch (RemoteException e) {
1017                // TTS died; restart it.
1018                Log.e("TextToSpeech.java - isSpeaking", "RemoteException");
1019                e.printStackTrace();
1020                mStarted = false;
1021                initTts();
1022            } catch (NullPointerException e) {
1023                // TTS died; restart it.
1024                Log.e("TextToSpeech.java - isSpeaking", "NullPointerException");
1025                e.printStackTrace();
1026                mStarted = false;
1027                initTts();
1028            } catch (IllegalStateException e) {
1029                // TTS died; restart it.
1030                Log.e("TextToSpeech.java - isSpeaking", "IllegalStateException");
1031                e.printStackTrace();
1032                mStarted = false;
1033                initTts();
1034            }
1035            return false;
1036        }
1037    }
1038
1039    /**
1040     * Interrupts the current utterance (whether played or rendered to file) and
1041     * discards other utterances in the queue.
1042     * 
1043     * @return Code indicating success or failure. See {@link #ERROR} and
1044     *         {@link #SUCCESS}.
1045     */
1046    public int stop() {
1047        if (!ttsBetaInstalled) {
1048            Log.d("TextToSpeechBeta", USING_PLATFORM_TTS + "stop");
1049            return super.stop();
1050        }
1051        synchronized (mStartLock) {
1052            int result = ERROR;
1053            if (!mStarted) {
1054                return result;
1055            }
1056            try {
1057                result = mITts.stop(mPackageName);
1058            } catch (RemoteException e) {
1059                // TTS died; restart it.
1060                Log.e("TextToSpeech.java - stop", "RemoteException");
1061                e.printStackTrace();
1062                mStarted = false;
1063                initTts();
1064            } catch (NullPointerException e) {
1065                // TTS died; restart it.
1066                Log.e("TextToSpeech.java - stop", "NullPointerException");
1067                e.printStackTrace();
1068                mStarted = false;
1069                initTts();
1070            } catch (IllegalStateException e) {
1071                // TTS died; restart it.
1072                Log.e("TextToSpeech.java - stop", "IllegalStateException");
1073                e.printStackTrace();
1074                mStarted = false;
1075                initTts();
1076            } finally {
1077                return result;
1078            }
1079        }
1080    }
1081
1082    /**
1083     * Sets the speech rate for the TextToSpeech engine. This has no effect on
1084     * any pre-recorded speech.
1085     * 
1086     * @param speechRate The speech rate for the TextToSpeech engine. 1 is the
1087     *            normal speed, lower values slow down the speech (0.5 is half
1088     *            the normal speech rate), greater values accelerate it (2 is
1089     *            twice the normal speech rate).
1090     * @return Code indicating success or failure. See {@link #ERROR} and
1091     *         {@link #SUCCESS}.
1092     */
1093    public int setSpeechRate(float speechRate) {
1094        if (!ttsBetaInstalled) {
1095            Log.d("TextToSpeechBeta",
1096                    "TextToSpeechBeta not installed - defaulting to basic platform TextToSpeech");
1097            return super.setSpeechRate(speechRate);
1098        }
1099        synchronized (mStartLock) {
1100            int result = ERROR;
1101            if (!mStarted) {
1102                return result;
1103            }
1104            try {
1105                if (speechRate > 0) {
1106                    int rate = (int) (speechRate * 100);
1107                    mCachedParams[Engine.PARAM_POSITION_RATE + 1] = String.valueOf(rate);
1108                    // the rate is not set here, instead it is cached so it will
1109                    // be
1110                    // associated
1111                    // with all upcoming utterances.
1112                    if (speechRate > 0.0f) {
1113                        result = SUCCESS;
1114                    } else {
1115                        result = ERROR;
1116                    }
1117                }
1118            } catch (NullPointerException e) {
1119                // TTS died; restart it.
1120                Log.e("TextToSpeech.java - setSpeechRate", "NullPointerException");
1121                e.printStackTrace();
1122                mStarted = false;
1123                initTts();
1124            } catch (IllegalStateException e) {
1125                // TTS died; restart it.
1126                Log.e("TextToSpeech.java - setSpeechRate", "IllegalStateException");
1127                e.printStackTrace();
1128                mStarted = false;
1129                initTts();
1130            } finally {
1131                return result;
1132            }
1133        }
1134    }
1135
1136    /**
1137     * Sets the speech pitch for the TextToSpeech engine. This has no effect on
1138     * any pre-recorded speech.
1139     * 
1140     * @param pitch The pitch for the TextToSpeech engine. 1 is the normal
1141     *            pitch, lower values lower the tone of the synthesized voice,
1142     *            greater values increase it.
1143     * @return Code indicating success or failure. See {@link #ERROR} and
1144     *         {@link #SUCCESS}.
1145     */
1146    public int setPitch(float pitch) {
1147        if (!ttsBetaInstalled) {
1148            Log.d("TextToSpeechBeta",
1149                    "TextToSpeechBeta not installed - defaulting to basic platform TextToSpeech");
1150            return super.setPitch(pitch);
1151        }
1152        synchronized (mStartLock) {
1153            int result = ERROR;
1154            if (!mStarted) {
1155                return result;
1156            }
1157            try {
1158                if (pitch > 0) {
1159                    result = mITts.setPitch(mPackageName, (int) (pitch * 100));
1160                }
1161            } catch (RemoteException e) {
1162                // TTS died; restart it.
1163                Log.e("TextToSpeech.java - setPitch", "RemoteException");
1164                e.printStackTrace();
1165                mStarted = false;
1166                initTts();
1167            } catch (NullPointerException e) {
1168                // TTS died; restart it.
1169                Log.e("TextToSpeech.java - setPitch", "NullPointerException");
1170                e.printStackTrace();
1171                mStarted = false;
1172                initTts();
1173            } catch (IllegalStateException e) {
1174                // TTS died; restart it.
1175                Log.e("TextToSpeech.java - setPitch", "IllegalStateException");
1176                e.printStackTrace();
1177                mStarted = false;
1178                initTts();
1179            } finally {
1180                return result;
1181            }
1182        }
1183    }
1184
1185    /**
1186     * Sets the language for the TextToSpeech engine. The TextToSpeech engine
1187     * will try to use the closest match to the specified language as
1188     * represented by the Locale, but there is no guarantee that the exact same
1189     * Locale will be used. Use {@link #isLanguageAvailable(Locale)} to check
1190     * the level of support before choosing the language to use for the next
1191     * utterances.
1192     * 
1193     * @param loc The locale describing the language to be used.
1194     * @return code indicating the support status for the locale. See
1195     *         {@link #LANG_AVAILABLE}, {@link #LANG_COUNTRY_AVAILABLE},
1196     *         {@link #LANG_COUNTRY_VAR_AVAILABLE}, {@link #LANG_MISSING_DATA}
1197     *         and {@link #LANG_NOT_SUPPORTED}.
1198     */
1199    public int setLanguage(Locale loc) {
1200        if (!ttsBetaInstalled) {
1201            Log.d("TextToSpeechBeta", USING_PLATFORM_TTS + "setLanguage");
1202            return super.setLanguage(loc);
1203        }
1204        synchronized (mStartLock) {
1205            int result = LANG_NOT_SUPPORTED;
1206            if (!mStarted) {
1207                return result;
1208            }
1209            try {
1210                mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language();
1211                mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country();
1212                mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = loc.getVariant();
1213                // the language is not set here, instead it is cached so it will
1214                // be
1215                // associated
1216                // with all upcoming utterances. But we still need to report the
1217                // language support,
1218                // which is achieved by calling isLanguageAvailable()
1219                result = mITts.isLanguageAvailable(
1220                        mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1],
1221                        mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1],
1222                        mCachedParams[Engine.PARAM_POSITION_VARIANT + 1], mCachedParams);
1223            } catch (RemoteException e) {
1224                // TTS died; restart it.
1225                Log.e("TextToSpeech.java - setLanguage", "RemoteException");
1226                e.printStackTrace();
1227             

Large files files are truncated, but you can click here to view the full file