it-swarm.com.ru

Java эквивалент C # system.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);
    }
    }
}
23
Glen654

Я не думаю, что есть способ играть мелодии1 с "гудком" в портативном2 Джава. Вам нужно использовать API javax.sound.*, я думаю ... если только вы не найдете стороннюю библиотеку, которая упростит вам задачу.

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


1 - Если ваши пользователи не глухие. Конечно, вы можете делать такие вещи, как писк в азбуке Морзе ... но это не мелодия.

2 - Очевидно, вы могли бы сделать собственные вызовы функции звукового сигнала Windows. Но это не будет портативным.

4
Stephen C

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

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

ПРАВКА

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

http://www.Oracle.com/technetwork/Java/index-139508.html

46
Hunter McMillen

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

System.out.println("\007")

Работает как минимум на MacOS.

7
Adrian

Я взломал функцию, которая работает для меня. Он использует кучу вещей из 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

4
Erhannis

Другое решение, зависящее от Windows, состоит в том, чтобы использовать JNA и напрямую вызывать функцию Windows Beep , доступную в 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>
3
EFalco
//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
whytfng

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

0
Bhavik Ambani

Используйте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
0
Nav