【问题标题】:Why the web audio output from oscillator is not working as expected?为什么振荡器的网络音频输出没有按预期工作?
【发布时间】:2020-02-08 16:03:03
【问题描述】:

代码如下:

我想创建一个音频程序,可以播放从低频到高频的音频。

但是,此代码会导致不同的输出(即使使用相同的设备):

  1. 声音突然发出 - 预期的结果是逐渐发出。我确信我的听力没问题,因为我已经让我的朋友听过;
  2. 同一频率下的音频听起来不同。

警告:请在运行此脚本之前将音量调至非常低,以防万一受伤。

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" />

警告:请在运行此脚本之前将音量调至非常低,以防万一受伤。

感谢您提出任何改进我的代码的建议。

【问题讨论】:

  • “逐渐出来”是什么意思?你是什​​么意思音频在相同频率下听起来不同?您的测试产生的频率不同。
  • “逐渐”这个词的意思是,我想创造一种从低频到高频的声音。
  • 不确定您在寻找什么。至少在 chrome 上,在按下停止之前您不会听到任何声音,因为 chrome 的自动播放策略会阻止输出,直到有用户手势。如果您添加一个启动按钮来启动振荡器,那么我怀疑它会为您工作。
  • 但是对于我的 Chrome,它会自动启动。它不需要开始按钮。而我正在寻找的只是这样的东西:youtube.com/watch?v=H-iCZElJ8m0我想用JavaScript来模拟这个视频中的东西。

标签: html5-audio web-audio-api audiocontext


【解决方案1】:

如果您希望振荡器像 YouTube 视频中的 you mentioned 一样扫描,您可以执行以下操作:

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();

300 更改为音调扫过的适当时间。我随意选择了5分钟。

我不知道为什么您的示例不起作用,但是这个 sn-p 是使用 WebAudio 扫音的典型方法。

【讨论】:

  • 嗨,雷蒙德,非常感谢。可以,但我还有一个问题,我用我的 iPhone-X 播放它不工作,Web Audio 是否只支持桌面?
  • WebAudio 当然可以在移动设备上运行。抱歉,但我不知道为什么它不能在 iPhone 上运行。我认为您最好的办法是向 Apple 和/或 WebKit 提出有关此问题的问题。
  • 你有其他可以播放声音的手机品牌吗?只是想知道...我有兴趣提出问题,但如果有可以运行的设备,推送它们会更容易:)
  • 我只有 Android 设备,你的 codepen 对我来说很好。
  • 我认为codepen在Safari中不起作用的原因是这一行let osc = new OscillatorNode(audioCtx);。 Safari 不支持构造函数语法。你可以这样重写它:let osc = audioCtx.createOscillator();。或者,如果您想坚持使用新语法,您可以使用standardized-audio-context,它也可以让您在 Safari 中使用构造函数。
猜你喜欢
  • 2013-09-11
  • 1970-01-01
  • 2020-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 1970-01-01
相关资源
最近更新 更多