View
682
Download
2
Category
Preview:
DESCRIPTION
An introduction of Web Audio API and their friends by explaining Web based sampler app for Firefox OS. This slide is for Firefox OS meeting at 2014/08/30 in Hiroshima, Japan.
Citation preview
サンプラーアプリを作ってみた
Mozilla Japan テクニカルマーケティング 清水智公
中国Firefox OS勉強会2nd, 2014/08/30
about:me
2
FFiirreeffooxx をよろしくね!
清水智公(しみずのりただ)
• Mozilla Japan テクニカルマーケティング
• 慶應義塾大学政策・メディア研究科非常勤
• @chikoski • https://slideshare.net/chikoski/
4
サンプラーをつくってみた
5
サンプリング
• https://www.ted.com/talks/mark_ronson_how_sampling_transformed_music
6
Audio 要素
• 音声コンテンツを表すHTML要素 • src属性で埋め込む音声リソースを指定 • コントロール、ロード方法なども属性で指定
7
<audio src="foo.mp3" autoplay control loop></audio>
Web Audio API
• 音声の処理を行うためのAPI • できること • 音声データのデコード • 変調、FFT、ミキシング、パンニング • オシレーション • オーディオグラフ
8
オーディオグラフ
• 音声データの処理の流れ • オーディオノードをつないで作成 • ノードはオーディオコンテキストから作成
9
オーディオノード
10
分類 クラス名
入力OscillatorNode, AudioBufferSourceNode, MediaElementAudioSourceNode, MediaStreamAudioSourceNode
エフェクトBiquadFilterNode, ConvolverNode, DelayNode, DynamicsCompressorNode, GainNode, WaveShaperNode, PeriodicWaveNode
出力 AudioDestinationNode, MediaStreamAudioDestinationNode
その他 PannerNode, AnalyserNode, ChannelSplitterNode, ChannelMergerNode, ScriptProcessorNode
単純なオーディオグラフの作成例
• AudioContextオブジェクトのファクトリメソッドを利用してオーディオノードを作成
• connectメソッドでノードを接続 • context.destination がスピーカー
11
var elm = document.querySelector("audio");!!var context = new AudioContext();!var source = context.createMediaElementSource(elm);!source.connect(context.destination);
単純なオーディオグラフの作成例
12
var elm = document.querySelector("audio");!!var context = new AudioContext();!var source = context.createMediaElementSource(elm);!source.connect(context.destination);
source context.destination
フィルタの追加
13
var elm = document.querySelector("audio");!!var context = new AudioContext();!var source = context.createMediaElementSource(elm);!var lowpass = context.createBiquadFilter();!lowpass.type = "lowpass";!!source.connect(lowpass);!lowpass.connect(context.destination);
source context.destinationlowpass
BiquadFilterNode:周波数によるフィルタ
14
種類 効果lowpass 指定された周波数より低い音のみ通過させる
highpass 指定された周波数より高い音のみ通過させる
bandpass 指定された範囲の周波数の音のみ通過させる
lowshelf 指定された値よりより低い周波数の音を増幅する
highshelf 指定された値よりより高い周波数の音を増幅する
peaking 指定された範囲の周波数の音を増幅する
notch 指定された範囲以外の周波数の音をのみを通過させる
allpass 全ての音を通過させる
BiquadFilterNodeの使い方
• フィルタの種類はtype属性に名前を代入して指定 • frequency, Q, gain のパラメータを持つ • パラメータの役割はMDNを参照してくださいhttps://developer.mozilla.org/ja/docs/Web/API/BiquadFilterNode
15
var context = new AudioContext();!var lowpass = context.createBiquadFilter();!lowpass.type = "lowpass";!lowpass.frequency.value = 2000;!lowpass.Q.value = 30;
AudioParamオブジェクト
• パラメータを表すオブジェクトhttps://developer.mozilla.org/docs/Web/API/AudioParam
• 例:BiquadFilterNodeオブジェクトのfrequency属性 • value と defaultValue の2つの属性を持つ • タイミングにあわせた値設定なども可能
16
var context = new AudioContext();!var lowpass = context.createBiquadFilter();!lowpass.frequency.value = 2000;
ループを伴うグラフの作成
17
var elm = document.querySelector("audio");!var context = new AudioContext();!var source = context.createMediaElementSource(elm);!!var delay = context.createDelay();!var wet = context.createGain();!var dry = context.createGain();!var feedback = context.createGain();!!source.connect(dry);!dry.connect(context.destination);!source.connect(delay);!delay.connect(wet);!wet.connect(context.destination);!delay.connect(feedback);!feedback.connect(delay);!
ループを伴うグラフ(つづき)
18
source
context.destination
delayfeedback dry
wet
var source = context.createMediaElementSource(elm);!var delay = context.createDelay();!var wet = context.createGain();!var dry = context.createGain();!var feedback = context.createGain();
ループを伴うグラフ(つづき)
19
source
context.destination
delayfeedback dry
wet
source.connect(dry);!dry.connect(context.destination);
ループを伴うグラフ(つづき)
20
source
context.destination
delayfeedback dry
wet
source.connect(delay);!delay.connect(wet);!wet.connect(context.destination);!
ループを伴うグラフ(つづき)
21
source
context.destination
delayfeedback dry
wet
delay.connect(feedback);!feedback.connect(delay);!
波形の可視化
• フィルタの効き方を目で確認するのに便利 • 概要 • AnalyserNode で高速フーリエ変換する • Canvas 要素へ 1の結果を描画する • 上記二つを1フレームごとに実行する
22
波形の可視化:AnalyserNode
23
var elm = document.querySelector("audio");!!var context = new AudioContext();!var source = context.createMediaElementSource(elm);!var lowpass = context.createBiquadFilter();!lowpass.type = "lowpass";!var analyser = context.createAnalyser();!!source.connect(lowpass);!lowpass.connect(context.destination);!lowpass.connect(analyser);
source context.destinationlowpass
analyser
波形の可視化:波形の描画
24
var update = function(){! var data = ! new Uint8Array(analyser.frequencyBinCount);! analyser.getByteFrequencyData(data);! fadeOut(gc);! gc.beginPath();! for(var i = 0; i < this.data.length; i++){! var pos = position.call(this, i);! if(i == 0){gc.moveTo(pos.x, pos.y);}! else{gc.lineTo(pos.x, pos.y);}! }! gc.stroke();! window.requestAnimationFrame(update);! };
• gcはCanvasの2Dコンテキスト • fadeOut は画面をクリアする自作関数
波形の可視化:周波数成分の分析
• frequencyBinCount属性で分析結果になる、周波数帯の数が取得できる
• getByteFrequencyDataメソッドを呼ぶことで、各周波数帯の強さが0~255の256段階で取得できる
25
var data = ! new Uint8Array(analyser.frequencyBinCount);!analyser.getByteFrequencyData(data);
サンプリング
• MediaRecording APIを利用して音声をblobに変更 • オーディオグラフとの接続にはMediaStreamDestinationNodeを利用する
26
source context.destination
mediaStreamDestination
recorder
オーディオグラフ参照
サンプリング(つづき)
• MediaStreamDestinationNode:WebRTCでのストリーミング先を表すノード
27
var elm = document.querySelector("audio");!var context = new AudioContext();!var source = context.createMediaElementSource(elm);!!var mediaStreamDestination = ! context.createMediaStreamDestination();!!source.connect(context.destination)!source.connect(mediaStreamDestination);
サンプリング(つづき)
• MediaRecorderオブジェクト:WebRTCのストリームを記録する
• MediaStreamDestinationNodeとつなぐことで、オーディオグラフの出力を記録できる
28
var recorder =! new MediaRecorder(mediaStreamDestination.stream);!!recorder.start(); // 録音開始!recorder.stop(); // 録音終了
サンプリング(つづき)
• 記録したデータはすぐ利用できる訳ではない • 利用可能時にdataavailableイベントが発火 • Blob イベントの一種 • イベントオブジェクトのdata属性の参照で、Blobとして記録が取得できる
29
recorder.ondataavailable = function(event){! console.log(event.data);!};
オーディオデータのデコード
• Blob → ArrayBuffer → AudioBuffer • AudioContextのdecodeAudioDataメソッドを利用してデコードする
30
var reader = new FileReader();!return function(blob, context){! return new Promise(function(resolve, fail){! reader.onload = function(event){! context.decodeAudioData(event.target.result, ! resolve);! };!! reader.readAsArrayBuffer(blob);!! });! };!}
オーディオデータのデコード(つづき)
• デコードされたデータの再生にはBufferSourceNodeを利用 • startメソッドで再生開始、stopメソッドで停止 • loop、開始時間、再生時間などをしてい可能 • stopメソッド呼び出し後、startメソッドを呼べないことに注意
31
var bufferSource = context.createBufferSoruce();!bufferSource.buffer = buffer; // デコードだされたデータ!bufferSource.start(); // 再生開始!bufferSource.stop(); // 再生終了
マイクの利用
• GetUserMedia APIを利用する • 利用にはmanifest.webappへの設定が必要 • 取得したマイクからのストリームからMediaStreamSourceNodeを作成することで、マイクからの入力おWeb Audio APIで処理できる
32
マイクの利用(つづき)
• manifest.webapp の permissionsに設定する • 項目名はaudio-capture • description属性に利用目的などを書いた説明文をつけておく
33
"permissions":{! "audio-capture": {! "description": ! "capture sound with mic input for sampling"! }!},
マイクの利用(つづき)
• navigator. getUserMedia はベンダープレフィックスがついている • 引数:メディアの種類、成功時コールバック、失敗時コールバック
• 成功時のコールバックには、マイクからのストリームが引数として渡される
34
navigator.getUserMedia = ! navigator.getUserMedia || navigator.mozGetUserMedia;!!navigator.getUserMedia({audio:true}, ! resolved, failed);
マイクの利用(つづき)
• GainNodeを挟むと、マイクの入力レベルをコントロールできる
35
var context = new AudioContext();!function resolved(stream){! var source = ! context.createMediaStreamSource(stream);! var gain = context.createGain();! source.connect(gain);! gain.connect(context.destination);!!}
source context.destinationgain
マイクの利用(つづき)
• マイクからのストリームはstopされるまで生きます • 使わなくなったらstopしたほうが良い
36
window.addEventListener("beforeunload", ! function(event){! stream.stop();!});
まとめ
37
サンプラーをつくろう
• Web Audio API:音声の処理 • オーディオグラフ • オーディオコンテキスト • GetUserMedia API:マイクの扱い • Media Recording API:録音
38
Web Audio Editor
• Firefox の開発ツールにある機能 • オーディオグラフの可視化、パラーメータの変更が可能
39
デモアプリ
• https://github.com/chikoski/sample-sampler
• 依存するライブラリ • RequireJS : http://requirejs.org/
• framework7:http://www.idangero.us/framework7/
40
レファレンス
• Web Audio API の利用https://developer.mozilla.org/ja/docs/Web/API/Web_Audio_API/Using_Web_Audio_API
• Web Audio APIhttps://developer.mozilla.org/ja/docs/Web/API/Web_Audio_API
• Web Audio Toyhttp://uglyhack.appspot.com/webaudiotoy/
• Vocoderhttp://webaudiodemos.appspot.com/Vocoder/
41
Recommended