I'm learning android development for the first time and my goal is to create a simple Hello World application that takes in some text, and reads them out loud.
I've based my code off an example I found and here's my code:
class MainFeeds : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main_feeds)
card.setOnClickListener{
Toast.makeText(this, "Hello", Toast.LENGTH_LONG).show()
TTS(this, "Hello this is leo")
}
}
}
class TTS(private val activity: Activity,
private val message: String) : TextToSpeech.OnInitListener {
private val tts: TextToSpeech = TextToSpeech(activity, this, "com.google.android.tts")
override fun onInit(i: Int) {
if (i == TextToSpeech.SUCCESS) {
val localeUS = Locale.US
val result: Int
result = tts.setLanguage(localeUS)
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
Toast.makeText(activity, "This Language is not supported", Toast.LENGTH_SHORT).show()
} else {
speakOut(message)
}
} else {
Toast.makeText(activity, "Initilization Failed!", Toast.LENGTH_SHORT).show()
}
}
private fun speakOut(message: String) {
tts.speak(message, TextToSpeech.QUEUE_FLUSH, null, null)
}
}
And it works perfectly fine, the issue that I'm running into is that the audio that's coming out of the synthesizer sounds extremely robotic, almost like when I'm using Google Maps and I get disconnected from the internet. Is using the voice Google Assistant leverages some other API that I have to enable?
EDIT: I've tried running the app on my pixel 2xl and it still sounds robotic, as in it's not using the Google Assistant voice.
I've made a little test program that should answer this question for you.
It shows you a list of all the voices the Google engine has in it, and you click on them and listen to them! Yay!
What it actually does:
This way, you can test all the voices to see if the "Google Assistant" voice you seek is somewhere in there, and if it's not available, you can keep checking as new versions of the Google text-to-speech engine are released. It seems to me that the highest quality voices in this test are both quality:400, and specify that a network connection is required.
NOTES:
A voice (especially English) will most likely still "play" even if it is "not installed." This is because when using setVoice(Voice v), the (Google) engine will return a "success" int even if the requested voice is not available(!), as long as it has some other "back-up" voice on hand of the same language. Unfortunately it does all this in the background and still sneakily reports that it's using the same exact voice you requested even if you use getVoice() and compare objects. :(.
Generally if a voice says it IS installed, then the voice you are hearing is the voice you requested.
For these reasons, you'll want to make sure you're on the internet when you test these voices (so that they auto-install when you request unavailable voices)... and also so that Voices that require a network connection will not "auto-downgrade."
You can swipe/refresh the listview of voices in order to check whether voices have been installed yet, or use the system's pull-down menu to watch for downloads... or go into Google's text-to-speech settings in the device system settings.
In the list view, the Voice features such as "network required," and "installed," are simply echoes of what the Google engine reports and may not be accurate. :(
The maximum possible voice quality specified in the Voice class documentation is 500. In my tests I could only find voices up to quality 400. This may be because I do not have the latest version of Google text-to-speech installed on my test device (and I don't have Play Store access on it in order to update it). If you're using a real device, I suggest installing the latest version of Google TTS using the Google Play Store. You can verify engine version in the Logs. According to Wikipedia, the latest version as of this writing is 3.15.18.200023596. The version on my test device is 3.13.1.
To re-create this test app, make a blank Java project in Android Studio with a minimum API of 21. (getVoices() does not work pre-21).
Manifest:
MainActivity:
VoiceAdapter.java:
activity_main.xml:
list_item_voice.xml:
The quality of speech first and foremost comes down to what "speech engine" is being used by the TextToSpeech object that you created:
If you had instead entered:
...then any device you run that code on will attempt to use the google speech engine... but it will only actually be used if it exists on the device.
Similarly, using "com.samsung.SMT" would attempt to use the Samsung speech engine (which is also high-quality, but usually only installed on Samsung [real] devices).
Whether or not the Google speech engine will be available is not so much dependent on the Android API level of the device (as long as it's recent enough to run the Google engine), but whether or not the actual Google text-to-speech engine is installed on the device at all.
To make sure that the Google engine is installed:
On an Android Studio Emulator:
Create a new emulator and select a system image that has "Google APIs" or "Google Play" in the "target" column.
On a real device:
Go to the Play Store and install the Google speech engine.
TTS on Android (or at least trying to predict its behavior) can be a real beast.
Documentation: Java | Kotlin.