媒介本文翻译自MDN上的《WebAudioAPIの运用》,这是HTML5中的WebAudioAPI的一个入门教程。原文是英文,但有日本同道翻译的日文版。我更熟习日文,所以重要依据日
媒介 本文翻译自MDN上的《Web Audio APIの运用》,这是HTML5中的Web Audio API的一个入门教程。原文是英文,但有日本同道翻译的日文版。我更熟习日文,所以重要依据日文版翻译成简体中文,也会对比英文版的。
Web Audio API的运用 Web Audio API供应给你一个简朴却壮大的机制,你可以运用它去完成与操纵web运用内的音频内容。经由历程它,在网页中你也可以举行混音、音效、平移等种种庞杂的音频处置惩罚功用的开辟。这篇文章重要想经由历程两个简朴的例子来申明Web Audio API的基础运用要领。
Web Audio API并非替换 标签的东西,换句话说Web Audio API实际上是对 标签功用上的补充。二者的关联可以类比 标签与 标签。详细改选用哪一个取决于你的目标是什么。假如只是为了简朴地掌握音频的播放的话,标签更适合吧。然则假如有更庞杂的音频处置惩罚需求的话,就必需运用Web Audio API。
Web Audio API的一个壮大的处所是它没有严厉的[发出声响的数量标限定]。比方,一秒内可以同时发出32个声响或64个声响,但这并非上限。CPU的处置惩罚才能充足的话,1000多种声响也可以不经由紧缩直接播放。假如如许发展下去的话,几年以后的中高端声卡的负荷会大大下降的吧。
PS:补充点背景学问,这里提到的32,64指的是复音数。复音数指MIDI乐曲在一秒钟内发出的最大声响数量。关于复音数和MIDI乐曲可以百度一下。声卡硬件会限定复音数,部份软件运用CPU完成声响播放的也会限定复音数。但理论上只需CPU处置惩罚才可以强复音数是不受限的。所以上段说起Web Audio Api是软件,但它没有复音数限定,所以说到只需CPU处置惩罚才可以强,将来也许可以下降对中高端声卡机能的需求
例子 为了展示Web Audio API的用法,我们编写了一些例子,这些例子会不断地增添更新。请人人发扬开源 精力为项目增加用例或许提出更好的改良看法!
PS:这些例子最幸亏最新版chrome中运转
起首引见一下 Voice-change-O-matic 。这是一个有变声及声响可视化功用的网页运用,且有一些变声结果与可视化结果可供挑选。虽然这个运用另有许多可以改良的处所,但也不失为综合运用Web Audio API的许多功用的一个好例子。(可以在这里运转 Voice-change-O-matic)
PS:上面的这个例子我运转没结果啊,不知道怎样玩 *PS:感谢vino24补充的,该例子须要https,在chrome下可运转
为了明白Web Audio而编写的另一个例子就是这个Violent Theremin。这是一个简朴的运用,它许可你经由历程鼠标指针的挪动来转变频次和音量。别的,鼠标挪动历程另有迷幻色泽的视觉结果。(Violent Theremin的源码在这里)
基础思路 备注:下面枚举的大多数的代码片断都在Violent Theremin中有运用。
Web Audio API的架构设想使得它可以轻松完成模块路由,个中包含对高低文中的音频内容的操纵。基础的音频编辑可以运用audio node举行。但这些节点互相可以衔接起来,可以组成一个节点图。多个音源或许差别品种的频道终究都可以对应到一个高低文中。如许模块化的设想是为了供应充足天真的特征以便开辟可以动态转变结果的庞杂的音频编辑功用。
audio node有进口和出口,多个节点组成相似链表一样的构造。从一个或许多个音源动身,经由一个或许多个处置惩罚节点,终究输出到输出节点(输出终端,平常是扬声器)。(假如有需求的话,也可以不指定输出节点。比方,想把音频数据用图表的情势展示的场所等。)web audio的一个简朴的典范的流程类是下面如许子:
竖立AudioContext对象
在AudioContext对象内设置音源,比方标签,震惊发声器,音频流
竖立effect node(结果节点)。比方reverb, biquad filter, panner, compressor(这些都是音频殊效)
挑选音频的终究输出节点。比方,你的电脑的扬声器
音频经由结果节点处置惩罚后,然后输出到下一个节点,这些节点衔接起来
竖立AudioContext对象 起首,为了构建audio节点图,我们起首要竖立竖立AudioContext对象。最简朴的要领就像如许:
var audioCtx = new AudioContext();
备注:虽然可以在一个document中竖立多个AudioContext对象,但这生怕没什么卵用。
然则,Webkit/Blink内核的浏览器不须要前缀,Firefox(desktop/mobile/OS)的浏览器能够须要前缀,所以为了兼容性斟酌,最好写成如许:
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
竖立AudioSource 经由历程竖立的AudioContext对象的要领,我们可以举行林林总总的操纵。最初举行的就是,准备要播放的音源。下面列出的东西都可以作为音源:
运用震惊发声器与Javascript竖立音源的状况:运用AudioContext.createOscillator这个要领竖立OscillatorNode。以后就可以运用震惊发声器做音源了。
运用原始的PCM数据的状况:假如是可以辨认的特定的花样的话(mp3之类的),运用AudioContext的特定的decode要领,来取得PCM数据。详细状况可以看这些,AudioContext.createBuffer()、AudioContext.createBufferSource()、AudioContext.decodeAudioData() 。
运用标签或许标签等HTML元素的状况:详细状况可以看这个,AudioContext.createMediaElementSource()
从WebRTC MediaStream(WebRTC媒体流)输入音频源的状况:可以运用麦克风或许Web摄像头。详细状况看这个,AudioContext.createMediaStreamSource()
简朴地把震惊发声器作为音源,运用gain节点掌握音量,这就组成我我们接下来要说的例子:
oscillator = audioCtx.createOscillator(); var gainNode = audioCtx.createGain();
备注:假如要播放音乐文件(mp3之类的),平常要运用XHR载入文件数据,那以后竖立BufferSource。在这个示例Voice-change-O-matic有代码。
备注:Scott Michaud封装了载入和解码音频的代码,开源了一个库,叫AudioSampleLoader。运用这个的话,XHR以及buffer的操纵都邑变得非常简朴。
输入与输出的衔接 要想音源(输入)经由历程扬声器(输出)播放出来,就必需要把二者衔接起来。将被衔接的节点作为参数,挪用本来节点的的connect要领就可以竖立节点间的衔接。大多数范例的节点对象都具有这个要领。
关于规范的输出节点可以参考,AudioContext.destination。规范的输出节点通常是装备的扬声器。把oscillator衔接到gainNode上,gainNode的输出衔接到规范输出上,代码以下:
oscillator.connect(gainNode); gainNode.connect(audioCtx.destination);
但假如像Voice-change-O-matic一样,比较庞杂的状况的话。须要像下面一样将多个节点衔接起来,构成一张图。:
source = audioCtx.createMediaStreamSource(stream); source.connect(analyser); analyser.connect(distortion); distortion.connect(biquadFilter); biquadFilter.connect(convolver); convolver.connect(gainNode); gainNode.connect(audioCtx.destination);
上面的代码竖立出的audio图以下:
多个节点可以同时衔接同一个节点。也可以让多个音源经由历程一个结果节点,到达混音的结果。
备注:Firefox 32 以上版本,在Firefox开辟工具中Web Audio编辑器了。有了它以后大大提高了对audio节点图举行debug的效力。
播放与声调的设定 竖立完audio节点图后,就可以经由历程设定audio节点的属性值或许挪用要领来调解节点的结果。下面的例子,我们来设定下震惊发声器的声调,运用Hz这个单元,以下:
oscillator.type = 0; // sine wave,正弦波 oscillator.frequency.value = 2500; // value in hertz oscillator.start();
在Violent Theremin这个顺序中,设定了音量与周波数的最大值,以下:
var WIDTH = window.innerWidth; var HEIGHT = window.innerHeight; var maxFreq = 6000; var maxVol = 1; var initialFreq = 3000; var initialVol = 0.5; // set options for the oscillator oscillator.type = 0; // sine wave oscillator.frequency.value = initialFreq; // value in hertz oscillator.start(); gainNode.gain.value = initialVol;
加下来是跟着鼠标的挪动,根据设定转变周波数。鼠标指针的X坐标和Y坐标以及周波数和音量的最大值,这些决议了终究输出声响的周波数和音量。代码以下:
// Mouse pointer coordinates var CurX; var CurY; // Get new mouse pointer coordinates when mouse is moved // then set new gain and putch values document.Onmousemove= updatePage; function updatePage(e) { CurX = (window.Event) ? e.pageX : event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft); CurY = (window.Event) ? e.pageY : event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); oscillator.frequency.value = (CurX/WIDTH) * maxFreq; gainNode.gain.value = (CurY/HEIGHT) * maxVol; canvasDraw(); }
运用Canvas完成简朴的可视化结果 canvasDraw()是一个每次鼠标挪动都邑挪用的要领。每次挪用这个要领,都邑在鼠标指针位置地点的处所,把输出音频的周波数和音量用差别大小和差别色彩表现(画)出来。
function random(number1,number2) { var randomNo = number1 + (Math.floor(Math.random() * (number2 - number1)) + 1); return randomNo; } var canvas = document.querySelector('.canvas'); canvas.width = WIDTH; canvas.height = HEIGHT; var canvasCtx = canvas.getContext('2d'); function canvasDraw() { rX = CurX; rY = CurY; rC = Math.floor((gainNode.gain.value/maxVol)*30); canvasCtx.globalAlpha = 0.2; for(i=1;i<=15;i=i+2) { canvasCtx.beginPath(); canvasCtx.fillStyle = 'rgb(' + 100+(i*10) + ',' + Math.floor((gainNode.gain.value/maxVol)*255) + ',' + Math.floor((oscillator.frequency.value/maxFreq)*255) + ')'; canvasCtx.arc(rX+random(0,50),rY+random(0,50),rC/2+i,(Math.PI/180)*0,(Math.PI/180)*360,false); canvasCtx.fill(); canvasCtx.closePath(); } }
静音 按下静音按钮后,会实行下面的函数。经由历程把Gain节点与前面衔接的节点割断,使得声响的输出消逝。再按一次按钮,就会恢复节点之间的衔接,使得声响恢复输出。
var mute = document.querySelector('.mute'); mute.Onclick= function() { if(mute.id == "") { gainNode.disconnect(audioCtx.destination); mute.id = "activated"; mute.innerHTML = "Unmute"; } else { gainNode.connect(audioCtx.destination); mute.id = ""; mute.innerHTML = "Mute"; } }
其他的节点 在 Web Audio API中其他另有许多的品种的节点可以运用。竖立节点、节点与节点之间衔接起来,构成节点图,以后经由历程属性和要领来转变声响。从这些点来看,所以节点的运用体式格局都差不多。
下面,我们概要地看一下几个节点。各个节点的详细状况可以在Web_Audio_API中看。
Wave shaper 节点 经由历程AudioContext.createWaveShaper这个要领,可以竖立WaveShaper节点。
var distortion = audioCtx.createWaveShaper();
要想让这个对象事情,必需赋予与决议波形的函数。经由历程将这个函数运用于输入的波形,WaveShaper节点可以歪曲声响。对新手来讲,一开始写出这个函数是很难题的吧。经由历程在收集上搜刮,选用适宜的计划就好了。下面是一个宣布在Stack Overflow上的例子:
function makeDistortionCurve(amount) { var k = typeof amount === 'number' ? amount : 50, n_samples = 44100, curve = new Float32Array(n_samples), deg = Math.PI / 180, i = 0, x; for ( ; i x = i * 2 / n_samples - 1; curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) ); } return curve; };
在Voice-Change-O-Metic这个例子中,竖立了一个叫做distortion的WaveShaper节点,供应了必要的音频歪曲结果。代码以下:
source.connect(analyser); analyser.connect(distortion); distortion.connect(biquadFilter); ... distortion.curve = makeDistortionCurve(400);
双二阶过滤器 双二阶过滤器的内部有多个设置项目。可以经由历程AudioContext.createBiquadFilter这个要领竖立。
var biquadFilter = audioCtx.createBiquadFilter();
在Voice-Change-o-Metic这个例子中,运用的是典范的lowshelf 过滤器。这是为了供应一个基础的低音増幅结果:
biquadFilter.type = "lowshelf"; biquadFilter.frequency.value = 1000; biquadFilter.gain.value = 25;
在这个例子中可以设定过滤器的品种,周波数,以至gain的值。假如是lowshelf过滤器的话,可以供应一个比指定周波数低25dB的低音増幅。
关于其他的Web Audio API的内容 运用Web Audio API的话,可以做到音频的可视化与立体化(比方音频平移等)。关于这些,我们在其他的文档中申明。
跋文 终究完了。
翻译技术文章远比设想的要难题,特别是碰到许多生疏的某个范畴下的专有辞汇。
日语真是奇异,许多硬是用片假名套英文的状况,呵呵呵,让我想起了,特律风。
文中难免有错的处所,愿望人人能指出来,协助文章更好,感谢。
感谢,@说说说说