2015-11-22 90 views
1

我有一個使用AudioTrack合成音符序列的線程,使用seekbar來改變速度。android如何停止按鈕上的音頻線程按?

t = new Thread() 
    { 
     public void run() 
     { 
      setPriority(Thread.MAX_PRIORITY); 

      int buffersize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO, 
        AudioFormat.ENCODING_PCM_16BIT); 

      audiotrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr, 
        AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, 
        buffersize, AudioTrack.MODE_STREAM); 

      short samples[] = new short[buffersize]; 

      int amplitude = 10000; 
      double twopi = 2*Math.PI; 

      double ph = 0.0; 


      audiotrack.play(); 
      double r = 1.0594630943593; //the 12th root of 2 
      frequency=261.63; 
      for(int k = 1; k<9; k++) //number of notes played 
      { 
       frequency*=r; 
       for (int i = 0; i < 4+4*temposliderval; i++) //duration of each note, if i = 50, note duration = 12 seconds 
       { 

        for (int j = 0; j < buffersize; j++) 
        { 
         samples[j] = (short) (amplitude * Math.sin(ph)); 
         ph += twopi * frequency/sr; 
        } 
        audiotrack.write(samples, 0, buffersize); 
       } 
      } 

      audiotrack.stop(); 
      audiotrack.release(); 

     } 
    }; 


    //play button 
    play = (Button)findViewById(R.id.play); 
    play.setBackgroundResource(R.mipmap.play); 
    play.setOnClickListener(new View.OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      t.start(); 
     } 
    }); 







    //stop button 
    stop = (Button)findViewById(R.id.stop); 
    stop.setBackgroundResource(R.mipmap.stop); 
    stop.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      t.interrupt(); 
     } 
    }); 

我希望能夠在停止按鈕被按下時停止音頻。調用t.interrupt()不起作用,所以我想知道如何在停止按鈕被按下時正確地停止線程。目標是能夠隨時停止音頻,並在再次按下播放按鈕時再次啓動。

回答

0

我想通了!這種方法似乎沒有在其他地方列出,所以我一定非常幸運:

只需將線程放在一個新的方法中,並在playbutton單擊時調用該方法,而不是嘗試停止線程,剛剛停止audiotrack的聲音:

play = (Button)findViewById(R.id.play); 
    play.setBackgroundResource(R.mipmap.play); 
    play.setOnClickListener(new View.OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      playScale(); 
     } 
    }); 







    //stop button 
    stop = (Button)findViewById(R.id.stop); 
    stop.setBackgroundResource(R.mipmap.stop); 
    stop.setOnClickListener(new View.OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      audiotrack.stop(); 
     } 
    }); 

現在每次播放按鈕被擊中時,該線程將只需重新啓動,儘管實際上並非停止

public void playScale() 
{ 
    t = new Thread() 
    { 
     public void run() 
     { 
      t.setPriority(Thread.MAX_PRIORITY); 

      int buffersize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO, 
        AudioFormat.ENCODING_PCM_16BIT); 

      audiotrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr, 
        AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, 
        buffersize, AudioTrack.MODE_STREAM); 

      short samples[] = new short[buffersize]; 

      int amplitude = 10000; 

      double twopi = 2 * Math.PI; 

      double ph = 0.0; 

      audiotrack.play(); 

      double r = 1.0594630943593; //the 12th root of 2 

      frequency = 261.63; 
      for (int k = 1; k < 9; k++) //number of notes played 
      { 
       frequency *= r; 
       for (int i = 0; i < 4 + 4 * temposliderval; i++) //duration of each note, if i = 50, note duration = 12 seconds; minimum tempo = 60 bpm 
       { 
        for (int j = 0; j < buffersize; j++) 
        { 
         samples[j] = (short) (amplitude * Math.sin(ph)); 
         ph += twopi * frequency/sr; 
        } 
        audiotrack.write(samples, 0, buffersize); 
       } 
      } 
     } 
    }; 
    t.start(); 
} 
0

做最簡單的事情可能是聲明volatile成員變量:

private volatile boolean mStop = false; 

這兩個線程可以訪問。您可以輪詢線程內部的變量,並在設置時停止循環,並在按下按鈕時將該變量設置爲true。

+0

你能告訴我如何在我上面發佈的代碼示例中做到這一點嗎?順便說一句,我只有一個線程。 –

+0

你有2個主題。您創建了一個,t,並且有一個Android主要的UI線程會將您的onClick處理程序調用。 – cwbowron