首页 > 解决方案 > 预录文件的Java声音播放和数据绘图协调

问题描述

我正在尝试编写一个程序来播放保存的 .wav 音频文件,同时显示声音幅度的图。我使用图形库 (JChart2D) 和 Java Sound 包来实现这一点。问题是向图表提供与音频相同频率(44100 赫兹)的数据点,以便它们协调。我已经尝试使用该Thread.sleep()方法,但它不够准确。一个 5 分钟的音频文件在结束时有超过 10 秒的延迟。我还看到一个类似主题的答案,建议使用“忙等待” System.nanoTime(),但这会导致处理器负载过大(100%)。

如何做到这一点?(也许对于其他软件包或库,尽管建议使用当前的软件包或库会更可取)。

数据保存在一个字节数组中,我将其传递给 aClip进行播放,并且我想以 44,100 赫兹的频率提供图形。

标签: javaperformanceaudiosynchronizationjavasound

解决方案


图形通常以 60 fps 的帧速率显示。那么,您能否在一个视觉帧中绘制 735 (= 44100 / 60) 个声音值,或者是否有特别需要尝试以与音频相同的速率运行?

就执行线程而言,Java 在实时保证方面并不重要,因此尝试协调两个线程将很困难。但是,由于 SourceDataLine 的 write() 方法采用了阻塞,Java 在保持稳定的馈送方面做得很好,这使得声音数据能够正确播放。

使用 SourceDataLine 可以让您有机会在播放声音时积累声音(因此有更好的时机)。SourceDataLine 的一些示例代码在以下链接中应该会有所帮助。

https://docs.oracle.com/javase/tutorial/sound/converters.html

在第一个示例中,代码中有一个点(在 while 循环中),我们有以下注释:

  // Here, do something useful with the audio data that's 
  // now in the audioBytes array...

那个“有用”的东西是将字节解码为 PCM 值并将它们累积到一个包含 735 个值的数组中,以便传递给图形线程。


推荐阅读