Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to loop a Midi sequence Java

Tags:

java

loops

midi

I am fairly new to Java programming, and would like to know how to properly loop a MIDI sequence whilst a game is playing. I have some code and I know that I should use setLoopCount() in order to do it but am unsure how to implement it.

Here is the code I have so far

Sequencer myseq; 
myseq = MidiSystem.getSequencer(); 
myseq.open();
File myMidiFile = new File("sounds/music.midi");
Sequence supersequence = MidiSystem.getSequence(myMidiFile);
myseq.setSequence(supersequence);
myseq.start(); 

Any help is appreciated.

like image 230
Wnt2bsleepin Avatar asked Nov 14 '11 22:11

Wnt2bsleepin


4 Answers

I think this could help you:

myseq.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
like image 130
Vladislav Bauer Avatar answered Nov 07 '22 16:11

Vladislav Bauer


You don't need an external method to loop a Midi Sequence. Based on your code above you should use the following:

import java.io.*;
import java.util.*;
import javax.sound.midi.*;
public class Midiplayer{
        public static void main(String[] args) throws InvalidMidiDataException, IOException, MidiUnavailableException {
            //Create scanner object
            Scanner in= new Scanner(System.in);

            //Request Loop Count
           System.out.println("How Many Loops?");
           int loops= in.nextInt();

           //Retrieve the MIDI File
           System.out.println("Please type in the exact location of your midi:");
           String fileAndLocation= in.next();
           Sequence myseq = MidiSystem.getSequence(new File(fileAndLocation));

           // Create a sequencer for the sequence
           final Sequencer sequencer = MidiSystem.getSequencer();
           sequencer.open();
           sequencer.setSequence(myseq);
           sequencer.setLoopCount(loops);

          //Exit message
          System.out.println("Press 'ctrl' and 'c' on keyboard simultaneously to end sequence and program.");
          // Start playback, repeats automatically
         sequencer.start();
          //Don't forget to close reader
          in.close();
     }
}

Do note though that the above does not create an infinite loop. My guess is that you need to set "loops" to 1 and increment it within a while statement that tests like the following:

while(loops>0){
    //Start/restart Midi Sequence
    sequencer.start();
    //increment loops
    loops++;
    //Re-instantiate .setLoopCount()
    sequencer.setLoopCount(loops);
 }

If the loop determination is user based, then have the user input 0 in in the place of infinity so that:

if(loops==0){
    //Declare and instantiate a boolean to test
    boolean infinite=true;
    //Make loops equal to 1 so that the later while statement initiates and repeates
    loops++;
    //Re-instantiate .setLoopCount()
    sequencer.setLoopCount(loops);
}
if(infinite==true){
    while(loops>0){
        //Start/restart Midi Sequence
        sequencer.start();
        //increment loops
        loops++;
       //Re-instantiate .setLoopCount(), thus always adding a loop to setLoopCount(), making it infinite because loops will always be greater than zero
       sequencer.setLoopCount(loops);
    }
}
else{
   //Starts sequence and repeats according to defined loop while loops>0 (so long as you have an error cather for loops<0)
   sequencer.start();
}

To end the user interface for an infinite loop, at some point remind the user that in COMMAND PROMPT, 'ctrl'+'c' quits the program.

I hope this helps a lot of people (I based it off my own midi program, which works). However, do note that anything about an infinite loop I have not yet tested. It is only theory based on heavy analysis of the situation and the available classes and variables. Do note that .setLoopCounter() is present in Java 1.4.1 and on. Thank you and I am glad to help.

like image 2
Midimistro Avatar answered Nov 07 '22 16:11

Midimistro


There is a good (but old) book about java game development: http://www.brackeen.com/javagamebook/ The source code is available at the website. Check out the chapter 4... In the SoundManagerTest.java file, you will find an example about looping midi sounds. I hope it is not too outdated.

Btw: There seems to be an issue with MIDI looping and Java 5. Have a look at the end of the page:

Sound Issues in Java 5 and Java 6.

Sun updated the sound engine in Java 5 which led to a few problems. Here are the fixes: MIDI music doesn't loop. Add this line (in bold) in MidiPlayer.java:

public void meta(MetaMessage event) {
  if (event.getType() == END_OF_TRACK_MESSAGE) {
   if (sequencer != null && sequencer.isOpen() && loop) {
       sequencer.setTickPosition(0);
       sequencer.start();
   }
  }
}
like image 1
Wintermute Avatar answered Nov 07 '22 16:11

Wintermute


Add a listener for the end of the song like this:

myseq.addMetaEventListener(new MetaEventListener() {
    public void meta(MetaMessage msg) {
        if (msg.getType() == 0x2F) { // End of track
            // Restart the song
            sequencer.setTickPosition(0);
            sequencer.start();
        }
    }
});

This is also useful if you want to create a playlist and have it continue to the next song.

like image 1
xthexder Avatar answered Nov 07 '22 17:11

xthexder