Browse Source

Remove the use of the native_data_t object.

master
Reece H. Dunn 9 years ago
parent
commit
e6f6e97680

+ 9
- 44
android/jni/jni/eSpeakService.cpp View File

SYNTH_ABORT = 1 SYNTH_ABORT = 1
}; };


struct native_data_t {
JNIEnv *env;
jobject object;

native_data_t() {
env = NULL;
object = NULL;
}
};

static JavaVM *jvm = NULL;
jmethodID METHOD_nativeSynthCallback; jmethodID METHOD_nativeSynthCallback;
jfieldID FIELD_mNativeData;


static inline native_data_t *getNativeData(JNIEnv *env, jobject object) {
return (native_data_t *) (env->GetIntField(object, FIELD_mNativeData));
static JNIEnv *getJniEnv() {
JNIEnv *env = NULL;
jvm->AttachCurrentThread(&env, NULL);
return env;
} }


/* Callback from espeak. Should call back to the TTS API */ /* Callback from espeak. Should call back to the TTS API */
static int SynthCallback(short *audioData, int numSamples, static int SynthCallback(short *audioData, int numSamples,
espeak_EVENT *events) { espeak_EVENT *events) {
native_data_t *nat = (native_data_t *) events->user_data;
JNIEnv *env = nat->env;
jobject object = nat->object;
JNIEnv *env = getJniEnv();
jobject object = (jobject)events->user_data;


if (numSamples < 1) { if (numSamples < 1) {
env->CallVoidMethod(object, METHOD_nativeSynthCallback, NULL); env->CallVoidMethod(object, METHOD_nativeSynthCallback, NULL);


JNIEXPORT jint JNIEXPORT jint
JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
jvm = vm;
JNIEnv *env; JNIEnv *env;


if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) { if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
JNIEnv* env, jclass clazz) { JNIEnv* env, jclass clazz) {
if (DEBUG) LOGV("%s", __FUNCTION__); if (DEBUG) LOGV("%s", __FUNCTION__);
METHOD_nativeSynthCallback = env->GetMethodID(clazz, "nativeSynthCallback", "([B)V"); METHOD_nativeSynthCallback = env->GetMethodID(clazz, "nativeSynthCallback", "([B)V");
FIELD_mNativeData = env->GetFieldID(clazz, "mNativeData", "I");


return JNI_TRUE; return JNI_TRUE;
} }
JNICALL Java_com_reecedunn_espeak_SpeechSynthesis_nativeCreate( JNICALL Java_com_reecedunn_espeak_SpeechSynthesis_nativeCreate(
JNIEnv *env, jobject object, jstring path, jint bufferSizeInMillis) { JNIEnv *env, jobject object, jstring path, jint bufferSizeInMillis) {
if (DEBUG) LOGV("%s [env=%p, object=%p]", __FUNCTION__, env, object); if (DEBUG) LOGV("%s [env=%p, object=%p]", __FUNCTION__, env, object);
native_data_t *nat = new native_data_t;

if (nat == NULL) {
LOGE("%s: out of memory!", __FUNCTION__);
return 0;
}

env->SetIntField(object, FIELD_mNativeData, (jint) nat);


const char *c_path = path ? env->GetStringUTFChars(path, NULL) : NULL; const char *c_path = path ? env->GetStringUTFChars(path, NULL) : NULL;


nat->object = env->NewWeakGlobalRef(object);
if (DEBUG) LOGV("Initializing with path %s", c_path); if (DEBUG) LOGV("Initializing with path %s", c_path);
int sampleRate = espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, bufferSizeInMillis, c_path, 0); int sampleRate = espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, bufferSizeInMillis, c_path, 0);


return sampleRate; return sampleRate;
} }


JNIEXPORT jboolean
JNICALL Java_com_reecedunn_espeak_SpeechSynthesis_nativeDestroy(
JNIEnv *env, jobject object) {
if (DEBUG) LOGV("%s [env=%p, object=%p]", __FUNCTION__, env, object);

native_data_t *nat = getNativeData(env, object);
if (nat) {
env->DeleteWeakGlobalRef(nat->object);
delete nat;
}

return JNI_TRUE;
}

JNIEXPORT jobject JNIEXPORT jobject
JNICALL Java_com_reecedunn_espeak_SpeechSynthesis_nativeGetVersion( JNICALL Java_com_reecedunn_espeak_SpeechSynthesis_nativeGetVersion(
JNIEnv *env, jclass clazz) { JNIEnv *env, jclass clazz) {
JNICALL Java_com_reecedunn_espeak_SpeechSynthesis_nativeSynthesize( JNICALL Java_com_reecedunn_espeak_SpeechSynthesis_nativeSynthesize(
JNIEnv *env, jobject object, jstring text, jboolean isSsml) { JNIEnv *env, jobject object, jstring text, jboolean isSsml) {
if (DEBUG) LOGV("%s", __FUNCTION__); if (DEBUG) LOGV("%s", __FUNCTION__);
native_data_t *nat = getNativeData(env, object);
const char *c_text = text ? env->GetStringUTFChars(text, NULL) : NULL; const char *c_text = text ? env->GetStringUTFChars(text, NULL) : NULL;
unsigned int unique_identifier; unsigned int unique_identifier;


nat->env = env;

espeak_SetSynthCallback(SynthCallback); espeak_SetSynthCallback(SynthCallback);
const espeak_ERROR result = espeak_Synth(c_text, strlen(c_text), 0, // position const espeak_ERROR result = espeak_Synth(c_text, strlen(c_text), 0, // position
POS_CHARACTER, 0, // end position (0 means no end position) POS_CHARACTER, 0, // end position (0 means no end position)
isSsml ? espeakCHARS_UTF8 | espeakSSML // UTF-8 encoded SSML isSsml ? espeakCHARS_UTF8 | espeakSSML // UTF-8 encoded SSML
: espeakCHARS_UTF8, // UTF-8 encoded text : espeakCHARS_UTF8, // UTF-8 encoded text
&unique_identifier, nat);
&unique_identifier, object);
espeak_Synchronize(); espeak_Synchronize();


if (c_text) env->ReleaseStringUTFChars(text, c_text); if (c_text) env->ReleaseStringUTFChars(text, c_text);

+ 0
- 7
android/src/com/reecedunn/espeak/SpeechSynthesis.java View File

attemptInit(); attemptInit();
} }


@Override
protected void finalize() {
nativeDestroy();
}

public static String getVersion() { public static String getVersion() {
return nativeGetVersion(); return nativeGetVersion();
} }


private native final int nativeCreate(String path, int bufferSizeInMillis); private native final int nativeCreate(String path, int bufferSizeInMillis);


private native final boolean nativeDestroy();

private native final static String nativeGetVersion(); private native final static String nativeGetVersion();


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

Loading…
Cancel
Save