제2회 hello world 오픈세미나 Web Audio API-가능성엿보기
Upcoming SlideShare
Loading in...5
×
 

제2회 hello world 오픈세미나 Web Audio API-가능성엿보기

on

  • 6,280 views

 

Statistics

Views

Total Views
6,280
Views on SlideShare
2,360
Embed Views
3,920

Actions

Likes
4
Downloads
33
Comments
0

7 Embeds 3,920

http://helloworld.naver.com 3710
http://www.hanrss.com 177
http://xing.xinics.com 26
http://cnpdump.com 3
http://translate.googleusercontent.com 2
http://mail.nhncorp.com 1
http://localhost 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

제2회 hello world 오픈세미나 Web Audio API-가능성엿보기 제2회 hello world 오픈세미나 Web Audio API-가능성엿보기 Presentation Transcript

  • Web Audio API의 가능성 엿보기http://www.flickr.com/photos/meaganjean/4263943043/ 2012.07.07 / 박재성_nhn
  • Index 1. Introduction • <audio> tag • Web Audio API • Brief History • 브라우저 지원 여부 • Modular Routing 2. 인터페이스 3. 기본 사용방법 4. How to use? : 다양한 응용방법 • Background music • <audio> to Web Audio API • Sound effects • 3D Positional sound : AudioPannerNode • Room effects and filters : ConvolverNode • Detect clipping : JavaScriptNode 5. Somethig more • Automation • 몇 가지 기억할 것들
  • 1. Introduction
  • <audio> tag : 웹에서의 사운드 이미 HTML5 <audio> 태그를 통해 사운드를 재생할 수 있다. <audio controls loop> <source src=“music.wav"> </audio> • 로딩과 디코딩에 대한 별도의 작업 없이 스트리밍으로 재생가능 • 다양한 재생 컨트롤 API 제공 (음량 조절, 재생시간 조절, etc) • Media event를 통한 다양한 이벤트 처리
  • <audio> tag : 한계 그러나… • 사운드 시그널에 필터를 적용할 수 없다. • Raw PCM 데이터 접근이 불가능 하다. • 청취자에 대한 개념이 없기 때문에, 음향에 대한 공간 및 방향 설정 자체가 불가능 하다.
  • Web Audio API?  웹 어플리케이션에서 오디오 데이터를 프로세싱 하거나 합성할 수 있는 하이레벨(High-level) JavaScript API.  Specification : http://www.w3.org/TR/webaudio/  AudioContext는 모든 사운드 데이터를 관리 및 재생한다.  음향 데이터가 최종적으로 송출 되려면 사운드 소스는, AudioContext 인스턴스와 연결 되어야 한다.
  • Web Audio API? : First step // 1. Audio Context 생성 var context = new webkitAudioContext(); // 2. 사운드 소스 생성 var source = context.createBufferSource(); source.buffer = AudioBuffer_데이터; // 3. 소스를 스피커와 연결 (또는 다른 모듈과 연결) source.connect(context.destination);
  • Brief History  Google과 Mozilla는 서로 다른 2개의 초안을 제안 (2011/12/15)  Google : Web Audio API - 하이레벨 함수(이미 기능들이 정의된) 제공  Mozilla : MediaStream Processing API(Audio Data API) - 로우레벨 접근 - <audio> 태그 기반 http://wiki.mozilla.org/Audio_Data_API
  • 브라우저 지원 여부  크롬 (윈도우, MacOS X, Linux)  ChromeOS  사파리 5.2 beta에서 지원예정 (nightly 빌드에서 이미 사용가능)  iOS6 Safari  http://developer.apple.com/technologies/ios6/
  • Modular Routing  연결은 꼭 스피커와 직접적일 필요는 없으며, 중간에 여러 단계의 AudioNode 들과 연결(Modular Routing)되어 파이프라이닝 될수 있다.  이를 통해 중간 단계의 AudioNode를 통해 음량 조정, 필터 적용 등을 처리 하게 된다.
  • 2. 인터페이스
  • 인터페이스 : AudioNode  모듈(노드)을 의미하며, 각 모듈들은 특별한 기능을 수행한다. interface AudioNode { void connect(in AudioNode destination, in unsigned long output = 0, in unsigned long input = 0); void disconnect(in int output = 0); readonly attribute AudioContext context; readonly attribute unsigned long numberOfInputs; readonly attribute unsigned long numberOfOutputs; }  source.connect(destination_node);
  • 인터페이스 : AudioParam  각각의 AudioNode들은 AudioParam 형식의 메서드를 갖으며, 이는 자동화 처리와 관련된 메서드를 제공한다.  http://www.w3.org/TR/webaudio/#AudioParam interface AudioParam { attribute float value; readonly attribute float minValue; readonly attribute float maxValue; readonly attribute float defaultValue; readonly attribute DOMString name; // Should define units constants here (seconds, decibels, cents, etc.) readonly attribute short units; // Parameter automation. void setValueAtTime(in float value, in float time); void linearRampToValueAtTime(in float value, in float time); void exponentialRampToValueAtTime(in float value, in float time); // Exponentially approach the target value with a rate having the given time constant. void setTargetValueAtTime(in float targetValue, in float time, in float timeConstant); // Sets an array of arbitrary parameter values starting at time for the given duration. // The number of values will be scaled to fit into the desired duration. void setValueCurveAtTime(in Float32Array values, in float time, in float duration); // Cancels all scheduled parameter changes with times greater than or equal to startTime. void cancelScheduledValues(in float startTime); }
  • 인터페이스 : AudioBuffer  메모리에 올려진 디코딩된 사운드 데이터를 의미한다.  http://www.w3.org/TR/webaudio/#AudioBuffer interface AudioBuffer { // linear gain (default 1.0) attribute AudioGain gain; readonly attribute float sampleRate; readonly attribute long length; // in seconds readonly attribute float duration; readonly attribute int numberOfChannels; Float32Array getChannelData(in unsigned long channel); }
  • 인터페이스 : AudioBufferSourceNode  AudioBuffer를 한번 재생할 수 있으며, 여러 개의 노드들은 동일한 AudioBuffer를 가리킬 수도 있다.  http://www.w3.org/TR/webaudio/#AudioBufferSourceNode interface AudioBufferSourceNode : AudioSourceNode { // Playback this in-memory audio asset // Many sources can share the same buffer attribute AudioBuffer buffer; readonly attribute AudioGain gain; attribute AudioParam playbackRate; attribute boolean loop; void noteOn(in double when); void noteGrainOn(in double when, in double grainOffset, in double grainDuration); void noteOff(in double when); } var source = context.createBufferSource(); source.buffer = AudioBuffer_데이터; source.loop = true | false; // 반복여부
  • 3. 기본 사용방법
  • 기본 사용방법 : 컨텍스트 생성과 루팅 // Audio Context 생성 var context = new webkitAudioContext(); // 사운드 소스 생성 var source = context.createBufferSource(); source.buffer = AudioBuffer_데이터;  스피커와 직접 연결 : source.connect(context.destination);  gainNode 연결 : var gainNode = context.createGainNode(); source.connect(gainNode); gainNode.connect(context.destination);  GainNode를 Compressor와 연결 : var compressor = context.createDynamicsCompressor(); gainNode.connect(compressor); compressor.connect(context.destination); source.noteOn(0); // play
  • 기본 사용방법 : 소스 데이터 로딩 var request = new XMLHttpRequest(); request.open(GET, sUrl, true); request.responseType = arraybuffer; // 전송받을 data가 바이너리이므로 arraybuffer로 설정 // XHR load callback request.onload = function() { // 비동기 디코딩 된다. 디코딩이 완료되면 디코딩된 PCM audio data를 사용할 수 있도록 준비된다. context.decodeAudioData(request.response, // 로드 콜백 함수 function(buffer) { ... }, // 에러 콜백 함수 function(e) { console.log(e); } ); }; request.send();
  • 4. How to use? : 다양한응용방법
  • Background music  게임에서 반복적이고 예측 가능한 BGM은 불편과 짜증을 유발할 수 있다.  특정 시점(마지막 보스와의 대결과 같은)에 BGM도 그에 따라 감성적으로 반영이 되어야 한다.  여러 사운드의 믹싱은 음악 프로그램에서 제공하는 기본적인 기능 중 하나이다.  Web Audio API를 활용해 XHR로 상황에 맞는 소스를 로딩해 재생할 수 있다.  로딩은 시간이 소요되므로, 최초 페이지 로딩시 또는 게임 진행 중 점진적으로 로딩을 하도록 한다.
  • Background music  사용될 각 노드들에 대한 소스를 생성하고 이를 연결한다.  여러 개의 사운드가 반복 재생되는 상태에서, 특정 장면에 사용되는 사운드의 음량을 키우고 사용되지 않는 사운드의 음량을 줄여 cross-fade 한다.
  • <audio> to Web Audio API  <audio>는 소스를 모두 다운로드 받지 않아도 실시간 스트리밍으로 재생 된다.  스트리밍 소스를 Web Audio API와 연결하면 스트리밍을 분석하거나 조작할 수 있게 된다.  <audio>를 Web Audio context로 가져오는 것도 가능하다. var audioElement = document.querySelector(audio); var mediaSourceNode = context.createMediaElementSource(audioElement); mediaSourceNode.connect(context.destination); audioElement.play();  createAnalyser() creates a RealtimeAnalyserNode which provide real-time frequency and time- domain analysis information.  context.createAnalyser()를 통한 equalizer graph 데모 : http://html5-demos.appspot.com/static/webaudio/createMediaSourceElement.html
  • Sound effects : 재생 시점이 다른 반복 재생  게임에서 여러 캐릭터가 다수 등장하는 배틀 장면인 경우에는 동시에 수많은 이펙트가 재생될 수 있다.  동일한 사운드 재생을 방지하기 위해 여러 종류의 사운드 풀을 준비해 사용할 수도 있지만, 모든 상황을 대비하도록 구성하는 것은 어렵다.  동일한 사운드를 재생시점을 다르게 지정해 풀을 구성하지 않고도, 동일한 이펙트를 만들 수 있다. // currentTime은 컨텍스트가 생성된 시점을 기준으로 0의 값으로 시작하며, 실시간 증가되는 값이다. var time = context.currentTime; for (var i = 0; i < rounds; i++) { var source = AudioBufferSource; source.noteOn(time + i * interval); }
  • Sound effects : 시그널 지연  DelayNode를 사용하면 오디오 시그널의 통과를 지연시킨다. var delayNode = context.createDelayNode(), now = context.currentTime; delayNode.delayTime.setValueAtTime(0, now); delayNode.delayTime.linearRampToValueAtTime(2, now + time);
  • Sound effects : 필터  BiquadFilterNode를 사용해, 사운드 시그널의 주파수를 필터링해 주파수의 응답을 변경할 수 있다. var filter = context.createBiquadFilter(); source.connect(filter); // 0:LOWPASS, 1:HIGHPASS, 2:BANDPASS, 3:LOWSHELF, 4:HIGHSHELF, 5:PEAKING, 6:NOTCH, 7:ALLPASS filter.type = 0; filter.Q.value = 12.06; filter.frequency.value = 400; filter.connect(context.destination);
  • 3D Positional sound  AudioPannerNode를 활용해 위치와 공간을 프로세싱 한다. var panner = context.createPanner(); // Directional model panner.coneOuterGain = 0.5; panner.coneOuterAngle = 180; panner.coneInnerAngle = 0; // Position, orientaion and velocity panner.setPosition(x, y, z); // 3D cartesian coordinate relative to the listener attribute panner.setOrientation(x, y, z); // pointing in the 3D cartesian coordinate space panner.setVelocity(x, y, z); // direction of travel and the speed in 3D space source.connect(panner); panner.connect(context.destination);
  • 3D Positional sound  Positional model은 OpenAL(Open Audio Library)에 기반한다.  http://connect.creativelabs.com/openal/default.aspx  Distance model은 소스로부터의 거리에 따라 gain 값을 다르게 갖는다.  Directional model은 외부 또는 내부 방향에 따라 gain 값을 다르게 갖는다. Demo: http://www.html5rocks.com/en/tutorials/webaudio/positional_audio/
  • Room effects and filters  동일한 소리를 장소에 따라 다르게 녹음된 데이터를 생성하는 것은 많은 비용을 필요로 한다.  동일한 사운드가 환경에 따라 다르게 들리는 것은 임펄스 응답(Impulse Response)의 차이라 할 수 있다.  ConvolverNode를 활용하면 임펄스 응답을 간단히 적용할 수 있다. var source = context.createBufferSource(); source.buffer = AudioBufferSource; var convolver = context.createConvolver(); convolver.buffer = AudioBufferSource; // 임펄스 데이터 source.connect(convolver); convolver.connect(context.destination);
  • Detect clipping  연결된 많은 AudioNode의 소리들이 normalize 되지 않으면 스피커 송출 용량을 넘어설 수 있다.  특정 채널의 시그널이 허용된 범위를 초과한 경우 clipping이 발생되며, -1 또는 1의 값으로 표현된다.  이를 위해 JavaScriptAudioNode를 사용한다. JavaScriptAudioNode는 audio를 JavaScript에서 직접 생성, 프로세스 또는 분석 할수 있게 한다. var meter = context.createJavaScriptNode( buffer_size, number_input_channel, number_output_channel ); meter.onaudioprocess = function(e) { … }
  • Detect clipping // Assume entire sound output is being piped through the mix node. var mix = context.createGainNode(); var meter = context.createJavaScriptNode(2048, 1, 1); // Porcess audio event binding meter.onaudioprocess = function (e) { var leftBuffer = e.inputBuffer.getChannelData(0); var rightBuffer = e.inputBuffer.getChannelData(1); checkClipping(leftBuffer); checkClipping(rightBuffer); }; mix.connect(meter); meter.connect(context.destination); mix.connect(context.destination); // Check if buffer exceeds function checkClipping(buffer) { var isClipping = false; // Iterate through buffer to check if any of the |values| exceeds 1. for (var i = 0; i < buffer.length; i++) { var absValue = Math.abs(buffer[i]); if (absValue >= 1) { isClipping = true; break; } } }
  • 5. Something more
  • Automation  AudioNode의 AudioParam의 메서드를 이용해 특정 시간에 다른 값을 같도록 처리할 수 있다.  음량조절을 스케줄링하면, 페이드 처리가 자동으로 발생하도록 할수 있다. var now = context.currentTime; // 지정된 시간에 특정 값을 같도록 한다. source.gain.setValueAtTime(0, now); // 특정 시간까지 값을 리니어하게 변경하도록 스케줄링 한다. source.gain.linearRampToValueAtTime(1.0, now + value); source.gain.linearRampToValueAtTime(0.0, now + value);
  • 몇 가지 기억할 것들  시그널이 부드럽고 튀지 않도록 DynamicCompressorNode를 활용하라.  페이지가 보이지 않는 경우에는 pageVisibility API를 활용해 불필요한 사운드 재생을 막는 것이 좋다.  Web Audio API에서 모든 시간 단위는 밀리세컨드(millisecond)가 아닌 초(second) 단위 이다.
  • 다루지 못한 주제들  Oscillator  RealtimeAnalyserNode  AudioChannelSplitter  AudioChannelMerger  WaveShaperNode
  • Reference  Google I/O 2012 – Turning the Web Up to 11  Presentaiton : http://webaudio-io2012.appspot.com  Video : http://youtu.be/hFsCG7v9Y4c  Getting started with Web Audio API  http://www.html5rocks.com/en/tutorials/webaudio/intro/  Developing game audio with the Web Audio API  http://www.html5rocks.com/en/tutorials/webaudio/games/..  Mixing positional audio and WebGL  http://www.html5rocks.com/en/tutorials/webaudio/positional_audio/  Web Audio Playground  http://webaudioplayground.appspot.com/  Web Audio Example  http://chromium.googlecode.com/svn/trunk/samples/audio/index.html
  • http://www.flickr.com/photos/robinfeder/3482072805/