在java中播放wav文件 - 如何扩展或连接播放的声音?

时间:2009-03-21 03:25:50

标签: java audio wav

是否可以创建一个包含wav文件“循环”的临时文件?

或者是否可以操纵发送给流读取器/写入器的流?

基本上我想在一段时间内播放一些wav文件,如果该时间大于wav文件提供的时间长度我想循环。

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:0)

我不确定我理解您实施解决方案的确切限制,但似乎最简单的方法是在您第一次播放文件时将音频数据存储在缓冲区中。然后,如果用户需要更多迭代(完整或部分),只需将已缓存的数据重写回SourceDataLine所需的次数。

这是示例声音文件播放器(PCM)的link,其代码应该非常容易修改(或者只是学习)。我还修改了一些(注意:未经测试的)代码,它只显示了我上面描述的逻辑:(您可能还想修改我下面的内容以符合有关仅编写大小为多倍的数据块的规则框架大小。)

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;
        }
    }
}

希望有所帮助!

答案 2 :(得分:0)

我想我会使用每秒帧数并对音频输入流中的帧大小信息进行计算。其他有用的信息是在SourceDataLine对象的getMicrosecondPosition()方法中,以确定到目前为止播放的时间/持续时间。

这与音频输入流中的标记和重置方法一起可能会处理所有这些。