2012-05-27 92 views
17

我正在開發一個Java程序,我真的需要能夠以某種頻率和持續時間播放聲音,類似於C#方法System.Beep,我知道如何在C#中使用它,但是我可以'在Java中找到一種方法來做到這一點。有沒有一些等價的方法可以做到這一點?如果你試圖播放時間的任何Java相當於C#system.beep?

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

編輯

,並用不同的聲音,你應該看看到Java MIDI庫:

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); 
    } 
    } 
} 
+6

據我所知,你只能發出蜂鳴聲默認的蜂鳴聲:'System.out.println(「\ 007」);' – SimpleVar

+0

也許[this](http://stackoverflow.com/q/691743/1285418)可以提供幫助。 –

+1

@YoryeNathan - 如果標準輸出沒有進入控制檯,那根本不會產生嘟嘟聲。 –

回答

2

我不認爲有一種方法可以在Java中用「嘟嘟」來播放音調。您需要使用我認爲的javax.sound.* API ......除非您可以找到能夠爲您簡化事情的第三方庫。

如果你想走這條路,那麼this page可能會給你一些想法。

+1

雖然OP認爲這是正確的,但這是不正確的;看到下一個條目的正確答案。 –

+0

@RobCranfill - 你不能用'「\ 007」'播放**曲調** ......如果這就是你所暗示的。如果不是,請解釋「下一個條目」如何回答問題。 –

+0

我對我的評論謙虛道歉。 *我的*評論是錯誤的,我錯過了這個問題的整個觀點,玩「曲調」。我的錯。 –

39

您可以使用此。默認的嘟嘟聲將無法滿足您的需求,因爲您無法更改嗶聲的長度。

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

+6

這太糟糕了,這在運行侏儒的Linux上不起作用... –

+0

@AndrewLandsverk是的,工具箱的東西在不同的平臺上真的很棘手 –

+2

@AndrewLandsverk從gnome 15.10和Java 7開始,它的工作很好! –

0

你可以得到工具包類here,該方法beep()定義的參考。

7

只是打印:至少

System.out.println("\007") 

作品在MacOS。

+0

這裏不工作(Win7)。 –

+2

也不能在這裏工作(Ubuntu 13.04) – math

+2

@ devoured-elysium,如果使用java.exe執行,則工作在W7上。如果用javaw.exe或eclipse執行(即沒有真正的控制檯),那麼沒有嗶聲。 – RealHowTo

0
//Here's the full code that will DEFINITELY work: (can copy & paste) 

import java.awt.*; 

public class beeper 
{ 
    public static void main(String args[]) 
    { 
     Toolkit.getDefaultToolkit().beep(); 
    } 
} 
+1

Andrew,已經解釋過(12年5月27日),這將不能在Linux下與Gnome一起工作,我再次測試它。 – math

+1

這是[更早的答案]的完整副本(http://stackoverflow.com/questions/10771441/java-equivalent-of-c-sharp-system-beep/10771452#10771452) –

+0

在Windows下無法運行。 –

3

我已經在一起攻擊了一個適用於我的函數。它使用了一堆來自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

+0

有了這個,我可以在Ubuntu 12.04下生成聲音。謝謝! – Joanis

+0

@Erhannis:我稍微增強了這個片段,現在它在我的系統上聽起來更清晰---免費將它合併到您的答案中:https://gist.github.com/jbzdak/61398b8ad795d22724dd –

+0

無法訪問類型一個變量聲明。而不只是調用類名稱,因爲它是靜態的。所以將行event.Type.START更改爲LineEvent.Type.START – ShihabSoft

2

另一種解決方案,Windows依賴是使用JNA和直接調用Windows的內核32中提供的Windows Beep function。不幸的是,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> 
+0

此解決方案的問題:1)它只能在Windows上工作。 OP沒有聲明只有Windows的解決方案是可以接受的。 2)您將依賴於可能會在未來的Java版本中更改或關閉的內部API。 3)如果JVM是沙盒,這不太可能工作。 (只是說)。 –