Why the web audio output from oscillator is not working as expected?

时间秒杀一切 提交于 2020-01-16 09:12:27

问题


Here is the code:

I want to create an audio program that can play audio from very low frequency to high frequency.

However, this code results in different output (even with the same device):

  1. The sound comes out suddenly - the expected result is it comes out gradually. I am sure my hearing is okay because I've asked my friends to hear;
  2. The audio sounds different on the same frequency.

WARNING: Please adjust your volume to very low in case of any hurting before running this script.

var audioCtx = new (window.AudioContext || window.webkitAudioContext)();

// create Oscillator node
var oscillator = audioCtx.createOscillator();

var osc_arr = [];

function purgeSound(){
  osc_arr.forEach(function(v){
    try {
      v.stop();
      v.disconnect(audioCtx.destination);
    } catch (e) {}
  })
}

function playSoundAtFreq(fq){
  purgeSound();
  var osc = audioCtx.createOscillator();
  osc_arr.push(osc);
  osc.type = 'square';
  osc.frequency.setValueAtTime(fq, audioCtx.currentTime); // value in hertz
  $('#fff').val(fq);
  osc.connect(audioCtx.destination);
  osc.start();
}

$('#stop').click(function(){
  purgeSound();
  _break = true;
})

var _break = false;
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}
var pointer = 0;
var go = appendAttemptAsync(10000);
async function appendAttemptAsync(range) {
  if(_break) return;
  var target = pointer+range;
  for (pointer; pointer<range; pointer++) {
    playSoundAtFreq(pointer);
    console.log(pointer)
    //if(pointer % 1 == 0) {
      await sleep(100)
    //}
  }
  return 5221;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id='stop'>stop</button>
<input id="fff" type="text" />

WARNING: Please adjust your volume to very low in case of any hurting before running this script.

Thanks for any kind of suggestions to improve my code.


回答1:


If you want an Oscillator to sweep like in the YouTube video that you mentioned, you can do something like:

let osc = new OscillatorNode(audioCtx);
osc.connect(audioCtx.destination);
osc.frequency.setValueAtTime(20, audioCtx.currentTime);
osc.frequency.linearRampToValueAtTime(audioCtx.sampleRate / 2, audioCtx.currentTime + 300);
osc.start();

Change the 300 to some appropriate time over which the tone sweeps. I arbitrarily chose 5 minutes.

I do not know why your example doesn't work, but this snippet is the typical way to sweep a tone using WebAudio.



来源:https://stackoverflow.com/questions/58335956/why-the-web-audio-output-from-oscillator-is-not-working-as-expected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!