2012-06-22 26 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代替。