关于本文
本文是通过利用生成式 AI 的自动化生成流程创建的。
我们查阅了 Web Audio API 的官方文档,并编写了一个无需发声即可观察波形的 JavaScript 教学材料。P1 到 P5 是在同一个 ChatGPT 内进行的自我审核,并非独立的 AI 审核。验证状态:📘 已确认官方规范/JavaScript 语法与频率边界 4 个条件通过/实际浏览器、公开 Pages、WordPress 显示尚未确认
确认于 2026 年 10 月 31 日。尚未在实际设备上确认音频播放、实际波形显示、移动端、打印/PDF 以及 WordPress 的蓝色边框。
当把频率从 220 Hz 更改为 440 Hz 时,波峰之间的间距会发生怎样的变化呢?通过本教学材料,用户无需发出声音即可仅观察屏幕上的波形。其目的是避免混淆波形的变化与音高,并理解在相同时间跨度内周期发生变化的样貌。
| 项目 | 本次条件 |
|---|---|
| 对象 | 支持 Web Audio API 和 Canvas 2D 的浏览器 |
| 使用技术 | OscillatorNode、AnalyserNode、Canvas |
| 费用 | 免费。无需 API 密钥或外部库 |
| 个人信息 | 无需麦克风、位置信息或登录 |
| 音频 | 初始静音。解除时也为小音量设置 |
| 限制 | 在真实浏览器和真实设备上未经确认 |
首先尝试:保持无声并观察波形
🔷 动态教材(已公开到达,浏览器运行情况未经确认)
打开 Web Audio 波形实验室
Daily Code 的 README 和完整源码(已保存在 GitHub 中)
页面的“开始(初始静音)”。初始设置是不发出声音。
频率的滑块从220 Hz 调到 440 Hz。
对比蓝色波形中波峰与波峰的间距以及“440 Hz”显示。观察结束后,点击“停止”。
尚未在真实浏览器中确认运行情况。以下是根据源码计算和 API 规范预测的结果。
| 操作 | 期待的变化 |
|---|---|
| 开始前 | 平坦线 / 停止中 |
| 以 220 Hz 开始 | 周期较长的波形 |
| 更改为 440 Hz | 波峰间距变短 |
| 保持静音 | 无声音输出,仅绘制波形 |
| 停止 | 音频处理结束・平坦线 |
操作后请看此处
即使频率数值翻倍,波的高度(振幅)也不会翻倍。在屏幕上需要关注的是波峰的数量和间距。由于 Canvas 会将固定数量的时域采样绘制到相同的宽度,因此频率越高,较短的周期就会紧密排列。不过,显示的波峰数量也会受到采样率和设备状态的影响。如果在操作系统或浏览器中启用了“减少动态效果”,由于设计上会停止自动绘制,请使用“绘制波形一次”进行更新。如果开始后显示平坦线,请稍等片刻再重新绘制。
为什么关闭声音也能看到波形
处理声音的 JavaScript 中,包含生成声音的组件和检测声音的组件。OscillatorNode用于生成正弦波,AnalyserNode负责获取其波形。GainNode负责调节音量。由于本教程会先进行分析再将音量设为 0,因此其结构是直接观察信号而不向耳朵输出声音。
flowchart LR
A["周波数スライダー"] --> B["OscillatorNode"]
B --> C["AnalyserNode"]
C --> D["Canvasに波形描画"]
C --> E["GainNode: 初期音量0"]
E --> F["スピーカー"]
图中的“扬声器”代表音频输出路径。由于初始 GainNode 的音量为 0,所以即使有路径也是刻意无声的。其中不包含从麦克风获取声音的处理,也不会读取外部音乐文件。
提取波形需要使用getByteTimeDomainData()。此方法将音频随时间的变化作为 0 到 255 的数值序列复制到Uint8Array中。128 附近的值相当于中心线,将其换算为 Canvas 的纵坐标即可连成线条。这显示的是波形,与表示各个频率音量的频谱不同。
代码核心:分析与绘制
完成版还包含音频连接、停止处理以及无障碍支持。此处仅展示核心部分。
const samples = new Uint8Array(analyser.fftSize); analyser.getByteTimeDomainData(samples); const y = samples[i] / 255 * canvas.height;
samples是接收波形数值的容器。将每个点转换为 Canvas 的垂直位置并绘制线条。实际的完成版使用requestAnimationFrame更新显示,在停止时取消动画,并通过AudioContext.close()结束处理。
为什么需要开始按钮也很重要。浏览器有时会限制仅在打开页面时就自动播放声音。因此,AudioContext的创建和resume()我们将其设计为从用户的点击开始。由于可以在初始静音状态下进行观察,因此播放声音的操作并不是学习的必要条件。
修改一处进行比较
比较过 220 Hz 和 440 Hz 后,接下来请设置为660 Hz。只需更改频率,并保持静音状态不变。
| 设置 | 预计的波形 |
|---|---|
| 220 Hz | 波峰间距较大 |
| 440 Hz | 波峰间距较小 |
| 660 Hz | 间距更小 |
在此,重要的是不要误解为“高频率=大声音”。频率主要与音高有关,而音量是另一个独立的要素。实验结束后,请点击“停止”,并确认屏幕是否恢复为平坦的直线。
注意音量
初始状态下静音功能为开启状态。取消勾选后会发出小音量的声音,但个人的实际感受会因设备的音量设置、耳机以及周围环境而异。本工具不能用于听力测试或保证安全的声压。如果耳朵感到不适,请立即停止。
当运行不正常时
| 症状 | 首先确认的事项 |
|---|---|
| 无法开始 | 浏览器的 Web Audio 支持和控制台 |
| 波形不运动 | 初始状态、标签页显示、减弱动画设置 |
| 听不到声音 | 初始静音是预期行为 |
| 波形呈扁平状 | 尝试“绘制一次波形” |
| 运行卡顿 | 停止并关闭标签页 |
如果操作系统或浏览器开启了“减少动态效果”设置,我们将停止自动动画,并允许通过按钮仅绘制一次波形。如果仅靠颜色难以判断,请同时查看频率文字显示。虽然采用了可通过键盘操作的标准按钮和滑块,但尚未进行辅助技术的实机测试。
如果无法打开 GitHub Pages,可能是因为发布准备或分发同步尚未完成。请检查 GitHub 的 README 和docs/demos/audio-waveform-lab/的源代码,然后继续了解如何在自己的电脑上安全运行。存在公开 URL 与实际能够运行是两件需要分别确认的事情。
在自己的电脑上运行
完成版由 HTML 和 JavaScript 两个文件组成。请将 README 中提到的index.html和app.js放在同一个文件夹中,然后用浏览器打开。如果受到本地文件限制,可从可靠的本地 HTTP 服务器进行分发。无需播放声音。也无需向浏览器授予麦克风、摄像头或位置信息的权限。
如果在工作或学习中使用
在编程课程中,数值输入→信号生成→解析→屏幕显示的数据流向。在声学基础学习中,它可作为解释周期与频率关系的引导工具。在业务应用中,也可以不处理音频输入,仅应用 Canvas 更新的机制。
另一方面,它不能用于声压测量、听力诊断和噪声违规判定。因为本次的波形是在浏览器中生成的正弦波,并未测量现实中房间或设备的真实声音。视觉上的动态效果与测量仪器的准确性是两回事。
附加实验:确认即使在静音状态下也能进行解析的原因
波形显示并不等同于“从扬声器中听到声音”。在 Web Audio 中,我们将生成波形的处理、提取数值的解析处理以及决定最终音量的处理分开考虑。即使在音量设为 0 的界面上,只要存在送达解析器的信号,其结构就支持作为数值进行观察。请确认哪个节点连接到了什么地方,切勿仅凭听不到声音就断定振荡器已停止工作。
当降低频率时,预计在相同的观察时间内波峰会显得更少。但是,如果绘图宽度或用于显示的样本数量发生变化,波峰的外观也会随之改变。仅改变频率的比较与改变横向显示比例的比较是不同的。首先确认显示是否在更新,其次确认设置的频率是否反映到了屏幕上,这样更容易排查原因。
波形的高度并不一定与实际音量相同。如果绘图处理将信号值根据屏幕宽度或高度进行了放大或缩小,那么在不改变音量的情况下也可以将线条显示得更大。在操作之前,先确定观察对象是振幅还是波的周期,这一点非常重要。当比较不同的频率时,请固定显示倍率,并确认刻度是否发生了变化。
根据浏览器的不同,音频处理的启动可能会受到用户操作的限制。如果在刚打开时无法运行,而在按下按钮后才能运行,请在断定需要权限之前检查 AudioContext 的状态。通过停止按钮是仅停止了绘图,还是连同声源一起停止了,这一点也很重要。为了确保结束后不会残留不必要的振荡器或绘图循环,请分别检查停止处理和恢复处理。
官方资料
MDN: AnalyserNode.getByteTimeDomainData()(于2026年10月31日验证)
MDN: Web Audio API 最佳实践(于2026年10月31日验证)
MDN: 使用 Web Audio API(于2026年10月31日验证)
MDN: 自动播放指南(于2026年11月1日验证,关于用户操作后的启动)
GitHub 示例
验证范围
已在 V8 中对保存在 GitHub 上的 JavaScript 进行了语法检查,并确认了频率上下限及非法输入等 4 个条件。实际浏览器中的 AudioContext 启动、音频播放与绘制、GitHub Pages 部署、WordPress 引用框变蓝、特色图像、智能手机以及打印/PDF 均未经验证。交由现有 WordPress 显示处理的项目未在正文中重复插入,也未添加自定义的生产环境 CSS 或未注册的图像。
