From c7b57997dcc96c2820714b2ef6e3bcfe93193614 Mon Sep 17 00:00:00 2001 From: Peter Staab Date: Sat, 27 Jan 2018 15:14:04 +0100 Subject: Add Android support for supported locales and voices 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 --- .../qt5/android/speech/QtTextToSpeech.java | 55 ++++++++++++++++++++++ .../tts/android/src/qtexttospeech_android.cpp | 49 +++++++++++++++++-- .../tts/android/src/qtexttospeech_android.h | 1 + 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 getAvailableVoices() + { + if (mInitialized && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { + //Log.d("QtTextToSpeech", "Voices: " + mTts.getVoices()); + return new ArrayList(mTts.getVoices()); + } + return new ArrayList(); + } + + public List getAvailableLocales() + { + if (mInitialized && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { + //Log.d("QtTextToSpeech", "Locales: " + mTts.getAvailableLanguages()); + return new ArrayList(mTts.getAvailableLanguages()); + } + return new ArrayList(); + } + + 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 QTextToSpeechEngineAndroid::availableLocales() const { - return QVector(); + auto locales = m_speech.callObjectMethod("getAvailableLocales", "()Ljava/util/List;"); + int count = locales.callMethod("size"); + QVector 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("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("toString").toString(); + return QLocale(localeName); + } return QLocale(); } +QVoice QTextToSpeechEngineAndroid::javaVoiceObjectToQVoice(QJNIObjectPrivate &obj) const +{ + auto voiceName = obj.callObjectMethod("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 QTextToSpeechEngineAndroid::availableVoices() const { - return QVector(); + auto voices = m_speech.callObjectMethod("getAvailableVoices", "()Ljava/util/List;"); + int count = voices.callMethod("size"); + QVector 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("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; -- cgit v1.2.3