4

私は一定の間隔でいくつかの音符を演奏しています。それぞれがランダムなミリ秒単位で遅延し、耳障りな不規則な効果を生み出します。どうすれば修正できますか?

注: 一貫性がある限り、多少の遅延は問題ありません。

「タイミングに敏感な再生用に最適化された、独自の小さなSoundManager2の代替品を実装する」タイプの回答は問題ありません.

可聴遅延がゼロのアプリの例については、フラッシュベースのToneMatrixを参照してください。

テストケース (ここで実際に見る、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>
4

4 に答える 4

10

これがあなたが聞きたい答えではないことは知っていますが、サウンドを再生するために独自のフラッシュライブラリを作成したかどうかに関係なく、これを止める方法はありません。

「私にとってはうまくいく!」と言ったすべての人のために。ポスターのデモが再生されたら、ブラウザウィンドウのサイズを変更するか移動してみてください。ほんのわずかな遅延以上のものが聞こえます。これはFirefoxとIEで最も顕著ですが、Chromeでも発生します。

さらに悪いことに、ブラウザウィンドウの閉じるボックスをクリックして押したままにすると、マウスを離すまで音が完全に停止します(閉じるボックスの外でマウスを離しても、実際にはウィンドウを閉じないでください、参考までに)。

ここで何が起こっているのですか?

ブラウザウィンドウのサイズ変更または移動を開始すると、ブラウザは、ウィンドウ内で進行中のjavascriptに追いつくという動作で、ウィンドウのプロパティを変更する動作をマルチタスクで実行しようとします。必要に応じてウィンドウを短く変更します。

ブラウザウィンドウの閉じるボックスの上にマウスを置くと、時間が完全に停止します。これは、ウィンドウのサイズを変更したり移動したりするときに少しずつ発生します。JavaScriptの世界では、時間は小さな散発的なチャンク(またはマシンの速度によっては大きなチャンク)で静止しています。

ここで、「確かに、ブラウザのサイズを変更するか、閉じるボタンを押したままにすると、ブラウザが一時停止しますが、通常、これは発生しません」と言うかもしれません。残念ながら、あなたは間違っているでしょう。

実際、それは常に起こります。テストを実行したところ、ブラウザウィンドウを完全に静止したままにしたり、マウスに触れたり、キーボードに触れたりしなくても、コンピュータのバックグラウンドプロセスによって「一時的な中断」が発生する可能性があります。つまり、短時間(おそらくわずか数ミリ秒)時間はブラウザで「静止」しており、完全にランダムな間隔で制御できません。

「じっと立っている」とはどういう意味ですか?33ミリ秒(毎秒約30フレーム)ごとに実行されるsetInterval()呼び出し(これはsetTimeoutにも適用されます)があるとします。これで、33ミリ秒ごとに関数が呼び出されることが期待されます。そして、ほとんどの場合、これは真実です。

ただし、「一時的な中断」が発生し始めると、setInterval呼び出しが43ミリ秒で発生する可能性があります。10ミリ秒の間に何が起こったのですか?何もない。時間が止まった。ブラウザには何も更新されていませんでした。サウンドを再生している場合は再生を継続しますが、JavaScriptがまったく実行されていないため、新しいサウンド呼び出しは再生を開始しません。5つのsetInterval()関数を実行している場合、それらはすべて、ある時点で10ミリ秒間一時停止されます。

「時間が静止している」ことを確認する唯一の方法は、setInterval関数のコールバックで実際の時間をポーリングすることです。ブラウザがほとんどの時間維持しようとしていることがわかりますが、ウィンドウのサイズ変更やストレスの多い作業を開始すると、間隔は通常より長くなりますが、すべてのコードは同期されたままになります(私はこの手法を使用してゲームを作成しているので、すべてのゲームの更新が同期して行われることがわかりますが、わずかに途切れます)。

通常、これらのスタッターは完全に目立たないことを指摘する必要があります。setInterval時間中に実際の時間をログに記録する関数を作成しない限り(私自身のテストで行ったように)、それについてさえ知りません。ただし、繰り返しplay()呼び出しを使用して、ある種の繰り返し音(Asteriodsのバックグラウンドでのビープ音など)を作成しようとすると、問題になります。

私のおすすめ?ループすることがわかっているサウンドがある場合は、10秒程度の長い時間を与えると、しゃっくりに気付く可能性が低くなります(現在、画面上のグラフィックはしゃっくりする可能性がありますが、問題が発生しています。 )。

ゲームを作成していて、主人公に機関銃を発射させる場合は、playSound('singleShot')を10回連続して呼び出したり、playSound('machineGunFire10Rounds')を1回呼び出したりしないでください。 。

あなたはそれを回避するためにいくつかのトリックをしなければならないでしょう、しかしほとんどの場合あなたは大丈夫でしょう。

Flashアプレットは、通常のブラウザ/ JavaScript環境で行われているこの「時間の凍結」全体に何とか影響が少ないプロセスで実行されているようですが、ToneMatrixの例へのリンクでも、次のように実行できます。ブラウザウィンドウのサイズ変更または移動。

しかし、FlashはJavaScriptよりもはるかに優れているようです。ブラウザをそのままにしておくと、Flashが一定時間フリーズせず、間隔が常に時間どおりに実行されていることに賭けたいと思います。

tl; dr:

  • あなたはあなたが達成したいと思っていることに夢中になっています
  • いくつかの回避策を使用してそれに対処してみてください
  • プロジェクトを純粋なフラッシュで書き直します(javascriptなし)
  • ブラウザが良くなるのを待ちます(Firefox 4はJaegerMonkeyと呼ばれる新しいjavascriptエンジンを取得しています。これは見るのが面白いでしょう)
  • どうすればこれをすべて知ることができますか?javascript、setInterval、soundManager/html5オーディオ呼び出しで多くのテストとロギングを行いました
于 2010-05-27T20:11:13.123 に答える
1

あなたの質問に対する私のコメントの中で、私はあなたのサンプルを演奏するときに不規則性が聞こえないと述べました。つまり、私は「リズムが聞こえない」か、セットアップにリアルタイムのパフォーマンスを妨げる何かがある可能性があります。環境の詳細については言及していませんが、CPUサイクルを消費している他のプロセスがコンピューター上で実行されているか、古いバージョンのFlashがサウンドレイテンシーの処理をうまく行っていない可能性があります。私自身は最新バージョンのFlash(10.something)を使用していますが、パラメーターはFlash 9を必要とします。しかし、SoundManager2とStackOverflowを使用するのに十分賢い場合は、これらの問題を解消できたと思います。

だからここに頭に浮かぶいくつかのトラブルシューティングの可能性とコメントがあります:

1)SoundManagerサイトには、 JS-DOM "painting" + Sound、V2を含む多数のデモがあります。不規則なレイテンシーと遅延が発生していますか?そうでない場合は、彼らがそこで行っていることとあなたが行っていることを比較できるかもしれません。もしそうなら、多分あなたのマシン環境を見てください。そのデモを実行すると、非常に応答性が高くなります。(編集:ただし、詳しく見ると、ストローク中にブラシスタンプのサイズがどのように変化するかを確認できます。マウスイベント間の時間間隔によって変化するため(一定のマウス速度を維持していると仮定)、視覚的に確認できます。マウスイベントのパターンに不規則性が見られます。スタンプサイズに時折変化が見られます。これは、マウスイベントが定期的に発生していないことを示しています。これにより、Javascriptイベントが発生します。

2)JavascriptsetTimeout()でありsetInterval()、タイミングに関してはあまり信頼できません。ほとんどの場合、それらは要求した間隔のボールパークに戻ってきますが、大きな変動、通常は遅延があり、信頼性が低くなる可能性があります。Flash内でActionScriptを使用する場合も同じことがわかりました。不規則性がの不規則性によるものかどうかを確認するために、sound.play()呼び出しが行われている時間を印刷することをお勧めしますsetTimeout/setInterval()。その場合は、間隔を短くしてから、システム時間をポーリングして、必要な300ミリ秒の間隔にかなり近づけることができます。を使用してシステム時刻をポーリングできますnew Date().getTime()、そしてこれはmsの精度を持っているようです。ポーリングはもちろん、他の目的に使用できるときにサイクルを吸い上げる恐ろしいハックであり、一般的にはお勧めしませんが、それが役立つかどうかを確認するために試してみてください。 編集:これは、jsでの入力イベントとタイマーイベントの処理に関するJohnResigによる記事です。

3)フラッシュがサウンドを再生する場合、通常はレイテンシーが発生します。これは、プレーヤーが「蒸気のヘッドを構築」し、次のバッファー要求が満たされる前に再生するのに十分なものがバッファーにあることを確認するためです。この待ち時間と中断のない再生の信頼性の間にはトレードオフがあります。これは、「独自の小さなSoundManager2の置き換えを実装する」ことを除いて、何もできない制限である可能性があります。

お役に立てれば。私は最近、いくつかの基本に触れたAS3サウンド実験を書きました。このスペースを見て、人々が思いつく他の提案を確認します。

于 2010-03-25T20:20:38.083 に答える
0

javascript間隔を使用していますが、正確な時間に起動することは保証できません。内部フラッシュのタイミングははるかに信頼できると確信しています。

しかし、これは役立つかもしれません、あなたがサウンドの再生をトリガーした後に繰り返し発砲します。

window.setTimeout(function() { func(); recur(func, delay); }, delay);
于 2010-03-23T17:46:10.687 に答える
0

別の回答で説明されているように、これを回避する方法はありません。しかし...

この問題を軽減するためにいくつかの実験を行いましたが、最終的には以下を使用することにしました:

デモのプロトタイプのソースをのぞいて、(可能であれば) lowLag を試してみてください。それは私にとってうまくいきました。

幸運を!

于 2013-05-31T12:14:49.733 に答える