wood burning stoves 2.0*
The moose likes Swing / AWT / SWT and the fly likes Don't rely on Swing timers? And concurrency Issues Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Don Watch "Don New topic
Author

Don't rely on Swing timers? And concurrency Issues

rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

Hello this is my first post on CR, basically i am a SO user, but din't had expected answers for this questions :/

Suppose timing a word with SwingTimer takes x milliseconds; if we are repeating a task (highlighting a word, like karaoke apps),
i included this code:



Here i should highlight the words as per the time for each word, divide by the number of letters.Suppose if i give 600 millisec for a word "wow"
then each letter should get 600/3 = 200 mili sec. Now i check this milisec, and subtract few milisec, cause of CPU delay...But this is ugly and...!!
Some better way?

Works quiet well, but i am definitely sure i cannot rely on this,as time, length may change! How to overcome this?As change in few millisec may bring disastrous results to me.

At the same time i wonder which techniques dose Karaoke maker&player softwares follow???, Very accurate.

At last, if it's somewhat complicated...Any API's? If there is any for this kind of job...i can R.I.P
Michael Dunn
Ranch Hand

Joined: Jun 09, 2003
Posts: 4632
as mentioned by the OP, here's the conversation at SO (saves repeating what's already been tried/dismissed)

http://stackoverflow.com/questions/14610436/swing-timer-dont-rely-on-swing-timers-question-mark-and-concurrency-issues

Ranganathan Kaliyur Mannar
Bartender

Joined: Oct 16, 2003
Posts: 1076
    
  10

and, Welcome to the Ranch!


Ranga.
SCJP 1.4, OCMJEA/SCEA 5.0.
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
I would imagine it is virtually impossible to keep exactly in sync with the audio without getting some sort of timing sync notifications from whatever is playing the audio.

Now i check this milisec, and subtract few milisec, cause of CPU delay...But this is ugly and...!!

Fudging in a factor for "CPU delay" will never work over any reasonable length of time because of all the other things the CPU may be doing whilst running your app and even if you could get it to work reasonably well it certainly won't work when run on a different spec machine or different OS etc etc.
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
I've just re-read the original post and I'm not sure if my previous answer was right. Are you syncing word highlighting with audio are were you just using that as an example?

If you are just providing a calculated delay between each highlight event then what you should do is calculate the time of the highlight event relative to some fixed point such as when you started the highlighting rather than from the last highlight event. The delays should then be the difference between this calculated time and the current time. Doing this prevents timing errors accumulating.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

@Tony thank you for your reply.

Are you syncing word highlighting with audio are were you just using that as an example?


I set the timings manually.I mean first you have to set the timings by pressing a key.As soon as you hit a key,
i will check the time elapse by 2 successive key press= gives me time taken for a word.
These timings are stored in array.Now i read these timings words by words...and set corresponding
Delay!!
And how to go about checking a fixed point?
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
I set the timings manually.I mean first you have to set the timings by pressing a key.As soon as you hit a key,
i will check the time elapse by 2 successive key press= gives me time taken for a word.
These timings are stored in array.Now i read these timings words by words...and set corresponding
Delay!!
And how to go about checking a fixed point?

Your fixed point will be the first key press.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

I have already taken that into account.I don't think you have understood me properly.
See, i have much problem when i have a word which has more time say 1.2 sec or 1200 milisec or above.
For less time (200 milisec or less ) there is no problem.So some where in the middle, it goes a bit slow.
thats the main thing.Can an SSCCE help?
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47

Definitely.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

Will try to build ASAP.


Here's a bit of my logic...Please forgive me for my bad coding style (a haste production and lot of static fields)




Instructions

Try to edit newh and ColoredTextTest class and add a clip to play a sound file (if possible) so that you can know the delay problem

Please choose a lyrics txt file for line number 53, 313, 323, 324

Press ESC key to highlight the words ...

once you are done, click on OK button on the left.

A new window will open choose play option

logic of auto highligh starts from 670-502(main logic)

Please ask if any problems.
Thank you so much to take this trouble.But i have heard CR people help alot cannot ask this kind of help on SO
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

@Tony Docherty
Please have a look at my SSCCE.But cannot keep it short :/
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37976
    
  22
That is not an SSCCE. That doesn’t help finding your problem with the Timer, and the code from NetBeans’ GUI creator is notorious for its illegibility.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

@Campbell Ritchie

Yeah..but..ok will try to remove the Builder code.
But please try to consider the auto-highlighting logic...
Any suggestions for improvements?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37976
    
  22
It is your responsibility to post things we can actually answer.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

Sorry for the delay..here is an SSCCE




When we see, it will highlight as per the timings given...but if the timing (in millisec) is more, there is some extra time taken...
I hope i'll get some good advice.
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
I hope i'll get some good advice.

I've already told you how to do it ie you need to work out the required time delay relative to a fixed point to stop timing errors accumulating.

Using the timings in your example:
1. When you start the process, record the current millis time in startTime and set totalDelay to 0.
2. Calculate and record the time delay for the first letter of "Test" ie delay = 1000/4.
3. Record the cumulative calculated delay so far ie totalDelay += delay.
4. Calculate the time delay from the start time ie startTime + totalDelay - System.currentTimeMillis().
5. Repeat steps 2 to 4 for each letter.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

Woha! nice logic! will try it out ..Hope it works !
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

@Tony Docherty

As per your advice, i did something...




But getting an invalid delay time...i am not sure with the logic...can you explain me again?
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19651
    
  18

(int)startTime +(int) totalDelay - (int)System.currentTimeMillis() is probably negative. That could be caused by premature truncating. Why don't you cast to int after the calculation?


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

@Rob Spoor

I corrected it, the exception..
but i am not getting the logic behind it.That is why cannot implement it correctly.
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
but i am not getting the logic behind it.That is why cannot implement it correctly.

I'm not sure if I can explain it any simpler than I have already but maybe an example will help.

Lets take the word "Test" and say it needs to be highlighted for 1 second, therefore each letter is highlighted for 250ms.
Doing things the way you originally did them meant that you set a timer for 250ms for each letter but if each cycle actually took 260ms and lets say the 'e' cycle took 400ms (maybe due to GC or something else using CPU cycles) by the end of the word you would have taken 180ms more than you should have. This error will continue to build for each word until the error is so large highlighting is no longer visually in sync.
The way I suggested was rather than repeatedly saying this letter needs to be highlighted for x amount of time, calculate the time for each letter relative to the beginning of the sequence ie T = 250, e = 500, s = 750, t = 1000. So to get the actual time delay you need to add the start time and subtract the current time. To run through the example using the timings I gave above:
So you should be able to see now that the timing for each letter is adjusted to take account of any overrun of time from the previous letter. Of course it is possible that a timing overrun is so great that you have to skip highlighting the next letter (or maybe more than 1) but at least you will remaining broadly in sync.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

@Tony Docherty
Thank you!
As per your logic, i did this :



But can you please tell me why i am getting -ve delay? Everything looks fine to me as per logic!
Sorry for so much trouble :/
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
If the code is correct and you are getting a negative value it's because it is too late to highlight the current letter and so you need to skip that one and go to the next letter.
I suggest you add some print statements in your code to print the start time, current time, totalDelay etc and the difference between the start and current time so you can see what is happening.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

Got it, so Edited:




For one or two lines, it works fine.But after that i dont know what happens, it becomes slow..why?
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
Got it

Err, no you haven't. You definitely don't want to reset the start point after every word or you are going to start to lose sync again.

For one or two lines, it works fine.But after that i dont know what happens, it becomes slow..why?

I've no idea, you need to use a profiler to see what is happening.

I suggest you go back to the previous version of code you posted and add your print statements to that to see what is happening and also post an SSCCE of the code so we can run it and see for ourselves.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

Grr Feeling like a ...!!
Ok..will try to debug, run again...and...will post soon...wish me good luck..
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
When you get frustrated with your code it is generally a sign that you shouldn't have even started coding yet as you don't fully understand the problem.

I suggest that, before you redo your code, you sit down in a quiet place and think about the problem and the solution I have outlined. When you are happy that you think you understand it all write it out all the steps in English (or your first language) then get a pen and paper and work through a few examples following your written instructions step by step. Only now should you start to code.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

@Tony Docherty

yeah..thats true...so i did something.

So now i have got your logic 101%.But again a lil problem:

Here's an SSCCE



I think i am almost there..whats the problem with the loop?
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
Several problems:

1. In the while loop, if you move to the next word you need to re-calculate the 'delay' value for the next word. You may also need to check to see if there actually is a next word.
2. The actual delay value you set the timer to should be totalDelay+startTime-System.currentTimeMillis().
3. I don't think you can change the timers delay value during a timer sequence. I got it working by setting the timer to not repeat (you don't want repeats as you are resetting the delay value each time), setting the initial delay value (not the delay value) and then calling timer.restart().
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

I think at last it's correct:



But to my disappointment, it's still slow.
Insted .setDelay() [setRepeats(true)] was much more faster than this.
Any ideas?
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
But to my disappointment, it's still slow.

What do you mean by it's still slow? Does it miss out letters?
Have you added up all the word times and checked to see if the total time it takes = the sum of the times you have given for each word.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

The song is played in background, so its easy to make out.Its very slow.
With the help of your logic and explaniation, and your EG , i have extended this post on SO with a bounty.
If you are intrested : please have a look at webpage
I'll be very glad if you could suggest your views.This post may be very intresting.
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
I'm not at all impressed that you have taken my posts and copied them wholesale onto another site and claimed them to be your own.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

I just..oh sorry should have edited details about our discussion.I liked your logic, so adopted it.
Will make an edit.Sorry din't realized.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

Edited.
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
Thank you, I think it is only fair that you give credit to and link to CodeRanch as you got the ideas from here.

As to your problem. I suspect your issue is with the times you have allotted to each word. I suggest you time how long it takes to play the music and then count up the times for each word and see if they are the same.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

The logic makes a lot of sense to me.But please notice the answer by @David Kroukamp .It's something similar what i was doing before.
And also he had found something very intresting: "my conclusion is the Swing Timer is actually running faster than it should for each letter and this of course causes an avalanche effect i.e the longer the timer runs the greater the difference will become." .I think this is the difference what we were thinking of.The Sync. (his code) is great.
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
And also he had found something very intresting: "my conclusion is the Swing Timer is actually running faster than it should for each letter and this of course causes an avalanche effect i.e the longer the timer runs the greater the difference will become."
The whole point of doing what I suggested was to remove any accumulative error regardless of whether the timings run faster or slower. If my solution gradually goes out of time either the implementation or the word times are wrong.
I've not time to look at the other code at the moment but If you have found something else that works great. Just make sure you try it on several different machines to make sure.
rohan sethi
Ranch Hand

Joined: Dec 14, 2012
Posts: 34

Thank you Tony for your time and help
Regards
 
 
subject: Don't rely on Swing timers? And concurrency Issues
 
Similar Threads
Making Typing "Game", any tips or pointers before I start?
Abecedarian Testing - Problem with char's and While loops
Java array and String problem
another NullPointerException problem
c++ code not compiling in online compiler?