Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0a854d4 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 4398 into donut

* changes:
  Using Locale to specify language and country for a TTS language to load, rather than a String. Cleanup in doc for TextToSpeech, and addition of queue mode constants.
parents 2cf3971e 679d728f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ interface ITts {

    void addSpeechFile(in String text, in String filename);

    void setLanguage(in String language);
    void setLanguage(in String language, in String country, in String variant);

    boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory);

+37 −35
Original line number Diff line number Diff line
@@ -22,13 +22,12 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import java.util.HashMap;
import java.util.Locale;

/**
 *
@@ -36,7 +35,7 @@ import java.util.HashMap;
 *
 * {@hide}
 */
//TODO #TTS# review + complete javadoc
//TODO #TTS# review + complete javadoc + add links to constants
public class TextToSpeech {

    /**
@@ -52,9 +51,18 @@ public class TextToSpeech {
     */
    public static final int TTS_ERROR_MISSING_RESOURCE = -2;

    /**
     * Queue mode where all entries in the playback queue (media to be played
     * and text to be synthesized) are dropped and replaced by the new entry.
     */
    public static final int TTS_QUEUE_FLUSH = 0;
    /**
     * Queue mode where the new entry is added at the end of the playback queue.
     */
    public static final int TTS_QUEUE_ADD = 1;

    /**
     * Called when the TTS has initialized
     * Called when the TTS has initialized.
     *
     * The InitListener must implement the onInit function. onInit is passed a
     * status code indicating the result of the TTS initialization.
@@ -73,9 +81,9 @@ public class TextToSpeech {
    }

    /**
     * Connection needed for the TTS
     * Connection needed for the TTS.
     */
    private ServiceConnection serviceConnection;
    private ServiceConnection mServiceConnection;

    private ITts mITts = null;
    private Context mContext = null;
@@ -104,8 +112,7 @@ public class TextToSpeech {
    }


    public void setOnSpeechCompletedListener(
            final OnSpeechCompletedListener listener) {
    public void setOnSpeechCompletedListener(final OnSpeechCompletedListener listener) {
        synchronized(mSpeechCompListenerLock) {
            mSpeechCompListener = listener;
        }
@@ -126,7 +133,7 @@ public class TextToSpeech {
        mStarted = false;

        // Initialize the TTS, run the callback after the binding is successful
        serviceConnection = new ServiceConnection() {
        mServiceConnection = new ServiceConnection() {
            public void onServiceConnected(ComponentName name, IBinder service) {
                synchronized(mStartLock) {
                    mITts = ITts.Stub.asInterface(service);
@@ -176,7 +183,7 @@ public class TextToSpeech {

        Intent intent = new Intent("android.intent.action.USE_TTS");
        intent.addCategory("android.intent.category.TTS");
        mContext.bindService(intent, serviceConnection,
        mContext.bindService(intent, mServiceConnection,
                Context.BIND_AUTO_CREATE);
        // TODO handle case where the binding works (should always work) but
        //      the plugin fails
@@ -190,7 +197,7 @@ public class TextToSpeech {
     */
    public void shutdown() {
        try {
            mContext.unbindService(serviceConnection);
            mContext.unbindService(mServiceConnection);
        } catch (IllegalArgumentException e) {
            // Do nothing and fail silently since an error here indicates that
            // binding never succeeded in the first place.
@@ -291,8 +298,8 @@ public class TextToSpeech {
     * @param text
     *            The string of text to be spoken.
     * @param queueMode
     *            The queuing strategy to use. Use 0 for no queuing, and 1 for
     *            queuing.
     *            The queuing strategy to use.
     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
     * @param params
     *            The hashmap of speech parameters to be used.
     */
@@ -329,8 +336,7 @@ public class TextToSpeech {
     * @param earcon
     *            The earcon that should be played
     * @param queueMode
     *            0 for no queue (interrupts all previous utterances), 1 for
     *            queued
     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
     * @param params
     *            The hashmap of parameters to be used.
     */
@@ -429,20 +435,22 @@ public class TextToSpeech {
     * Note that the speech rate is not universally supported by all engines and
     * will be treated as a hint. The TTS library will try to use the specified
     * speech rate, but there is no guarantee.
     *
     * Currently, this will change the speech rate for the espeak engine, but it
     * has no effect on any pre-recorded speech.
     * This has no effect on any pre-recorded speech.
     *
     * @param speechRate
     *            The speech rate for the TTS engine.
     *            The speech rate for the TTS engine. 1 is the normal speed,
     *            lower values slow down the speech (0.5 is half the normal speech rate),
     *            greater values accelerate it (2 is twice the normal speech rate).
     */
    public void setSpeechRate(int speechRate) {
    public void setSpeechRate(float speechRate) {
        synchronized (mStartLock) {
            if (!mStarted) {
                return;
            }
            try {
                mITts.setSpeechRate(speechRate);
                if (speechRate > 0) {
                    mITts.setSpeechRate((int)(speechRate*100));
                }
            } catch (RemoteException e) {
                // TTS died; restart it.
                mStarted = false;
@@ -457,24 +465,18 @@ public class TextToSpeech {
     *
     * Note that the language is not universally supported by all engines and
     * will be treated as a hint. The TTS library will try to use the specified
     * language, but there is no guarantee.
     *
     * Currently, this will change the language for the espeak engine, but it
     * has no effect on any pre-recorded speech.
     * language as represented by the Locale, but there is no guarantee.
     *
     * @param language
     *            The language to be used. The languages are specified by their
     *            IETF language tags as defined by BCP 47. This is the same
     *            standard used for the lang attribute in HTML. See:
     *            http://en.wikipedia.org/wiki/IETF_language_tag
     * @param loc
     *            The locale describing the language to be used.
     */
    public void setLanguage(String language) {
    public void setLanguage(Locale loc) {
        synchronized (mStartLock) {
            if (!mStarted) {
                return;
            }
            try {
                mITts.setLanguage(language);
                mITts.setLanguage(loc.getISO3Language(), loc.getISO3Country(), loc.getVariant());
            } catch (RemoteException e) {
                // TTS died; restart it.
                mStarted = false;
+10 −8
Original line number Diff line number Diff line
@@ -269,10 +269,10 @@ android_tts_SynthProxy_native_finalize(JNIEnv *env, jobject thiz, jint jniData)
    }
}

// TODO update to use language, country, variant

static void
android_tts_SynthProxy_setLanguage(JNIEnv *env, jobject thiz, jint jniData,
        jstring language)
        jstring language, jstring country, jstring variant)
{
    if (jniData == 0) {
        LOGE("android_tts_SynthProxy_setLanguage(): invalid JNI data");
@@ -281,14 +281,16 @@ android_tts_SynthProxy_setLanguage(JNIEnv *env, jobject thiz, jint jniData,

    SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
    const char *langNativeString = env->GetStringUTFChars(language, 0);
    const char *countryNativeString = env->GetStringUTFChars(country, 0);
    const char *variantNativeString = env->GetStringUTFChars(variant, 0);
    // TODO check return codes
    if (pSynthData->mNativeSynthInterface) {
        // TODO update to use language, country, variant
        //      commented out to not break the build
        //pSynthData->mNativeSynthInterface->setLanguage(langNativeString,
        //        strlen(langNativeString));
        pSynthData->mNativeSynthInterface->setLanguage(langNativeString, countryNativeString,
                variantNativeString);
    }
    env->ReleaseStringUTFChars(language, langNativeString);
    env->ReleaseStringUTFChars(language, countryNativeString);
    env->ReleaseStringUTFChars(language, variantNativeString);
}


@@ -496,6 +498,7 @@ android_tts_SynthProxy_getLanguage(JNIEnv *env, jobject thiz, jint jniData)
    return env->NewStringUTF(buf);
}


JNIEXPORT int JNICALL
android_tts_SynthProxy_getRate(JNIEnv *env, jobject thiz, jint jniData)
{
@@ -531,7 +534,7 @@ static JNINativeMethod gMethods[] = {
        (void*)android_tts_SynthProxy_synthesizeToFile
    },
    {   "native_setLanguage",
        "(ILjava/lang/String;)V",
        "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
        (void*)android_tts_SynthProxy_setLanguage
    },
    {   "native_setSpeechRate",
@@ -567,7 +570,6 @@ static JNINativeMethod gMethods[] = {
#define SP_JNIDATA_FIELD_NAME                "mJniData"
#define SP_POSTSPEECHSYNTHESIZED_METHOD_NAME "postNativeSpeechSynthesizedInJava"

// TODO: verify this is the correct path
static const char* const kClassPathName = "android/tts/SynthProxy";

jint JNI_OnLoad(JavaVM* vm, void* reserved)
+4 −3
Original line number Diff line number Diff line
@@ -70,8 +70,8 @@ public class SynthProxy {
    /**
     * Sets the language
     */
    public void setLanguage(String language) {
        native_setLanguage(mJniData, language);
    public void setLanguage(String language, String country, String variant) {
        native_setLanguage(mJniData, language, country, variant);
    }

    /**
@@ -141,7 +141,8 @@ public class SynthProxy {

    private native final void native_synthesizeToFile(int jniData, String text, String filename);

    private native final void native_setLanguage(int jniData, String language);
    private native final void native_setLanguage(int jniData, String language, String country,
            String variant);

    private native final void native_setSpeechRate(int jniData, int speechRate);

+12 −15
Original line number Diff line number Diff line
@@ -129,7 +129,9 @@ public class TtsService extends Service implements OnCompletionListener {
        mSpeechQueue = new ArrayList<SpeechItem>();
        mPlayer = null;

        setLanguage(prefs.getString("lang_pref", "en-rUS"));
        // TODO set default settings
        //setLanguage(prefs.getString("lang_pref", "en-rUS"));
        setLanguage("eng", "USA", "");
        setSpeechRate(Integer.parseInt(prefs.getString("rate_pref", "140")));
    }

@@ -155,7 +157,7 @@ public class TtsService extends Service implements OnCompletionListener {
        nativeSynth.setSpeechRate(rate);
    }

    private void setLanguage(String lang) {
    private void setLanguage(String lang, String country, String variant) {
        if (prefs.getBoolean("override_pref", false)) {
            // This is set to the default here so that the preview in the prefs
            // activity will show the change without a restart, even if apps are
@@ -163,7 +165,8 @@ public class TtsService extends Service implements OnCompletionListener {
            // allowed to change the defaults.
            lang = prefs.getString("lang_pref", "en-rUS");
        }
        nativeSynth.setLanguage(lang);
        Log.v("TTS", "TtsService.setLanguage("+lang+", "+country+", "+variant+")");
        nativeSynth.setLanguage(lang, country, variant);
    }

    /**
@@ -683,20 +686,14 @@ public class TtsService extends Service implements OnCompletionListener {
        }

        /**
         * Sets the speech rate for the TTS. Note that this will only have an
         * effect on synthesized speech; it will not affect pre-recorded speech.
         * Sets the speech rate for the TTS, which affects the synthesized voice.
         *
         * @param language
         *            Language values are based on the Android conventions for
         *            localization as described in the Android platform
         *            documentation on internationalization. This implies that
         *            language data is specified in the format xx-rYY, where xx
         *            is a two letter ISO 639-1 language code in lowercase and
         *            rYY is a two letter ISO 3166-1-alpha-2 language code in
         *            uppercase preceded by a lowercase "r".
         * @param lang  the three letter ISO language code.
         * @param country  the three letter ISO country code.
         * @param variant  the variant code associated with the country and language pair.
         */
        public void setLanguage(String language) {
            mSelf.setLanguage(language);
        public void setLanguage(String lang, String country, String variant) {
            mSelf.setLanguage(lang, country, variant);
        }

        /**