首先让我感到震惊的是:System.currentTimeMillis()
我认为非常准确,给出了long
值,以及SwingTimers
请求int
参数的位置;它是什么意思?不要认为SwingTimers
是准确的吗?
2)假设用SwingTimer
定时一个字需要x毫秒;如果我们重复一项任务(突出显示单词,如卡拉OK应用程序),我会包含以下代码:
/*see the time taken for each letter*/
int tik=(int) delay / words[index].length();
/* make adjustment(subtract few millisecs) as per the time taken by each word*/
if(tik <69)
timer.setDelay((int) (delay / words[index].length())-3);
if(tik >=69&&tik<=149)
timer.setDelay((int) (delay / words[index].length())-6);
else if(tik <=150)
timer.setDelay((int) (delay / words[index].length())-9);
else if(tik >150)
timer.setDelay((int) (delay / words[index].length())-100);
工作安静很好,但我绝对肯定我不能依赖这个,因为时间,长度可能会改变!如何克服这个问题?因为几毫秒的变化可能给我带来灾难性的后果。
3)同时我想知道卡拉OK制造商和播放器软件采用哪种技术?非常准确。答案 0 :(得分:6)
与此同时,我想知道卡拉OK制造商和卡拉OK制造商采用哪种技术?播放器软件如何?
我猜卡拉OK软件有一个输入节拍和时间签名的引擎,并且音符持续时间(整个音符,半音符,四分音符等)与歌词一起输入。
引擎计算每季度音符的毫秒数,并根据计算一次显示一个字母。
我怀疑必须手动输入音符持续时间,但如果引擎收听音乐并确定音乐的音符持续时间,则会非常有效。
保持完美时间
正如您已经确定的那样,Thread.sleep()和Swing计时器不能保持完美的时间。
如果你想要精确的时间,你将不得不建立自己的计时器。这是一个版本。
public void moreAccurateTimer(int period) { // Sleep time in
// milliseconds
long beforeTime, timeDiff, sleepTime;
beforeTime = System.currentTimeMillis();
boolean running = true;
while (running) {
doStuff();
timeDiff = System.currentTimeMillis() - beforeTime;
sleepTime = period - timeDiff;
if (sleepTime <= 0L) { // Even if doing stuff took longer than
// period
sleepTime = 5L; // sleep some anyway
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
}
beforeTime = System.currentTimeMillis();
}
}
答案 1 :(得分:6)
基于计算机/操作系统时钟计时的方法,无论时间源的准确程度如何 - 通常都存在缺陷,尽管在某些情况下,时间不正常可能会有效需要准确无误。
一种聪明的方法是从你想要同步的东西中获取时间信息 - 所以对于卡拉OK,从播放音频中获取时间并响应。这种方法自然避免了常见的麻烦:处理(用户启动)音频播放中的暂停以及音频和系统硬件之间的微小时间偏差。
答案 2 :(得分:2)
我们必须接受我们永远无法准时到达;我们可以早或晚。
多年来一直考虑,每秒24帧已经制作了连续看电影。而现在,我们已经升至59 FPS?因此,+ / - 20ms左右对人类来说是不明显的。
如果您的应用程序需要在电子级别上进行精确计时,请考虑调度和并发性可能会导致各种问题。当我在Y2K周围的C ****** e工作时,这是一个非常重要的事情,并且经常受到视频设置的影响等等。时序相关问题的伪像显示为延迟,故障和音调不准确。
假设我们使用while循环方法(原谅我的伪代码):
/ ** psuedocode ** /
something.idLikeToTriggerNow();
time_now = time_then = system.getMicroseconds();
while(time_now&lt; time_then + 1000){
// NOP
time_now = system.getMicroseconds();
}
something.idLikeToTrigger1msLater();
/ **结束psuedocode ** /
这只能保证您在进入后一毫秒之前不会离开。但是,你可能会以某种方式中断获取系统时间,并在半秒后退出,而不是因为Norton Antivirus。我的观点与Java无关,尤其如此。此外,即使while循环工作正常,下一个操作可能会被你的NVidia驱动程序延迟,也许,这可能比你在宏观计划中的Java应用程序具有更高的优先级。
在Java中是否有一种方法可以使两个事件更容易相隔1毫秒,容差可能为+/- 100us?