I have a runnable Game.class and a runnable OggStreamer.class, to allow the music to run in its own separate thread, which I send as a parameter for the Game-class to use. When I run the game from my IDE the OggStreamer always works, but when I've exported it to a .jar-file, it only works 1/3 of the times I start it up. And it's not like the first piece of music doesn't start, and then the next piece of music started will play..it doesn't work at all, until I've started the game a few times.

Has any of you good people had a similar problem? I could understand it if it didn't work at all, which could indicate there was something wrong with the file-references to the music inside the jar-file...but it DOES work, just not consistently outside the IDE. I've seen similar posts around the web, but none have any definitive answers to them. I'm using vorbisspi 1.0.3, jorbis 0.0.15, tritonus_share and jogg 0.0.7 as referenced libraries for playing the ogg-files, if that helps.

EDIT: The ogg-files are running a sample rate of 44100Hz, Stereo, encoded with variable bitrate 128-256 Kbps.They are between 1 and 15mb in filesize.

NOTE: This is my first attempt at Game-programming, and I know it's not very pretty and that I am a sort of newbie There are many things I'd change about the general design, but I'm using this as a project to help me understand the problems I'll encounter when I sit down to design a real framework for my next game. I'm on the third semester of Computer Science, so I've coded quite a lot, just never any games. Mostly apps.

If it works in IDE but doesn't in JAR, then this sounds like a path issue. However you mentioned it sometimes works, which is interesting. I myself have a game that uses OggVorbis and very similar code for my sounds, and it always works on all platforms.

Do the SOPs show that it should play, even though it doesn't? Do you have any more information?

Do the SOPs show that it should play, even though it doesn't? Do you have any more information?

Yes, all the SOPs tell me it's working fine, but frankly they only give info about when I call the methods to start and stop the streamer. Nothing useful about what the problem might be. As you can see, I've tried putting in some JOptionPanes to abruptly tell me if something is wrong with the execution of the code, like not getting a Line, but I've never seen any of them pop out. I'll remove them.

It is not guaranteed that the streamer thread is actually running before the game thread, and thus is ready to work.

Also the inner streamer loop looks suspicious, as it plays the the given url again and again.Threading problem(s), I would say.

Then, modifying the stop flag from outside need some synchronization, or at least the stop boolean must be made volatile.

A threading-issue could very well be the culprit. I'm just very concerned that it always works from the IDE. So strange!Game.init() does nothing with it. The streamer is started almost instantly inside the gameloop, because it plays music on the title-screen.

How would I go about ensuring the musicstreamer-thread is running, before I execute the game-thread? It seems to be running just fine, because if it wasn't, I'd get an error when trying to use it, because I've sent it as a parameter for the game-thread, right?

The thing about the looping...well, I want the music to loop, until it gets another piece of music to play, which is done by calling stop(), and then startLoop(String filenameString), where filenameString is the full Jar-path. This works very well, assuming the streamer works initially.

I will make the stop-boolean volatile. I doubt it'll solve this particular issue, but it will probably solve some issues I'd run into later on. Seems legit

Erhm...I must admit. I can't replicate it anymore. Maybe they fixed it in the newest Java-update or something. I don't understand. I've had this problem for 2½-3 months (ever since I put music in the game), and now all of my old versions seem to work too (I keep a library of Jars from each update). I've even tried overloading the system, playing all sorts of things in the background and running benchmarks while starting the game, and either way the music works. That's so weird! I'll test it on some more systems tomorrow, but for now, the problem has fixed itself.

I would still like to know how to ensure that one thread is running properly, if you would be so kind.

From Executor#execute(): "Executes the given command at some time in the future"Take a look at Thread#isAlive().

stopLoop() can break your streamer. Don't modify private internals from other threads, just switch the stop flag. Make sure to clean up after leaving the outer Runnable loop.

Btw: did you test your error handling ?

Thread.isAlive(), of course I had been pondering about that one, I just wasn't sure.

My first stopLoop() did do what you're suggesting, and the rest of parameters were reset after end of the while(!this.isStop)-loop. Only problem with that, was that the music would be running for a little while before changing. I guess that's because it plays the rest of the buffer before stopping, and what I did to the stopLoop() (as it is now) stops it imediately. But if it might break the streamer, I guess I have to live with that.

What should I clean up after leaving the outer Runnable loop?

About the error handling, what do you mean test? If I catch any exceptions, they're sent to my ErrorHandler, which prints them in an errorlog-file for me. Do you mean if I've tested that I also catch the exceptions in the streamer, and not just the Game-class?

About the error handling, what do you mean test? If I catch any exceptions, they're sent to my ErrorHandler, which prints them in an errorlog-file for me. Do you mean if I've tested that I also catch the exceptions in the streamer, and not just the Game-class?

Here, the error causes are not shown, that is quite bad (Microsoft style)The streamer should not mess with UI stuff like JOptionPane.In case of exception in the lower loop, it keeps on running, opens a new stream, and produces another and another message boxe, If I don't miss anything.

Oh, I didn't mean I'd have to live with the fact that it's breaking. I meant I'd have to live with the fact that it plays for a little while before stopping. Meaning, I'll fix the thing It would be possible to make it run in smaller increments, meaning it'll play less per loop, right?Like, instead of this: byte[] data = new byte[4096];Do this: byte[] data = new byte[2048];

Or am I breaking some rules then?EDIT: Well, doesn't make a difference in the waiting-period with the modifications posted below.

About the error handling, what do you mean test? If I catch any exceptions, they're sent to my ErrorHandler, which prints them in an errorlog-file for me. Do you mean if I've tested that I also catch the exceptions in the streamer, and not just the Game-class?

The streamer should not mess with UI stuff like JOptionPane.In case of exception in the lower loop, it keeps on running, opens a new stream, and produces another and another message box, If I don't miss anything.

Of course you're right. I only put those in there because I was desperate to be thrown from the game when an error occurred, since nothing was ever caught in my previous tries with exceptions. I was so sure the problem was in the streamer-script, that I was oblivious to the fact that my streamer-thread might not be ready to work.

Thank you so very much for your help! Even though it seems to have fixed itself, the main problem anyway, I'll implement the changes you've suggested. It's for my own good, so when it does break for real, I'll know what broke.You're a gem! Here's another appreciation

One more question, though. In the code below, namely the startLoop() method, is it ok to use Thread.sleep(long) in this case? I didn't think it would work, since I'm putting the thread to sleep, while it's waiting for itself to end the current streaming-process and set the url to null. If I set it to sleep, it works, but if I don't put it to sleep, and have an empty while-loop, it stops working the second it tries to start the second piece of music.A simple SOP instead of sleep works too, but that just seems weird.

Fighting threading issues with artificial sleeps is bad.I don't see the intention here, you would implement a blocking start method ?For immediate stopping, how about checking the boolean stop flag in the read/write loop and call line#stop() ?

Fighting threading issues with artificial sleeps is bad.For immediate stopping, how about checking the boolean stop flag in the read/write loop and call line#stop() ?

Well, I did that, and I've changed quite a bit. It seems to be very happy about all my changes. No hick-ups I've tried different things to make startLoop() wait for the streamer to be closed, before introducing a new song to it, but while this approach with a SOP in a while-loop (instead of Thread#sleep) works fine, I doubt this is the method I should be using. I can leave the SOP completely empty (""), but it just doesn't seem right. If I remove the while-loop completely, the game keeps running, but without changing the music.

The looping-boolean is there, because I also have a method that starts a piece of music that doesn't loop.

I've added some comments as to my intentions. I hope you can make sense of it. Otherwise I'm more than happy to elaborate.I've included a read-out of my SOPs at the bottom. Even though they seem to print out quite a lot of lines, the change in music is almost instant.

// if we have called this.stop(), we break out of the streaming while-loopif(stop) break; }

// if song has ended and we're not looping, make sure to stop the streamerif(!looping) stop = true;

// clean-up after stop-call or end of songline.stop();line.close();if(this.decodedStream!=null) this.decodedStream.close();if(this.stream!=null) this.stream.close();

// if stop has been called, we make sure it doesn't try to loop,// and set the url to null, so startLoop() and startMusic() know// that we're ready to run a new song.if(stop){looping = false;url = null; } } catch (IOExceptionio) {// Do nothingSystem.out.println("Line cannot start!"); } } }while (this.looping); }else{System.out.println("Streamer is stopped."); } }

Streamer is stopped.Streamer is stopped.Streamer is stopped.Starting loop with: /snm/sound/oggs/Prelude.oggStreamer is stopped.Streamer is stopped.Streamer is stopped.Streamer is stopped.Streamer is running...Playing song: Prelude.ogg

Going to worldmap...Stopping streamerStarting loop with: /snm/sound/oggs/Worldmap.oggWaiting for streamer to stop 0...many of these...Waiting for streamer to stop 2318Streamer is stopped...many of these...Streamer is stopped.Streamer is running...Playing song: Worldmap.ogg

That's what I meant with blocking. Do not do such loops. Without sleep it will even raise CPU occupation. Here, it might work, but it is bad style. Just pass in your new file and let the streamer decide how to handle it.

If stop is volatile, there is no need to synchronize stop(). That only keeps multiple threads calling stop() simultaneously, while they could still invoke start() for instance.

Yeah, and since I only have the Game-class using the streamer, that doesn't really do anything. And synchronizing both startLoop() and stop() makes the entire thing break down. Plus it doesn't make sense, really.

Just pass in your new file and let the streamer decide how to handle it.

I'd love to, but when I remove the while-loop in startLoop(), it doesn't change the music, because it doesn't have time to shut down the streamer before starting the next loop (setting stop = false again). The stop-flag isn't true long enough for it to shut down the streamer. I'm not sure how I can correctly get around this problem without waiting at some point.

Looks like a candidate for simplification: three all embracing code blocks.Maybe think about extracting methods: it does not look very easy to understand.

Well, the ' if(!this.stop)' loop was only implemented to tell me when the streamer is stopped and when it's running. Merely a debugging-thing.The while(running) keeps the thread alive, and the do-while(looping) makes it loop if it is set to loop.

I don't want it to block; I just want it to wait until the streamer has stopped, and has relinquished its resources, before it starts a new song.

Just a thought: why not make another fresh OggStreamer object and use that? Then you don't have to wait for the first to relinquish anything. You can let the first thread die a natural death by running out of code to execute. If you do wish to reuse it, and to wait for the streamer to finish, you could look into adding a LineListener() to notify you when the line is ready. That is a LOT better than trying to manage thread timing with Sleep commands!

65K is also correct, I think, with the advice about your run() routine having too many loops. Along those lines, you might find the example in the Java sound tutorial interesting--the sample code while loop in SourceDataLine is the pertinent section. The OggStreamer has definite similarities in structure to SourceDataLine playback.http://docs.oracle.com/javase/tutorial/sound/playing.html

"We all secretly believe we are right about everything and, by extension, we are all wrong." W. Storr, The Unpersuadables

Thank you very much for your thoughts. I think I know what I have to do now.

Right now, it is a sort of mix between a single-shot music streamer (opening and closing everything constantly), and a music-streamer that allows for changing of the playing music. Since I'm planning on having some sort of music running at all times, there's no need to reset the line. I just need to stop it, right? Only the stream, decodedStream and formats need to change when a new piece of music is introduced. That should make it much easier to write, so it can comprehend a change in music.

Then I should be able to use the line-object as described in the Java-tutorial you linked, so I can have a LineListener help me start the music with the correct timing. But I'll still have to use some sort of waiting-mechanism. How else would I make the streamer start a piece of music some time in the future, when it is ready?

I don't see the problem in implementing a blocking/waiting-mechanism in a thread, when it is a sort of wingman-thread doing its own thing, other than the obvious cost in CPU-cycles. Is there really no way to wait?No one but the Game-class is depending on it. But there has to be some method of making a function await a certain variable-change. Somehow, the streamer HAS to wait until it is ready, before it starts the next song.

If that is truly impossible, then I guess I have to make a one-shot musicStreamer, which starts a new instance every time there's a new piece of music starting. I'm just wondering if they won't intersect somehow, giving me some other problems...I guess I'll have to try it.

Well, it was a long, hard fight, but I finally did it. Now it can play looping songs, and non-looping songs.The extra all-embracing loops are gone

I solved it with a bunch of your brilliant comments. Mainly, the thought about not using any variables that are used in the streaming-loop, in the startLoop(). Instead, I use some temporary variables in startLoop(), and let the while(running)-loop declare when it is ready to play the next song, and when it's ready, it sets the main-variables to the temporary ones for the next song.

stop() is no longer called from outside the streamer-thread. The startLoop()- and startMusic()-methods call stop() before doing anything else, and prep temporary variables for playing the new song. You CAN however still call stop() from outside the streamer-thread, and it will stop the playback correctly.

Thank you all SO very much! I could not have done this without you! I hope this is a viable solution.

I don't see the problem in implementing a blocking/waiting-mechanism in a thread, when it is a sort of wingman-thread doing its own thing, other than the obvious cost in CPU-cycles. Is there really no way to wait?

I'm in the process of reading Doug Lea's "Concurrent Programming in Java" and just entered the 3rd chapter where he discusses things like "spin waiting" and "latches" and "guards" and such. The book is a classic reference for design-patterns for concurrent threads, and quite relevant despite being over 10 years old.

But, I'm not convinced you need anything so fancy. If you do have the LineListener working, is there really a need to have the new song cue thread spinning, waiting for it? Instead, the LineListener can initiate, can call a method that launches a "readied" new song cue.

It is possible that you don't need to use synchronization. (I don't when I call sound cues, but I don't know the details of your implementation.) If the issue is the "stopped" boolean (in the tutorial example I cited, both "start" and "stop" methods [presumably], and the while loop in the run method use this variable), then setting it to be volatile should suffice.

And as I reread your last post, I'm thinking the Head First "Design Patterns" book might be a good recommendation. It is a much easier/friendlier read than the Lea book which is more advanced. It talks about the very things you mention, such as the best way to pass parameters between threads. The LineListener idea comes in part as a variation of the Observer or Subscriber pattern which is discussed in that book.

"We all secretly believe we are right about everything and, by extension, we are all wrong." W. Storr, The Unpersuadables

If a thread enters a synchronized method, it aquires a lock for the whole object. Thus, other threads are blocked from entering any synchronized method of the same object, as well as from locking the object directly.

If you only synchronize startLoop() and startMusic() then it will never be possible for two threads executing those methods at the same time. As those methods are usually not invoked from the streamer thread, it would have no effect on it - not before you work with the same lock from inside the streamer loops.

Or just use a volatile boolean flag.Or synchronize a (non-volatile) boolean flag in start, stop and in the streamer loop.

It is possible that you don't need to use synchronization. (I don't when I call sound cues, but I don't know the details of your implementation.) If the issue is the "stopped" boolean (in the tutorial example I cited, both "start" and "stop" methods [presumably], and the while loop in the run method use this variable), then setting it to be volatile should suffice.

It works well, and acts the exact same way, whether I synchronize the start and/or stop-methods or not, so it seems you're right. Thanks for clarifying.

And as I reread your last post, I'm thinking the Head First "Design Patterns" book might be a good recommendation. It is a much easier/friendlier read than the Lea book which is more advanced. It talks about the very things you mention, such as the best way to pass parameters between threads. The LineListener idea comes in part as a variation of the Observer or Subscriber pattern which is discussed in that book.

Thanks a lot. I'll see if I can find some place to buy it. I'm very much into getting to know this whole threading-thing. I'm building a few programs, such as an elevator-simulator, to learn more about it. I'm sure this book will become very handy!

If a thread enters a synchronized method, it aquires a lock for the whole object. Thus, other threads are blocked from entering any synchronized method of the same object, as well as from locking the object directly.

If you only synchronize startLoop() and startMusic() then it will never be possible for two threads executing those methods at the same time. As those methods are usually not invoked from the streamer thread, it would have no effect on it - not before you work with the same lock from inside the streamer loops.

Or just use a volatile boolean flag.Or synchronize a (non-volatile) boolean flag in start, stop and in the streamer loop.

OK, so I can either do what I've done so far, just have the stop-boolean be volatile, or I could make it non-volatile and synchronize the start and stop methods and the streamer-loop? How would I make it synchronized in the streamer-lopp? Just synchronize the entire run()?

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org