javaaudiomidisynthesizer

MIDI Java generates messed sound


I've been working in a project where I need to manipulate each instrument in a MIDI file in java. Then I decided to get each MIDI Event from each track from the Sequence and send it to a Receiver. After that the thread waits the time each tick lasts then do it again with the next tick. The problem is: the sound of the instruments gets very messed, as well as their order. I tried to execute each track alone too, but it's still messed! The code:

    Sequence    sequence        = MidiSystem.getSequence(new File(source));
    Synthesizer synth           = MidiSystem.getSynthesizer();

    //Gets a MidiMessage and send it to Synthesizer
    Receiver    rcv             = synth.getReceiver();

    //Contains all tracks and events from MIDI file
    Track[]     tracks          = sequence.getTracks();
    synth.open();

    //If there are tracks
    if(tracks != null)
    {
        //Verify the division type of the sequence (PPQ, SMPT)
        if(sequence.getDivisionType() == Sequence.PPQ)
        {
            int     ppq         = sequence.getResolution();
            //Do the math to get the time (in miliseconds) each tick takes 
            long    tickTime    = TicksToMiliseconds(BPM,ppq);
            //Returns the number of ticks from the longest track
            int     longestTrackTicks   = LongestTrackTicks(tracks);

            //Each iteration sends a new message to 'receiver'
            for(int tick = 0; tick < maiorTick ; tick++)
            {   
                //Iteration of each track
                for(int trackNumber = 0; trackNumber < tracks.length; trackNumber++)
                {
                    //If the number of ticks from a track isn't already finished
                    //continue
                    if(tick < tracks[trackNumber].size())
                    {
                        MidiEvent ev = tracks[trackNumber].get(tick);
                        rcv.send(ev.getMessage(),-1);
                    }
                }
                Thread.sleep(tickTime);
            }

        }
    }
    synth.close();

Solution

  • As ntabee said, Track.get(n) returns the nth event in the track; to get events by time, you have to compare the events' times manually.

    Furthermore, Thread.sleep() is not very precise and can wait for a longer time than desired. These errors will add up.


    To change MIDI messages in real time, tell the sequencer to play to your own Receiver, then do whatever you want to the events and pass them on to the 'real' Receiver.