Question

I am having trouble with creating a very small music player following the HeadFirstJava recipe. I followed the code in the book but it still has some bugs... When I first compiled it it gave me this error:

Dez 15, 2013 4:13:02 PM java.util.prefs.WindowsPreferences 
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.

After googling the error I found out that I should create HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs and also give full permision for JavaSoft on regedit. That did solve the problem but only partially. The code compliles, the sound is made by the computer but the program will not close util I hit CTRL + C. Here is the code:

import javax.sound.midi.*;//importam pachetul sound.mini 

public class MiniMiniMusicApp {

public static void main (String [] args) {

  MiniMiniMusicApp mini = new MiniMiniMusicApp();
  mini.play();
} //inchidem main

public void play() {

  try {

    Sequencer player = MidiSystem.getSequencer();
    player.open();

    Sequence seq = new Sequence(Sequence.PPQ, 4);

    Track track = seq.createTrack();

    //ShortMessage first = new ShortMessage();
    //first.setMessage(192, 1, 102, 0);
    //MidiEvent noteOn1 = new MidiEvent(first, 1);
    //track.add(noteOn1);


    ShortMessage a = new ShortMessage();
    a.setMessage(144, 1, 44, 100);
    MidiEvent noteOn = new MidiEvent(a, 1);
    track.add(noteOn);

    ShortMessage b = new ShortMessage();
    b.setMessage(128, 1, 44, 100);
    MidiEvent noteOff = new MidiEvent(b, 16);
    track.add(noteOff);

    player.setSequence(seq);

    player.start();

  } catch (Exception ex) {
    ex.printStackTrace();
  }
} //inchidem play
} 

I would like to mention that I am not using any GUI and that I am a total novice. Any help would be appreciated. Thank you.

Was it helpful?

Solution

The MIDI sequencer is a special thread that runs in the background. As long as it is active (or, in fact, any non-daemon thread is active), Java will not exit on its own.

Try adding this after the player.start(); line:

Thread.sleep(5000);
player.close();

OTHER TIPS

Command Prompt doesn't support the multi-programming. So when you run the above program, the program is in the running state, after it's play() method and wait for the some event to occur(like another Framed based program in java). you can write System.exit() after putting some delay(so that your voice would come). Currently you are killing the process from the DOS.

The docs [MidiDevice.open()] for player.open() says:

An application opening a device explicitly with this call has to close the device by calling close. This is necessary to release system resources and allow applications to exit cleanly.

So you may use a try-with-resource-statement (Java 7+) to close it safely and wait gracefully (at the end of your try-block) for your track to finish:

try (Sequencer player = MidiSystem.getSequencer()) {
    ...

    while (player.isRunning()) {
        Thread.sleep(100);
    }
} catch (Exception ex) {
    ex.printStackTrace();
}

Prior to Java 7 you would have called player.close(); in a finally-block attached to your try-catch-statement.

Note: The access warning for the root users Preferences could have been suppressed by:

PlatformLogger.getLogger("java.util.prefs")
        .setLevel(PlatformLogger.Level.SEVERE);

To solve the first error, just run your compiler as administrator.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top