gpt4 book ai didi

高速 Java 节拍器

转载 作者:搜寻专家 更新时间:2023-10-31 08:23:26 24 4
gpt4 key购买 nike

作为练习,我正在尝试使用 Thread.sleep 作为计时器并使用 JMF 作为声音来使用 Java 创建一个节拍器。它运行良好,但出于某种原因,JMF 似乎只能以每分钟最多 207 拍的速度播放声音。

来 self 的节拍器类:

public void play() {
soundPlayer.play();
waitPulse();
play();
}

来 self 的 SoundPlayer 类:

public void play() {
new Thread(new ThreadPlayer()).start();
}

private class ThreadPlayer implements Runnable {
public void run() {
System.out.println("Click");
player.setMediaTime(new Time(0));
player.start();
}
}

我已经将 SoundPlayer.play() 作为一个线程来测试它是否会有所作为,但事实并非如此。 我可以很容易地改变速度,最高可达 207bpm,但即使我将计时器设置为 1000bpm,声音的播放速度也不会超过 207bpm

我已将 System.out.println("Click"); 放入我的 ThreadPlayer.run() 中以检查我的循环是否正常工作 – 它是。

问题似乎与我对 JMF 的实现有关。我很确定有一个简单的解决方案,有人可以帮助我吗?

非常感谢您的帮助! :)

最佳答案

关于 Thread.sleep() 不可靠的答案是正确的:您不能指望它会在您指定的时间内准确返回。事实上,我很惊讶你的节拍器居然还能用,尤其是当你的系统负载不足时。阅读 Thread.sleep() 的文档以获取更多详细信息。 Max Beikirch 关于 MIDI 的回答是一个很好的建议:MIDI 可以很好地处理时序。

但是你问如何用音频做到这一点。诀窍是打开音频流并在节拍器点击之间用静音填充它,然后在您想要的地方插入节拍器点击。当您这样做时,您的声卡会以恒定速率播放样本(无论它们包含咔哒声还是静音)。这里的关键是保持音频流打开并且永远不要关闭它。那么,时钟就是音频硬件,而不是您的系统时钟——一个微妙但重要的区别。

那么,假设您要生成 44100 Hz 的 16 位单声道样本。这是一个将以请求的速率创建点击声音的函数。请记住,这种咔嗒声对扬声器(和您的耳朵)不利,因此如果您实际使用它,请以低音量播放。 (另外,这段代码未经测试——它只是为了演示这个概念)

int interval = 44100; // 1 beat per second, by default
int count = 0;
void setBPM( float bpm ) {
interval = ( bpm / 60 ) * 44100 ;
}
void generateMetronomeSamples( short[] s ) {
for( int i=0; i<s.length; ++i ) {
s = 0;
++count;
if( count == 0 ) {
s = Short.MAX_VALUE;
}
if( count == interval ) {
count = 0;
}
}
}

使用 setBPM 设置节奏后,您可以播放通过重复调用 generateMetronomeSamples() 函数生成的样本,并使用 JavaSound 将该输出流式传输到您的扬声器。 (有关好的教程,请参阅 JSResources.org)

一旦你成功了,你就可以用从 WAV 或 AIFF 或短音或其他任何声音中获得的声音代替刺耳的咔哒声。

关于高速 Java 节拍器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14164921/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com