【问题标题】:Java equivalent of C# system.beep?Java 相当于 C# system.beep?
【发布时间】:2012-06-02 00:59:17
【问题描述】:

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

【问题讨论】:

  • 据我所知,只能发出默认的哔声:System.out.println("\007");
  • 也许this 可以提供帮助。
  • @YoryeNathan - 如果标准输出不进入控制台,则根本不会发出哔哔声。
  • @YoryeNathan 这会在任何 IDE 中打印 07
  • @HunterMcMillen 即使使用工具包解决方案(也并非总是有效 - 因为这只是 java 的本质),您仍然只能发出默认声音。

标签: c# java audio frequency beep


【解决方案1】:

你可以用这个:

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

编辑

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

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

【讨论】:

  • @AndrewLandsverk 是的,工具包的东西在不同的平台上真的很棘手
  • @AndrewLandsverk 仅供参考,从 gnome 15.10 和 Java 7 开始,一切都很好!
  • @YanFoto sweet,我一定要试试!
  • 哇!那是老学校。我已经 20 多年没有使用 AWT 了。
【解决方案2】:

可以获取Toolkit类here的引用,其中定义了方法beep()

【讨论】:

    【解决方案3】:

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

    如果你想走这条路,那么this page 可能会给你一些想法。


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

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

    【讨论】:

      【解决方案4】:

      打印出来:

      System.out.println("\007")
      

      适用于 Windows 和 MacOS。

      【讨论】:

      • @devoured-elysium,如果使用 java.exe 执行,则适用于 W7。如果使用 javaw.exe 或 eclipse(即没有真正的控制台)执行,则不会发出哔声。
      • 而且你不能演奏这样的曲子......除非你的用户都完全聋了。
      【解决方案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

      【讨论】:

      • 有了这个,我可以在 Ubuntu 12.04 下产生声音。谢谢!
      • @Erhannis:我稍微增强了这个 sn-p,现在它在我的系统上听起来更清晰 --- 随意将它合并到你的答案中:gist.github.com/jbzdak/61398b8ad795d22724dd
      • Can't access Type from a variable declared.Instead just call it with class name because it is static.所以将行event.Type.START更改为LineEvent.Type.START
      • @ShihabSoft 我...没看到这样的一行?有event.getType() == Type.START,但不一样。
      • @jb:对我来说 Erhannis 的第一个解决方案效果更好 - 更流畅。
      【解决方案6】:

      另一个解决方案,依赖于 Windows 是使用 JNA 并直接调用 Windows Beep function,在 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>
      

      【讨论】:

      • 此解决方案的问题: 1) 它仅适用于 Windows。 OP 并未声明仅适用于 Windows 的解决方案是可以接受的。 2) 您依赖的内部 API 可能会在未来的 Java 版本中更改或关闭。 3) 如果 JVM 是沙盒的,这不太可能工作。 (只是说)。
      【解决方案7】:

      Use 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
      

      【讨论】:

        【解决方案8】:

        如果您使用的是 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

        【讨论】:

          猜你喜欢
          • 2011-06-29
          • 2010-09-24
          • 2023-04-06
          • 2014-12-11
          • 1970-01-01
          • 1970-01-01
          • 2014-09-29
          • 2011-01-21
          • 1970-01-01
          相关资源
          最近更新 更多