javascript - SoundManager2的延迟不规则

标签 javascript audio latency soundmanager2

我会定期演奏一些音符。每个延迟都会随机延迟几毫秒,从而产生刺耳的不规则效果。我如何解决它?

注意:只要保持一致,我就可以保留一些延迟。

如果您知道如何执行“您自己的小型SoundManager2替代品,针对时序敏感的播放进行了优化”的回答,就可以了,但是我现在想避免在Flash中重写整个应用程序。

有关可听见延迟为零的应用示例,请参见基于Flash的ToneMatrix

测试用例
(see it here liveget it in an zip):

<head>
<title></title>
<script type="text/javascript" 
src="http://www.schillmania.com/projects/soundmanager2/script/soundmanager2.js">
</script>
<script type="text/javascript">
soundManager.url = '.'
soundManager.flashVersion = 9
soundManager.useHighPerformance = true
soundManager.useFastPolling = true
soundManager.autoLoad = true

function recur(func, delay) {
    window.setTimeout(function() { recur(func, delay); func(); }, delay)
}

soundManager.onload = function() {
    var sound = soundManager.createSound("test", "test.mp3")
    recur(function() { sound.play() }, 300)
}
</script>
</head>
<body>
</body>
</html>

最佳答案

我知道这不是您想听到的答案,但是无论您是否编写了自己的闪存库来播放声音,都无法阻止它。

对于每个说“对我来说都很好”的人!尝试在发布者演示播放时调整大小或移动浏览器窗口。您不仅会听到微妙的延迟,还会听到更多。这在Firefox和IE中最明显,但是即使Chrome也可以体验到。

更糟糕的是,如果在浏览器窗口的关闭框中单击并按住鼠标,声音将完全停止,直到释放鼠标为止(您可以在关闭框之外释放鼠标,而实际上不关闭窗口,FYI)。

这里发生了什么?

事实证明,当您开始调整浏览器窗口的大小或在浏览器窗口中移动时,浏览器会尝试将更改窗口属性的行为与保持窗口中运行的javascript的行为多任务处理。它在需要时短时更改窗口。

当您在浏览器窗口的关闭框中按下鼠标时,时间将完全停止。这是在调整窗口大小或移动窗口时以较小的增量发生的事情:在JavaScript世界中,时间零散地停留在小而零星的小块(或大块,具体取决于计算机的运行速度)。

现在,您可能会说“确定,调整浏览器的大小或按住关闭按钮会使浏览器暂停,但通常不会发生”。不幸的是你会错的。

实际上,它一直在发生。我已经进行了测试,结果表明,即使使浏览器窗口完全静止不动,不触摸鼠标,也不触摸键盘,计算机上的后台进程仍然会引起“打ic”,这意味着在很短的时间内(也许在浏览器中,系统会以完全随机的时间间隔“停滞”仅几毫秒的时间。

我所说的“静止不动”是什么意思?假设您有一个setInterval()调用(这也适用于setTimeout),该调用每33毫秒(每秒约30帧)运行一次。现在,您希望每33个“真实世界”毫秒后就会调用您的函数。在大多数情况下,这是事实。

但是,当“打ic”开始发生时,您的setInterval调用可能会在43毫秒内发生。在10毫秒内发生了什么?没有。时间暂停。浏览器上的任何内容均未更新。如果您正在播放声音,它将继续播放,但是不会播放新的声音调用,因为根本没有执行任何javascript。如果您有5个setInterval()函数正在运行,则它们将全部在某个时刻暂停10ms。

告诉我们“时间静止”的唯一方法是在setInterval函数回调中轮询实际时间。您将能够看到浏览器在大多数情况下都尝试保持同步,但是当您开始调整窗口大小或进行一些压力较大的操作时,间隔将比平时更长,但是所有代码将保持同步(我正在使用这种技术制作游戏,因此您会看到所有游戏更新都是同步进行的,只是有些卡顿了)。

通常,我应该指出,这些断断续续是完全不明显的,除非您编写一个函数来记录setInterval期间的实际时间(就像我在自己的测试中所做的那样),否则您甚至都不知道。但是,如果您尝试使用重复play()调用来创建某种类型的重复声音(例如Asteriods背景中的哔哔声),就会出现问题。

我的建议?如果您知道会循环播放的声音,请给它一个较长的持续时间(可能是10秒),并且您不太可能注意到打ic声(现在,屏幕上的图形仍然可能打h,但是您被困在那里了) )。

如果您正在编写游戏并让主角用机枪射击,请不要对playSound('singleShot')进行10次快速成功调用,也不要对playSound('machineGunFire10Rounds')进行一次调用,或者执行类似的操作。

您必须采取一些技巧才能解决它,但是在大多数情况下,您会没事的。

看来,Flash小程序的运行过程在某种程度上对常规浏览器/ JavaScript环境中发生的整个“时间冻结”事件的影响较小,但是即使您链接到ToneMatrix示例,我仍然可以实现它调整大小或移动浏览器窗口。

但是Flash似乎仍然比javascript好得多。当我不理会浏览器时,我会打赌Flash不会冻结任何时间,并且间隔总是按时运行。

tl; dr:

  • 您迷上了想要实现
  • 的目标
  • 尝试使用一些解决方法来处理它
  • 以纯Flash(无javascript)重写您的项目
  • 等待浏览器变得更好(Firefox 4正在获得一个名为JaegerMonkey的新JavaScript引擎,这将很有趣)
  • 我怎么知道这一切?我已经使用javascript,setInterval和soundManager / html5音频调用
  • 做了大量测试和记录

    关于javascript - SoundManager2的延迟不规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2452697/

    相关文章:

    javascript - javascript构造函数和object.create可以结合使用吗?

    javascript - 使用 % 进行查询(ajax+javascript+html)

    javascript - 从声音片段的原始音频数组数据评估持续时间

    android - 从 SD 卡中删除音频

    java - Java 中的音乐循环

    android - Android 播放、暂停/停止和设置音频音量的相对延迟

    javascript - JSON 嵌套元素未定义

    javascript - 从 mongodb connect 和 find 返回一个数组

    node.js - "Hello world"从 Chrome 而非 curl 测量时,Rust 网络服务器比 Node 慢

    mysql - 在具有数百万行的 MySQL 表中进行高效查找