2014-10-20 115 views
1

我有一个与Android TTS的问题。文本到语音崩溃

我已经构建了一个游戏,为游戏的每个周期发布一个数字。经过多次循环后,游戏崩溃。看看logcat,看起来AudioPlayer没有空间“AudioFlinger?没有更多可用的曲目名称”。

所以经过一番搜索,我发现了这个问题。

AudioFlinger could not create track. status: -12

哪有益指出Android有每个设备32个活性AudioTrack对象的硬性限制。回到logcat,我发现它已经宣布了32次。所以,似乎我已经没有物体了。

所以我最初的想法是关闭TTS引擎并在30次公告后重新初始化它,游戏中会暂停一段时间,但不会太糟糕。这不幸的是并没有做到这一点。似乎关闭TTS引擎不会重置AudioTrack对象。

我玩过这个游戏,发现你可以在崩溃前玩,关闭程序,重新启动它,并继续玩没有崩溃(直到它连续32次)。所以有一个发布AudioTrack对象的方法,在logcat中,它讲述了在线搜索“AwesomePlayer reset”,我不认为有一种方法可以控制AwesomePlayer。

所以我的问题是,如何清除AudioTrack对象?有一个函数“release()”,并且只有一组音频轨道,我只是不确定如何让它工作。

有关如何清除AudoTrack对象的任何其他想法都会受到欢迎。

谢谢TC

P.S.我很确定我已经正确实施了TTS这里是我的代码

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"); 
     } 
    } 
} 
+0

对不起 - 我想我的意思是说“指出Android有每个设备32个活动AudioTrack对象的硬性限制。” – 2014-10-20 09:08:29

+0

不确定它会真正解决您的问题,但是您不必每次调用'speak()'方法时都设置'UtteranceProgressListener'。在'mTts = new TextToSpeech(this,this);'后面设置一次就足够了。 – 2014-10-20 09:37:38

+0

另外,你应该考虑为'TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID'使用唯一标识符,而不仅仅是一个硬编码的''TTS停止''字符串。 – 2014-10-20 09:40:35

回答

0

我想通了我的问题。

我真的觉得有点傻,这个问题跟TTS引擎无关。当玩家得到正确答案时,我正在玩的媒体播放器剪辑中出现了实际问题。按照我设置的方式,每次答案正确时,都会创建一个新的mediaplayer对象,因此这会达到32 AudioTrack限制,而不是TTS。我只是把mediaPlayer.create函数放在onCreate中它应该已经存在的地方,现在一切都很好!

这教导我不把所有的代码放在上面,我相信有更多经验的人会马上注意到这一点。