WebAudio APIで
ブラウザ上で動く
DJアプリケーションは
作れるか?
(WebAudio API アプリケーション作成入門)
2014.5.19 / Koizumi Ryo / @Mayu_mic
自己紹介
- 小泉 亮 (Koizumi Ryo)
- @Mayu_mic
- (株)ドワンゴ エンジニア
- JavaScript(TypeScript)
- London Elektricity, Squarepusher, mondo g...
WebAudio APIとは?
W3C によって開発されている、
ウェブアプリケーション用の音声処理と
音声合成のための高レベルJavaScript API。
(http://ja.wikipedia.org/wiki/HTML5オーディオ)
HTML5 <Audio> 要素との違い
- 音の再生タイミングの制御ができる
- 音の出力にエフェクトを載せることができる
- 波形データの生成・編集・加工ができる
- etc.
ブラウザ対応状況
(http://caniuse.com/#feat=audio-api)
ただし、細かいところで対応状況への違いあり
(MediaStreamingに対してエフェクトが効かない@Safari など…)
多くの作曲および音楽制作アプリケーションが作れるようになります。
オーディオイベントのタイトなスケジューリングが必要なアプリケーショ
ンも実装でき、教育的なものとエンターテインメント的なものの両方が可
能です。 ドラムマシン、デジタルDJアプリ...
多くの作曲および音楽制作アプリケーションが作れるようになります。
オーディオイベントのタイトなスケジューリングが必要なアプリケーショ
ンも実装でき、教育的なものとエンターテインメント的なものの両方が可
能です。 ドラムマシン、デジタルDJアプリ...
本当?
音源 音源
エフェクト エフェクト
エフェクト
ミキサー
目標 :
ブラウザ上だけで動く
DJアプリケーションを作る
WebAudio APIの基本
Source Node
Effect Node
Destination Node
基本は3種類のノードをつなぎ合わせる
音を出現させる
音を加工する
音の最終出力先を決める
一番簡単な形
SourceNode Destination
ソースから入力された音が、

そのままDestinationに向かう
var source = context.createBufferSource();
source.connect...
入力を加工する
SourceNode DestinationEffectNode
ソースから入力された音が、

EffectNodeで加工されてDestinationに向かう
var source = context.createBufferS...
直列に連結したり、
複数のノードを受けることも可能
組み合わせることで、複雑な音の流れを制御する
DeckA
DeckB
Filter
Filter
Sample
Gain
Gain
Gain
MasterGain
Dest
実際に
DJアプリケーションを
設計する
音源 音源
SourceNode : 音を出現させる
- AudioBufferSourceNode
- MediaStreamingSourceNode
- OscillatorNode
MP3, Wavなどのサンプルを読み込んで(任意のタイミングで)再...
SourceNode : 音を出現させる
- AudioBufferSourceNode
- MediaStreamingSourceNode
- OscillatorNode
MP3, Wavなどのサンプルを読み込んで(任意のタイミングで)再...
AudioBufferNode : ロード
private _loadArrayBuffer(path: string, timeout: number = 20000): JQueryPromise<ArrayBuffer> {
var d ...
AudioBufferNode : ロード
private _loadArrayBuffer(path: string, timeout: number = 20000): JQueryPromise<ArrayBuffer> {
var d ...
AudioBufferNode : デコード
private _decodeAudioBufferAsynchronously(data: ArrayBuffer, context: AudioContext)
: JQueryPromise<...
AudioBufferNode : 再生
play(when: number = 0) {
var source = this._context.createBufferSource(); // ソースは再生のたびに使い捨てる
source.b...
エフェクト エフェクト
エフェクト
EffectNode : 音を加工する
- GainNode
- 音量を上げ下げする
- PannerNode
- 音を左右に振る
- BiquadFilterNode
- 音の周波数をフィルタリングする
- DynamicsCompresso...
EffectNode : 音を加工する
- GainNode
- 音量を上げ下げする
- PannerNode
- 音を左右に振る
- BiquadFilterNode
- 音の周波数をフィルタリングする
- DynamicsCompresso...
GainNode : 音量を上げ下げする
set volume(value:number) {
this._gainNode.gain.value = value;
}
value = 0.5
Source GainNode Destinati...
BiquadFilterNode : フィルターをつくる
set freq(value:number) {
var minValue = 40;
var maxValue = context.sampleRate / 2;
var number...
ミキサー
ミキサーの設計 (2-channel: 例)
GainNode
Source Source
Effect Effect
Mixer
GainNode(Master)
Destination
GainNode
deckA deckB
Amp
CrossFader Pos
set crossFade(pos: number) {
this._deckAGain.gain.value = Math.cos(pos * 0.5*Math.PI);
this._deckBGain....
Destination Node
: 音の最終出力先を決める
- AudioDestinationNode
- MediaStreamingAudioDestinationNode
デバイスのオーディオハードウェアから出力する
リモートストリー...
今回話してないこと
- テンポチェンジ・BPM同期
- AudioBufferNodeでplayback rateをいじる(未確認)
!
- 波形描画
- Analyzer Nodeを使う?(未確認)
!
- Monitor Out
- オーデ...
参考
- 資料
- Web Audio API (日本語訳)
- http://g200kg.github.io/web-audio-api-ja/
!
- ソースコード
- Getting Started with Web Audio API...
WebAudio APIでブラウザ上で動くDJアプリケーションは作れるか? (WebAudio API アプリケーション作成入門)
Upcoming SlideShare
Loading in …5
×

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

1,382 views

Published on

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

Published in: Engineering
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,382
On SlideShare
0
From Embeds
0
Number of Embeds
79
Actions
Shares
0
Downloads
6
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

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

  1. 1. WebAudio APIで ブラウザ上で動く DJアプリケーションは 作れるか? (WebAudio API アプリケーション作成入門) 2014.5.19 / Koizumi Ryo / @Mayu_mic
  2. 2. 自己紹介 - 小泉 亮 (Koizumi Ryo) - @Mayu_mic - (株)ドワンゴ エンジニア - JavaScript(TypeScript) - London Elektricity, Squarepusher, mondo grosso, etc.
  3. 3. WebAudio APIとは? W3C によって開発されている、 ウェブアプリケーション用の音声処理と 音声合成のための高レベルJavaScript API。 (http://ja.wikipedia.org/wiki/HTML5オーディオ)
  4. 4. HTML5 <Audio> 要素との違い - 音の再生タイミングの制御ができる - 音の出力にエフェクトを載せることができる - 波形データの生成・編集・加工ができる - etc.
  5. 5. ブラウザ対応状況 (http://caniuse.com/#feat=audio-api) ただし、細かいところで対応状況への違いあり (MediaStreamingに対してエフェクトが効かない@Safari など…)
  6. 6. 多くの作曲および音楽制作アプリケーションが作れるようになります。 オーディオイベントのタイトなスケジューリングが必要なアプリケーショ ンも実装でき、教育的なものとエンターテインメント的なものの両方が可 能です。 ドラムマシン、デジタルDJアプリケーション、GarageBandに ある機能の幾つかを持ったタイムラインベースのデジタルミュージック・ プロダクションソフトウェアさえ書くことができます。 W3C Working Draft 10 October 2013 (http://g200kg.github.io/web-audio-api-ja/)
  7. 7. 多くの作曲および音楽制作アプリケーションが作れるようになります。 オーディオイベントのタイトなスケジューリングが必要なアプリケーショ ンも実装でき、教育的なものとエンターテインメント的なものの両方が可 能です。 ドラムマシン、デジタルDJアプリケーション、GarageBandに ある機能の幾つかを持ったタイムラインベースのデジタルミュージック・ プロダクションソフトウェアさえ書くことができます。 W3C Working Draft 10 October 2013 (http://g200kg.github.io/web-audio-api-ja/)
  8. 8. 本当?
  9. 9. 音源 音源 エフェクト エフェクト エフェクト ミキサー
  10. 10. 目標 : ブラウザ上だけで動く DJアプリケーションを作る
  11. 11. WebAudio APIの基本
  12. 12. Source Node Effect Node Destination Node 基本は3種類のノードをつなぎ合わせる 音を出現させる 音を加工する 音の最終出力先を決める
  13. 13. 一番簡単な形 SourceNode Destination ソースから入力された音が、
 そのままDestinationに向かう var source = context.createBufferSource(); source.connect(context.destination);
  14. 14. 入力を加工する SourceNode DestinationEffectNode ソースから入力された音が、
 EffectNodeで加工されてDestinationに向かう var source = context.createBufferSource(); var gainNode = context.createGain(); source.connect(gainNode); gainNode.connect(context.destination);
  15. 15. 直列に連結したり、 複数のノードを受けることも可能
  16. 16. 組み合わせることで、複雑な音の流れを制御する DeckA DeckB Filter Filter Sample Gain Gain Gain MasterGain Dest
  17. 17. 実際に DJアプリケーションを 設計する
  18. 18. 音源 音源
  19. 19. SourceNode : 音を出現させる - AudioBufferSourceNode - MediaStreamingSourceNode - OscillatorNode MP3, Wavなどのサンプルを読み込んで(任意のタイミングで)再生する Audioタグや、ネットワーク上からストリーミング経由で再生する 周期的な波形を生成する
  20. 20. SourceNode : 音を出現させる - AudioBufferSourceNode - MediaStreamingSourceNode - OscillatorNode MP3, Wavなどのサンプルを読み込んで(任意のタイミングで)再生する Audioタグや、ネットワーク上からストリーミング経由で再生する 周期的な波形を生成する
  21. 21. 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形式で読み込む
  22. 22. 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()をうまく使い 非同期処理させる
  23. 23. 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; }); }
  24. 24. AudioBufferNode : 再生 play(when: number = 0) { var source = this._context.createBufferSource(); // ソースは再生のたびに使い捨てる source.buffer = this._buffer; source.connect(context.destination); source.start(when); } - ソースノードにbufferを入れて再生する
  25. 25. エフェクト エフェクト エフェクト
  26. 26. EffectNode : 音を加工する - GainNode - 音量を上げ下げする - PannerNode - 音を左右に振る - BiquadFilterNode - 音の周波数をフィルタリングする - DynamicsCompressorNode - 音の音量の差異をつぶす - ConvolverNode - 音にリバーブなどのエフェクトをかける etc…
  27. 27. EffectNode : 音を加工する - GainNode - 音量を上げ下げする - PannerNode - 音を左右に振る - BiquadFilterNode - 音の周波数をフィルタリングする - DynamicsCompressorNode - 音の音量の差異をつぶす - ConvolverNode - 音にリバーブなどのエフェクトをかける etc…
  28. 28. GainNode : 音量を上げ下げする set volume(value:number) { this._gainNode.gain.value = value; } value = 0.5 Source GainNode Destination vol vol
  29. 29. 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など
  30. 30. ミキサー
  31. 31. ミキサーの設計 (2-channel: 例) GainNode Source Source Effect Effect Mixer GainNode(Master) Destination GainNode deckA deckB
  32. 32. 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
  33. 33. Destination Node : 音の最終出力先を決める - AudioDestinationNode - MediaStreamingAudioDestinationNode デバイスのオーディオハードウェアから出力する リモートストリーミング経由で出力する
  34. 34. 今回話してないこと - テンポチェンジ・BPM同期 - AudioBufferNodeでplayback rateをいじる(未確認) ! - 波形描画 - Analyzer Nodeを使う?(未確認) ! - Monitor Out - オーディオ出力デバイスに依存する
  35. 35. 参考 - 資料 - 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/

×