Question

Is it possible to create a temporary file that contains a "loop" of a wav file?

Or is it possible to manipulate the stream sent to a stream reader/writer?

Basically I want to play some wav file for a period of time and if that time is greater than the length of time that the wav file provides I want to loop.

Was it helpful?

Solution

     AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
     Clip clip = AudioSystem.getClip();
     clip.loop((int)(Math.ceil(timeRequested / audioIn.getFrameLength())));

OTHER TIPS

I'm not sure I understand the exact limitations you have for implementing a solution, but it seems that the cleanest way to do this would be to store the audio data in a buffer the first time you play through the file. Then, if there are more iterations (full or partial) wanted by the user, just rewrite the data you have cached back out to the SourceDataLine the desired number of times.

Here is a link to a sample sound file player (PCM) that has code that should be very easy to modify (or just learn from). I also hacked up some (note: untested) code that just shows the logic I described above: (You probably also want to modify what I have below to conform to the rules concerning only writing chunks of data that have a size that is a multiple of the frame size.)

public void playSoundFile(SourceDataLine line, InputStream inputStream, AudioFormat format, long length, float times)
{
    int index = 0;
    int size = length * format.getFrameSize();
    int currentSize = 0;
    byte[] buffer = new byte[size];
    AudioInputStream audioInputStream = new AudioInputStream(inputStream, format, length);
    while (index < size)
    {
        currentSize = audioInputStream.read(buffer, index, size - index);
        line.write(buffer, index, currentSize);
        index += currentSize;
    }

    float currentTimes = 1.0;
    while (currentTimes < times)
    {
        float timesLeft = times - currentTimes;
        int writeBlockSize = line.available();
        index = 0;

        if (timesLeft >= 1.0)
        {
            while (index < size)
            {
                currentSize = ((size - index) < writeBlockSize) ? size - index : writeBlockSize;
                line.write(buffer, index, currentSize);
                index += currentSize;
            }
            currentTimes += 1.0;
        }
        else
        {
            int partialSize = (int)(timesLeft * ((float) size) + 0.5f);
            while (index < partialSize)
            {
                currentSize = ((partialSize - index) < writeBlockSize) ? partialSize - index : writeBlockSize;
                line.write(buffer, index, currentSize);
                index += currentSize;
            }
            currentTimes += timesLeft;
        }
    }
}

Hope that helps!

I think I'll use the frames per second and framesize information in the audio input stream to figure this out. Other useful information is in getMicrosecondPosition() method of the SourceDataLine object to determine the time/duration played so far.

this along with mark and reset methods in the audio input stream probably take care of it all.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top