32

我正在做一个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);
    }
    }
}
4

8 回答 8

58

你可以使用这个:

java.awt.Toolkit.getDefaultToolkit().beep();

编辑

如果您尝试播放任何持续时间和不同声音的东西,您应该真正查看 Java MIDI 库。默认哔声将无法满足您的需求,因为您无法更改哔声的长度。

http://www.oracle.com/technetwork/java/index-139508.html

于 2012-05-27T03:29:13.903 回答
9

只需打印它:

System.out.println("\007")

适用于 Windows 和 MacOS。

于 2013-04-19T23:15:47.250 回答
5

我已经组合了一个对我有用的功能。它使用了一堆来自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);
    }
}

编辑:显然有人改进了我的代码。我还没有尝试过,但试一试: https ://gist.github.com/jbzdak/61398b8ad795d22724dd

于 2014-03-17T23:01:15.870 回答
4

我认为在便携式2 Java中没有办法用“哔”声播放曲调1 。你需要使用我认为的 API……除非你能找到一个可以为你简化事情的第三方库。javax.sound.*

如果你想走这条路,那么这个页面可能会给你一些想法。


1 - 除非您的用户都是音盲。当然,你可以做一些事情,比如在摩尔斯电码中发出哔哔声……但这不是一首曲子。

2 - 显然,您可以对 Windows 蜂鸣功能进行本机调用。但这不是便携式的。

于 2012-05-27T03:36:52.507 回答
4

另一个依赖于 Windows 的解决方案是使用 JNA 并直接调用 Windows Beep 函数,在 kernel32 中可用。不幸的是,JNA 中的 Kernel32 在 4.2.1 中没有提供此方法,但您可以轻松扩展它。

public interface Kernel32 extends com.sun.jna.platform.win32.Kernel32 {

        /**
         * Generates simple tones on the speaker. The function is synchronous; 
         * it performs an alertable wait and does not return control to its caller until the sound finishes.
         * 
         * @param dwFreq : The frequency of the sound, in hertz. This parameter must be in the range 37 through 32,767 (0x25 through 0x7FFF).
         * @param dwDuration : The duration of the sound, in milliseconds.
         */
        public abstract void Beep(int dwFreq, int dwDuration);
}

要使用它:

static public void main(String... args) throws Exception {
    Kernel32 kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
    kernel32.Beep(800, 3000);
}

如果使用 maven,则必须添加以下依赖项:

<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>4.2.1</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna-platform</artifactId>
    <version>4.2.1</version>
</dependency>
于 2017-02-15T09:16:55.910 回答
0

您可以在此处获取 Toolkit 类的引用,其中beep()定义了方法。

于 2012-05-27T03:31:20.483 回答
0

改为使用 Applet。您必须将哔声音频文件作为wav文件提供,但它可以工作。我在 Ubuntu 上试过这个:

package javaapplication2;

import java.applet.Applet;
import java.applet.AudioClip;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

public class JavaApplication2 {

    public static void main(String[] args) throws MalformedURLException {
        File file = new File("/path/to/your/sounds/beep3.wav");
        URL url = null;
        if (file.canRead()) {url = file.toURI().toURL();}
        System.out.println(url);
        AudioClip clip = Applet.newAudioClip(url);
        clip.play();
        System.out.println("should've played by now");
    }
}
//beep3.wav was available from: http://www.pacdv.com/sounds/interface_sound_effects/beep-3.wav
于 2019-01-24T07:53:48.453 回答
0

如果您正在使用 SWT 小部件,您可以这样做(系统声音!)

org.eclipse.swt.widgets.Display.getCurrent().beep();

如果你想要 NATIVE JAVA,这里有一个类:https ://github.com/marcolopes/dma/blob/master/org.dma.java/src/org/dma/java/util/SoundUtils.java

于 2019-11-15T03:57:20.110 回答