2015-11-08 89 views
1

在java中創建Clip並打開聲音後,可以使用clip.start()播放聲音。您可以使用clip.stop()暫停播放此聲音,然後通過致電clip.start()繼續播放。Java在暫停後繼續循環剪輯

使用clip.loop(i)時,有沒有做同樣的事情?

調用clip.loop(3)後,該剪輯應播放四次。但是,如果您在聲音上調用clip.stop(),然後通過調用clip.start()恢復它,剪輯將會取消暫停,但只會完成當前的播放,無論它需要做多少循環。因此,如果我理解正確,clip.stop()將停止播放而不重置微秒位置,並且clip.start()只會從當前微秒位置繼續播放一次到剪輯結束。

那麼如何在Java中恢復循環剪輯而不會丟失循環量?如果有一種方法可以獲得剪輯循環的次數,我可能會想出來。

回答

1

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/com/sun/media/sound/DirectAudioDevice.java

首先,獲得某種異常後我搜索,發現這個網頁,這是一個實現了接口夾,的DataLine,和其他幾個人一類的文檔。 很難確切地說出這些方法的作用,但看起來類中有一個我們無法訪問的循環計數器。基本上,如果你想計算你需要的Clip.LOOP_CONTINUOUSLY循環,並有自己的計數器在軌道末尾遞增。注意stop()會影響Clip實例的很多值,所以在start()之後,你需要再次使用loop(-1)[Clip.LOOP_CONTINUOUSLY = -1,但是用API確認]。

我決定實現我自己的setLoopPoints(int,int)和loop(int)加入的方法,並將其發佈到下面。請注意(可能是因爲它在一個線程中)getFramePosition()似乎只返回每第441幀,或有時第882幀或第1323幀,這意味着這不是一個完美的解決方案,但我不認爲有一個完美的解決方案。

請注意,如果您在UI線程上使用剪輯(如移動位置)執行任何操作,則可能會影響此操作並導致異常。

下面是代碼:

public class ClipLooper extends Thread 
{ 
    private Clip c; 
    private int firstFrame, lastFrame, numLoops, currentLoop = 1; 

    public ClipLooper(Clip c, int ff, int lf, int nl) throws Exception 
    { 
     if(ff < 0 || lf < ff || c.getFrameLength() < lf) 
      throw new Exception("you screwed up!! \n"); 
     this.c = c; 
     firstFrame = ff; 
     lastFrame = lf; 
     numLoops = nl; 
    } 

    @Override 
    public void run() 
    { 
     while(currentLoop <= numLoops || numLoops <= 0) 
     { 
      c.setFramePosition(firstFrame); 

      c.start(); 
      c.loop(-1); 

      while(c.getFramePosition() < lastFrame-220) 
      {} 

      c.stop(); 
      ++currentLoop; 
     } 
    } 
}