2011-09-10 4 views
2

Я расследую с помощью звукового генератора Mozilla API тон:Создание звукового сигнала не с помощью 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 к нулю. Однако этот метод, похоже, не работает. Я думаю, это связано с тем, что функция повторного заполнения буфера происходит каждые 100 мс, но это сейчас выходит за рамки моих знаний. Любая помощь будет очень высоко ценится.

ответ

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++; 
} 

Образцы 22050 до 44100 установлены равными нулю, и что, кажется, производит именно эффект вы хотели. Здесь вы можете попробовать код: http://jsfiddle.net/95jCt/

+0

Большое спасибо, я потратил годы, пытаясь заставить это работать. Я очень ценю это! – Lars

 Смежные вопросы

  • Нет связанных вопросов^_^