2

I'd really to start work soon on a series of music based apps for www.daveconservatoire.org .

The thing holding me back at the moment is that from reading various articles/posts etc I can't work out whether it is realistic to use javascript to produce accurate timing in applications. We are talking correct to maybe 10ms.

For example, one of the more simple applications would be a metrnonme that can be set to tick at a given interval - 60BMP, for example, would require the ticking sound to be played once every second.

Is this achievable with javascript/html5? All the examples of metronomes that I've found have been written in flash, presumably because it is difficult to work with accurate timing in JS.

4

2 に答える 2

3

あなたの質問は面白いと思ったので、自分で少しテストすることにしました。JavascriptのsetInterval関数は、メトロノームタイプのアプリケーションを実行するには十分ではないようです。そこで、代わりに現在の時刻を使用するカスタムの「クラス」を作成しました。これは、+-3ミリ秒以内に正確であるようです。あなたのマイレージは異なる場合があります。コードはここにあります:http://jsfiddle.net/66YJz/

// Custom timer class

// f = function to call
// m = ms
function timer(f, m)
{
    var target_time = (new Date()).getTime() + m;
    var margin = 3;

    setInterval(function(){
        var now = (new Date()).getTime();
        var dif = target_time - now;
        // If within acceptable timeframe, call function
        if (dif <= margin && dif >= -margin) {
            target_time = now + m + dif;
            f();
        }
        // For some reason we missed the time frame.
        // Skip and move on to next
        if (dif < -margin ) {
           target_time += m;
           //margin += 1;
        }
    },
    1);
}

これを泡立てただけなので、改善の余地は十分あると思います。

于 2012-10-31T15:58:55.990 に答える
0

JavaScript の High-Resolution Timeの作業中の仕様があります。

ただし、それが便利に利用できるようになるまでは、状況はより複雑になります。

このテーマに関する興味深いチュートリアルを見つけました: http://www.html5rocks.com/en/tutorials/audio/scheduling/

関連するさまざまな問題について詳しく説明し、適切と思われるアプローチを提案します。特に、順序付けするのが WebAudio の場合です。私はまだそれを自分でテストしていませんが、問題を説明するために記事からいくつかの顕著な引用と、それらに効果的にアプローチする方法の概要を以下に示します。

JavaScript タイミング API の最悪の部分は、Date.now() のミリ秒単位の精度はそれほど悪くないように思えますが、JavaScript でのタイマー イベントの実際のコールバック (window.setTimeout() または window.setInterval による) です。レイアウト、レンダリング、ガベージ コレクション、XMLHTTPRequest およびその他のコールバックによって、簡単に言えば、メイン実行スレッドで発生するさまざまなことが原因で、数十ミリ秒以上簡単にゆがむ可能性があります。

...

[与えられた例] が堅実なタイミングを維持しながらテンポ制御を可能にする方法は、コラボレーションです: setTimeout タイマーが頻繁に起動し、個々のノートの将来の Web オーディオ スケジューリングを設定します。setTimeout タイマーは基本的に、現在のテンポに基づいて「すぐに」ノートをスケジュールする必要があるかどうかを確認し、それらをスケジュールします...

また、requestAnimationFrame を setTimeout の代わりに使用して、グラフィックスとの正確な同期を可能にすることも提案しています。これはゲームにとって自然なアプローチです。

このチュートリアルでは、シーケンスしようとしているのが WebAudio でない場合に何をするかについては説明していません。私のややあいまいなケースでは、ネットワーク経由で SuperCollider のインスタンスを実際に制御したいと考えています。これが機能するために、各 OSC メッセージの一部として実行が発生する時間を指定し、scsynth スケジューラーが WebAudio スケジューラーの代わりになるようにすることで、提案されたアプローチを適応させることができます。

しかし、そう簡単には適応できない状況もあるかもしれません: 例えば、通常の MIDI シンセをノートメッセージで制御することは、このアプローチではうまくいきません。草案 WebMIDI 仕様の作成者は、この回答の冒頭で言及した High Resolution Time API で使用されることを想定しています。

于 2013-11-03T20:05:17.003 に答える