为了账号安全,请及时绑定邮箱和手机立即绑定

无限期地播放正弦波 - java

无限期地播放正弦波 - java

小怪兽爱吃肉 2023-05-17 14:50:36
我正在尝试制作一段可以连续播放正弦波的代码。我希望能够播放 MIDI 音符的频率。Java 中的 MIDI 库感觉有点草率(当我告诉它播放时,按键和音符播放之间有一个小延迟)。我见过这样的例子,你生成一个确定长度的正弦波,然后你通过给一个SourceDataLine字节数组来播放它。这行得通,但字节数组只能这么长,最终会停止播放。我的下一个想法是不断地向该行写入一个字节,计算下一行并继续。这是我的代码:int i = 0;int sampleRate = 8000;int freq = 440;while (true) {    double samplingInterval = (double) (sampleRate / freq);    double angle = (2.0 * Math.PI * i) / samplingInterval;    byte toPlay = (byte) (Math.sin(angle) * 127);    line.write(new byte[] {toPlay}, 0, 1);    i++;}我希望这会给我一个频率为 440hz 的恒定输出,但它给了我这个错误:java.lang.IllegalArgumentException: illegal request to write non-integral number of frames (1 bytes, frameSize = 2 bytes)如果没有,有没有办法在 Java 中加速 MIDI 库,或者我只是犯了一个愚蠢的错误?提前致谢。
查看完整描述

2 回答

?
噜噜哒

TA贡献1784条经验 获得超7个赞

一帧音频是一个或多个同时定时的音频样本。在您的情况下,立体声 ( frames ==2)。在流中,它们通常是交错的(例如 L、R、L、R....)。

您可以通过将每个示例编写两次来解决此问题。

虽然 Java(或任何其他具有停止世界垃圾收集功能的 JITd 语言运行时)从来都不是低延迟音频软件的实现选择,但我怀疑您检测到的“草率”实际上是一个较长的音频缓冲期:默认设置缓冲期可能只有几分之一秒。


查看完整回答
反对 回复 2023-05-17
?
Cats萌萌

TA贡献1805条经验 获得超9个赞

对于这个特定的想法,您可以使用


while (true) {

    double samplingInterval = (double) (sampleRate / freq);

    double angle = (2.0 * Math.PI * i) / samplingInterval;

    byte toPlay = (byte) (Math.sin(angle) * 127);

    byte[] data=new byte[1024];

    for(int j=0; j<data.length; j++) data[j]=toPlay;

    line.write(data, 0, data.length);

    i++;

}

或者长度为 4 就足够了。


查看完整回答
反对 回复 2023-05-17
  • 2 回答
  • 0 关注
  • 172 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信