Java 实时wav播放

Java 实时wav播放,java,audio,stream,javasound,Java,Audio,Stream,Javasound,我写了一个播放.wav文件的代码。它很好用。 现在,另一段代码从音频接收器获取音乐数据,并不断附加到.wav文件 假设在我运行播放器时,音频长度为5秒,现在尽管使用更新程序代码更新了wav文件,但播放器只播放最初的5秒 播放代码很简单: try{ AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("junk.wav")); Clip clip = AudioSystem.get

我写了一个播放.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();
}

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

您没有发布问题,因此答案将是一般性的

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

打开AudioInputStream类的docu时,第一条语句是: “音频输入流是具有指定音频格式和长度的输入流。”

从操作系统的角度来看

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

你能做什么


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

您没有发布问题,因此答案将是一般性的

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

打开AudioInputStream类的docu时,第一条语句是: “音频输入流是具有指定音频格式和长度的输入流。”

从操作系统的角度来看

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

你能做什么

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

请参阅Java教程中的“捕获音频”

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

我怀疑,如果您在读取.wav时将其追加到该.wav,您将得到一个并发错误

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

请参阅Java教程中的“捕获音频”

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

我怀疑,如果您在读取.wav时将其追加到该.wav,您将得到一个并发错误


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

无法使用
剪辑。此外,要获得显示添加到
垃圾.wav
中的新数据的
InputStream
也很困难。任何让
InputStream
工作的方法?不能让
Clip
工作。此外,要获得一个显示添加到
垃圾.wav
的新数据的
InputStream
也很困难。有什么方法可以让
InputStream
工作吗?哦,对不起,我错过了。我想实时播放那个wav文件。麦克风中的输入应该在atmost 2-3秒延迟的情况下播放。“哦,对不起,我错过了。我想要…”这也不是问题,而“如何实时播放该wav文件?”是问题。这是你的问题吗?哦,对不起,我错过了。我想在现实中播放wav文件