You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Web Audio API底鼓合成器按钮每次点击都从头发声?

Web Audio API底鼓合成器重复触发问题解决

问题描述

使用Web Audio API构建底鼓合成器时,按钮触发函数可生成带音高和增益扫频的正弦波,但按钮仅能生效一次,再次点击无法从头播放声音。尝试将osc.start()放入自定义函数中失败,因为振荡器的.start()方法无法被多次调用。

原代码:

const audioCtx = new AudioContext(); // Initiate Audio Context
const osc = audioCtx.createOscillator(); // Create An Oscillator
const volume = audioCtx.createGain(); // Create A Gain

osc.type = "sine"; // Set the type of the waveform
osc.frequency.value = 440; // Set the frequency value of the oscillator

osc.start(); // Start playing the oscillator
osc.connect(volume); // Set the destination of the oscillator  

function generateKick() {
   volume.gain.value = 1;
   osc.frequency.setTargetAtTime(22, 0, 0.1)
   volume.gain.setTargetAtTime(0, audioCtx.currentTime, 0.1);
   volume.connect(audioCtx.destination);
}

解决方案

Web Audio API中的振荡器节点(OscillatorNode)是一次性的,调用start()后无法再次启动。解决核心是每次触发声音时创建新的振荡器和增益节点,具体修改如下:

const audioCtx = new AudioContext(); // 初始化音频上下文

function generateKick() {
  // 每次点击都创建新的振荡器和增益节点
  const osc = audioCtx.createOscillator();
  const volume = audioCtx.createGain();

  osc.type = "sine";
  osc.frequency.value = 440; // 初始频率

  // 构建音频节点链:振荡器 → 增益 → 系统输出
  osc.connect(volume);
  volume.connect(audioCtx.destination);

  // 设置初始增益
  volume.gain.value = 1;
  // 音高扫频:从当前时间开始,0.1秒内降到22Hz
  osc.frequency.setTargetAtTime(22, audioCtx.currentTime, 0.1);
  // 增益淡出:从当前时间开始,0.1秒内衰减至0
  volume.gain.setTargetAtTime(0, audioCtx.currentTime, 0.1);

  // 启动振荡器
  osc.start();
  // 0.2秒后停止振荡器(确保扫频和淡出完成)
  osc.stop(audioCtx.currentTime + 0.2);
  // 振荡器停止后断开连接,释放资源
  osc.onended = () => {
    osc.disconnect();
    volume.disconnect();
  };
}

关键说明

  • 一次性节点特性:振荡器节点无法重复启动,因此每次触发必须创建新实例。
  • 资源管理:通过stop()指定停止时间,并在onended事件中断开节点连接,避免不必要的内存占用。
  • 节点链重建:每次触发时重新连接振荡器、增益和输出节点,确保声音正确路由。

内容的提问来源于stack exchange,提问作者Alp Seyrekbasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 07:01:05