• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Application doesn't quit -- MiniMiniMusicApp sample from Head First Java

 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I don't find the reason why MiniMiniMusicApp hangs. I tried to add a player.close() after looking in the API docs, but that doesn't help :-/ Any ideas what goes wrong?

Here's the source:




import javax.sound.midi.*;
import javax.sound.midi.Sequence;


public class MiniMiniMusicApp {

public static void main(String[] args) {
MiniMiniMusicApp mini = new MiniMiniMusicApp();
mini.play();
}

public void play() {
try {
Sequencer player = MidiSystem.getSequencer();
player.open();

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

Track track = seq.createTrack();

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

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

player.setSequence(seq);
player.start();
player.close();

}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
 
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What page is this application found in Head First Java ? I have the book, so I'd like to try typing the code in myself and compiling.
 
Marshal
Posts: 79153
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Have you any idea where it hangs?
It hasn't got multiple threads, has it?
Have you tried it on a full-blown IDE? That means NetBeans or Eclipse or similar. Put it on an IDE, set a breakpoint somewhere, and then follow its execution with the debugger. See how far it gets and where it hangs.

See whether that gives you some idea what is going wrong, then come back.

I am not familiar with these musical programs myself; maybe somebody else can help better.
 
Ranch Hand
Posts: 4632
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
don't know if this is the best way, but it seems to work OK on this app.

 
Peter Karp
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for all the answers. The example is from page 342 in Head First Java (2nd edition).

_I_ haven't created a new thread, but I'm not sure if this might be the answer to the question. I have used a text editor and Netbeans. There is no difference. The program itself runs, but it will not stop, so setting a breakpoint won't help. I found a typo in my first posting (a instead of b), but that doesn't effect the problem.

I finally found the source code for the book and in the file there are some important differences to the printed version. I have added a /////new comment in the added lines.


// --------- code begin --------------

import javax.sound.midi.*;


public class MiniMiniMusicApp { // this is the first one

public static void main(String[] args) {
MiniMiniMusicApp mini = new MiniMiniMusicApp();
mini.play();
}

public void play() {

try {

// make (and open) a sequencer, make a sequence and track

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

Sequence seq = new Sequence(Sequence.PPQ, 4);
Track track = seq.createTrack();

// now make two midi events (containing a midi message)
MidiEvent event = null; //////////new

// first make the message
// then stick the message into a midi event
// and add the event to the track

ShortMessage a = new ShortMessage();
a.setMessage(144, 1, 44, 100);
MidiEvent noteOn = new MidiEvent(a, 1); // <-- means at tick one, the above event happens
track.add(noteOn);

ShortMessage b = new ShortMessage();
b.setMessage(128, 1, 44, 100);
MidiEvent noteOff = new MidiEvent(b, 16); // <-- means at tick one, the above event happens
track.add(noteOff);

// add the events to the track

// add the sequence to the sequencer, set timing, and start
sequencer.setSequence(seq);

sequencer.start();
Thread.sleep(1000); /////////new
sequencer.close(); /////////new
System.exit(0); ////////new
} catch (Exception ex) {ex.printStackTrace();}
} // close play

} // close class


// --------- code end --------------

The first difference is
MideEvent event = null;
which is _not_used anywhere in the program!?

Then later
Thread.sleep(1000); /////////new
sequencer.close(); /////////new
System.exit(0); ////////new
are added.

Threads are not explained at this point in the book, but without the sleep()-method the piano tone can not always be heard when one closes the sequencer. If the sequencer is not closed the program will not terminate, neither on Windows XP nor on OS X.

After forcing the thread to sleep so the tone can be heard the sequencer is closed. I found this myself by looking in the API docs. And now comes an interesting point I found out.

sequencer.close() is sufficient for the program to stop itself when I run the program in Windows XP. But when running the program on OS X (with latest Java 5) the program will not terminate. One has to add
System.exit();

I'm somewhat confused now about the different behavior and the additional System.exit() needed on OS X.

It took me quite some time to figure these things out. That's not the real problem, but IMO this wasn't neccessary. There's an errata for the book which fixes errors, but this wrong listing is not mentioned, allthough I found two postings on the Javaranch forum which asked a similar question to mine. One was not answered at all. The other was

https://coderanch.com/t/399099/java/java/stop-music

I twice e-mailed Kathy and Bert (the authors) with suggestions and questions, but got no answer :-( I hoped that a here -- the official unofficial "Head First Java" homepage -- would be a place where additions to the book could be posted or better could be organized in a Wiki. This would be greatly beneficial for the readers of the book.

If someone knows how to get through to Kathy and Bert I like to get a pointer (not a reference here ;-)

Thank you for taking the time to read and answer my post.

Greetings from germany
Peter
 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for you guys' input. I couldn't even get the darn code to compile the way it was written in the book and even from their printed out code from wickedlysmart.com.

I kept getting the following errors.

MiniMiniMusicApp.java:20: cannot find symbol
symbol : variable PPQ
location: class Sequence
Sequence seq = new Sequence(Sequence.PPQ, 4);
^
MiniMiniMusicApp.java:20: internal error; cannot instantiate Sequence.<init> at
Sequence to ()
Sequence seq = new Sequence(Sequence.PPQ, 4);
^
MiniMiniMusicApp.java:22: cannot find symbol
symbol : method createTrack()
location: class Sequence
Track track = seq.createTrack();
^
MiniMiniMusicApp.java:34: cannot find symbol
symbol : method setSequence(Sequence)
location: interface javax.sound.midi.Sequencer
player.setSequence(seq);


I see that some of you guys also imported the javax.sound.midi.Sequence class explicitly and that made it compile and run (it never terminated, but the solution to that problem works as well).

But my question is why would have to import the javax.sound.midi.Sequence class explicitly if I already imported javax.sound.midi.*? Doesn't the * automatically include everything in that package?

In other words, isnt the code below redundant? And if so why do I have to do this to get the code to compile?

import javax.sound.midi.*;
import javax.sound.midi.Sequence;

[ September 26, 2006: Message edited by: Bobby Roberts ]
 
Greenhorn
Posts: 1
Eclipse IDE Firefox Browser Windows XP
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am having the same issue. Both the MiniMiniMusicApp and the MiniMusicCmdLine applications run, play a note, and then just sit there. The program never terminates, and when I put some extra lines of System.out to find the hold-up, it just showed that the program does indeed complete main(). At that point there's nothing left to process, so what could keep it open?
 
Ranch Hand
Posts: 143
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@bobby, the code isn't redundant... code you use will leave off where you imported (example: Sequencer comes after javax.sound.midi.(Sequencer), so if you say javax.sound.midi.*, anywhere in your code you can say Sequencer, and really all the compiler does is add javax.sound.midi. right before it. so you say Sequencer player = MidiSystem.getSequencer(); and since you imported javax.sound.midi.*, the compiler automatically (invisibly) changes that to say javax.sound.midi.Sequencer player = javax.sound.midi.MidiSystem.getSequencer()
hope that made sense
So when you have to import javax.sound.midi.Sequence, it looks to me like somewhere you just said PPQ instead of Sequence.PPQ, and since PPQ extends javax.sound.midi.Sequence, the problem goes away when you import that.
As far as the program not terminating, I'm using Eclipse IDE, and had the same problem. I think I fixed it though... right after player.start(), I put Thread.sleep(1000) and then I put player.close(). I think because the player was never closed, the program never terminates. and Thread.sleep(1000) just makes sure 1000 milliseconds pass before the player closes. You can put in whatever you want, just make sure it's enough time to hear the music play before the program closes your player. Thread.sleep(1) will close it so fast you will hear nothing. Hope that helps!
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The way I solved it was by creating a while loop:



Using the isRunning() method it is possible to see when the sequencer stops playing. When the sequencer stops the while loop ends and the rest of the code runs closing the sequencer.
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
set sequencer's loop count to 0.
sequencer.setLoopCount(0);
 
Campbell Ritchie
Marshal
Posts: 79153
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch

Is that a different way to exit from that shown in the book?
 
look! it's a bird! it's a plane! It's .... a teeny tiny ad
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic