2015-11-08 55 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; 
     } 
    } 
}