2009-12-19 15 views
7

Creé un clon de pong y me gustaría agregar algunos efectos de sonido cuando se producen colisiones. Mi problema es que cada ejemplo que pude encontrar sobre la sintetización de sonido requiere aproximadamente 30 líneas de código, considerando que toda mi aplicación tiene solo 90 líneas de código. Estoy buscando un enfoque más simple. ¿Hay una manera simple de crear un pitido de diferentes tonos? La duración no importa. Solo quiero una serie de pitidos con diferentes tonos.Sonido generador de Java

+2

30 líneas de código no son muchas. ¿Qué pasa con el uso de los ejemplos que encontraste? – Joe

+1

Sí, lo sé, pero todo el clon es de 90 líneas. un tercio del código se usará para crear un simple pitido. para mí un poco sin sentido, pero si no puedo encontrar otra forma, me iré con eso. –

+4

Una cuarta parte del código, después del hecho. Si eso te hace sentir mejor ... – Sev

Respuesta

17

Aquí hay un pequeño ejemplo tomado (y corto) de 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

¿Puede explicar por qué multiplica por 100 en lugar de 128 en esta línea: buf [0] = (byte) (Math.sin (ángulo) * 100); Me resulta muy confuso, ya que sospecho que la señal va entre -127 a 127 ish Además, el enlace está muerto. Por favor, actualízalo si es posible. – Felix

+0

Eso solo afectará la amplitud (es decir, el volumen) del sonido. – while

+1

¿Qué sentido tiene 'i <1000 * (float) 44100/1000' no es lo mismo que' i <(float) 44100'? – dk14

1

java.awt.Toolkit.getDefaultToolkit(). Pitido()

serie de pitidos?

int numbeeps = 10; 

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

"Distintos tonos" Dijo. –

+1

Además, .beep() no funciona en todas las plataformas. –

1

Puede utilizar JSyn. Esta es una lib que tiene que instalar (con un .DLL y un .JAR). Pero muy simple para crear tonos diferentes.

Link (También tutoriales disponibles)

Este es un ejemplo:

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 ahora es Java puro y ya no requiere una DLL nativa. – philburk

0

Aquí está mismo código que el anterior con un poco de descripción en 16 bits

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(); 
    } 
} 
Cuestiones relacionadas