Gle*_*654 27 c# java audio frequency beep
我正在研究一个Java程序,我真的需要能够以一定的频率和持续时间播放声音,类似于c#方法System.Beep,我知道如何在C#中使用它,但我找不到一种在Java中执行此操作的方法.是否有一些等效或其他方式来做到这一点?
using System;
class Program
{
static void Main()
{
// The official music of Dot Net Perls.
for (int i = 37; i <= 32767; i += 200)
{
Console.Beep(i, 100);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Hun*_*len 51
你可以用这个:
java.awt.Toolkit.getDefaultToolkit().beep();
Run Code Online (Sandbox Code Playgroud)
编辑
如果你试图播放持续时间和不同声音的任何东西,你应该真正研究Java MIDI库.默认蜂鸣声无法满足您的需求,因为您无法更改蜂鸣声的长度.
http://www.oracle.com/technetwork/java/index-139508.html
只需打印它:
System.out.println("\007")
Run Code Online (Sandbox Code Playgroud)
至少在MacOS上运行.
我已经编写了一个对我有用的函数。它使用了一堆来自javax.sound.sampled. 我已将其调整为使用我的系统自动提供的新剪辑的音频格式AudioSystem.getClip()。可能有各种各样的方法可以使它更健壮和更高效。
/**
* Beeps. Currently half-assumes that the format the system expects is
* "PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian"
* I don't know what to do about the sample rate. Using 11025, since that
* seems to be right, by testing against A440. I also can't figure out why
* I had to *4 the duration. Also, there's up to about a 100 ms delay before
* the sound starts playing.
* @param freq
* @param millis
*/
public static void beep(double freq, final double millis) {
try {
final Clip clip = AudioSystem.getClip();
AudioFormat af = clip.getFormat();
if (af.getSampleSizeInBits() != 16) {
System.err.println("Weird sample size. Dunno what to do with it.");
return;
}
//System.out.println("format " + af);
int bytesPerFrame = af.getFrameSize();
double fps = 11025;
int frames = (int)(fps * (millis / 1000));
frames *= 4; // No idea why it wasn't lasting as long as it should.
byte[] data = new byte[frames * bytesPerFrame];
double freqFactor = (Math.PI / 2) * freq / fps;
double ampFactor = (1 << af.getSampleSizeInBits()) - 1;
for (int frame = 0; frame < frames; frame++) {
short sample = (short)(0.5 * ampFactor * Math.sin(frame * freqFactor));
data[(frame * bytesPerFrame) + 0] = (byte)((sample >> (1 * 8)) & 0xFF);
data[(frame * bytesPerFrame) + 1] = (byte)((sample >> (0 * 8)) & 0xFF);
data[(frame * bytesPerFrame) + 2] = (byte)((sample >> (1 * 8)) & 0xFF);
data[(frame * bytesPerFrame) + 3] = (byte)((sample >> (0 * 8)) & 0xFF);
}
clip.open(af, data, 0, data.length);
// This is so Clip releases its data line when done. Otherwise at 32 clips it breaks.
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
if (event.getType() == Type.START) {
Timer t = new Timer((int)millis + 1, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
clip.close();
}
});
t.setRepeats(false);
t.start();
}
}
});
clip.start();
} catch (LineUnavailableException ex) {
System.err.println(ex);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:显然有人改进了我的代码。我还没有尝试过,但试一试:https : //gist.github.com/jbzdak/61398b8ad795d22724dd