WebAudioAPI 入门

audio context 整个audio的上下文
audio nodes 控制连续每一个声音
audio routing graph 连续的声音组成

三种声音的来源:
1.Oscillator(振荡器),由数学计算出来的声音
2.Audio Samples,audio/vidio文件
3.Audio Stream 从麦克风传来的声音

oscillator

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,然后connectchain


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 APIcurrentTime,使用双精度的时间戳.
如果让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/

你可能感兴趣的:(js)