audio context
整个audio的上下文
audio nodes
控制连续每一个声音
audio routing graph
连续的声音组成
三种声音的来源:
1.Oscillator(振荡器),由数学计算出来的声音
2.Audio Samples,audio/vidio文件
3.Audio Stream 从麦克风传来的声音
oscillator是重复的声波,有frequency(频率)和(peak amplitude)振幅
振荡器有4种:1)sine 2)trangle 3)square 4)sawtooth
OscillatorNode.type
来控制振荡器的类型
OscillatorNode.type = 'sine'|'square'|'triangle'|'sawtooth';
使用setPeriodicWave()
来自定义振荡器的类型
var context = new (window.AudioContext || window.webkitAudioContext)();
var oscillator = context.createOscillator(); // 创建振荡器
oscillator.type = 'sine'; // 设置振荡器类型
oscillator.frequency.value = 440; //设置振荡器频率
oscillator.connect(context.destination); //context中所有音频(节点)的最终目标节点
oscillator.start(); //开始
接下来来控制音量,我们需要在context
中创建gain node
,然后connect
到chain
中
var gain = context.createGain();
oscillator.connect(gain);
gain.connect(context.destination);
var now = context.currentTime;
gain.gain.setValueAtTime(1, now);
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.5);
oscillator.start(now);
oscillator.stop(now + 0.5);
javascript clock
不好,它不够准确.Web Audio API
有currentTime
,使用双精度的时间戳.
如果让oscillator
立刻工作,使用start(0)
(0可以省略)
var now = context.currentTime;
oscillator.play(now + 1); //1s后开始
oscillator.stop(now + 3); //3s后结束
AudioParam.setValueAtTime(value, startTime)
可以在指定的时间更改频率
oscillator.frequency.setValueAtTime(261.6, context.currentTime + 1); //1s后更改频率
AudioParam.exponentialRampToValueAtTime(value, endTime)
渐进更改声音
gain.gain.exponentialRampToValueAtTime(0.001, context.currentTime + 1); //声音淡出效果,不能使用0,必须是正值(0,代表了关闭)
class Sound {
constructor(context) { //构造器,传入context,这样所有的对象都能共用这一个构造器
this.context = context;
}
init() {//初始化,创建oscillator,gainnode
this.oscillator = this.context.createOscillator();
this.gainNode = this.context.createGain();
this.oscillator.connect(this.gainNode);
this.gainNode.connect(this.context.destination);
this.oscillator.type = 'sine';
}
play(value, time) {//value是声音的频率,time是开始的时间
this.init();
this.oscillator.frequency.value = value;
this.gainNode.gain.setValueAtTime(1, this.context.currentTime);
this.oscillator.start(time);
this.stop(time);
}
stop(time) {
this.gainNode.gain.exponentialRampToValueAtTime(0.001, time + 1); //1s内指数衰减音量
this.oscillator.stop(time + 1);
}
}
let context = new (window.AudioContext || window.webkitAudioContext)();
let note = new Sound(context);
let now = context.currentTime;
note.play(261.63, now);
note.play(293.66, now + 0.5);
note.play(329.63, now + 1);
note.play(349.23, now + 1.5);
note.play(392.00, now + 2);
note.play(440.00, now + 2.5);
note.play(493.88, now + 3);
note.play(523.25, now + 3.5);
参考:
https://developer.mozilla.org/zh-CN/docs/Web/API/AudioContext
https://css-tricks.com/introduction-web-audio-api/
https://www.sitepoint.com/using-fourier-transforms-web-audio-api/