2009-12-19 48 views
7

Tôi đã tạo một bản sao pong và tôi muốn thêm một số hiệu ứng âm thanh khi va chạm xảy ra. Vấn đề của tôi là mỗi ví dụ tôi có thể tìm thấy về tổng hợp âm thanh mất khoảng 30 dòng mã, xem xét toàn bộ ứng dụng của tôi chỉ có 90 dòng mã. Tôi đang tìm cách tiếp cận đơn giản hơn. Có cách nào đơn giản để tạo ra âm thanh tiếng bíp của các tông màu khác nhau không? Thời lượng không quan trọng. Tôi chỉ muốn một loạt tiếng bíp với các tông màu khác nhau.Âm thanh tạo Java

+2

30 dòng mã không nhiều. Có gì sai khi sử dụng các ví dụ bạn tìm thấy? – Joe

+1

yeah tôi biết nhưng toàn bộ bản sao là 90 dòng. một phần ba mã sẽ được sử dụng để tạo ra một tiếng bíp đơn giản. đối với tôi là vô nghĩa nhưng nếu tôi không thể tìm ra bất kỳ cách nào khác, tôi sẽ đi với điều đó. –

+4

Một phần tư mã, sau khi thực tế. Nếu điều đó làm cho bạn cảm thấy tốt hơn ... – Sev

Trả lời

17

Dưới đây là một ví dụ nhỏ chụp (và rút ngắn) từ Java Sound - Example: Code to generate audio tone

byte[] buf = new byte[ 1 ];; 
    AudioFormat af = new AudioFormat((float)44100, 8, 1, true, false); 
    SourceDataLine sdl = AudioSystem.getSourceDataLine(af); 
    sdl.open(); 
    sdl.start(); 
    for(int i = 0; i < 1000 * (float)44100/1000; i++) { 
     double angle = i/((float)44100/440) * 2.0 * Math.PI; 
     buf[ 0 ] = (byte)(Math.sin(angle) * 100); 
     sdl.write(buf, 0, 1); 
    } 
    sdl.drain(); 
    sdl.stop(); 
+1

Bạn có thể giải thích tại sao bạn nhân với 100 thay vì 128 trong dòng này: buf [0] = (byte) (Math.sin (angle) * 100); Tôi thấy điều này rất khó hiểu, vì tôi nghi ngờ tín hiệu sẽ chuyển từ -127 đến 127 ish Ngoài ra, liên kết đã chết. Vui lòng cập nhật nếu có thể. – Felix

+0

Điều đó sẽ chỉ ảnh hưởng đến biên độ (tức là âm lượng) của âm thanh. – while

+1

Điểm của 'i <1000 * (float) 44100/1000' không giống với 'i <(float) 44100'? – dk14

1

java.awt.Toolkit.getDefaultToolkit(). Beep()

loạt tiếng bíp?

int numbeeps = 10; 

for(int x=0;x<numbeeps;x++) 
{ 
    java.awt.Toolkit.getDefaultToolkit().beep(); 
} 
+1

"Các tông màu khác nhau", ông nói. –

+1

Plus, .beep() không hoạt động trên tất cả các nền tảng. –

1

Bạn có thể sử dụng JSyn. Đây là một lib bạn phải cài đặt (với .DLL.JAR). Nhưng rất đơn giản để tạo ra các tông màu khác nhau.

Link (Ngoài ra hướng dẫn có sẵn)

Đây là một ví dụ:

public static void main(String[] args) throws Exception { 
    SawtoothOscillatorBL osc; 
    LineOut lineOut; 
    // Start JSyn synthesizer. 
    Synth.startEngine(0); 

    // Create some unit generators. 
    osc = new SawtoothOscillatorBL(); 
    lineOut = new LineOut(); 

    // Connect oscillator to both left and right channels of output. 
    osc.output.connect(0, lineOut.input, 0); 
    osc.output.connect(0, lineOut.input, 1); 

    // Start the unit generators so they make sound. 
    osc.start(); 
    lineOut.start(); 

    // Set the frequency of the oscillator to 200 Hz. 
    osc.frequency.set(200.0); 
    osc.amplitude.set(0.8); 

    // Sleep for awhile so we can hear the sound. 
    Synth.sleepForTicks(400); 

    // Change the frequency of the oscillator. 
    osc.frequency.set(300.0); 
    Synth.sleepForTicks(400); 

    // Stop units and delete them to reclaim their resources. 
    osc.stop(); 
    lineOut.stop(); 
    osc.delete(); 
    lineOut.delete(); 

    // Stop JSyn synthesizer. 
    Synth.stopEngine(); 
} 

Martijn

+0

JSyn bây giờ là thuần Java và không còn yêu cầu một DLL gốc. – philburk

0

Đây là cùng một mã như trên với một chút mô tả trong 16 bit

import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.SourceDataLine; 

public class MakeSound { 
    public static void main(String[] args) throws LineUnavailableException { 
    System.out.println("Make sound"); 
    byte[] buf = new byte[2]; 
    int frequency = 44100; //44100 sample points per 1 second 
    AudioFormat af = new AudioFormat((float) frequency, 16, 1, true, false); 
    SourceDataLine sdl = AudioSystem.getSourceDataLine(af); 
    sdl.open(); 
    sdl.start(); 
    int durationMs = 5000; 
    int numberOfTimesFullSinFuncPerSec = 441; //number of times in 1sec sin function repeats 
    for (int i = 0; i < durationMs * (float) 44100/1000; i++) { //1000 ms in 1 second 
     float numberOfSamplesToRepresentFullSin= (float) frequency/numberOfTimesFullSinFuncPerSec; 
     double angle = i/(numberOfSamplesToRepresentFullSin/ 2.0) * Math.PI; // /divide with 2 since sin goes 0PI to 2PI 
     short a = (short) (Math.sin(angle) * 32767); //32767 - max value for sample to take (-32767 to 32767) 
     buf[0] = (byte) (a & 0xFF); //write 8bits ________WWWWWWWW out of 16 
     buf[1] = (byte) (a >> 8); //write 8bits WWWWWWWW________ out of 16 
     sdl.write(buf, 0, 2); 
    } 
    sdl.drain(); 
    sdl.stop(); 
    } 
}