【问题标题】:How to make a Timer accurate? (Flash / ActionScript 3.0)如何使计时器准确? (Flash / ActionScript 3.0)
【发布时间】:2011-05-10 19:01:44
【问题描述】:

我正在使用以下方法在 X 次/分钟内发送声音(X 是通过 bpm 确定的,它是一个 NumericStepper 对象)

var mainTimer:Timer = new Timer(60 / (bpm.value * 1000),0);
mainTimer.addEventListener(TimerEvent.TIMER, fl_TimerHandler,false, 0, true); 
mainTimer.start();

function fl_TimerHandler(event:TimerEvent):void
     {
        metroTransform.volume = vol;
        flash.media.SoundMixer.soundTransform = metroTransform;
        metroChannel = metro.play();
        mainTimer.delay = 60 / bpm.value * 1000;
      }

根据这个http://www.metronomeonline.com/ 声音不是很好。有什么办法可以解决我遇到的这个问题吗?

我得到的输出文件的路径:http://conatur.net/metroBig.swf

【问题讨论】:

  • 您是否尝试禁用音量转换?每次调用函数时,您都在调用 flash.media.SoundMixer,您应该创建一个对象并在函数外部实例化它,就像 metroTransform 一样。这里只是一个猜测,但如果您使用的帧速率非常低,可以尝试提高它。
  • 这里有很多问题。第一个也是最致命的是 Flash 存在无法治愈的声音延迟问题,因此即使您的代码已经完善,您仍然无法确保声音完全按提示播放。 @Valkie 有你一半的答案,但另一半只是你永远无法真正“治愈”延迟问题的症状。

标签: flash actionscript-3 actionscript timer


【解决方案1】:

http://cookbooks.adobe.com/post_Accurate_timer-17332.html 可能会对您有所帮助。

问题
计时器类的 2 个事件之间的延迟取决于许多因素(fps、内存、播放的影片剪辑结束,即)。定时器类属性延迟设置的超时时间只是近似值,因此需要有一种方法来提高定时器的准确性。

解决方案
我提高准确性的解决方案是扩展计时器类并强制计时器根据自定义属性准确地进行更多周期。这样,定时器的 2 个事件之间的延迟将设置为延迟 - + 准确 /2。因为事件的上升取决于许多因素,所以 2 个事件之间的真正延迟来自:延迟 - 准确/2 到 Flash 播放器的下一个触发事件。

【讨论】:

    【解决方案2】:

    嗯,延迟值不应该是

    60000 / bpm.value
    // with BPM = 80 we have 60000/80 = 750
    

    而不是

    60 / (bpm.value * 1000)
    // with BPM = 80 we have 60/80000 = 0.00075
    

    正如文档中描述的时间延迟值:

    delay:Number — 定时器之间的延迟 事件,以毫秒为单位。延迟更低 超过 20 毫秒不是 受到推崇的。定时器频率为 限制为每秒 60 帧, 表示延迟低于 16.6 毫秒会导致运行时问题。

    我想 750 毫秒比 0.00075 毫秒更合适。

    不过,当我测试您的 SWF 并将 BPM 设置为 60 时,每秒听起来都没有问题,所以 我猜 bpm.value 不是它看起来的样子


    无论如何,当我在两个选项卡(或窗口)上打开您的 swf 和“metronomeonline”网站并将它们设置为相同的 BPM 时,它们听起来对我来说是同步的。

    【讨论】:

    • 你听了一段时间了吗?此外,当 bpm 高于 130 时,问题会变得更糟
    • 130 BTM 大约是 460 毫秒,所以它远高于 20 毫秒的限制,应该不是问题。然而,几乎所有语言中的 AS3 中的计时器都是基于主循环的,并且有时循环比其他循环花费的时间更长(出于技术原因)......这就是为什么很难拥有一个非常高精度的计时器,尤其是对于像 AS3 那样包装在其他语言之上的语言也是如此。我认为时间事件还可以。
    • 验证计时器事件是否正常的最佳方法是不要将显示计数器重置为 5,然后将给定的 BTM(比如 180)设置为相对“长”的时间(比如5分钟,所以用手表很容易计数),最后将得到的计数器值除以总时间(以分钟为单位)。因此,您将知道它是否被触发了很多时间(180 BPM 的 5 分钟应该给出 900)。您的结果越接近预期结果,您的计时器事件就越精确......如果它足够精确,则意味着问题来自于没有一直播放的声音。
    • 每次抽动播放的声音有多长(以毫秒为单位)?当您致电下一个 metro.play(); 时,您的声音可能并不总是完成并重置(我不记得确切的声音在 AS3 中是如何工作的,我现在没有任何要测试的东西)。
    猜你喜欢
    • 1970-01-01
    • 2010-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多