I've got a problem with android TTS.
I've built a game which announces a number for every cycle of game play. After a number of cycles the game crashes. Looking at the logcat it appear that the AudioPlayer is running out of room "AudioFlinger? no more track names available".
So after a little searching I've found this question.
AudioFlinger could not create track. status: -12
Which helpfully points out that Android has a hard limit of 32 active AudioTrack objects per device. Checking back to the logcat I found that it had announced 32 times. So seems that I am running out of objects.
So my initial idea was to shut down the TTS engine and re-initialise it after 30 announcements, there would be a short pause it game play but not too bad. This unfortunately didn’t do the trick. It seems that shutting down the TTS engine doesn’t reset the AudioTrack objects.
I've played around with the game and found that you can play up to before the crash, close the program, restart it and keep on playing with no crashes (until it reaches 32 continuous plays.) So there is a way to release the AudioTrack objects, in the logcat it talks about “AwesomePlayer reset” searching online I don't think there's is a way to control the AwesomePlayer.
So my question is, how do I clear the AudioTrack objects? There is a function “release()” and There is only one set of AudioTracks, I'm just not sure on how to get that to work.
Any other ideas on how to clear the AudoTrack objects would be welcome.
Thank TC
P.S. I'm pretty sure I've implemented the TTS correctly here's my code
private void playNumber() {
if (inPlay) {
numbersPlayed += 1;
Log.d("TOM", "playNumber");
Locale loc = new Locale("spa", "ESP");
mTts.setLanguage(loc);
String genNum = String.valueOf(generatedNumber);
Log.d("TOM", "genNum to String");
HashMap<String, String> map = new HashMap<String, String>();
Log.d("TOM", "toHashMap");
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "TTS Stopped");
Log.d("TOM", "mapPut");
mTts.speak(genNum, TextToSpeech.QUEUE_FLUSH, map);
Log.d("TOM", "TTSSpeak");
mTts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
enterLock = true;
Log.d("TOM", "uttStart");
}
@Override
public void onDone(String utteranceId) {
enterLock = false;
timerCount.start();
Log.d("TOM", "uttDone");
}
@Override
public void onError(String utteranceId) {
Log.d("TOM", "uttError");
}
});
}
}
public void onInit(int i) {
if (generatedNumber == -2) {
enterLock = false;
Toast.makeText(this, getString(R.string.ttsReady_toast), Toast.LENGTH_SHORT).show();
Log.d("TOM", "onInit: " + Boolean.toString(inPlay));
} else {
playNumber();
Log.d("TOM", "New Start Play");
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
mTts = new TextToSpeech(this, this);
Log.d("TOM", "ttsEngineOK");
} else {
Intent installIntent = new Intent();
installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
Log.d("TOM", "ttsEngineError");
}
}
}