Browse Source

SpeechSynthesis.java: expose the different voice options from eSpeak

This makes the following changes:

1.  setVoice takes a Voice object instead of a language string.

    This is to make the API cleaner and allows SpeechSynthesis
    to pass the correct parameter (identifier for SetVoiceByName,
    or name for SetVoiceByProperties) to espeak.

2.  The espeak_SetVoiceByName API is also exposed to support passing
    the voice variant to use.

3.  The age parameter has been re-added with the constants:
    *  SpeechSynthesis.AGE_ANY
    *  SpeechSynthesis.AGE_YOUNG
    *  SpeechSynthesis.AGE_OLD
    based on the behaviour of the eSpeak voice selection algorithm.

NOTE: Due to the way that voice selection is implemented in eSpeak,
if variant is specified, the age and gender cannot be specified and
vice versa.
master
Reece H. Dunn 12 years ago
parent
commit
cc72825682

+ 25
- 3
android/jni/jni/eSpeakService.cpp View File

} }


JNIEXPORT jboolean JNIEXPORT jboolean
JNICALL Java_com_reecedunn_espeak_SpeechSynthesis_nativeSetVoice(
JNIEnv *env, jobject object, jstring language, jint gender) {
JNICALL Java_com_reecedunn_espeak_SpeechSynthesis_nativeSetVoiceByName(
JNIEnv *env, jobject object, jstring name) {
const char *c_name = name ? env->GetStringUTFChars(name, NULL) : NULL;

if (DEBUG) LOGV("%s(name=%s)", __FUNCTION__, c_name);

const espeak_ERROR result = espeak_SetVoiceByName(c_name);

if (c_name) env->ReleaseStringUTFChars(name, c_name);

switch (result) {
case EE_OK: return JNI_TRUE;
case EE_INTERNAL_ERROR: LOGE("espeak_SetVoiceByName: internal error."); break;
case EE_BUFFER_FULL: LOGE("espeak_SetVoiceByName: buffer full."); break;
case EE_NOT_FOUND: LOGE("espeak_SetVoiceByName: not found."); break;
}

return JNI_FALSE;
}

JNIEXPORT jboolean
JNICALL Java_com_reecedunn_espeak_SpeechSynthesis_nativeSetVoiceByProperties(
JNIEnv *env, jobject object, jstring language, jint gender, jint age) {
const char *c_language = language ? env->GetStringUTFChars(language, NULL) : NULL; const char *c_language = language ? env->GetStringUTFChars(language, NULL) : NULL;


if (DEBUG) LOGV("%s(language=%s, gender=%d)", __FUNCTION__, c_language, gender);
if (DEBUG) LOGV("%s(language=%s, gender=%d, age=%d)", __FUNCTION__, c_language, gender, age);


espeak_VOICE voice_select; espeak_VOICE voice_select;
memset(&voice_select, 0, sizeof(espeak_VOICE)); memset(&voice_select, 0, sizeof(espeak_VOICE));
voice_select.languages = c_language; voice_select.languages = c_language;
voice_select.gender = (int) gender; voice_select.gender = (int) gender;
voice_select.age = (int) age;


const espeak_ERROR result = espeak_SetVoiceByProperties(&voice_select); const espeak_ERROR result = espeak_SetVoiceByProperties(&voice_select);



+ 15
- 3
android/src/com/reecedunn/espeak/SpeechSynthesis.java View File

public static final int GENDER_MALE = 1; public static final int GENDER_MALE = 1;
public static final int GENDER_FEMALE = 2; public static final int GENDER_FEMALE = 2;


public static final int AGE_ANY = 0;
public static final int AGE_YOUNG = 12;
public static final int AGE_OLD = 60;

static { static {
System.loadLibrary("ttsespeak"); System.loadLibrary("ttsespeak");


return voices; return voices;
} }


public void setVoice(String language, int gender) {
nativeSetVoice(language, gender);
public void setVoice(Voice voice, String variant, int gender, int age) {
// 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);
} else {
nativeSetVoiceByName(voice.identifier + "+" + variant);
}
} }


public void setRate(int rate) { public void setRate(int rate) {


private native final String[] nativeGetAvailableVoices(); private native final String[] nativeGetAvailableVoices();


private native final boolean nativeSetVoice(String language, int gender);
private native final boolean nativeSetVoiceByName(String name);

private native final boolean nativeSetVoiceByProperties(String language, int gender, int age);


private native final boolean nativeSetRate(int rate); private native final boolean nativeSetRate(int rate);



+ 1
- 1
android/src/com/reecedunn/espeak/TtsService.java View File

mCallback.start(mEngine.getSampleRate(), mEngine.getAudioFormat(), mCallback.start(mEngine.getSampleRate(), mEngine.getAudioFormat(),
mEngine.getChannelCount()); mEngine.getChannelCount());


mEngine.setVoice(mMatchingVoice.name, gender);
mEngine.setVoice(mMatchingVoice, null, gender, SpeechSynthesis.AGE_ANY);
mEngine.setRate(rate); mEngine.setRate(rate);
mEngine.setPitch(pitch); mEngine.setPitch(pitch);
mEngine.synthesize(text, text.startsWith("<speak")); mEngine.synthesize(text, text.startsWith("<speak"));

Loading…
Cancel
Save