2017-01-28 14 views
0

dur(ミリ秒)の間にfreqヘルツで音を演奏する単純な関数playTone(freq, dur)を作成しようとしています。JS睡眠機能付きオシレーターからのノートのオーディオシーケンス

新しいノートブックを開始する前に、前のノートが終了するのを待つ機能が得られません。このサイトのsleep機能を使用して私のコードは以下の通りです。私はまだJSとの同期/非同期のことを理解していないので、できるだけシンプルにしたいと思います。誰も私のコードを動作させるのに役立つことができますか?現在、ノートはすべて一緒に演奏されます。

<script> 
function sleep (time) { 
    return new Promise((resolve) => setTimeout(resolve, time)); 
} 

function playTone(freq, dur) { 
    var audio = new AudioContext(); 
    var osc = audio.createOscillator(); 
    var gainNode = audio.createGain() 
    gainNode.gain.value = 0.2 
    osc.frequency.value = freq; 
    osc.type = "square"; 
    osc.connect(gainNode); 
    gainNode.connect(audio.destination); 
    osc.start(0); 
    osc.stop(dur); 
} 

for (var i = 0; i < 20; i++) { 
    playTone(440 + 10 * i, 1); 
    sleep(1000); 
} 
</script> 

答えて

0

それは最善のアプローチではないのですが、あなたは再帰的なメソッドを作成することができ、このような:

function playTone(freqs, idx, dur) { 
    var audio = new AudioContext(); 
    var osc = audio.createOscillator(); 
    var gainNode = audio.createGain() 
    gainNode.gain.value = 0.2 
    osc.frequency.value = freqs[idx]; 
    osc.type = "square"; 
    osc.connect(gainNode); 
    gainNode.connect(audio.destination); 
    osc.start(0); 

    setTimeout(function() { 
     osc.stop(0); //Now setTimeout controls the stop 
     if (freqs[idx + 1]) { 
      playTone(freqs, idx + 1, dur); 
     } 
    }, dur); 
} 

var frequencies = []; 

for (var i = 0; i < 20; i++) { 
    frequencies.push(440 + 10 * i); 
} 

playTone(frequencies, 0, 1000); 
+0

おかげで、それはブロックされる必要があり、必要に応じて一度に一つだけのノートを演奏します。私はそれを使って亀のグラフィックアニメーションにサウンドを追加し、それぞれの亀のコマンドにトーンが付くようにしたい。それはまた、任意の関数の外でコール可能である必要があります... – Robin

+1

問題は、遅れやJSのスリープがないので、あなたのコードの残りがsetTimeoutの内側にない限り、sleepに最も近いアプローチであるsetTimeoutを呼び出すときです。それは実行され続けるでしょう。再帰関数では、1つの周波数だけの配列を渡すことができます。がんばろう! o / –