实时wav播放

时间:2013-06-28 15:09:02

标签: java audio stream javasound

我写了一个播放.wav文件的代码。它工作正常。 现在,另一段代码从音频接收器获取音乐数据并继续附加到该.wav文件。

假设当我运行播放器时音频长度为5秒,现在尽管使用更新程序代码更新了wav文件,但播放器只播放了最初的5秒。

播放代码很简单:

try{
    AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("junk.wav"));
    Clip clip = AudioSystem.getClip();
    clip.open(audioInputStream);
    clip.start();
}catch(Exception ex){
    System.out.println("Error with playing sound.");
    ex.printStackTrace();
}

如何在输入进入麦克风插孔后播放音频流(允许一些延迟)?

2 个答案:

答案 0 :(得分:1)

你没有发布这个问题,所以答案一般。

wav文件具有严格定义的格式。它包含标题和数据(声音样本)。标头定义了wav文件中的数据数量。要播放音频,标题会提供其他信息,如采样率。如果使用AudioInputStream打开wav文件,它会解析这些信息。由于标头中定义的数据长度,您无法将数据附加到wav文件。您可以修改wav文件数据样本,但必须确保交换的数据具有相同的格式。

当您打开Class AudioInputStream的文档时,第一个语句是: "音频输入流是具有指定音频格式和长度的输入流。"

从OS的角度来看。

在实时播放器中使用文件作为缓冲区可能是个问题。文件系统在许多级别上进行缓冲/缓存,以提供对大块内存的快速访问。即时读取/写入文件可能会导致文件损坏。如果我理解你想在WAV文件中创建一个循环缓冲区(一次又一次地覆盖相同的样本)。您将发现其他问题,以便将文件的新内容(随编写器提供)与在循环中播放它的Clip同步。

你能做什么?

您可以使用SourceDataLine / TargetDataLine。接下来读取苍蝇中的样本并将其保留在字节缓冲区(例如byte []或ByteBuffer)中而不是文件中。您必须首先使用传入数据填充缓冲区,然后在/ xxxDataLine的循环中进行读/写操作。您必须知道为特定的AudioFormat打开了该行。输入和输出使用相同的格式。并非所有格式都受支持(这取决于硬件,所以这是一个使用Java的温和的东西)。请注意,有时数据大小即使以字节为单位也必须调整为帧大小(每个样本16位= 2个字节)。

答案 1 :(得分:0)

请参阅Java教程Sound Trail

中的“捕获音频”

要理解本节,您还必须阅读前面的章节。这不是一个容易阅读。但基本上,传单(+1)所提到的TargetDataLine是关键。

我怀疑如果你在读取时附加.wav,你会收到并发错误。

如果您只是想从麦克风输入声音,并且正确设置了TargetDataLine,那么您应该能够获得相当低的延迟。