summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Staab <peter.staab76@gmail.com>2018-01-27 15:14:04 +0100
committerPeter Staab <peter.staab76@gmail.com>2018-02-07 05:51:36 +0000
commitc7b57997dcc96c2820714b2ef6e3bcfe93193614 (patch)
treeeaef9e7d8e330dd7e020d635660a3cb5db5743a9
parentf5aaee80166be7969a71496d2fd9a8152d8effb4 (diff)
Add Android support for supported locales and voices5.10
This patch adds support for availableLocales() and availableVoices() to the Android QtSpeech module. [ChangeLog][Android] Added support for availableLocales, availableVoices and setting voices on Android. Task-number: QTBUG-65930 Change-Id: I7457cecb69a07f1e2926c861658a0894cc154a85 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
-rw-r--r--src/plugins/tts/android/jar/src/org/qtproject/qt5/android/speech/QtTextToSpeech.java55
-rw-r--r--src/plugins/tts/android/src/qtexttospeech_android.cpp49
-rw-r--r--src/plugins/tts/android/src/qtexttospeech_android.h1
3 files changed, 101 insertions, 4 deletions
diff --git a/src/plugins/tts/android/jar/src/org/qtproject/qt5/android/speech/QtTextToSpeech.java b/src/plugins/tts/android/jar/src/org/qtproject/qt5/android/speech/QtTextToSpeech.java
index a6e6091..83332fc 100644
--- a/src/plugins/tts/android/jar/src/org/qtproject/qt5/android/speech/QtTextToSpeech.java
+++ b/src/plugins/tts/android/jar/src/org/qtproject/qt5/android/speech/QtTextToSpeech.java
@@ -50,6 +50,8 @@ import android.util.Log;
import java.lang.Float;
import java.util.HashMap;
import java.util.Locale;
+import java.util.List;
+import java.util.ArrayList;
public class QtTextToSpeech
{
@@ -60,6 +62,7 @@ public class QtTextToSpeech
private TextToSpeech mTts;
private final long mId;
+ private boolean mInitialized = false;
private float mPitch = 1.0f;
private float mRate = 1.0f;
private float mVolume = 1.0f;
@@ -70,8 +73,10 @@ public class QtTextToSpeech
public void onInit(int status) {
Log.w("QtTextToSpeech", "tts initialized");
if (status == TextToSpeech.SUCCESS) {
+ mInitialized = true;
notifyReady(mId);
} else {
+ mInitialized = false;
notifyError(mId);
}
}
@@ -206,4 +211,54 @@ public class QtTextToSpeech
return (result != TextToSpeech.LANG_NOT_SUPPORTED) && (result != TextToSpeech.LANG_MISSING_DATA);
}
+ public List<Object> getAvailableVoices()
+ {
+ if (mInitialized && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
+ //Log.d("QtTextToSpeech", "Voices: " + mTts.getVoices());
+ return new ArrayList<Object>(mTts.getVoices());
+ }
+ return new ArrayList<Object>();
+ }
+
+ public List<Locale> getAvailableLocales()
+ {
+ if (mInitialized && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
+ //Log.d("QtTextToSpeech", "Locales: " + mTts.getAvailableLanguages());
+ return new ArrayList<Locale>(mTts.getAvailableLanguages());
+ }
+ return new ArrayList<Locale>();
+ }
+
+ public Locale getLocale()
+ {
+ //Log.d("QtTextToSpeech", "getLocale: " + mLocale);
+ return mTts.getLanguage();
+ }
+
+ public Object getVoice()
+ {
+ if (mInitialized && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
+ return mTts.getVoice();
+ }
+ return null;
+ }
+
+ public boolean setVoice(String voiceName)
+ {
+ if (!mInitialized)
+ return false;
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
+ for (android.speech.tts.Voice voice : mTts.getVoices()) {
+ if (voice.getName().equals(voiceName)) {
+ int result = mTts.setVoice(voice);
+ if (result == TextToSpeech.SUCCESS) {
+ //Log.d("QtTextToSpeech", "setVoice: " + voice);
+ return true;
+ }
+ break;
+ }
+ }
+ }
+ return false;
+ }
}
diff --git a/src/plugins/tts/android/src/qtexttospeech_android.cpp b/src/plugins/tts/android/src/qtexttospeech_android.cpp
index a3cac58..b4bb006 100644
--- a/src/plugins/tts/android/src/qtexttospeech_android.cpp
+++ b/src/plugins/tts/android/src/qtexttospeech_android.cpp
@@ -250,7 +250,16 @@ bool QTextToSpeechEngineAndroid::setVolume(double volume)
QVector<QLocale> QTextToSpeechEngineAndroid::availableLocales() const
{
- return QVector<QLocale>();
+ auto locales = m_speech.callObjectMethod("getAvailableLocales", "()Ljava/util/List;");
+ int count = locales.callMethod<jint>("size");
+ QVector<QLocale> result;
+ result.reserve(count);
+ for (int i = 0; i < count; ++i) {
+ auto locale = locales.callObjectMethod("get", "(I)Ljava/lang/Object;", i);
+ auto localeName = locale.callObjectMethod<jstring>("toString").toString();
+ result << QLocale(localeName);
+ }
+ return result;
}
bool QTextToSpeechEngineAndroid::setLocale(const QLocale &locale)
@@ -272,21 +281,53 @@ bool QTextToSpeechEngineAndroid::setLocale(const QLocale &locale)
QLocale QTextToSpeechEngineAndroid::locale() const
{
+ auto locale = m_speech.callObjectMethod("getLocale", "()Ljava/util/Locale;");
+ if (locale.isValid()) {
+ auto localeName = locale.callObjectMethod<jstring>("toString").toString();
+ return QLocale(localeName);
+ }
return QLocale();
}
+QVoice QTextToSpeechEngineAndroid::javaVoiceObjectToQVoice(QJNIObjectPrivate &obj) const
+{
+ auto voiceName = obj.callObjectMethod<jstring>("getName").toString();
+ QVoice::Gender gender;
+ if (voiceName.contains(QStringLiteral("#male"))) {
+ gender = QVoice::Male;
+ } else if (voiceName.contains(QStringLiteral("#female"))) {
+ gender = QVoice::Female;
+ } else {
+ gender = QVoice::Unknown;
+ }
+ return createVoice(voiceName, gender, QVoice::Other, voiceName);
+}
+
QVector<QVoice> QTextToSpeechEngineAndroid::availableVoices() const
{
- return QVector<QVoice>();
+ auto voices = m_speech.callObjectMethod("getAvailableVoices", "()Ljava/util/List;");
+ int count = voices.callMethod<jint>("size");
+ QVector<QVoice> result;
+ result.reserve(count);
+ for (int i = 0; i < count; ++i) {
+ auto voice = voices.callObjectMethod("get", "(I)Ljava/lang/Object;", i);
+ result << javaVoiceObjectToQVoice(voice);
+ }
+ return result;
}
-bool QTextToSpeechEngineAndroid::setVoice(const QVoice & /* voice */)
+bool QTextToSpeechEngineAndroid::setVoice(const QVoice &voice)
{
- return false;
+ return m_speech.callMethod<jboolean>("setVoice", "(Ljava/lang/String;)Z",
+ QJNIObjectPrivate::fromString(voiceData(voice).toString()).object());
}
QVoice QTextToSpeechEngineAndroid::voice() const
{
+ auto voice = m_speech.callObjectMethod("getVoice", "()Ljava/lang/Object;");
+ if (voice.isValid()) {
+ return javaVoiceObjectToQVoice(voice);
+ }
return QVoice();
}
diff --git a/src/plugins/tts/android/src/qtexttospeech_android.h b/src/plugins/tts/android/src/qtexttospeech_android.h
index 60cb32d..94c59f5 100644
--- a/src/plugins/tts/android/src/qtexttospeech_android.h
+++ b/src/plugins/tts/android/src/qtexttospeech_android.h
@@ -81,6 +81,7 @@ public Q_SLOTS:
private:
void setState(QTextToSpeech::State state);
+ QVoice javaVoiceObjectToQVoice(QJNIObjectPrivate &obj) const;
QJNIObjectPrivate m_speech;
QTextToSpeech::State m_state;