Fix for bug 2564771 - pitch setting between apps can

interfere with one another.

Root cause was not caching all the params that were needed.
This change fixes that bug as well as related bugs for remembering
the default engine and for making sure that the right engine is
loaded when checking for language availability.

Change-Id: I2a76da8faec8112036e68d27539db444c53a1509
This commit is contained in:
Charles Chen
2010-04-01 17:16:28 -07:00
parent 9d32d24dbd
commit 1a2712ce2a
3 changed files with 87 additions and 27 deletions

View File

@@ -43,7 +43,7 @@ interface ITts {
String[] getLanguage();
int isLanguageAvailable(in String language, in String country, in String variant);
int isLanguageAvailable(in String language, in String country, in String variant, in String[] params);
int setLanguage(in String callingApp, in String language, in String country, in String variant);

View File

@@ -314,6 +314,10 @@ public class TextToSpeech {
* {@hide}
*/
public static final String KEY_PARAM_ENGINE = "engine";
/**
* {@hide}
*/
public static final String KEY_PARAM_PITCH = "pitch";
/**
* Parameter key to specify the audio stream type to be used when speaking text
* or playing back a file.
@@ -365,7 +369,12 @@ public class TextToSpeech {
/**
* {@hide}
*/
protected static final int NB_CACHED_PARAMS = 7;
protected static final int PARAM_POSITION_PITCH = 14;
/**
* {@hide}
*/
protected static final int NB_CACHED_PARAMS = 8;
}
/**
@@ -409,9 +418,10 @@ public class TextToSpeech {
mCachedParams[Engine.PARAM_POSITION_STREAM] = Engine.KEY_PARAM_STREAM;
mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID] = Engine.KEY_PARAM_UTTERANCE_ID;
mCachedParams[Engine.PARAM_POSITION_ENGINE] = Engine.KEY_PARAM_ENGINE;
mCachedParams[Engine.PARAM_POSITION_PITCH] = Engine.KEY_PARAM_PITCH;
// Leave all defaults that are shown in Settings uninitialized so that
// the values set in Settings will take effect if the application does
// Leave all defaults that are shown in Settings uninitialized/at the default
// so that the values set in Settings will take effect if the application does
// not try to change these settings itself.
mCachedParams[Engine.PARAM_POSITION_RATE + 1] = "";
mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = "";
@@ -421,6 +431,7 @@ public class TextToSpeech {
String.valueOf(Engine.DEFAULT_STREAM);
mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = "";
mCachedParams[Engine.PARAM_POSITION_ENGINE + 1] = "";
mCachedParams[Engine.PARAM_POSITION_PITCH + 1] = "100";
initTts();
}
@@ -435,6 +446,9 @@ public class TextToSpeech {
synchronized(mStartLock) {
mITts = ITts.Stub.asInterface(service);
mStarted = true;
// Cache the default engine and current language
setEngineByPackageName(getDefaultEngine());
setLanguage(getLanguage());
if (mInitListener != null) {
// TODO manage failures and missing resources
mInitListener.onInit(SUCCESS);
@@ -1008,15 +1022,13 @@ public class TextToSpeech {
return result;
}
try {
// the pitch is not set here, instead it is cached so it will be associated
// with all upcoming utterances.
if (pitch > 0) {
result = mITts.setPitch(mPackageName, (int)(pitch*100));
int p = (int)(pitch*100);
mCachedParams[Engine.PARAM_POSITION_PITCH + 1] = String.valueOf(p);
result = SUCCESS;
}
} catch (RemoteException e) {
// TTS died; restart it.
Log.e("TextToSpeech.java - setPitch", "RemoteException");
e.printStackTrace();
mStarted = false;
initTts();
} catch (NullPointerException e) {
// TTS died; restart it.
Log.e("TextToSpeech.java - setPitch", "NullPointerException");
@@ -1057,16 +1069,27 @@ public class TextToSpeech {
return result;
}
try {
mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language();
mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country();
mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = loc.getVariant();
// the language is not set here, instead it is cached so it will be associated
// with all upcoming utterances. But we still need to report the language support,
// which is achieved by calling isLanguageAvailable()
result = mITts.isLanguageAvailable(
mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1],
mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1],
mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] );
String language = loc.getISO3Language();
String country = loc.getISO3Country();
String variant = loc.getVariant();
// Check if the language, country, variant are available, and cache
// the available parts.
// Note that the language is not actually set here, instead it is cached so it
// will be associated with all upcoming utterances.
result = mITts.isLanguageAvailable(language, country, variant, mCachedParams);
if (result >= LANG_AVAILABLE){
mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = language;
if (result >= LANG_COUNTRY_AVAILABLE){
mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = country;
} else {
mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = "";
}
if (result >= LANG_COUNTRY_VAR_AVAILABLE){
mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = variant;
} else {
mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = "";
}
}
} catch (RemoteException e) {
// TTS died; restart it.
Log.e("TextToSpeech.java - setLanguage", "RemoteException");
@@ -1104,11 +1127,18 @@ public class TextToSpeech {
return null;
}
try {
String[] locStrings = mITts.getLanguage();
if ((locStrings != null) && (locStrings.length == 3)) {
return new Locale(locStrings[0], locStrings[1], locStrings[2]);
// Only do a call to the native synth if there is nothing in the cached params
if (mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1].length() < 1){
String[] locStrings = mITts.getLanguage();
if ((locStrings != null) && (locStrings.length == 3)) {
return new Locale(locStrings[0], locStrings[1], locStrings[2]);
} else {
return null;
}
} else {
return null;
return new Locale(mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1],
mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1],
mCachedParams[Engine.PARAM_POSITION_VARIANT + 1]);
}
} catch (RemoteException e) {
// TTS died; restart it.
@@ -1151,7 +1181,7 @@ public class TextToSpeech {
}
try {
result = mITts.isLanguageAvailable(loc.getISO3Language(),
loc.getISO3Country(), loc.getVariant());
loc.getISO3Country(), loc.getVariant(), mCachedParams);
} catch (RemoteException e) {
// TTS died; restart it.
Log.e("TextToSpeech.java - isLanguageAvailable", "RemoteException");

View File

@@ -321,6 +321,10 @@ public class TtsService extends Service implements OnCompletionListener {
TextToSpeech.Engine.DEFAULT_RATE);
}
private int getDefaultPitch() {
// Pitch is not user settable; the default pitch is always 100.
return 100;
}
private String getDefaultLanguage() {
String defaultLang = android.provider.Settings.Secure.getString(mResolver,
@@ -786,6 +790,7 @@ public class TtsService extends Service implements OnCompletionListener {
String variant = "";
String speechRate = "";
String engine = "";
String pitch = "";
if (speechItem.mParams != null){
for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){
String param = speechItem.mParams.get(i);
@@ -809,6 +814,8 @@ public class TtsService extends Service implements OnCompletionListener {
}
} else if (param.equals(TextToSpeech.Engine.KEY_PARAM_ENGINE)) {
engine = speechItem.mParams.get(i + 1);
} else if (param.equals(TextToSpeech.Engine.KEY_PARAM_PITCH)) {
pitch = speechItem.mParams.get(i + 1);
}
}
}
@@ -831,6 +838,11 @@ public class TtsService extends Service implements OnCompletionListener {
} else {
setSpeechRate("", getDefaultRate());
}
if (pitch.length() > 0){
setPitch("", Integer.parseInt(pitch));
} else {
setPitch("", getDefaultPitch());
}
try {
sNativeSynth.speak(speechItem.mText, streamType);
} catch (NullPointerException e) {
@@ -885,6 +897,7 @@ public class TtsService extends Service implements OnCompletionListener {
String variant = "";
String speechRate = "";
String engine = "";
String pitch = "";
if (speechItem.mParams != null){
for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){
String param = speechItem.mParams.get(i);
@@ -901,6 +914,8 @@ public class TtsService extends Service implements OnCompletionListener {
utteranceId = speechItem.mParams.get(i+1);
} else if (param.equals(TextToSpeech.Engine.KEY_PARAM_ENGINE)) {
engine = speechItem.mParams.get(i + 1);
} else if (param.equals(TextToSpeech.Engine.KEY_PARAM_PITCH)) {
pitch = speechItem.mParams.get(i + 1);
}
}
}
@@ -923,6 +938,11 @@ public class TtsService extends Service implements OnCompletionListener {
} else {
setSpeechRate("", getDefaultRate());
}
if (pitch.length() > 0){
setPitch("", Integer.parseInt(pitch));
} else {
setPitch("", getDefaultPitch());
}
try {
sNativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
} catch (NullPointerException e) {
@@ -1377,7 +1397,17 @@ public class TtsService extends Service implements OnCompletionListener {
* TTS_LANG_COUNTRY_AVAILABLE, TTS_LANG_COUNTRY_VAR_AVAILABLE as defined in
* android.speech.tts.TextToSpeech.
*/
public int isLanguageAvailable(String lang, String country, String variant) {
public int isLanguageAvailable(String lang, String country, String variant,
String[] params) {
for (int i = 0; i < params.length - 1; i = i + 2){
String param = params[i];
if (param != null) {
if (param.equals(TextToSpeech.Engine.KEY_PARAM_ENGINE)) {
mSelf.setEngine(params[i + 1]);
break;
}
}
}
return mSelf.isLanguageAvailable(lang, country, variant);
}