Reputation: 23
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");
}
}
}
Upvotes: 1
Views: 732
Reputation: 23
I figured out my problem.
I feel a bit silly really, the problem had nothing to do with the TTS engine. The actual problem lied in the mediaplayer clip that I was playing when the player got a correct answer. The way I had it set up, every time the answer was correct a new mediaplayer object was created and so this hit the 32 AudioTrack limit not the TTS. I've just put the mediaPlayer.create function in onCreate where it should have been and everything is fine now!!!
That teaches me for not putting all my code on, I'm sure someone with more experience would have noticed that straight away.
Upvotes: 0