web audio apis 種類豐富腌且,看這些apis純屬個人興趣,沒事折騰一下千诬。
比較好的網(wǎng)站:
- 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中的一些筆記:
基礎(chǔ)介紹
web audio api提供了很多控制音頻的apis.允許開發(fā)者選取音頻源敏储,添加音頻效果,創(chuàng)建音頻可視化踩麦,應用空間效果等。
1.創(chuàng)建
AudioContext
這是是用來鏈接一系列節(jié)點氓癌,從而形成一條信號鏈(singal path):
Inputs --> Effects --> Destination
從Inputs到Destination就是通過這個上下文來鏈接起來的谓谦。
創(chuàng)建audioContext:
var audioContext = new AudioContext();
OscillatorNode
OscillatorNode(振蕩節(jié)點): 它能夠產(chǎn)生任何頻率(frequency)和所有基本波形(wave shapes),比如: sine
| sawtooth(鋸齒)
| triangle
| square
。
1.type
波形type
1.創(chuàng)建一個簡單的音頻音調(diào)
例如:
# 創(chuàng)建一個振蕩器
var oscillator = audioContext.createOscillator();
# 選擇一種信號波形(waveform shape)
# 可選的有 sine, sawtooth, triangle, square
oscillator.type = 'sawtooth';
# 連接Destination(揚聲器)
oscillator.connect(audioContext.destination);
# currentTime 可讀可寫贪婉, 未設(shè)置默認為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
振蕩器節(jié)點有個屬性叫 frequency反粥, 單位: Hz(赫茲), 默認為 440Hz疲迂。
改變音調(diào)才顿。
oscillator.frequency是 AudioParam實例,大多數(shù)Audio Nodes都是AudioParam實例尤蒿,這個類有很多的屬性郑气。
設(shè)置頻率:
oscillator.frequency.value = 880; // 單位Hz
# 直接設(shè)置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
注意點
- 頻率與音調(diào)(半音階)之間的關(guān)系計算:
baseFrequency * Math(2, noteOffset / 12)
- Middle A 是440Hz, 即振蕩器默認的頻率
- Octave指八度音階奏属, semitones 指音階跨跨, chromatic scale指半音階
- 使用detune來轉(zhuǎn)換音頻,以100分之一直接設(shè)置
noteOffset
即可
連續(xù)播放示例
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);
// 開始和結(jié)束
oscillator.start(startTime);
oscillator.end(endTime);
}
// 調(diào)用,通過delay產(chǎn)生連續(xù)的音頻
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.調(diào)節(jié)音頻(modulate filter cutoff)
對于 AudioParam 實例 frequency 有幾個方法可以在指定時間內(nèi)改變音頻
setValueAtTime(value, time)
在一個精確的時間設(shè)置一個常量更改AudioParam的值慰技,以AudioContext.currentTime來衡量
linearRampToValueAtTime(value, endTime)
線性的改變AudioParam的值
exponentialRampToValueAtTime(value, endTime)
以指數(shù)方式該案AudioParam的值
示例:
// 預設(shè)頻率椭盏,避免在起始時就跳動
filter.frequency.value = 200;
// 計劃開始時間
filter.frequency.setValueAtTime(200, audioContext.currentTime)
// 變化(ramp)到指定值,在規(guī)定時間內(nèi)
filter.frequency.linearRampToValueAtTime(6000, audioContext.currentTime + 2) // 2s
6.Gain Node 增益效果
使用 GainNode 來改變輸出音量
# 創(chuàng)建增益節(jié)點
var amp = audioContext.createGain();
# 連接到destination
amp.connect(audioContext.destination);
# 音量減半
amp.gain.value = 0.5
可以使用 setTargetAtTime()
對增益的值進行實時掃描
/*
* targetValue: 0 | 1, 0表示開始時吻商, 1表示結(jié)束時
* startTime: audioContext.currentTime
* tiemConstant: 指數(shù)衰減率(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);
總結(jié)
對一些新的API進行了粗略的了解乌叶,大多專業(yè)名詞,但是實現(xiàn)原理比較簡單柒爸, 輸入音頻源准浴,經(jīng)過AudioContext,將各種效果節(jié)點連接起來,然后輸出音頻源
專業(yè)詞匯比如:
- 振蕩器(OscillatorNode)
- 半音階使用frequency表示的公式捎稚,也可以使用失諧detune表示
- 音頻過濾器BiquadFilterNode
- 增益都節(jié)點音量進行調(diào)節(jié)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() // 音頻過濾器