2009-12-19 5 views
7

J'ai créé un clone pong et j'aimerais ajouter quelques effets sonores en cas de collision. Mon problème est que chaque exemple que je pourrais trouver sur la synthèse du son prend environ 30 lignes de code, étant donné que mon application entière n'a que 90 lignes de code. Je suis à la recherche d'une approche plus simple. Existe-t-il un moyen simple de créer un bip sonore de différentes tonalités? La durée n'a pas d'importance. Je veux juste une série de bips avec des tons différents.Java générant du son

+2

30 lignes de code ne sont pas beaucoup. Quel est le problème avec l'utilisation des exemples que vous avez trouvés? – Joe

+1

ouais je sais mais tout le clone est de 90 lignes. un tiers du code sera utilisé pour créer un bip simple. pour moi un peu inutile mais si je ne trouve pas d'autre moyen, je vais aller avec ça. –

+4

Un quart du code, après le fait. Si cela vous fait sentir mieux ... – Sev

Répondre

17

Voici un petit exemple pris (et raccourci) 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

Pouvez-vous expliquer pourquoi vous multipliez par 100 au lieu de 128 dans cette ligne: buf [0] = (octet) (Math.sin (angle) * 100); Je trouve cela très confus, car je soupçonne le signal d'aller entre -127 à 127 ish En outre, le lien est mort. Veuillez le mettre à jour si possible. – Felix

+0

Cela affectera simplement l'amplitude (c'est-à-dire le volume) du son. – while

+1

Quel est le point de 'i <1000 * (float) 44100/1000' n'est pas la même chose que' i <(float) 44100'? – dk14

1

java.awt.Toolkit.getDefaultToolkit(). Bip()

série de bips?

int numbeeps = 10; 

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

"Différents tons" Il a dit. –

+1

De plus, .beep() ne fonctionne pas sur toutes les plates-formes. –

1

Vous pouvez utiliser JSyn. C'est une lib que vous devez installer (avec un .DLL et un .JAR). Mais très simple pour créer des tons différents.

Link (tutoriels Aussi disponible)

Voici un exemple:

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 est maintenant Java pur et ne nécessite plus de DLL native. – philburk

0

est ici même code comme ci-dessus avec un peu de la description 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(); 
    } 
}