Summary

  • W3C 于 2011 年 12 月 15 日发布 Web Audio API 工作草案,以 AudioContext 中相连的 AudioNode 构成音频路由图,让网页能处理和合成声音。
  • 2021 年 6 月 17 日的正式建议书进一步规定了参数按时间变化、离线渲染和 AudioWorklet 自定义处理。脚本布置声路,浏览器的音频机制负责运行。

排练室角落有台老点唱机,正中间是一枚骄傲的红色按钮。作曲者提出要求:先轻轻响起,经过滤波,在房间里向左移动,等游戏人物落地的瞬间再收住。点唱机的建议是把唱片重播一遍。它没有坏,只是工作说明变了。网页有了播放录音的能力以后,互动声音仍需要一套能现场安排的设备。

2011 年 12 月 15 日的 W3C 工作草案提出处理与合成音频的高级接口。核心是音频路由图:一个个 AudioNode 相连,决定声音怎样流动。声源可以经过滤波、音量调节、空间位置处理,最后到达输出。JavaScript 设置节点和连接。草案说明,主要的实际处理通常在浏览器底层经过优化的实现中完成,同时也允许脚本直接处理。作曲者接线,机器让空气振动。

这一区分解决了真实问题。HTML 的 audio 元素让网页可以直接播放声音,已经是重要一步。2011 年草案的介绍却把目光投向游戏和互动应用:它们要混音、滤波、合成,要随用户行为改变声音。固定的录音可以陪伴画面,不能只靠一个播放命令就根据人物位置改变声场。路由图给应用一组共同零件,应用则决定零件怎样组合。

草案列出的零件颇为具体。AudioContext 是声路的工作空间;声源节点提供声音,gain 节点调节电平,滤波节点处理频率,delay 节点加上时间差,分析节点可以把声音信息交给可视化界面,destination 节点通向听得见的终点。还有拆分与合并声道的节点。一个声源可以经过几种效果,多路声音也可以在输出前汇合。声响来自各部分的接法,不来自一枚神奇按钮。

声音还需要自己的时钟。游戏画面已经撞上墙,碰撞音半秒后才到,就不是艺术留白,而是让玩家怀疑耳朵和眼睛谁先离职。早期接口描述了 AudioContext 的时间与相对于这只时钟安排声音事件的方式。应用可以指定何时开始或停止某段声音。JavaScript 的工作是排节目,而不是守着每一个采样点,祈祷网页主线程那一刻恰好闲着。

2013 年 10 月 10 日的工作草案仍把声路图放在中心。那已经是第五份公开草案,说明共同词汇还在磨合。文档提到复杂游戏声音、互动应用、混音、处理和滤波。简单的整首歌曲仍可以交给播放按钮;新的接口服务于那些需要“做出声音”的网页,而不只是播放一段现成声音的网页。

到2021 年 6 月 17 日的 W3C 正式建议书,这张调音台有了更完整的谱子。AudioParam 让音量等参数的变化进入音频时间线,而不是靠一串焦急的页面回调。OfflineAudioContext 可以把整张声路图先渲染进缓冲区,不必马上从扬声器放出。应用能准备、查看或重复使用结果。声源、处理、时间与输出,仍是贯穿十年的基本骨架。

自定义效果也获得明确位置。建议书描述 AudioWorkletNode 与 AudioWorkletProcessor 配对:前者在主声路一侧,后者在专门的 worklet 环境中实现处理。程序可以给调音台增添自己的零件,浏览器仍保有专用的音频运行路径。规范还区分控制线程和渲染线程。页面上别的任务可以等一等,现场声音却不能为一个菜单动画排队。分工并非让脚本亲手搬动每一个采样值,而是让它指挥一套会按时工作的设备。

W3C 的发布历史从 2011 年 12 月工作草案走到 2021 年 6 月正式建议书。这些是规范文件的日期,并不自动告诉我们哪款浏览器何时先上线、用户增长了多少。它们能说明设计工作的体量:连接规则、声道处理、时钟、资源和输出都必须能一起工作。调音台的价值不是旋钮数量,而是旋钮接上去以后会发生什么。

应用因此有了宽阔的创作空间。游戏可给爆炸声安排方位;在线乐器可连接振荡器与滤波器;教学工具可用分析节点把声音画出来。浏览器提供共同的运转机制,应用决定自己的曲目。网页的要求从“播这个文件”变成“按这条线路做出我需要的声音”。

老点唱机不用被赶出房间。有时一首歌和一个按钮刚好合适。可当互动世界需要整支乐队跟着人的动作演奏,一枚按钮的编制就太寒酸了。Web Audio 把调音台搬进浏览器,把线路交给应用,剩下的仍要看作曲者有没有好耳朵。