Reputation: 533
After you create a Clip
in java and open a sound, you can play the sound using clip.start()
. You can pause the playing of this sound by using clip.stop()
and resume after that by calling clip.start()
.
Is there any to do the same thing when using clip.loop(i)
?
After calling clip.loop(3)
the clip should play four times. However, if you call clip.stop()
on the sound and then resume it by calling clip.start()
the clip will unpause, but will only finish the current playthrough no matter how many more loops it needed to do. So if I understand correctly, clip.stop()
stops playthrough without resetting microsecond position and clip.start()
continues playthrough from the current microsecond position to the end of the clip only once.
So then how do I resume a looping clip in java without losing the loop amount? If there was a way to get the amount of times a clip looped I could probably figure it out.
Upvotes: 1
Views: 536
Reputation: 305
Firstly, after getting an Exception of some sort I searched and found this web page, which is the documentation for one class that implements the interfaces Clip, DataLine, and a few others. It's hard to tell exactly what the methods do but it seems there is a loop counter in the class that we don't have access to. Basically, if you want to count the loops you need to Clip.LOOP_CONTINUOUSLY and have your own counter that increments at the end of the track. Note that stop() will affect a lot of the values of your instance of Clip, so after start() you will need loop(-1) again [Clip.LOOP_CONTINUOUSLY = -1, but confirm with API].
I decided to implement my own setLoopPoints(int, int) and loop(int) joined method and will post it below. Note that (perhaps because it's in a Thread) getFramePosition() seems to only return every 441st frame, or sometimes 882nd frame or 1323rd frame, which means this is not a perfect solution, but I don't think there is a perfect solution.
Caution, also, that if you do anything on the UI thread with the clip (like moving position), you might affect this and cause an Exception.
Here is the code:
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;
}
}
}
Upvotes: 1