2012-05-27 7 views
17

Я работаю над программой Java, и мне действительно нужно иметь возможность воспроизводить звук с определенной частотой и продолжительностью, подобно методу C# System.Beep, я знаю, как использовать его в C#, но я могу " t найти способ сделать это в Java. Есть ли какой-то эквивалент или другой способ сделать это?Java-эквивалент C# system.beep?

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

Возможно, [это] (http://stackoverflow.com/q/691743/1285418) может помочь. –

+1

@YoryeNathan - если стандартный вывод не идет на консоль, это вообще не приведет к звуку. –

ответ

2

Я не думаю, что есть способ воспроизвести мелодии с «beep» в Java. Вам нужно будет использовать API-интерфейсы javax.sound.*, я думаю ... если вы не найдете стороннюю библиотеку, которая упростит для вас все.

Если вы хотите пойти по этому пути, то this page может дать вам несколько идей.

+1

Хотя ОП принял это как правильное, это неверно; см. следующую запись для правильного ответа. –

+0

@RobCranfill - Вы не можете воспроизвести ** мелодию ** с '' \ 007 "' ... если это то, что вы подразумеваете. Если нет, объясните, как «следующая запись» отвечает на вопрос. –

+0

Я смиренно извиняюсь за свой комментарий. * Мой * комментарий неправильный, мне не хватало всей цели этого вопроса, чтобы играть «мелодии». Виноват. –

39

Вы можете использовать это:

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

EDIT

Если вы пытаетесь играть что-нибудь длительности и различных звуков, вы должны реально смотреть в библиотеку Java MIDI. Звуковой сигнал по умолчанию не сможет удовлетворить ваши потребности, так как вы не можете изменить длину звукового сигнала.

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

+6

Слишком плохо, что это не работает на Linux, работающем Gnome ... –

+0

@AndrewLandsverk Да, материал инструментария действительно сложный на разных платформах –

+2

@AndrewLandsverk FYI от gnome 15.10 и Java 7 все работает хорошо! –

0

Вы можете получить ссылку на Toolkit класса here, где метод beep() определен.

7

Просто распечатайте его:

System.out.println("\007") 

Работы по крайней мере, на Mac OS.

+0

Здесь не работает (Win7). –

+2

Здесь не работает (Ubuntu 13.04) – math

+2

@ devoured-elysium, работает на W7, если выполняется с java.exe. Если выполняется с 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, уже объяснил (27 мая 12), ЭТО не будет работать под 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); 
    } 
} 

EDIT: Видимо кто-то улучшил свой код. Я еще не пробовал, но пробовал это: https://gist.github.com/jbzdak/61398b8ad795d22724dd

+0

С этим я мог бы генерировать звук под Ubuntu 12.04. Благодаря! – Joanis

+0

@Erhannis: Я немного улучшил этот фрагмент, и теперь он стал более ясным в моей системе --- feek бесплатно включить его в свой ответ: https://gist.github.com/jbzdak/61398b8ad795d22724dd –

+0

Невозможно получить доступ к типу от переменная объявлена. Вместо этого просто вызывайте ее с именем класса, потому что она является static.So изменить строку события.Type.START на LineEvent.Type.START – ShihabSoft

2

Другое решение, зависящее от Windows, должно использовать JNA и напрямую звонить Windows Beep function, доступный в kernel32. К сожалению, Kernel32 в JNA не предоставляет этот метод в 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) Вы зависите от внутреннего API, который может измениться или быть закрыт в будущей версии Java. 3) Это вряд ли будет работать, если JVM изолирован. (Просто говорю). –