#1 浏览器 make sound

web audio apis 种类丰富,看这些apis纯属个人兴趣,没事折腾一下。
比较好的网站:

  1. learning-web-audio-api
  2. Get start with web audio api
  3. web audio school && web-audio-school github
  4. web audio tool
  5. MDN web audio api

本文就是链接3中的一些笔记:

基础介绍

web audio api提供了很多控制音频的apis.允许开发者选取音频源,添加音频效果,创建音频可视化,应用空间效果等。

1.创建AudioContext

这是是用来链接一系列节点,从而形成一条信号链(singal path):

Inputs --> Effects --> Destination

InputsDestination就是通过这个上下文来链接起来的。

创建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.frequencyAudioParam实例,大多数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)

#1 浏览器 make sound_第1张图片

计算公式

# 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,将各种效果节点连接起来,然后输出音频源

专业词汇比如:

  1. 振荡器(OscillatorNode)
  2. 半音阶使用frequency表示的公式,也可以使用失谐detune表示
  3. 音频过滤器BiquadFilterNode
  4. 增益都节点音量进行调节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() // 音频过滤器

你可能感兴趣的:(#1 浏览器 make sound)