mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-14 09:37:47 +00:00
Support voice variants and ages.
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user