Search code examples
javaaudiojavasoundwavetrigonometry

Sine Wave Sound Generator in Java


What's the simplest way to generate a sine wave sound at any frequency in Java? A sample size more than 2 bytes would help, but it doesn't really matter.


Solution

  • See Beeper for a self-contained example.


    Perhaps something simpler?

    That 51 lines of snippet (repeated below - spaced out for single line & in-line comments) as shown at the top of the linked answer, is about as simple as generating a tone gets (OK, you can take out 5+ lines for the harmonic).

    People seem to assume it should be a method built into the toolkit to produce a pure tone. It is not, and takes a little calculating to make one.

    /** Generates a tone, and assigns it to the Clip. */
    public void generateTone()
        throws LineUnavailableException {
        if ( clip!=null ) {
            clip.stop();
            clip.close();
        } else {
            clip = AudioSystem.getClip();
        }
        boolean addHarmonic = harmonic.isSelected();
    
        int intSR = ((Integer)sampleRate.getSelectedItem()).intValue();
        int intFPW = framesPerWavelength.getValue();
    
        float sampleRate = (float)intSR;
    
        // oddly, the sound does not loop well for less than
        // around 5 or so, wavelengths
        int wavelengths = 20;
        byte[] buf = new byte[2*intFPW*wavelengths];
        AudioFormat af = new AudioFormat(
            sampleRate,
            8,  // sample size in bits
            2,  // channels
            true,  // signed
            false  // bigendian
            );
    
        int maxVol = 127;
        for(int i=0; i<intFPW*wavelengths; i++){
            double angle = ((float)(i*2)/((float)intFPW))*(Math.PI);
            buf[i*2]=getByteValue(angle);
            if(addHarmonic) {
                buf[(i*2)+1]=getByteValue(2*angle);
            } else {
                buf[(i*2)+1] = buf[i*2];
            }
        }
    
        try {
            byte[] b = buf;
            AudioInputStream ais = new AudioInputStream(
                new ByteArrayInputStream(b),
                af,
                buf.length/2 );
    
            clip.open( ais );
        } catch(Exception e) {
            e.printStackTrace();
        }
    }