blob: 09a2e8f81fd899d69f632f1eecaa364051be6a97 [file] [log] [blame]
/*
* BRLTTY - A background process providing access to the console screen (when in
* text mode) for a blind person using a refreshable braille display.
*
* Copyright (C) 1995-2023 by The BRLTTY Developers.
*
* BRLTTY comes with ABSOLUTELY NO WARRANTY.
*
* This is free software, placed under the terms of the
* GNU Lesser General Public License, as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any
* later version. Please see the file LICENSE-LGPL for details.
*
* Web Page: http://brltty.app/
*
* This software is maintained by Dave Mielke <dave@mielke.cc>.
*/
#include "prologue.h"
#include <stdio.h>
#include <string.h>
#include "log.h"
#include "spk_driver.h"
#include "system_java.h"
struct SpeechDataStruct {
JNIEnv *env;
jclass driverClass;
jmethodID startMethod;
jmethodID stopMethod;
jmethodID sayMethod;
jmethodID muteMethod;
jmethodID setVolumeMethod;
jmethodID setRateMethod;
jmethodID setPitchMethod;
};
static int
findDriverClass (SpeechSynthesizer *spk) {
return findJavaClass(
spk->driver.data->env, &spk->driver.data->driverClass,
JAVA_OBJ_BRLTTY("speech/SpeechDriver")
);
}
static void
releaseDriverClass (SpeechSynthesizer *spk) {
jclass class = spk->driver.data->driverClass;
if (class) {
JNIEnv *env = spk->driver.data->env;
(*env)->DeleteGlobalRef(env, class);
}
}
static int
findDriverMethod (SpeechSynthesizer *spk, jmethodID *method, const char *name, const char *signature) {
if (findDriverClass(spk)) {
if (findJavaStaticMethod(spk->driver.data->env, method, spk->driver.data->driverClass, name, signature)) {
return 1;
}
}
return 0;
}
JAVA_STATIC_METHOD (
org_a11y_brltty_android_speech_SpeechDriver, tellLocation, void,
jlong synthesizer, jint location
) {
tellSpeechLocation(javaPtrFromLong(synthesizer), location);
}
JAVA_STATIC_METHOD (
org_a11y_brltty_android_speech_SpeechDriver, tellFinished, void,
jlong synthesizer
) {
tellSpeechFinished(javaPtrFromLong(synthesizer));
}
static void
spk_say (SpeechSynthesizer *spk, const unsigned char *buffer, size_t length, size_t count, const unsigned char *attributes) {
if (findDriverMethod(spk, &spk->driver.data->sayMethod, "sayText",
JAVA_SIG_METHOD(JAVA_SIG_BOOLEAN,
JAVA_SIG_LONG // synthesizer
JAVA_SIG_CHAR_SEQUENCE // text
))) {
jstring string = (*spk->driver.data->env)->NewStringUTF(spk->driver.data->env, (const char *)buffer);
if (string) {
jboolean result = (*spk->driver.data->env)->CallStaticBooleanMethod(
spk->driver.data->env, spk->driver.data->driverClass,
spk->driver.data->sayMethod, javaPtrToLong(spk), string
);
(*spk->driver.data->env)->DeleteLocalRef(spk->driver.data->env, string);
string = NULL;
if (!clearJavaException(spk->driver.data->env, 1)) {
if (result == JNI_TRUE) {
}
}
} else {
logMallocError();
clearJavaException(spk->driver.data->env, 0);
}
}
}
static void
spk_mute (SpeechSynthesizer *spk) {
if (findDriverMethod(spk, &spk->driver.data->muteMethod, "stopSpeaking",
JAVA_SIG_METHOD(JAVA_SIG_BOOLEAN,
))) {
jboolean result = (*spk->driver.data->env)->CallStaticBooleanMethod(spk->driver.data->env, spk->driver.data->driverClass, spk->driver.data->muteMethod);
if (!clearJavaException(spk->driver.data->env, 1)) {
if (result == JNI_TRUE) {
}
}
}
}
static void
spk_setVolume (SpeechSynthesizer *spk, unsigned char setting) {
if (findDriverMethod(spk, &spk->driver.data->setVolumeMethod, "setVolume",
JAVA_SIG_METHOD(JAVA_SIG_BOOLEAN,
JAVA_SIG_FLOAT // volume
))) {
jboolean result = (*spk->driver.data->env)->CallStaticBooleanMethod(spk->driver.data->env, spk->driver.data->driverClass, spk->driver.data->setVolumeMethod, getFloatSpeechVolume(setting));
if (!clearJavaException(spk->driver.data->env, 1)) {
if (result == JNI_TRUE) {
}
}
}
}
static void
spk_setRate (SpeechSynthesizer *spk, unsigned char setting) {
if (findDriverMethod(spk, &spk->driver.data->setRateMethod, "setRate",
JAVA_SIG_METHOD(JAVA_SIG_BOOLEAN,
JAVA_SIG_FLOAT // rate
))) {
jboolean result = (*spk->driver.data->env)->CallStaticBooleanMethod(spk->driver.data->env, spk->driver.data->driverClass, spk->driver.data->setRateMethod, getFloatSpeechRate(setting));
if (!clearJavaException(spk->driver.data->env, 1)) {
if (result == JNI_TRUE) {
}
}
}
}
static void
spk_setPitch (SpeechSynthesizer *spk, unsigned char setting) {
if (findDriverMethod(spk, &spk->driver.data->setPitchMethod, "setPitch",
JAVA_SIG_METHOD(JAVA_SIG_BOOLEAN,
JAVA_SIG_FLOAT // pitch
))) {
jboolean result = (*spk->driver.data->env)->CallStaticBooleanMethod(spk->driver.data->env, spk->driver.data->driverClass, spk->driver.data->setPitchMethod, getFloatSpeechPitch(setting));
if (!clearJavaException(spk->driver.data->env, 1)) {
if (result == JNI_TRUE) {
}
}
}
}
static int
spk_construct (SpeechSynthesizer *spk, char **parameters) {
if ((spk->driver.data = malloc(sizeof(*spk->driver.data)))) {
memset(spk->driver.data, 0, sizeof(*spk->driver.data));
spk->driver.data->env = getJavaNativeInterface();
spk->driver.data->driverClass = NULL;
spk->driver.data->startMethod = 0;
spk->driver.data->stopMethod = 0;
spk->driver.data->sayMethod = 0;
spk->driver.data->muteMethod = 0;
spk->driver.data->setVolumeMethod = 0;
spk->driver.data->setRateMethod = 0;
spk->driver.data->setPitchMethod = 0;
spk->setVolume = spk_setVolume;
spk->setRate = spk_setRate;
spk->setPitch = spk_setPitch;
if (spk->driver.data->env) {
if (findDriverMethod(spk, &spk->driver.data->startMethod, "startEngine",
JAVA_SIG_METHOD(JAVA_SIG_BOOLEAN,
))) {
jboolean result = (*spk->driver.data->env)->CallStaticBooleanMethod(spk->driver.data->env, spk->driver.data->driverClass, spk->driver.data->startMethod);
if (!clearJavaException(spk->driver.data->env, 1)) {
if (result == JNI_TRUE) {
return 1;
}
}
}
}
releaseDriverClass(spk);
free(spk->driver.data);
} else {
logMallocError();
}
return 0;
}
static void
spk_destruct (SpeechSynthesizer *spk) {
if (findDriverMethod(spk, &spk->driver.data->stopMethod, "stopEngine",
JAVA_SIG_METHOD(JAVA_SIG_VOID,
))) {
(*spk->driver.data->env)->CallStaticVoidMethod(spk->driver.data->env, spk->driver.data->driverClass, spk->driver.data->stopMethod);
clearJavaException(spk->driver.data->env, 1);
}
releaseDriverClass(spk);
free(spk->driver.data);
spk->driver.data = NULL;
}