Beeping in Java
The objective of this article is to write a beep() method in Java. It will just play a tone in a specified frequency. Before we look into the details of the beep() method, let's have a look at the caller first.  // main program to call the beep() method
  public static void main(String[] args) throws Exception
  {
    int frequency=400;   // hz
    int duration =2000;  // milliseconds
    beep(frequency,duration);
  }
Physics of Sound
Before we can define the beep() method, we must know the mathematical modeling of a sound wave.  Mathematically, a "pure tone" can be represented by a sine wave.  The following program will generate a sine wave.  Just compile the program and go to the "Visualize" section below.
/******************************************************************************
* File : Sine.java
* Author : http://java.macteki.com/
* Description :
*   Create sample data points of a Sine wave
* Tested with : JDK 1.6
******************************************************************************/
class Sine
{
  static short[] makeSineSample()
  {
    double frequency = 400;
    double sampleRate = 16000;  // 16000 samples per second
    int bytesPerSample = 2;
    short[] audioData = new short[160];   // 160 sample points = 10 ms 
    int sampleLength = audioData.length;
    double volume = 8192;
    for(int i = 0; i < sampleLength; i++){
      double time = i/sampleRate;
      double angle = 2*Math.PI*frequency*time;
      double sinValue = Math.sin(angle);
      short amplitude = (short) (volume*sinValue);
      audioData[i]=amplitude;
    }
    return audioData;
  }
  public static void main(String[] args) throws Exception
  {
    short[] buffer=makeSineSample();
    for (int i=0;i<160;i++)
    {
      System.out.println(buffer[i]);
    }
  }
}
The above program will create 160 sample pixels of the sine wave with frequency 400hz. That is, the sine wave will complete 400 cycles in 1 second. If we generate 10 ms of data, there would be 4 cycles. Since the sampling rate is 16000 samples per second, 160 samples will contains 10 ms of data.
Visualize the Sample Data
First execute the program :
java Sine >out.txtLoad the output file into a excel file, then insert a graph with the sample data. You should see 4 cycles of sine wave as expected.
Java Sound API
The javax.sound.sampled package provides API to play a sound wave. All we have to do is to feed the sound wave sample data points to a SourceDataLine object. The following is a complete sample of playing a beep sound.
/******************************************************************************
* File : Beep.java
* Author : http://java.macteki.com/
* Description :
*   Play a pure tone with specified frequency
* Tested with : JDK 1.6
******************************************************************************/
class Beep
{
  static void beep(double frequency, int duration) throws Exception
  {
    
    int nChannel = 1;         // number of channel : 1 or 2
    // samples per second
    float sampleRate = 16000;  // valid:8000,11025,16000,22050,44100
    int nBit = 16;             // 8 bit or 16 bit sample
    int bytesPerSample = nChannel*nBit/8;
    double durationInSecond = duration/1000;
    int bufferSize = (int) (nChannel*sampleRate*durationInSecond*bytesPerSample);
    byte[] audioData = new byte[bufferSize];
    // "type cast" to ShortBuffer
    java.nio.ByteBuffer byteBuffer = java.nio.ByteBuffer.wrap(audioData);
    java.nio.ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
    int sampleLength = audioData.length/bytesPerSample;
    // generate the sine wave
    double volume = 8192;   // 0-32767
    double PI = Math.PI;
    for(int i = 0; i < sampleLength; i++){
      double time = i/sampleRate;
      double freq = frequency;
      double angle = 2*PI*freq*time;
      double sinValue = Math.sin(angle);
      short amplitude = (short) (volume*sinValue);
      for (int c=0;c<nChannel;c++)
      {
        shortBuffer.put(amplitude);
      }
    }//end generating sound wave sample
    boolean isSigned=true;
    boolean isBigEndian=true;
    // Define audio format
    javax.sound.sampled.AudioFormat audioFormat =
      new javax.sound.sampled.AudioFormat(sampleRate, nBit, nChannel, isSigned,isBigEndian);
    javax.sound.sampled.DataLine.Info dataLineInfo =
      new javax.sound.sampled.DataLine.Info(
         javax.sound.sampled.SourceDataLine.class, audioFormat);
    // get the SourceDataLine object
    javax.sound.sampled.SourceDataLine sourceDataLine = 
      (javax.sound.sampled.SourceDataLine)
      javax.sound.sampled.AudioSystem.getLine(dataLineInfo);
    sourceDataLine.open(audioFormat);
    sourceDataLine.start();
    // actually play the sound
    sourceDataLine.write(audioData,0,audioData.length);
    // "flush",  wait until the sound is completed
    sourceDataLine.drain();
  }
  
  public static void main(String[] args) throws Exception
  {
    int frequency=400;   // hz
    int duration =2000;  // milliseconds
    beep(frequency,duration);
  }
}

Can you tell me why double volume = 8192; ? Why this value?
ReplyDeleteThe volume level 8192 is just an arbitrary choice between 0 and 32767.
DeleteThis comment has been removed by the author.
ReplyDeletewhy volume is a number from 0 to 32767
ReplyDeleteBecause it is a 16 bit sound sample (see line 19 of Beep.java).
DeleteFor a 16 bit sample, the amplitude is stored in a short integer (see line 43).
And for a 16 bit short integer, the range is from -32768 to +32767. That means your sine wave will have a maximum amplitude of 32767. And in Physics, amplitude is volume.
Hope this help.
thx you for these sound posts. i was looking for this for quite some time.
Deletewhy sample rates must be // valid:8000,11025,16000,22050,44100 ?
They are typical rates that most codec would support. Selecting a value from one of them is a safe choice.
DeleteGambling in the Casino 888: No deposit bonus casino - Air
ReplyDeleteGambling in the where can i find air jordan 18 retro red suede Casino 888: No deposit bonus casino. Gambling in the Casino 888: No deposit bonus replica air jordan 18 retro men red casino. show to buy air jordan 18 retro varsity red Gambling in the Casino 888: good air jordan 18 retro No deposit Wholesale jordan 13 retro Sale bonus casino. Gambling in the Casino 888: No