Results 1 to 2 of 2
  1. #1
    sandydo is offline Member
    Join Date
    Apr 2014
    Posts
    1
    Rep Power
    0

    Default No proper soundplaying with Javax.sound.sampled

    Hello everyone,

    I found a programm with which you can create a tone on my computer, by giving exactly the function for the vibration. The problem is now, that the sound output on my computer (and on an other also) sounds quite terrible.
    1) After and before evey tone, the speakers are "clicking"
    2) and when I let the programm sleep between the notes, it is hearable, that when he wakes up again, the first tiny part of the next note is still the one from before.
    Here is the program:

    Java Code:
    import javax.sound.sampled.*;
    
    public final class ToneGenerator {
    
        /**
         *  The sample rate - 44,100 Hz for CD quality audio.
         */
        public static final int SAMPLE_RATE = 44100;
        private static final int BYTES_PER_SAMPLE = 2;                // 16-bit audio
        private static final int BITS_PER_SAMPLE = 16;                // 16-bit audio
        private static final double MAX_16_BIT = Short.MAX_VALUE;     // 32,767
        private static final int SAMPLE_BUFFER_SIZE = 4096;
    
    
        private static SourceDataLine line;   // to play the sound
        private static byte[] buffer;         // our internal buffer
        private static int bufferSize = 0;    // number of samples currently in internal buffer
    
        // do not instantiate
        private ToneGenerator() { }
    
       
        // static initializer
        static { init(); }  
    
        // open up an audio stream
        private static void init() {
            try {
                // 44,100 samples per second, 16-bit audio, mono, signed PCM, little Endian
                AudioFormat format = new AudioFormat((float) SAMPLE_RATE, BITS_PER_SAMPLE, 1, true, false);
                DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
    
                line = (SourceDataLine) AudioSystem.getLine(info);
                line.open(format, SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE);
                
                // the internal buffer is a fraction of the actual buffer size, this choice is arbitrary
                // it gets divided because we can't expect the buffered data to line up exactly with when
                // the sound card decides to push out its samples.
                buffer = new byte[SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE/3];
            } catch (Exception e) {
                System.out.println(e.getMessage());
                System.exit(1);
            }
    
            // no sound gets made before this call
            line.start();
        }
        /**
         * Close standard audio.
         */
        public static void close() {
            line.drain();
            line.stop();
        }
        
        /**
         * Write one sample (between -1.0 and +1.0) to standard audio. If the sample
         * is outside the range, it will be clipped.
         */
        public static void play(double in) {
    
            // clip if outside [-1, +1]
            if (in < -1.0) in = -1.0;
            if (in > +1.0) in = +1.0;
    
            // convert to bytes
            short s = (short) (MAX_16_BIT * in);
            buffer[bufferSize++] = (byte) s;
            buffer[bufferSize++] = (byte) (s >> 8);   // little Endian
    
            // send to sound card if buffer is full        
            if (bufferSize >= buffer.length) {
                line.write(buffer, 0, buffer.length);
                bufferSize = 0;
            }
        }
    
        /**
         * Write an array of samples (between -1.0 and +1.0) to standard audio. If a sample
         * is outside the range, it will be clipped.
         */
        public static void play(double[] input) {
            for (int i = 0; i < input.length; i++) {
                play(input[i]);
            }
        }
       /***********************************************************************
        * sample test client
        ***********************************************************************/
    
        // create a note (sine wave) of the given frequency (Hz), for the given
        // duration (seconds) scaled to the given volume (amplitude)
        private static double[] note(double hz, double duration, double amplitude) {
            int N = (int) (ToneGenerator.SAMPLE_RATE * duration);
            double[] a = new double[N+1];
            for (int i = 0; i <= N; i++)
                a[i] = amplitude * Math.sin(2 * Math.PI * i * hz / ToneGenerator.SAMPLE_RATE);
            return a;
        }
    
        /**
         * Test client - play an A major scale to standard audio.
         */
        public static void main(String[] args) {
            
            // 440 Hz for 1 sec
            double freq = 440.0;
            for (int i = 0; i <= SAMPLE_RATE; i++) {
                ToneGenerator.play(0.5 * Math.sin(2*Math.PI * freq * i / SAMPLE_RATE));
            }
            
            // scale increments
            int[] steps = { 0, 2, 4, 5, 7, 9, 11, 12 };
            for (int i = 0; i < steps.length; i++) {
                double hz = 440.0 * Math.pow(2, steps[i] / 12.0);
              
              try {
            	  Thread.sleep(200);
              } catch (Exception e) {
            	  System.out.println(e.getMessage());
              }
                ToneGenerator.play(note(hz, 1.0, 0.5));
            }
            // need to call this in non-interactive stuff so the program doesn't terminate
            // until all the sound leaves the speaker.
            ToneGenerator.close(); 
    
            // need to terminate a Java program with sound
            System.exit(0);
        }
    }
    For me it seems to have something to do with the buffer, because when I decrease the size of the buffer in line 34, the clicking gets even worse.

    I know that it is quite much to read, but it would be very nice if somebody could help me!!

    Greetings Sandydo

  2. #2
    jashburn is offline Senior Member
    Join Date
    Feb 2014
    Posts
    219
    Rep Power
    1

    Default Re: No proper soundplaying with Javax.sound.sampled

    Note: I'm not familiar with Java audio, so this is just from the perspective of what works, rather than understanding why it works...

    Looking through similar code at __.si.SimpleSoundPlayer - Java Examples, it appears that the buffer setting, which is based on the format frame size, used for both when opening SourceDataLine and in the buffer writing into SourceDataLine, seems to work well. Give it a try and see if it helps.

Similar Threads

  1. Replies: 1
    Last Post: 06-23-2013, 01:52 PM
  2. javax.sound play midi
    By Dennis in forum Advanced Java
    Replies: 6
    Last Post: 06-08-2010, 04:59 PM
  3. javax sound set volume
    By Dennis in forum Advanced Java
    Replies: 0
    Last Post: 06-08-2010, 03:33 PM
  4. Details using javax.sound.sampled
    By toadaly in forum Advanced Java
    Replies: 0
    Last Post: 04-20-2010, 05:37 AM
  5. javax.sound.sampled
    By carderne in forum New To Java
    Replies: 5
    Last Post: 02-28-2009, 10:12 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •