How to play a known frequency sound in java

70 views Asked by At

I found a snippet of code here or online and have been using it to play a sound. The problem is that for frequencies out of human range and even upper level human range there appears to be a substitution of the sound frequency into an audible one. In other words instead of being very high accurate pitched frequency it suddenly plays a random tone that we can hear. The ranges I am interested in are 15,000Hz to 30,000Hz. I don't fully understand this code and would like some help.

public static void tone(int hz, int msecs, double vol) throws LineUnavailableException {        
    byte[] buf = new byte[1];
    AudioFormat af = new AudioFormat(SAMPLE_RATE,8,1,true,false);     
    SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
    sdl.open(af);
    sdl.start();
    for (int i=0; i < msecs*8; i++) {
          double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI;
          buf[0] = (byte)(Math.sin(angle) * 127.0 * vol);
          sdl.write(buf,0,1);
    }
    sdl.drain();
    sdl.stop();
    sdl.close();
}

What I have done is make a form with a button on it and it calls a sound class

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    // TODO add your handling code here:
    try{     
       Sound.tone(15000,2000,1);
    }catch(Exception ex){System.out.println(ex);}   
}        

The sound class code is:

import javax.sound.sampled.*;

public class Sound { 
    public static float SAMPLE_RATE = 8000f;

    public static void tone(int hz, int msecs) throws LineUnavailableException {
        tone(hz, msecs, 1.0);
    }

    public static void tone(int hz, int msecs, double vol) throws LineUnavailableException {
    
        byte[] buf = new byte[1];
        AudioFormat af = new AudioFormat(SAMPLE_RATE,8,1,true,false);     
        SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
        sdl.open(af);
        sdl.start();
        for (int i=0; i < msecs*8; i++) {
            double angle = i / (SAMPLE_RATE / hz) * 2.0 * Math.PI;
            buf[0] = (byte)(Math.sin(angle) * 127.0 * vol);
            sdl.write(buf,0,1);
        }
        sdl.drain();
        sdl.stop();
        sdl.close();
    }
}
0

There are 0 answers