Support voice variants and ages.

This commit is contained in:
Reece H. Dunn
2013-05-05 13:25:46 +01:00
parent dde42239f3
commit a42f748f2b
52 changed files with 147 additions and 87 deletions
@@ -173,13 +173,13 @@ public class SpeechSynthesis {
return voices;
}
public void setVoice(Voice voice, String variant, int gender, int age) {
public void setVoice(Voice voice, VoiceVariant variant) {
// NOTE: espeak_SetVoiceByProperties does not support specifying the
// voice variant (e.g. klatt), but espeak_SetVoiceByName does.
if (variant == null) {
nativeSetVoiceByProperties(voice.name, gender, age);
if (variant.variant == null) {
nativeSetVoiceByProperties(voice.name, variant.gender, variant.age);
} else {
nativeSetVoiceByName(voice.identifier + "+" + variant);
nativeSetVoiceByName(voice.identifier + "+" + variant.variant);
}
}
@@ -345,6 +345,59 @@ public class SpeechSynthesis {
void onSynthDataComplete();
}
public static class VoiceVariant {
public final String variant;
public final int gender;
public final int age;
protected VoiceVariant(String variant, int age) {
if (variant.equals("male")) {
this.variant = null;
this.gender = GENDER_MALE;
} else if (variant.equals("female")) {
this.variant = null;
this.gender = GENDER_FEMALE;
} else {
this.variant = variant;
this.gender = GENDER_UNSPECIFIED;
}
this.age = age;
}
@Override
public String toString() {
final String ret;
if (gender == GENDER_MALE) {
ret = "male";
} else if (gender == GENDER_FEMALE) {
ret = "female";
} else {
ret = variant;
}
if (age == AGE_YOUNG) {
return ret + "-young";
} else if (age == AGE_OLD) {
return ret + "-old";
}
return ret;
}
}
public static VoiceVariant parseVoiceVariant(String value) {
String[] parts = value.split("-");
int age = AGE_ANY;
switch (parts.length) {
case 1: // variant
break;
case 2: // variant-age
age = parts[1].equals("young") ? AGE_YOUNG : AGE_OLD;
break;
default:
return null;
}
return new VoiceVariant(parts[0], age);
}
public class Voice {
public final String name;
public final String identifier;
@@ -196,24 +196,36 @@ public class TtsService extends TextToSpeechService {
if (text == null)
return;
final int gender = getPreferenceValue("default_gender", 0);
final Bundle params = request.getParams();
int rate = getPreferenceValue("espeak_rate", Integer.MIN_VALUE);
if (rate == Integer.MIN_VALUE) {
// Try the old eyes-free setting:
rate = (getPreferenceValue("default_rate", 100) / 100) * mEngine.Rate.getDefaultValue();
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
final String variantString = prefs.getString("espeak_variant", null);
final SpeechSynthesis.VoiceVariant variant;
if (variantString == null) {
final int gender = getPreferenceValue(prefs, "default_gender", SpeechSynthesis.GENDER_MALE);
if (gender == SpeechSynthesis.GENDER_FEMALE) {
variant = SpeechSynthesis.parseVoiceVariant("default-female");
} else {
variant = SpeechSynthesis.parseVoiceVariant("default-male");
}
} else {
variant = SpeechSynthesis.parseVoiceVariant(variantString);
}
int pitch = getPreferenceValue("espeak_pitch", Integer.MIN_VALUE);
int rate = getPreferenceValue(prefs, "espeak_rate", Integer.MIN_VALUE);
if (rate == Integer.MIN_VALUE) {
// Try the old eyes-free setting:
rate = (getPreferenceValue(prefs, "default_rate", 100) / 100) * mEngine.Rate.getDefaultValue();
}
int pitch = getPreferenceValue(prefs, "espeak_pitch", Integer.MIN_VALUE);
if (pitch == Integer.MIN_VALUE) {
// Try the old eyes-free setting:
pitch = getPreferenceValue("default_pitch", 100) / 2;
pitch = getPreferenceValue(prefs, "default_pitch", 100) / 2;
}
if (DEBUG) {
Log.i(TAG, "Received synthesis request: {language=\"" + mMatchingVoice.name + "\"}");
final Bundle params = request.getParams();
for (String key : params.keySet()) {
Log.v(TAG,
"Synthesis request contained param {" + key + ", " + params.get(key) + "}");
@@ -231,16 +243,15 @@ public class TtsService extends TextToSpeechService {
mCallback.start(mEngine.getSampleRate(), mEngine.getAudioFormat(),
mEngine.getChannelCount());
mEngine.setVoice(mMatchingVoice, null, gender, SpeechSynthesis.AGE_ANY);
mEngine.setVoice(mMatchingVoice, variant);
mEngine.Rate.setValue(rate, request.getSpeechRate());
mEngine.Pitch.setValue(pitch, request.getPitch());
mEngine.PitchRange.setValue(getPreferenceValue("espeak_pitch_range", mEngine.PitchRange.getDefaultValue()));
mEngine.Volume.setValue(getPreferenceValue("espeak_volume", mEngine.Volume.getDefaultValue()));
mEngine.PitchRange.setValue(getPreferenceValue(prefs, "espeak_pitch_range", mEngine.PitchRange.getDefaultValue()));
mEngine.Volume.setValue(getPreferenceValue(prefs, "espeak_volume", mEngine.Volume.getDefaultValue()));
mEngine.synthesize(text, text.startsWith("<speak"));
}
private int getPreferenceValue(String preference, int defaultValue) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
private int getPreferenceValue(SharedPreferences prefs, String preference, int defaultValue) {
final String prefString = prefs.getString(preference, null);
if (prefString == null) {
return defaultValue;
@@ -57,10 +57,14 @@ public class TtsSettingsActivity extends PreferenceActivity {
editor.putString("espeak_rate", Integer.toString(rateValue));
}
String gender = prefs.getString("default_gender", "0");
if (gender.equals("0")) {
// Convert the "Default" value to "Male":
editor.putString("default_gender", "1");
String variant = prefs.getString("espeak_variant", null);
if (variant == null) {
String gender = prefs.getString("default_gender", "0");
if (gender.equals("2")) {
editor.putString("espeak_variant", "female");
} else {
editor.putString("espeak_variant", "male");
}
}
editor.commit();