2012-06-22 29 views
0

我正在创建一个应用程序,当您按下屏幕上的一系列按钮时播放音符。当按下按钮时,还会弹出一系列音符(最多10个音符)。该应用程序首先运行良好。但是,如果您有一系列要播放的音符,并且连续几次按下播放按钮,应用程序将最终强制关闭。任何帮助将不胜感激。播放声音序列导致强制关闭

private final int duration = 1; // seconds 
private final int sampleRate = 10000; 
private final int numSamples = duration * sampleRate; 
private final double sample[] = new double[numSamples]; 
private double freqOfTone; // hz 

private final byte generatedSnd[] = new byte[2 * numSamples]; 

public void onPlayButtonClick(View v){ 
    playMultiNoteSound(); 
} 
synchronized void playMultiNoteSound(){ 

    CharSequence chrs1; 
    TextView lblNoteList; 
    lblNoteList=(TextView)findViewById(R.id.lblNoteList); 
    chrs1=lblNoteList.getText(); 

    for(int i=0;i<chrs1.length();i++){ 
     final int int1=i; 

     Thread thrdPlay=new Thread(new Runnable(){ 

      public void run(){ 
       int minSize =AudioTrack.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT); 
       audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
         sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
         AudioFormat.ENCODING_PCM_16BIT, minSize, 
         AudioTrack.MODE_STREAM); 
       char chrCurrent; 
       CharSequence chrs; 


       TextView lblNoteList; 
       lblNoteList=(TextView)findViewById(R.id.lblNoteList); 
       chrs=lblNoteList.getText(); 
       chrCurrent=chrs.charAt(int1); 
       Double[]allTones; 
       allTones= new Double[chrs.length()]; 
       allTones[int1]=getToneForText(chrCurrent); 
       byte[] results; 
       results=genSelectTone(allTones[int1]); 
       audioTrack.write(results, 0, results.length); 
       audioTrack.setStereoVolume(1.0f, 1.0f); 
       audioTrack.play(); 
       if(audioTrack.getPlayState()==AudioTrack.PLAYSTATE_STOPPED){ 
        audioTrack.stop(); 
        audioTrack.release(); 
       } 
      } 
     }); 
     thrdPlay.setDaemon(true); 
     thrdPlay.start(); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     if(thrdPlay!=null){ 
      thrdPlay.stop(); 
      thrdPlay=null; 
     } 
     } 

} 
public double getToneForText(char val){ 
    Float dblResult; 
    dblResult=0f; 
    switch (val){ 
    case '1': 
     dblResult=261.63f; 
     break; 
    case '2': 
     dblResult=293.66f; 
     break; 
    case '3': 
     dblResult=329.63f; 
     break; 
    case '4': 
     dblResult=349.23f; 
     break; 
    case '5': 
     dblResult=392.0f; 
     break; 
    case '6': 
     dblResult=440.0f; 
     break; 
    case '7': 
     dblResult=493.88f; 
     break; 
    case '8': 
     dblResult=523.25f; 
     break; 
    case '9': 
     dblResult=587.33f; 
     break; 
    case '0': 
     dblResult=659.26f; 
     break; 
    }  
    return dblResult; 
} 

我相信这是所有的相关代码。如果您需要其他信息/代码,请告诉我。

+1

如果有一个力量关闭,会有一个引起异常的堆栈跟踪。发布logcat输出。 – Squonk

+1

除了@Squonk建议的(你应该这样做)之外,你也可以考虑查看如何读取logcat。每次您的应用程序抛出一个“例外”时,它都会让您不必再问一个新问题。 – adneal

+0

我忽略提及我已经使用LogCat。错误如下所示:getsBuffer track已禁用,重新启动。 – user1458354

回答

0

对于每次迭代,您都不应该重新初始化audioTrack。请在循环之前初始化它,并在循环中使用audioTrack.write。你只是重新初始化它而不填充缓冲区。其次,正如一个offer不应该更新gui并在同一个线程中播放声音一样。尝试使用AsyncTask代替。