web audio apis 种类丰富,看这些apis纯属个人兴趣,没事折腾一下。
比较好的网站:
- learning-web-audio-api
- Get start with web audio api
- web audio school && web-audio-school github
- web audio tool
- MDN web audio api
本文就是链接3中的一些笔记:
基础介绍
web audio api提供了很多控制音频的apis.允许开发者选取音频源,添加音频效果,创建音频可视化,应用空间效果等。
1.创建
AudioContext
这是是用来链接一系列节点,从而形成一条信号链(singal path):
Inputs --> Effects --> Destination
从Inputs到Destination就是通过这个上下文来链接起来的。
创建audioContext:
var audioContext = new AudioContext();
OscillatorNode
OscillatorNode(振荡节点): 它能够产生任何频率(frequency)和所有基本波形(wave shapes),比如: sine
| sawtooth(锯齿)
| triangle
| square
。
1.type
波形type
1.创建一个简单的音频音调
例如:
# 创建一个振荡器
var oscillator = audioContext.createOscillator();
# 选择一种信号波形(waveform shape)
# 可选的有 sine, sawtooth, triangle, square
oscillator.type = 'sawtooth';
# 连接Destination(扬声器)
oscillator.connect(audioContext.destination);
# currentTime 可读可写, 未设置默认为0
oscillator.start(audioContext.currentTime); // 开始
oscillator.stop(audioContext.currentTime + 2); // 2s后停止
完整代码:
var audioContext = new AudioContext();
var oscillator = audioContext.createOscillator();
oscillator.type = 'square';
oscillator.connect(audioContext.destination);
oscillator.start(audioContext.currentTime);
oscillator.stop(audioContext.currentTime + 2);
2.frequency
振荡器节点有个属性叫 frequency, 单位: Hz(赫兹), 默认为 440Hz。
改变音调。
oscillator.frequency是 AudioParam实例,大多数Audio Nodes都是AudioParam实例,这个类有很多的属性。
设置频率:
oscillator.frequency.value = 880; // 单位Hz
# 直接设置frequency,错误
oscillator.frequency = 800; // 错误
3.半音阶(Chromatic Scale)
半音阶计算有些技巧,因为频率(frequency)将倍率(octave)(12个半音)翻倍。
(Chromatic note frequencies are slightly tricky to calculate because the frequency doubles every octace(12 semitones) you go up)
计算公式:
# noteOffset: 音色偏移
baseFrequency * Math.pow(2, noteOffset / 12)
比如从 middle A 上升7个半音(7 semitones) E, 则计算为:
oscillator.frequency.value = 440 * Math.pow(2, 7 / 12); // 659.255..
再比如,下降14个半音到 G:
oscillator.frequency.value = 440 * Math.pow(2, -14 / 12); // 195.998..
一个简单点的计算方式
使用OscillatorNode的 detune(失谐)属性,这个属性允许使用半音的百分之一。
比如使用detune,如果想从 Middle A 上升 7个半音到 E,则可以:
oscillator.detune.value = 700 // noteOffset * 100
注意点
- 频率与音调(半音阶)之间的关系计算:
baseFrequency * Math(2, noteOffset / 12)
- Middle A 是440Hz, 即振荡器默认的频率
- Octave指八度音阶, semitones 指音阶, chromatic scale指半音阶
- 使用detune来转换音频,以100分之一直接设置
noteOffset
即可
连续播放示例
var ctx = new AudioContext();
function play(delay, pitch, duration) {
var startTime = ctx.currentTime + delay;
var endTime = startTime + duration;
// 定义一个振荡器
var oscillator = ctx.createOscillator();
// 定义音色
oscillator.frequency.value = 440 * Math.pow(2, pitch / 12);
// 或者
// oscillator.detune.value = pitch * 100;
// 连接destination
oscillator.connect(ctx.destination);
// 开始和结束
oscillator.start(startTime);
oscillator.end(endTime);
}
// 调用,通过delay产生连续的音频
play(0, 3, 0.5);
play(1, 10, 0.5);
play(2, 15, 0.5);
4.对音频进行过滤:BiquadFilterNode
高通滤波(high-pass filter):即对低频的音色进行过滤,保留高频的音色。
使用 BiquadFilterNode 对音频进行控制, 过滤的类型有 lowpass
(默认值) | highpass
| bandpass
| lowshelf
| highshelf
| peaking
| notch
| allpass
.
Biquad Filter 字面意思是: 二阶滤波器。
Lowpass
lowpass 过滤是默认的类型,允许低于该频率的信号通过,高频的则过滤掉。
var filter = audioContext.createBiquadFilter();
filter.connect(audioContext.destination);
oscillator.connect(filter);
// 过滤掉所有高于500Hz的音频
filter.type = 'lowpass';
filter.frequency.value = 500;
highpass
highpass指高频的通过,低频的过滤掉
// 低于3000都被过滤
filter.type = 'highpass';
filter.frequency.value = 3000;
bandpass
允许频率有个公差(tolerance), 通过 Q 来指定, Q值越大, frequency越低
filter.type = 'bandpass';
filter.frequency.value = 1000;
filter.Q.value = 1
5.调节音频(modulate filter cutoff)
对于 AudioParam 实例 frequency 有几个方法可以在指定时间内改变音频
setValueAtTime(value, time)
在一个精确的时间设置一个常量更改AudioParam的值,以AudioContext.currentTime来衡量
linearRampToValueAtTime(value, endTime)
线性的改变AudioParam的值
exponentialRampToValueAtTime(value, endTime)
以指数方式该案AudioParam的值
示例:
// 预设频率,避免在起始时就跳动
filter.frequency.value = 200;
// 计划开始时间
filter.frequency.setValueAtTime(200, audioContext.currentTime)
// 变化(ramp)到指定值,在规定时间内
filter.frequency.linearRampToValueAtTime(6000, audioContext.currentTime + 2) // 2s
6.Gain Node 增益效果
使用 GainNode 来改变输出音量
# 创建增益节点
var amp = audioContext.createGain();
# 连接到destination
amp.connect(audioContext.destination);
# 音量减半
amp.gain.value = 0.5
可以使用 setTargetAtTime()
对增益的值进行实时扫描
/*
* targetValue: 0 | 1, 0表示开始时, 1表示结束时
* startTime: audioContext.currentTime
* tiemConstant: 指数衰减率(0 - 1),时间常量,秒为单位
*/
setTargetAtTime(targetValue, startTime, timeConstant)
有两种方式 Attact(开始时柔化声音0-1) 和 Release(在尾部柔化声音1-0)
var startTime = audioContext.currentTime;
amp.gain.value = 0; // 0 - 100
amp.gain.setTargetAtTime(0, startTime, 0.1);
var endTime = startTime + 2;
amp.setTargetAtTime(1, endTime, 0.2)
7.颤音(Vibrato)
在振荡器连接 oscillator.detune 之前放大输出效果
改变失谐(detune)值 在 2Hz时, +/- 100 cents
var vibrato = audioContext.createGain();
vibrato.gain.value = 100;
vibrato.connect(oscillator.detune);
var lfo = audioContext.createOscillator();
lfo.connect(vibrato);
lfo.frequency.value = 2;
lfo.start(audio.currentTime);
lfo.stop(audio.currentTime + 2);
总结
对一些新的API进行了粗略的了解,大多专业名词,但是实现原理比较简单, 输入音频源,经过AudioContext,将各种效果节点连接起来,然后输出音频源
专业词汇比如:
- 振荡器(OscillatorNode)
- 半音阶使用frequency表示的公式,也可以使用失谐detune表示
- 音频过滤器BiquadFilterNode
- 增益都节点音量进行调节GainNode, 还可以使用颤音效果, 对特定频率的音色进行波动
其他的一些效果如下:
var audioContext = new AudioContext()
var analyser = audioContext.createAnalyser() // 分析器
var distortion = audioContext.createWaveShaper() // 扭曲器
var gainNode = audioContext.createGain() // 增益
var convolver = audioContext.createConvolver() // 卷积器
var biquadFilter = audioContext.createBiquadFilter() // 音频过滤器