15

I created a pong clone and I would like to add some sound effects when collisions occur. My problem is that every example I could find about synthesizing sound takes about 30 lines of code, considering my whole application has only 90 lines of code. I am looking for a simpler approach. Is there a simple way to create a beep sound of different tones? Duration does not matter. I just want a series of beeps with different tones.

iBug
  • 35,554
  • 7
  • 89
  • 134
Hamza Yerlikaya
  • 49,047
  • 44
  • 147
  • 241
  • 2
    30 lines of code isn't much. What's wrong with using the examples you found? – Joe Dec 19 '09 at 09:55
  • 1
    yeah i know but whole clone is 90 lines. one third of the code will be used to just create a simple beep. to me kinda pointless but if i can't find any other way i'll go with that. – Hamza Yerlikaya Dec 19 '09 at 10:07
  • 7
    One fourth of the code, after the fact. If that makes you feel any better... – Sev Dec 19 '09 at 23:58

4 Answers4

24

Here's a small example taken (and shortened) from 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();
Peter Perháč
  • 20,434
  • 21
  • 120
  • 152
tangens
  • 39,095
  • 19
  • 120
  • 139
  • 2
    Can you explain why you multiply by 100 instead of 128 in this line: buf[ 0 ] = (byte )( Math.sin( angle ) * 100 ); I find it very confusing, as I would suspect the signal to go between -127 to 127 ish Also, the link is dead. Please update it if possible. – Felix Apr 15 '11 at 11:45
  • That will just affect the amplitude (i.e volume) of the sound. – while Oct 21 '15 at 18:05
  • 1
    What's the point of `i < 1000 * (float )44100 / 1000` isn't that the same as `i < (float )44100` ? – dk14 Apr 16 '16 at 15:54
  • 1
    @dk14, the first 1000 will allow you to change the length of the sample, which I assume is milliseconds. – Firedan1176 May 22 '16 at 02:42
9

Here is same code as above with a bit of description in 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();
  }
}
Bojan Vukasovic
  • 2,054
  • 22
  • 43
6

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

series of beeps?

int numbeeps = 10;

for(int x=0;x<numbeeps;x++)
{
  java.awt.Toolkit.getDefaultToolkit().beep();
}
Sev
  • 15,401
  • 9
  • 56
  • 75
6

You can use JSyn. This is a lib you have to install (with a .DLL and a .JAR). But very simple to create diffrent tones.

Link (Also tutorials available)

This is an example:

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

Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287