Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 2 of 2

Thread: Playing created midi sounds simultaneously

  1. #1
    Junior Member
    Join Date
    Sep 2014
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Playing created midi sounds simultaneously

    I have a problem and I hope to get here an answer. I want to create many midi sounds without saving them on the client pc, because this should work in an Applet. The creating sound part isn't the problem, the problem is to play these sound simultaneously. I searched now more than 3 days for an asnwer, but couldn't find one that helped me.

    Here is what i have at the moment:
    My Sound (found part of it in an open-spurce project):
    import java.io.*;
    import javax.sound.sampled.*;
    import java.net.URL;
    import javax.sound.*;
     
    public class Sound {
     
        /**
         *  The sample rate - 44,100 Hz for CD quality audio.
         */
        public static int channels = 2;
     
     
     
     
        public static final int SAMPLE_RATE = 44100;
     
        private static final int BYTES_PER_SAMPLE = 4;                // 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;
     
     
        static SourceDataLine[] line = new SourceDataLine[channels];    // to play the         sound
        private static byte[][] buffer = new byte[2][];         // our internal buffer
        private static int i = 0;             // number of samples currently in internal buffer
        private static int i2 = 0;
     
        public static Mixer mainmix;
     
        // static initializer
       public Sound()
       {
           init();
       }
     
        // open up an audio stram
        static void init() {
            try {
     
                Mixer.Info[] mixerinfo = AudioSystem.getMixerInfo();    
     
                mainmix = AudioSystem.getMixer(mixerinfo[0]);
     
                Line.Info lineinf[] = mainmix.getSourceLineInfo();
     
                // 44,100 samples per second, 16-bit audio, mono, signed PCM, little Endian
                AudioFormat format = new AudioFormat((float) SAMPLE_RATE, BITS_PER_SAMPLE, 2, true, false);
                DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
     
     
                line[0] = (SourceDataLine) mainmix.getLine(info);
                line[1] = (SourceDataLine) mainmix.getLine(info);
                //line[2] = (SourceDataLine) mainmix.getLine(info);
     
                Control[] linectrl = line[0].getControls();
                Control[] linectrl1 = line[1].getControls();
     
     
     
                //line = (SourceDataLine) AudioSystem.getLine(info);
                line[0].open(format, SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE);
                line[1].open(format, SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE);
               // line[2].open(format, SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE);
                //line[1].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 diveded because we can't expect the buffered data to line up exactly with when
                // the sound card decides to push out its samples.
                buffer[0] = new byte[SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE];
                buffer[1] = new byte[SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE];
                //buffer[2] = new byte[SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE];
            } catch (Exception e) {
                System.out.println(e.getMessage());
                System.exit(1);
        }
     
     
            // no sound gets made before this call
            line[0].flush();
            line[0].start();
            line[1].flush();
            line[1].start();
    }
     
        /**
         * Close standard audio.
         */
        public final void close() {
            line[0].drain();
            line[0].stop();
     
           line[1].drain();
           line[1].stop();        
        }
     
        public final 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[0][i++] = (byte) s;
            buffer[0][i++] = (byte) (s >> 8);   // little Endian
            buffer[0][i++] = (byte) s;
            buffer[0][i++] = (byte) (s >> 8);   // little Endian
     
     
            // send to sound card if buffer is full        
            if (i >= buffer.length) {
                line[0].write(buffer[0], 0, 4);
     
                i = 0;
            }
        }
     
        public void play(double[] input) {
            for (int i = 0; i < input.length; i++) {
                play(input[i]);
     
            }
        }
     
        public final void play(double in, double an) {
     
     
            // 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[1][i++] = (byte) s;
            buffer[1][i++] = (byte) (s >> 8);   // little Endian
            buffer[1][i++] = (byte) s;
            buffer[1][i++] = (byte) (s >> 8);   // little Endian
     
            // clip if outside [-1, +1]
            if (an < -1.0) an = -1.0;
            if (an > +1.0) an = +1.0;
     
            // convert to bytes
            short a = (short) (MAX_16_BIT * an);
            buffer[0][i2++] = (byte) a;
            buffer[0][i2++] = (byte) (a >> 8);   // little Endian
            buffer[0][i2++] = (byte) a;
            buffer[0][i2++] = (byte) (a >> 8);   // little Endian
     
            // send to sound card if buffer is full        
            if (i >= buffer.length) {
     
                line[1].write(buffer[1], 0, 4);
                line[0].write(buffer[0], 0, 4);
     
     
                i2 = 0;
                i = 0;
            }
        }
     
     public void play(double[] input,double[] input1) {
            for (int i = 0; i < input.length; i++) {
                play(input[i],input1[i]);
     
            }
        }
    }

    This is where i create my sound:
    public class Note {
        private final int SAMPLE_RATE = 44100;
        private double[] tone;
        public Note(double hz, double duration, double amplitude)
        {
            int N = (int) Math.round(SAMPLE_RATE * duration);
            tone = new double[N+1];
            for (int i = 0; i <= N; i++)
                tone[i] = amplitude * Math.sin(2 * Math.PI * i * hz / SAMPLE_RATE);
        }
     
        public double[] getTone()
        {
            return tone;
        }
     
    }

    Here my Temporary Main class:
     
    public class test {
    public static void main(String[] args) {
            Sound sound = new Sound();
     
            //Note(hz (freg),seconds (duration),vol(amplitude))
            Note note1 = new Note(50.0,3.0,6);
            Note note2 = new Note(10.0,3.0,6);
            sound.play(note1.getTone(),note2.getTone());
        }
     
    }

    I thought about Threads but I don't think if I have 20-30++ Thread, that won't be simultaneously and the perfomance wouldn't be that good. I saw examples were they played sounds simultaneously, but then they loaded the sounds from a file and when I tried it with midi it didn't work.


  2. #2
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,520
    My Mood
    Mellow
    Thanks
    215
    Thanked 697 Times in 679 Posts

    Default Re: Playing created midi sounds simultaneously

    Welcome to the forum! Thanks for taking the time to learn how to post code correctly. If you haven't already, please read this topic to learn other useful info for new members.

Similar Threads

  1. Why can't I play sounds?
    By sakonpure6 in forum Java Theory & Questions
    Replies: 4
    Last Post: December 11th, 2013, 08:26 AM
  2. Replies: 1
    Last Post: October 1st, 2013, 05:07 AM
  3. Can't simultaneously run two threads??
    By shadysback in forum Threads
    Replies: 15
    Last Post: December 10th, 2012, 04:33 PM
  4. Simultaneously running statements
    By CrashOverride in forum Java Theory & Questions
    Replies: 2
    Last Post: October 19th, 2012, 02:32 PM
  5. How to use PrintSteam and BufferedReader Simultaneously
    By bigmac025 in forum What's Wrong With My Code?
    Replies: 2
    Last Post: March 29th, 2011, 07:30 AM

Tags for this Thread