36
WebAudio APIで ブラウザ上で動く DJアプリケーションは 作れるか? (WebAudio API アプリケーション作成入門) 2014.5.19 / Koizumi Ryo / @Mayu_mic

WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

Embed Size (px)

DESCRIPTION

2014/5/19に社内LT発表会で発表する際に作成した資料です。 スライド中のソースコードはTypeScriptで書かれています。

Citation preview

Page 1: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

WebAudio APIで ブラウザ上で動く DJアプリケーションは 作れるか? (WebAudio API アプリケーション作成入門)

2014.5.19 / Koizumi Ryo / @Mayu_mic

Page 2: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

自己紹介

- 小泉 亮 (Koizumi Ryo) - @Mayu_mic - (株)ドワンゴ エンジニア - JavaScript(TypeScript) - London Elektricity, Squarepusher, mondo grosso, etc.

Page 3: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

WebAudio APIとは?

W3C によって開発されている、 ウェブアプリケーション用の音声処理と 音声合成のための高レベルJavaScript API。

(http://ja.wikipedia.org/wiki/HTML5オーディオ)

Page 4: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

HTML5 <Audio> 要素との違い

- 音の再生タイミングの制御ができる - 音の出力にエフェクトを載せることができる - 波形データの生成・編集・加工ができる - etc.

Page 5: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

ブラウザ対応状況

(http://caniuse.com/#feat=audio-api)

ただし、細かいところで対応状況への違いあり (MediaStreamingに対してエフェクトが効かない@Safari など…)

Page 6: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

多くの作曲および音楽制作アプリケーションが作れるようになります。 オーディオイベントのタイトなスケジューリングが必要なアプリケーションも実装でき、教育的なものとエンターテインメント的なものの両方が可能です。 ドラムマシン、デジタルDJアプリケーション、GarageBandにある機能の幾つかを持ったタイムラインベースのデジタルミュージック・プロダクションソフトウェアさえ書くことができます。

”W3C Working Draft 10 October 2013”

(http://g200kg.github.io/web-audio-api-ja/)

Page 7: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

多くの作曲および音楽制作アプリケーションが作れるようになります。 オーディオイベントのタイトなスケジューリングが必要なアプリケーションも実装でき、教育的なものとエンターテインメント的なものの両方が可能です。 ドラムマシン、デジタルDJアプリケーション、GarageBandにある機能の幾つかを持ったタイムラインベースのデジタルミュージック・プロダクションソフトウェアさえ書くことができます。

”W3C Working Draft 10 October 2013”

(http://g200kg.github.io/web-audio-api-ja/)

Page 8: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

本当?

Page 9: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)
Page 10: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

音源 音源

エフェクト エフェクト

エフェクト

ミキサー

Page 11: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

目標 : ブラウザ上だけで動く

DJアプリケーションを作る

Page 12: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

WebAudio APIの基本

Page 13: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

Source Node

Effect Node

Destination Node

基本は3種類のノードをつなぎ合わせる

音を出現させる

音を加工する

音の最終出力先を決める

Page 14: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

一番簡単な形

SourceNode Destination

ソースから入力された音が、そのままDestinationに向かう

var source = context.createBufferSource(); source.connect(context.destination);

Page 15: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

入力を加工する

SourceNode DestinationEffectNode

ソースから入力された音が、EffectNodeで加工されてDestinationに向かう

var source = context.createBufferSource(); var gainNode = context.createGain(); source.connect(gainNode); gainNode.connect(context.destination);

Page 16: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

直列に連結したり、

複数のノードを受けることも可能

Page 17: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

組み合わせることで、複雑な音の流れを制御する

DeckA

DeckB

Filter

Filter

Sample

Gain

GainGain

MasterGainDest

Page 18: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

実際に DJアプリケーションを

設計する

Page 19: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

音源 音源

Page 20: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

SourceNode : 音を出現させる

- AudioBufferSourceNode

- MediaStreamingSourceNode

- OscillatorNode

MP3, Wavなどのサンプルを読み込んで(任意のタイミングで)再生する

Audioタグや、ネットワーク上からストリーミング経由で再生する

周期的な波形を生成する

Page 21: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

SourceNode : 音を出現させる

- AudioBufferSourceNode

- MediaStreamingSourceNode

- OscillatorNode

MP3, Wavなどのサンプルを読み込んで(任意のタイミングで)再生する

Audioタグや、ネットワーク上からストリーミング経由で再生する

周期的な波形を生成する

Page 22: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

AudioBufferNode : ロード

private _loadArrayBuffer(path: string, timeout: number = 20000): JQueryPromise<ArrayBuffer> { var d = $.Deferred(); setTimeout(d.reject, timeout); // タイムアウトで失敗させる ! var request = new XMLHttpRequest(); request.open("GET", path, true); request.responseType = 'arraybuffer'; ! request.addEventListener('load', (ev: Event) => { if (request.status == 200) { console.info(“ロード成功”); d.resolve(request.response); } d.reject(request.status.toString()); }); ! // エラーで失敗させる request.addEventListener('error', (ev: Event) => { console.error("ロード失敗"); d.reject(); }); ! request.send(); return d.promise(); }

- MP3などの音楽データをArrayBuffer形式で読み込む

Page 23: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

AudioBufferNode : ロード

private _loadArrayBuffer(path: string, timeout: number = 20000): JQueryPromise<ArrayBuffer> { var d = $.Deferred(); setTimeout(d.reject, timeout); // タイムアウトで失敗させる ! var request = new XMLHttpRequest(); request.open("GET", path, true); request.responseType = 'arraybuffer'; ! request.addEventListener('load', (ev: Event) => { if (request.status == 200) { console.info(“ロード成功”); d.resolve(request.response); } d.reject(request.status.toString()); }); ! // エラーで失敗させる request.addEventListener('error', (ev: Event) => { console.error("ロード失敗"); d.reject(); }); ! request.send(); return d.promise(); }

- MP3などの音楽データをArrayBuffer形式で読み込む

※point※ jQuery.Deferred()をうまく使い 非同期処理させる

Page 24: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

AudioBufferNode : デコード

private _decodeAudioBufferAsynchronously(data: ArrayBuffer, context: AudioContext) : JQueryPromise<AudioBuffer> { var d = $.Deferred(); context.decodeAudioData(data, (buffer: AudioBuffer) => { console.info('バッファのデコード完了'); d.resolve(buffer); }, () => { console.error("バッファのデコードに失敗"); d.reject(); }); return d.promise(); }

- 読み込んだArrayBufferをAudioBuffer形式にデコードする

load(buffer: ArrayBuffer): JQueryPromise<AudioBuffer> { return this._decodeAudioBufferAsynchronously(buffer) .done((buffer: AudioBuffer) => { this._buffer = buffer; this._isLoaded = true; }); }

Page 25: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

AudioBufferNode : 再生

play(when: number = 0) { var source = this._context.createBufferSource(); // ソースは再生のたびに使い捨てる source.buffer = this._buffer; source.connect(context.destination); source.start(when); }

- ソースノードにbufferを入れて再生する

Page 26: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

エフェクト エフェクト

エフェクト

Page 27: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

EffectNode : 音を加工する

- GainNode - 音量を上げ下げする

- PannerNode - 音を左右に振る

- BiquadFilterNode - 音の周波数をフィルタリングする

- DynamicsCompressorNode - 音の音量の差異をつぶす

- ConvolverNode - 音にリバーブなどのエフェクトをかける

etc…

Page 28: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

EffectNode : 音を加工する

- GainNode - 音量を上げ下げする

- PannerNode - 音を左右に振る

- BiquadFilterNode - 音の周波数をフィルタリングする

- DynamicsCompressorNode - 音の音量の差異をつぶす

- ConvolverNode - 音にリバーブなどのエフェクトをかける

etc…

Page 29: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

GainNode : 音量を上げ下げする

set volume(value:number) { this._gainNode.gain.value = value; }

value = 0.5

Source GainNode Destination

vol vol

Page 30: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

BiquadFilterNode : フィルターをつくる

set freq(value:number) { var minValue = 40; var maxValue = context.sampleRate / 2; var numberOfOctaves = Math.log(maxValue / minValue) / Math.LN2; var multiplier = Math.pow(2, numberOfOctaves * (value - 1.0)); this._filterNode.frequency.value = maxValue * multiplier; }

周波数

Gain Q

frequency

※Lowpassの場合

this._filterNode.type = this._filterType = <any>’lowpass'; // 他にhighpass, bandpassなど

Page 31: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

ミキサー

Page 32: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

ミキサーの設計 (2-channel: 例)

GainNode

Source Source

Effect EffectMixer

GainNode(Master)

Destination

GainNode

deckA deckB

Page 33: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

Amp

CrossFader Pos

set crossFade(pos: number) { this._deckAGain.gain.value = Math.cos(pos * 0.5*Math.PI); this._deckBGain.gain.value = Math.cos((1.0 - pos) * 0.5*Math.PI); }

ミキサー : クロスフェーダー

deckA deckB

Page 34: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

Destination Node : 音の最終出力先を決める

- AudioDestinationNode

- MediaStreamingAudioDestinationNode

デバイスのオーディオハードウェアから出力する

リモートストリーミング経由で出力する

Page 35: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

今回話してないこと

- テンポチェンジ・BPM同期 - AudioBufferNodeでplayback rateをいじる(未確認) !

- 波形描画 - Analyzer Nodeを使う?(未確認)

!

- Monitor Out - オーディオ出力デバイスに依存する

Page 36: WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)

参考

- 資料 - Web Audio API (日本語訳) - http://g200kg.github.io/web-audio-api-ja/

!- ソースコード - Getting Started with Web Audio API - HTML5 Rocks

- http://www.html5rocks.com/ja/tutorials/webaudio/intro/