【问题标题】:Real time wav playing实时wav播放
【发布时间】:2013-06-26 10:02:02
【问题描述】:

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

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

【问题讨论】:

  • A Clip 不能为此工作。此外,甚至获得一个显示添加到junk.wav 的新数据的InputStream 也是很棘手的。
  • 有什么方法可以让InputStream 工作?

标签: java audio stream javasound


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    您没有发布问题,所以回答将是一般性的。

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

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

    从操作系统的角度。

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

    你能做什么?

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

    【讨论】:

    • 对不起,我错过了。我想实时播放那个wav文件。麦克风中的输入最多会延迟 2 3 秒。
    • “对不起,我错过了。我想要..” 这也不是问题,而 “如何实时播放那个 wav 文件?” 一个问题。 是你的问题吗?
    猜你喜欢
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多