Web audio apiで
できること
2013/6/8 htmlday 大阪 
フィ
@huydx
Friday, June 7, 2013
自己紹介
名前:ドースアンフイ @huydx
出身:ベトナム
職業:学生 (ShareWis Incでインターン)
Ruby + javascript
http://huydx.com
Friday, June 7, 2013
なぜ今日Web audio API
について発表?
Friday, June 7, 2013
アジェンダ
‣ イントロダクション
‣ 歴史
‣ Web audio api使うため必要な知識
‣ Web audio apiの紹介/構成
‣ デモタイム
‣ Web audio apiのライブラリ等を紹介
‣ 質問タイム
Friday, June 7, 2013
Web audio apiについて
ですが。。
Friday, June 7, 2013
• 質問1:名前を聞いたことがある人!
• 質問2:使ったことがある人!
• 質問3:Web audio apiとても詳しい人
Friday, June 7, 2013
• 質問1:名前を聞いたことがある人!
• 質問3:とても詳しい人!
• 質問2:使った事がある人!
Friday, June 7, 2013
• 質問1:名前を聞いたことがある人!
• 質問3:とても詳しい人!
• 質問2:Web audio apiとても詳しい人
Friday, June 7, 2013
Web audio apiの歴史
•Google Chromeから始め
•OpenALを基づく
•2011 / 15 / 12 : First Draft
•2012 / 13 / 12 : 現在の版
Friday, June 7, 2013
Friday, June 7, 2013
ウェブでAudioの歴史?
‣ <bgsound> タグ (IE のみ!)
‣ 背景で音を鳴らす
‣ <bgsound src=”audio/welcome.wav” />
‣ フラッシュ
‣ <audio>タグ
‣ 実装簡単
‣ 簡単な音声制御できる
‣ Web audio API 登場!!!!
Friday, June 7, 2013
なぜWeb audio api要る?
• 複数データソースを用いて精密な時間制御
• Audioのパイプライン/ルーティング.
• Audioのストリームをフックして、オンザフ
ライで処理できる
Friday, June 7, 2013
まずAudioの基本の知識
物体の振動が空気などの振動(音波)
として伝わって起す聴覚の内容
quote:wikipedia
Friday, June 7, 2013
時間軸
振幅軸
音声のRaw データ
電子化
フーリエ変換
Friday, June 7, 2013
Play time!
Friday, June 7, 2013
まずはaudioデータをロード
function init() {
if (typeof AudioContext !== "undefined") {
context = new AudioContext();
} else if (typeof webkitAudioContext !== "undefined") {
context = new webkitAudioContext();
} else {
throw new Error('AudioContext not supported. :(');
}
}
Friday, June 7, 2013
まずはaudioデータをロード
function init() {
if (typeof AudioContext !== "undefined") {
context = new AudioContext();
} else if (typeof webkitAudioContext !== "undefined") {
context = new webkitAudioContext();
} else {
throw new Error('AudioContext not supported. :(');
}
}
Friday, June 7, 2013
まずはaudioデータをロード
function startSound() {
// Note: this loads asynchronously
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "arraybuffer";
request.onload = function() {
var audioData = request.response;
context.decodeAudioData(audioData, function(buffer) {
playmusic(buffer)
}, onError);
};
request.send();
}
Friday, June 7, 2013
まずはaudioデータをロード
function playmusic(buffer) {
sourceNode = context.createBufferSource( );
sourceNode.connect( context.destination );
sourceNode.buffer = buffer;
sourceNode.noteOn( 0 );
}
initSound( );
startSound( );
皆大体の流れを把握するでしょう
Friday, June 7, 2013
デモ
Friday, June 7, 2013
web audio api構成
ノード(AudioNode)
を繋がることにより、
グラフを構成する
各ノードは Inputsか/とOutputsを持つ
Friday, June 7, 2013
Source
Destination
Input
(audio
data)
Output
(speaker)
Audio Context
一番簡単なグラフ
Friday, June 7, 2013
もっとややこしいグラフ
quote:W3C
Friday, June 7, 2013
簡単に言うと
Input 処理 Output
AudioSourceNodeに
Audioデータ入力
Friday, June 7, 2013
簡単に言うと
Input 処理 Output
ここで勝手に処理する
Friday, June 7, 2013
処理ノードの種類
‣ GainNode (利得)
‣ BiquadFilterNode (フィルタ)
‣ PannerNode(3次元Audio操作)
‣ ConvolverNode(畳み込み)
‣ AnalyzerNode(分析)
‣ .......
Friday, June 7, 2013
簡単に言うと
Input 処理 Output
AudioDestinationNodeに
調整したものを出力
Friday, June 7, 2013
Play time!
Friday, June 7, 2013
遊びアジェンダ
‣再生で時間調整
‣各ノード種類でAudio調整をためしてやる
‣AnalyzerNode
‣ConvolverNode
‣OscillatorでAudio生成を試してやる
Friday, June 7, 2013
時間調整
• 複数データソースを用いて精密な時間制御
• 秒単位で再生を調整できる
Friday, June 7, 2013
時間調整
Gun.prototype.shoot = function (type, rounds, interval, random,
random2) {
if (typeof random == 'undefined') {
random = 0;
}
var time = context.currentTime;
for (var i = 0; i < rounds; i++) {
var source = this.makeSource(this.buffers[type]);
source.playbackRate.value = 1 + Math.random() * random2;
source.noteOn(time + i * interval + Math.random() * random);
}
}
デーモ
Friday, June 7, 2013
各ノード種類でAudio調整
AnalyzerNode
FFTした結果を基づいて解析などするため
のノード (fftSize)
AnalyzerNodeを用いて、周波数を分かれば
可視化が簡単にできる
Friday, June 7, 2013
AnalyzerNode
もっとややこしいの例:
http://html5-demos.appspot.com/static/webaudio/createMediaSourceElement.html
http://chimera.labs.oreilly.com/books/1234000001552/ch05.html#s05_3
function getAverageVolume(array) {
var vals = 0;
var length = array.length;
for (var i=0; i<length; i++) {
vals += array[i];
}
return (vals / length)
}
window.javascriptnode.onaudioprocess = function() {
var array = new Uint8Array(analyzer.frequencyBinCount);
analyzer.getByteFrequencyData(array);
var average = getAverageVolume(array);
ctx.clearRect(0, 0, 60, 130);
ctx.fillStyle="#00FFFF";
ctx.fillRect(0, 130-average,25,130);
}
周波数をarrayに保存
Friday, June 7, 2013
各ノード種類でAudio調整
ConvolverNode
畳み込み演算で部屋のエフェクト
などを再現する (例えば:歌劇場等)
Friday, June 7, 2013
ConvolverNode
function audioGraph(audioData) {
var convolver;
soundSource = context.createBufferSource();
soundBuffer = context.createBuffer(audioData, true);
soundSource.buffer = soundBuffer;
convolver = context.createConvolver();
soundSource.connect(convolver);
convolver.connect(context.destination);
Convolve('echo.mp3', convolver, function() {playSound()});
}
function Convolve(url, convolver, callback) {
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "arraybuffer";
request.onload = function () {
convolver.buffer = context.createBuffer(request.response, false);
callback();
}
request.send();
}
Friday, June 7, 2013
OscillatorでAudio生成(シンセシス)
波形の種類 (type)
周波数(frequency) 
デチュン(detune)
自分で音声を生成できる!
Friday, June 7, 2013
OscillatorでAudio生成(シンセシス)
var osc = audioctx.createOscillator();
var gain = audioctx.createGain();
osc.connect(gain);
gain.connect(audioctx.destination);
function Setup() {
if(play == 0) {
osc.start(0);
play = 1;
}
var type = document.getElementById("type").selectedIndex;
var freq = parseFloat(document.getElementById("freq").value);
var level = parseFloat(document.getElementById("level").value);
osc.type = type;
osc.frequency.value = freq;
gain.gain.value = level;
}
Friday, June 7, 2013
web audio apiで
音声処理から
音声生成まで
Friday, June 7, 2013
Friday, June 7, 2013
実際の応用
• ゲーム(AngryBird, CasinoRPG)
• アプリのUXフィッドバック(可視化)
• Musicalアプリケーション(DJ, シンセシ
ス等)
• RealTimeでAudioエフェクト追加等
Friday, June 7, 2013
ライブラリ等
‣ MusicJS (楽器のシンセシス用)
‣ Howler.js (Web audio apiのラッパ)
‣ Dancer.js (Web audio apiのラッパ)
‣ ......
Friday, June 7, 2013
結論
Web Audio APIは
Friday, June 7, 2013
Friday, June 7, 2013
•ハイレベルのAPIを提供する(デー
タの形式等を考慮しなくてよい)
• 別のスレッドで処理→GUIブロックしない
• 豊な機能(フィルタ、FFT等)を提供
Friday, June 7, 2013
ご清聴ありがとうございます
Friday, June 7, 2013

[Htmlday]present