使用 OscillatorNode 切换正弦波与方波,核心是通过设置 oscillator.type 属性并确保振荡器处于运行状态;若已停止则需重新创建并启动,推荐封装 playAs() 方法管理生命周期与类型切换。

使用 AudioContext 的 OscillatorNode 切换正弦波与方波,核心是调用 oscillator.type 属性并重新启动振荡器(或在支持的情况下直接修改类型)。
创建并启动 OscillatorNode
先获取音频上下文,创建振荡器节点,并连接到输出(如 destination)。注意:OscillatorNode 一旦停止就不能再次启动,需重新创建或使用 start()/stop() 控制生命周期。
基本初始化示例:
const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); const oscillator = audioCtx.createOscillator(); oscillator.type = 'sine'; // 默认即 sine oscillator.frequency.value = 440; // A4 音高 oscillator.connect(audioCtx.destination); // 必须显式调用 start() 才会发声 oscillator.start();
切换波形类型(sine ↔ square)
OscillatorNode 的 type 属性可读写,但规范要求在振荡器处于“已启动未停止”状态时直接赋值新类型是允许的(现代浏览器普遍支持),无需重启。不过为确保兼容性与稳定性,推荐以下方式:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 若当前振荡器仍在运行,直接设置
oscillator.type = 'square'即可切换(Chrome/Firefox/Safari 均支持) - 若已调用过
stop(),则必须新建一个OscillatorNode并重新start() - 避免在已停止的节点上设
type后不重启——它不会自动恢复发声
切换示例(实时更改):
// 切换为方波 oscillator.type = 'square'; // 切换回正弦波 oscillator.type = 'sine';
安全切换的推荐做法(带状态管理)
为防止误操作(如重复 start、对已停止节点赋值),建议封装切换逻辑:
let oscillator = null;
let isPlaying = false;
function createOscillator(type) {
if (oscillator) oscillator.stop();
oscillator = audioCtx.createOscillator();
oscillator.type = type;
oscillator.frequency.value = 440;
oscillator.connect(audioCtx.destination);
}
function playAs(type) {
if (isPlaying && oscillator) {
oscillator.type = type; // 直接切换类型
} else {
createOscillator(type);
oscillator.start();
isPlaying = true;
}
}
// 使用
playAs('sine'); // 播放正弦波
playAs('square'); // 立即切为方波
注意事项与常见问题
以下细节容易出错,需特别留意:
-
时间精度:类型切换是瞬时的,无交叉淡入;如需平滑过渡,需用多个振荡器 +
GainNode混音控制 -
浏览器差异:Safari 旧版本可能不支持运行中修改
type,建议检测:if ('type' in oscillator) -
内存管理:频繁创建/停止振荡器不会泄漏,但长期运行建议复用节点(优先用直接改
type) -
静音策略:移动端需在用户手势(如点击)后首次调用
audioCtx.resume(),否则无声音
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










