2

mozilla オーディオ API トーン ジェネレーターを使用して調査しています。

  function AudioDataDestination(sampleRate, readFn) {
    // Initialize the audio output.
    var audio = new Audio();
    audio.mozSetup(1, sampleRate);

    var currentWritePosition = 0;
    var prebufferSize = sampleRate / 2; // buffer 500ms
    var tail = null, tailPosition;

    // The function called with regular interval to populate 
    // the audio output buffer.
    setInterval(function() {
      var written;
      // Check if some data was not written in previous attempts.
      if(tail) {
        written = audio.mozWriteAudio(tail.subarray(tailPosition));
        currentWritePosition += written;
        tailPosition += written;
        if(tailPosition < tail.length) {
          // Not all the data was written, saving the tail...
          return; // ... and exit the function.
        }
        tail = null;
      }

      // Check if we need add some data to the audio output.
      var currentPosition = audio.mozCurrentSampleOffset();
      var available = currentPosition + prebufferSize - currentWritePosition;
      if(available > 0) {
        // Request some sound data from the callback function.
        var soundData = new Float32Array(available);
        readFn(soundData);

        // Writting the data.
        written = audio.mozWriteAudio(soundData);
        if(written < soundData.length) {
          // Not all the data was written, saving the tail.
          tail = soundData;
          tailPosition = written;
        }
        currentWritePosition += written;
      }
    }, 100);
  }

  // Control and generate the sound.

  var frequency = 0, currentSoundSample;
  var sampleRate = 44100;

  function requestSoundData(soundData) {
    if (!frequency) { 
      return; // no sound selected
    }

    var k = 2* Math.PI * frequency / sampleRate;
    for (var i=0, size=soundData.length; i<size; i++) {
      soundData[i] = Math.sin(k * currentSoundSample++);
    }        
  }

  var audioDestination = new AudioDataDestination(sampleRate, requestSoundData);

  function start() {
    currentSoundSample = 0;
    frequency = parseFloat(document.getElementById("freq").value);
  }

  function stop() {
    frequency = 0;
  }

このトーンを 500 ミリ秒オンにしてから 500 ミリ秒オフにし、停止ボタンが押されるまで繰り返すようにしたいと思います。サンプル番号 22,050 から 44,100 を 0 に設定するだけで、これを行うことができると思いました。ただし、この方法は機能しないようです。100ミリ秒ごとにバッファを再投入する機能が発生するためだと思いますが、これは私の知識の限界を超えています。どんな助けでも大歓迎です。

4

1 に答える 1

0

実際、私にはうまく機能しているようです。requestSoundData関数のループを次のように変更しました。

for (var i=0, size=soundData.length; i<size; i++) {
  if (currentSoundSample % 44100 < 22050)
    soundData[i] = Math.sin(k * currentSoundSample);
  else
    soundData[i] = 0;
  currentSoundSample++;
}

サンプル 22,050 から 44,100 は 0 に設定されており、まさに希望どおりの効果が得られているようです。ここでコードを試すことができます: http://jsfiddle.net/95jCt/

于 2011-09-12T06:01:06.133 に答える