aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/api/web_audio_api/index.html
blob: f7178d006c326bf89e8bd7af36c3018d04b5c82f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
---
title: Web Audio API
slug: Web/API/Web_Audio_API
tags:
  - HTML5音频
  - Web Audio API
translation_of: Web/API/Web_Audio_API
---
<div>
<p>Web Audio API 提供了在Web上控制音频的一个非常有效通用的系统,允许开发者来自选音频源,对音频添加特效,使音频可视化,添加空间效果 (如平移),等等。</p>
</div>

<h2 id="Web_audio_概念与使用">Web audio 概念与使用</h2>

<p>Web Audio API使用户可以在<strong>音频上下文</strong>(AudioContext)中进行音频操作,具有<strong>模块化路由</strong>的特点。在<strong>音频节点</strong>上操作进行基础的音频, 它们连接在一起构成<strong>音频路由图</strong>。即使在单个上下文中也支持多源,尽管这些音频源具有多种不同类型通道布局。这种模块化设计提供了灵活创建动态效果的复合音频的方法。</p>

<p>音频节点通过它们的输入输出相互连接,形成一个链或者一个简单的网。一般来说,这个链或网起始于一个或多个音频源。音频源可以提供一个片段一个片段的音频采样数据(以数组的方式),一般,一秒钟的音频数据可以被切分成几万个这样的片段。这些片段可以是经过一些数学运算得到 (比如{{domxref("OscillatorNode")}}),也可以是音频或视频的文件读出来的(比如{{domxref("AudioBufferSourceNode")}}{{domxref("MediaElementAudioSourceNode")}}),又或者是音频流({{domxref("MediaStreamAudioSourceNode")}})。其实,音频文件本身就是声音的采样数据,这些采样数据可以来自麦克风,也可以来自电子乐器,然后混合成一个单一的复杂的波形。</p>

<p>这些节点的输出可以连接到其它节点的输入上,然后新节点可以对接收到的采样数据再进行其它的处理,再形成一个结果流。一个最常见的操作是通过把输入的采样数据放大来达到扩音器的作用(缩小就是一个弱音器)(参见{{domxref("GainNode")}})。声音处理完成之后,可以连接到一个目的地({{domxref("AudioContext.destination")}}),这个目的地负责把声音数据传输给扬声器或者耳机。注意,只有当用户期望听到声音时,才需要进行最后一个这个连接。</p>

<p>一个简单而典型的web audio流程如下:</p>

<ol>
 <li>创建音频上下文</li>
 <li>在音频上下文里创建源 — 例如 <code>&lt;audio&gt;</code>, 振荡器, 流</li>
 <li>创建效果节点,例如混响、双二阶滤波器、平移、压缩</li>
 <li>为音频选择一个目的地,例如你的系统扬声器</li>
 <li>连接源到效果器,对目的地进行效果输出</li>
</ol>

<p><img alt="A simple box diagram with an outer box labeled Audio context, and three inner boxes labeled Sources, Effects and Destination. The three inner boxes have arrow between them pointing from left to right, indicating the flow of audio information." src="https://mdn.mozillademos.org/files/12241/webaudioAPI_en.svg"></p>

<p>使用这个API,时间可以被非常精确地控制,几乎没有延迟,这样开发人员可以准确地响应事件,并且可以针对采样数据进行编程,甚至是较高的采样率。这样,鼓点和节拍是准确无误的。</p>

<p>Web Audio API 也使我们能够控制音频的<em>空间化</em>。在基于<em>源 - 侦听器模型</em>的系统中,它允许控制<em>平移模型</em>和处理<em>距离引起的衰减</em>或移动源(移动侦听)引起的<em>多普勒效应</em></p>

<div class="note">
<p><strong>注意</strong>: 你可以阅读我们关于 Web Audio API 的文章来了解更多细节 <a href="/en-US/docs/Web/API/Web_Audio_API/Basic_concepts_behind_Web_Audio_API">Web Audio API背后的基本概念</a></p>
</div>

<h2 id="Web_Audio_API_接口">Web Audio API 接口</h2>

<p>Web Audio API共有一系列接口和相关的事件,我们已经把它们分成了九类功能。</p>

<h3 id="通用音频图定义">通用音频图定义</h3>

<p>Web Audio API 中与生成音频图相关的定义与通用容器。</p>

<dl>
 <dt>{{domxref("AudioContext")}}</dt>
 <dd><strong><code>AudioContext</code></strong>接口代表由音频模块构成的音频处理图。音频上下文控制其所包含节点的创建和音频处理、解码。使用其它接口前你必需创建一个<code>音频上下文</code>,一切操作都在这个环境里进行。</dd>
 <dt>{{domxref("AudioNode")}}</dt>
 <dd><strong><code>音频节点</code></strong><strong> </strong>接口是一个音频处理模块, 例如音频源({{HTMLElement("audio")}}{{HTMLElement("video")}}),音频输出、中间处理模块(例如:滤波器 {{domxref("BiquadFilterNode")}} 或者音量控制器 {{domxref("GainNode")}})。</dd>
 <dt>{{domxref("AudioParam")}}</dt>
 <dd><strong><code>AudioParam</code></strong><strong> </strong>接口代表音频相关的参数,比如一个 {{domxref("AudioNode")}}的参数。它可以设置为特定值或值的变化,并且可以在指定的时间之后以指定模式变更。</dd>
 <dt>{{event("ended")}}结束事件</dt>
 <dd>当媒体播放停止时,会触发<code>ended</code>事件。</dd>
</dl>

<h3 id="定义音频源">定义音频源</h3>

<p>Web Audio API 使用的音频源接口。</p>

<dl>
 <dt>{{domxref("OscillatorNode")}}</dt>
 <dd><strong><code style="font-size: 14px;">OscillatorNode</code></strong>接口代表一种随时间变化的波形,比如正弦波形或三角波形。类型是{{domxref("AudioNode")}},功能是音频处理模块,可以产生指定<em>频率</em>的波形。</dd>
 <dt>{{domxref("AudioBuffer")}}</dt>
 <dd><strong><code>AudioBuffer</code></strong>代表内存中的一段音频数据,可以通过{{ domxref("AudioContext.decodeAudioData()") }}方法从音频文件创建,也可以通过{{ domxref("AudioContext.createBuffer()") }}方法从原始数据创建。当音频数据被解码成这种格式之后,就可以被放入一个{{ domxref("AudioBufferSourceNode") }}中使用。</dd>
 <dt>{{domxref("AudioBufferSourceNode")}}</dt>
 <dd><strong><code>AudioBufferSourceNode</code></strong>表示由内存音频数据组成的音频源,音频数据存储在{{domxref("AudioBuffer")}}中。这是一个作为音频源的{{domxref("AudioNode")}}</dd>
 <dt>{{domxref("MediaElementAudioSourceNode")}}</dt>
 <dd><code><strong>MediaElementAudio</strong></code><strong><code>SourceNode</code></strong>接口表示由HTML5 {{ htmlelement("audio") }}{{ htmlelement("video") }}元素生成的音频源。这是一个作为音频源的{{domxref("AudioNode")}}</dd>
 <dt>{{domxref("MediaStreamAudioSourceNode")}}</dt>
 <dd><code><strong>MediaStreamAudio</strong></code><strong><code>SourceNode</code></strong>接口表示由 WebRTC {{domxref("MediaStream")}}(如网络摄像头或麦克风)生成的音频源。这是一个作为音频源的{{domxref("AudioNode")}}</dd>
</dl>

<h3 id="定义音效">定义音效</h3>

<p>应用到音频源上的音效。</p>

<dl>
 <dt>{{domxref("BiquadFilterNode")}}</dt>
 <dd><strong><code>BiquadFilterNode</code></strong><strong> </strong>接口表示一个简单的低频滤波器。它是一个{{domxref("AudioNode")}},可以表示不同种类的滤波器、调音器或图形均衡器。<code>BiquadFilterNode</code> 总是只有一个输入和一个输出。</dd>
 <dt>{{domxref("ConvolverNode")}}</dt>
 <dd><code><strong>Convolver</strong></code><strong><code>Node</code></strong><strong> </strong>接口是一个<span style="line-height: 1.5;">{{domxref("AudioNode")}}</span><span style="line-height: 1.5;">对给定的 AudioBuffer 执行线性卷积,通常用于实现混响效果</span><span style="line-height: 1.5;"></span></dd>
 <dt>{{domxref("DelayNode")}}</dt>
 <dd><strong><code>DelayNode</code></strong><strong> </strong>接口表示<a href="http://en.wikipedia.org/wiki/Digital_delay_line" title="http://en.wikipedia.org/wiki/Digital_delay_line">延迟线</a>;是{{domxref("AudioNode")}} 类型的音频处理模块,使输入的数据延时输出。</dd>
 <dt>{{domxref("DynamicsCompressorNode")}}</dt>
 <dd><strong><code>DynamicsCompressorNode</code></strong> 提供了一个压缩效果,当多个音频在同时播放并且混合的时候,可以通过它降低音量最大的部分的音量来帮助避免发生削波和失真。</dd>
 <dt>{{domxref("GainNode")}}</dt>
 <dd><strong><code>GainNode</code></strong><strong> </strong>接口用于音量变化。它是一个 {{domxref("AudioNode")}} 类型的音频处理模块,输入后应用<em>增益</em> 效果,然后输出。</dd>
 <dt>{{domxref("StereoPannerNode")}}</dt>
 <dd><code><strong>StereoPannerNode</strong></code> 接口表示一个简单立体声控制节点,用来左右移动音频流。</dd>
 <dt>{{domxref("WaveShaperNode")}}</dt>
 <dd><strong><code>WaveShaperNode</code></strong>接口表示一个非线性的扭曲。它是{{domxref("AudioNode")}}类型,可以利用曲线来对信号进行扭曲。除了一些效果明显的扭曲,还常被用来给声音添加温暖的感觉。</dd>
 <dt>{{domxref("PeriodicWave")}}</dt>
 <dd>用来定义周期性的波形,可被用来重塑 {{ domxref("OscillatorNode") }}的输出.</dd>
</dl>

<h3 id="定义音频目的地">定义音频目的地</h3>

<p>在你处理完音频之后,这些接口定义了输出到哪里。</p>

<dl>
 <dt>{{domxref("AudioDestinationNode")}}</dt>
 <dd><strong><code>AudioDestinationNode</code></strong> 定义了最后音频要输出到哪里,通常是输出到你的扬声器。</dd>
 <dt>{{domxref("MediaStreamAudioDestinationNode")}}</dt>
 <dd><code><strong>MediaStreamAudio</strong></code><strong><code>DestinationNode</code></strong>定义了使用 <a href="https://developer.mozilla.org/en-US/docs/WebRTC" title="/en-US/docs/WebRTC">WebRTC</a> 的{{domxref("MediaStream")}} (只包含单个AudioMediaStreamTrack)应该连接的目的地,AudioMediaStreamTrack的使用方式和从{{ domxref("MediaDevices.getUserMedia", "getUserMedia()") }}中得到{{domxref("MediaStream")}}相似。这个接口是{{domxref("AudioNode")}}类型的音频目的地。</dd>
</dl>

<h3 id="数据分析和可视化">数据分析和可视化</h3>

<p>如果你想从音频里提取时间、频率或者其它数据,你需要 AnalyserNode。</p>

<dl>
 <dt>{{domxref("AnalyserNode")}}</dt>
 <dd><strong><code>AnalyserNode</code></strong>表示一个可以提供实时频率分析与时域分析的切点,这些分析数据可以用做数据分析和可视化。</dd>
</dl>

<h3 id="分离、合并声道">分离、合并声道</h3>

<p>你将使用这些接口来拆分、合并声道。</p>

<dl>
 <dt>{{domxref("ChannelSplitterNode")}}</dt>
 <dd><code><strong>ChannelSplitterNode</strong></code>可以把输入流的每个声道输出到一个独立的输出流。</dd>
 <dt>{{domxref("ChannelMergerNode")}}</dt>
 <dd><code><strong>ChannelMergerNode</strong></code>用于把一组输入流合成到一个输出流。输出流的每一个声道对应一个输入流。</dd>
</dl>

<h3 id="声音空间效果">声音空间效果</h3>

<p>这些接口用来添加空间平移效果到音频源。</p>

<dl>
 <dt>{{domxref("AudioListener")}}</dt>
 <dd><strong><code>AudioListener</code></strong>代表场景中正在听声音的人的位置和朝向。</dd>
 <dt>{{domxref("PannerNode")}}</dt>
 <dd><strong><code>PannerNode</code></strong>用于表示场景是声音的空间行为。它是{{domxref("AudioNode")}}类型的音频处理模块,这个节点用于表示右手笛卡尔坐标系里声源的位置信息,运动信息(通过一个速度向量表示),方向信息(通过一个方向圆锥表示)。</dd>
</dl>

<h3 id="使用_JavaScript_处理音频">使用 JavaScript 处理音频</h3>

<p>可以编写JavaScript代码来处理音频数据。当然,这需要用到下面的接口和事件。</p>

<div class="note">
<p><strong>注意:</strong>这些功能在Web Audio API的2014年8月9日版本中已经标记为不推荐的,这些功能很快会被{{ anch("Audio_Workers") }}代替。</p>
</div>

<dl>
 <dt>{{domxref("ScriptProcessorNode")}}</dt>
 <dd><strong><code>ScriptProcessorNode</code></strong>接口用于通过JavaScript代码生成,处理,分析音频。它是一个{{domxref("AudioNode")}}类型的音频处理模块,但是它与两个缓冲区相连接,一个缓冲区里包含当前的输入数据,另一个缓冲区里包含着输出数据。每当新的音频数据被放入输入缓冲区,就会产生一个{{domxref("AudioProcessingEvent")}}事件,当这个事件处理结束时,输出缓冲区里应该写好了新数据。</dd>
 <dt>{{event("audioprocess")}} (event)</dt>
 <dd>当一个Web Audio API {{domxref("ScriptProcessorNode")}}已经准备好进行处理时,这个事件回调会被调用。</dd>
 <dt>{{domxref("AudioProcessingEvent")}}</dt>
 <dd>{{domxref("ScriptProcessorNode")}}的输入流数据准备好了时,<code>AudioProcessingEvent</code>事件会产生。</dd>
</dl>

<h3 id="离线(后台)音频处理">离线(后台)音频处理</h3>

<p>在后台进行音频的快速处理也是可以的。仅仅生成包含音频数据的{{domxref("AudioBuffer")}},而不在扬声器里播放它。</p>

<dl>
 <dt>{{domxref("OfflineAudioContext")}}</dt>
 <dd><strong><code>OfflineAudioContext</code></strong>离线音频上下文也是音频上下文{{domxref("AudioContext")}},也表示把{{domxref("AudioNode")}}连接到一起的一个音频处理图。但是,与一个标准的音频上下文相比,离线上下文不能把音频渲染到扬声器,仅仅是把音频渲染到一个缓冲区。</dd>
 <dt>{{event("complete")}} (event)</dt>
 <dd>Complete事件,当离线音频上下文被终止时产生。</dd>
 <dt>{{domxref("OfflineAudioCompletionEvent")}}</dt>
 <dd><code>OfflineAudioCompletionEvent</code>表示上下文被终止时的事件。</dd>
</dl>

<h3 id="Audio_Workers" name="Audio_Workers">音频工作者</h3>

<p>在了解这一部分内容之前,你可以先了解一个新的WebWorker方面的内容。音频工作者提供了一种可以在一个<a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers">WebWorker</a>上下文中直接进行音频处理的方式。现在已经定义了一些这部分功能的新接口,接口定义是在2014年的8月29日文档中。到目前为止,还没有浏览器已经对这些接口进行了实现。当这些接口被实现后,{{domxref("ScriptProcessorNode")}}<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Audio_API$edit#Audio_processing_via_JavaScript">前文</a>中提到的其它接口都会被替代。</p>

<dl>
 <dt>{{domxref("AudioWorkerNode")}}</dt>
 <dd>AudioWorkerNode也是{{domxref("AudioNode")}}类型,但是它用于与工作者线程合作来直接完成音频的生成,处理或分析等操作。</dd>
 <dt>{{domxref("AudioWorkerGlobalScope")}}</dt>
 <dd><code>AudioWorkerGlobalScope<font face="Open Sans, arial, sans-serif">继承于</font></code><code>DedicatedWorkerGlobalScope</code>。代表一个工作者上下文。这个工作者上下文里运行着对音频进行处理的脚本。设计这个接口的目的,是为了直接通过编写JavaScript代码,来完成对音频数据的生成,处理,分析工作。</dd>
 <dt>{{domxref("AudioProcessEvent")}}</dt>
 <dd>这是一个事件对象。这个对象会被分发给{{domxref("AudioWorkerGlobalScope")}}对象来进行处理。</dd>
</dl>

<h2 id="Example" name="Example">过时的接口</h2>

<p>下面介绍到的这些接口定义于比较老的Web Audio API标准,现在已经过时了,而且已经被新接口取代。</p>

<dl>
 <dt>{{domxref("JavaScriptNode")}}</dt>
 <dd>用于通过编写JavaScript代码直接处理音频数据,现在已经被{{domxref("ScriptProcessorNode")}}取代。</dd>
 <dt>{{domxref("WaveTableNode")}}</dt>
 <dd>用于定义一个周期性波形,现在已经被{{domxref("PeriodicWave")}}取代。</dd>
</dl>

<h2 id="Example" name="Example">示例</h2>

<p>下面的这个示例使用了较多的Web Audio API接口,可以通过访问<a href="https://mdn.github.io/voice-change-o-matic/">网址</a>来查看它的时时运行情况,也可以访问GitHub上它的<a href="https://github.com/mdn/voice-change-o-matic">源代码</a>。这个示例里会对声音的音量进行改变,打开页面时,可以先把扬声器的音量调小一些。</p>

<p>Web Audio API接口在下面的代码里已经高亮显示。</p>

<pre class="brush: js; highlight:[1,2,9,10,11,12,36,37,38,39,40,41,62,63,72,114,115,121,123,124,125,147,151]">var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); // define audio context
// Webkit/blink browsers need prefix, Safari won't work without window.

var voiceSelect = document.getElementById("voice"); // select box for selecting voice effect options
var visualSelect = document.getElementById("visual"); // select box for selecting audio visualization options
var mute = document.querySelector('.mute'); // mute button
var drawVisual; // requestAnimationFrame

var analyser = audioCtx.createAnalyser();
var distortion = audioCtx.createWaveShaper();
var gainNode = audioCtx.createGain();
var biquadFilter = audioCtx.createBiquadFilter();

function makeDistortionCurve(amount) { // function to make curve shape for distortion/wave shaper node to use
  var k = typeof amount === 'number' ? amount : 50,
    n_samples = 44100,
    curve = new Float32Array(n_samples),
    deg = Math.PI / 180,
    i = 0,
    x;
  for ( ; i &lt; n_samples; ++i ) {
    x = i * 2 / n_samples - 1;
    curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );
  }
  return curve;
};

navigator.getUserMedia (
  // constraints - only audio needed for this app
  {
    audio: true
  },

  // Success callback
  function(stream) {
    source = audioCtx.createMediaStreamSource(stream);
    source.connect(analyser);
    analyser.connect(distortion);
    distortion.connect(biquadFilter);
    biquadFilter.connect(gainNode);
    gainNode.connect(audioCtx.destination); // connecting the different audio graph nodes together

    visualize(stream);
    voiceChange();

  },

  // Error callback
  function(err) {
    console.log('The following gUM error occured: ' + err);
  }
);

function visualize(stream) {
  WIDTH = canvas.width;
  HEIGHT = canvas.height;

  var visualSetting = visualSelect.value;
  console.log(visualSetting);

  if(visualSetting == "sinewave") {
    analyser.fftSize = 2048;
    var bufferLength = analyser.frequencyBinCount; // half the FFT value
    var dataArray = new Uint8Array(bufferLength); // create an array to store the data

    canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);

    function draw() {

      drawVisual = requestAnimationFrame(draw);

      analyser.getByteTimeDomainData(dataArray); // get waveform data and put it into the array created above

      canvasCtx.fillStyle = 'rgb(200, 200, 200)'; // draw wave with canvas
      canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

      canvasCtx.lineWidth = 2;
      canvasCtx.strokeStyle = 'rgb(0, 0, 0)';

      canvasCtx.beginPath();

      var sliceWidth = WIDTH * 1.0 / bufferLength;
      var x = 0;

      for(var i = 0; i &lt; bufferLength; i++) {

        var v = dataArray[i] / 128.0;
        var y = v * HEIGHT/2;

        if(i === 0) {
          canvasCtx.moveTo(x, y);
        } else {
          canvasCtx.lineTo(x, y);
        }

        x += sliceWidth;
      }

      canvasCtx.lineTo(canvas.width, canvas.height/2);
      canvasCtx.stroke();
    };

    draw();

  } else if(visualSetting == "off") {
    canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);
    canvasCtx.fillStyle = "red";
    canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
  }

}

function voiceChange() {
  distortion.curve = new Float32Array;
  biquadFilter.gain.value = 0; // reset the effects each time the voiceChange function is run

  var voiceSetting = voiceSelect.value;
  console.log(voiceSetting);

  if(voiceSetting == "distortion") {
    distortion.curve = makeDistortionCurve(400); // apply distortion to sound using waveshaper node
  } else if(voiceSetting == "biquad") {
    biquadFilter.type = "lowshelf";
    biquadFilter.frequency.value = 1000;
    biquadFilter.gain.value = 25; // apply lowshelf filter to sounds using biquad
  } else if(voiceSetting == "off") {
    console.log("Voice settings turned off"); // do nothing, as off option was chosen
  }

}

// event listeners to change visualize and voice settings

visualSelect.onchange = function() {
  window.cancelAnimationFrame(drawVisual);
  visualize(stream);
}

voiceSelect.onchange = function() {
  voiceChange();
}

mute.onclick = voiceMute;

function voiceMute() { // toggle to mute and unmute sound
  if(mute.id == "") {
    gainNode.gain.value = 0; // gain set to 0 to mute sound
    mute.id = "activated";
    mute.innerHTML = "Unmute";
  } else {
    gainNode.gain.value = 1; // gain set to 1 to unmute sound
    mute.id = "";
    mute.innerHTML = "Mute";
  }
}
</pre>

<h2 id="规范">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('Web Audio API')}}</td>
   <td>{{Spec2('Web Audio API')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>

{{Compat("api.AudioContext", 0)}}

<h2 id="相关链接">相关链接</h2>

<ul>
 <li><a href="/en-US/docs/Web/API/Web_Audio_API/Using_Web_Audio_API">Using the Web Audio API</a></li>
 <li><a href="/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API">Visualizations with Web Audio API</a></li>
 <li><a href="http://mdn.github.io/voice-change-o-matic/">Voice-change-O-matic example</a></li>
 <li><a href="http://mdn.github.io/violent-theremin/">Violent Theremin example</a></li>
 <li><a href="/en-US/docs/Web/API/Web_Audio_API/Web_audio_spatialisation_basics">Web audio spatialisation basics</a></li>
 <li><a href="http://www.html5rocks.com/tutorials/webaudio/positional_audio/" title="http://www.html5rocks.com/tutorials/webaudio/positional_audio/">Mixing Positional Audio and WebGL</a></li>
 <li><a href="http://www.html5rocks.com/tutorials/webaudio/games/" title="http://www.html5rocks.com/tutorials/webaudio/games/">Developing Game Audio with the Web Audio API</a></li>
 <li><a href="/en-US/docs/Web/API/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext" title="/en-US/docs/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext">Porting webkitAudioContext code to standards based AudioContext</a></li>
 <li><a href="https://github.com/bit101/tones">Tones</a>: a simple library for playing specific tones/notes using the Web Audio API.</li>
 <li><a href="https://github.com/goldfire/howler.js/">howler.js</a>: a JS audio library that defaults to <a href="https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html">Web Audio API</a> and falls back to <a href="http://www.whatwg.org/specs/web-apps/current-work/#the-audio-element">HTML5 Audio</a>, as well as providing other useful features.</li>
</ul>

<section id="Quick_links">
<h3 id="Quicklinks">Quicklinks</h3>

<ol>
 <li data-default-state="open"><strong><a href="#">Guides</a></strong>

  <ol>
   <li><a href="/zh-CN/docs/Web/API/Web_Audio_API/Basic_concepts_behind_Web_Audio_API">Basic concepts behind Web Audio API</a></li>
   <li><a href="/zh-CN/docs/Web/API/Web_Audio_API/Using_Web_Audio_API">Using the Web Audio API</a></li>
   <li><a href="/zh-CN/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API">Visualizations with Web Audio API</a></li>
   <li><a href="/zh-CN/docs/Web/API/Web_Audio_API/Web_audio_spatialisation_basics">Web audio spatialisation basics</a></li>
   <li><a href="/zh-CN/docs/Web/API/Web_Audio_API/Porting_webkitAudioContext_code_to_standards_based_AudioContext">Porting webkitAudioContext code to standards based AudioContext</a></li>
  </ol>
 </li>
 <li data-default-state="open"><strong><a href="#">Examples</a></strong>
  <ol>
   <li><a href="http://mdn.github.io/voice-change-o-matic/">Voice-change-O-matic</a></li>
   <li><a href="http://mdn.github.io/violent-theremin/">Violent Theremin</a></li>
  </ol>
 </li>
 <li data-default-state="open"><strong><a href="#">Interfaces</a></strong>
  <ol>
   <li>{{domxref("AnalyserNode")}}</li>
   <li>{{domxref("AudioBuffer")}}</li>
   <li>{{domxref("AudioBufferSourceNode")}}</li>
   <li>{{domxref("AudioContext")}}</li>
   <li>{{domxref("AudioDestinationNode")}}</li>
   <li>{{domxref("AudioListener")}}</li>
   <li>{{domxref("AudioNode")}}</li>
   <li>{{domxref("AudioParam")}}</li>
   <li>{{event("audioprocess")}} (event)</li>
   <li>{{domxref("AudioProcessingEvent")}}</li>
   <li>{{domxref("BiquadFilterNode")}}</li>
   <li>{{domxref("ChannelMergerNode")}}</li>
   <li>{{domxref("ChannelSplitterNode")}}</li>
   <li>{{event("complete")}} (event)</li>
   <li>{{domxref("ConvolverNode")}}</li>
   <li>{{domxref("DelayNode")}}</li>
   <li>{{domxref("DynamicsCompressorNode")}}</li>
   <li>{{event("ended_(Web_Audio)", "ended")}} (event)</li>
   <li>{{domxref("GainNode")}}</li>
   <li>{{domxref("MediaElementAudioSourceNode")}}</li>
   <li>{{domxref("MediaStreamAudioDestinationNode")}}</li>
   <li>{{domxref("MediaStreamAudioSourceNode")}}</li>
   <li>{{domxref("OfflineAudioCompletionEvent")}}</li>
   <li>{{domxref("OfflineAudioContext")}}</li>
   <li>{{domxref("OscillatorNode")}}</li>
   <li>{{domxref("PannerNode")}}</li>
   <li>{{domxref("PeriodicWaveNode")}}</li>
   <li>{{domxref("ScriptProcessorNode")}}</li>
   <li>{{domxref("WaveShaperNode")}}</li>
  </ol>
 </li>
</ol>
</section>