SlideShare a Scribd company logo
1 of 19
Download to read offline
Developing game audio with
the Web Audio API




                       2012_05_15 / nhn_박재성
Index

  Web Audio API
  Modular routing
  Basic usage
  Background Music
  Sound effects
  3D Positional sound
  Room effects and filters
  Detect clipping
제한적인 <audio>

  단순한 게임은 <audio>로 가능하지만, 제한적이다.

 <audio controls loop>
   <source src=“music.wav">
 </audio>




 <audio> can’t :
  No ability to apply filters to the sound signal
  No way to access the raw PCM data
  No concept of position and direction of sources and listeners
  No fine-grained timing
Web Audio API

  High-level JavaScript API for processing and synthesizing audio in web
   application.
    http://www.w3.org/TR/webaudio/

  AudioContext는 모든 사운드 데이터를 관리 및 재생한다.

  재생을 위해선 사운드 소스를 생성한 후, AudioContext 인스턴스와 연결해야
   한다.
Modular Routing
  연결은 꼭 직접적일 필요는 없으며, 중간에 여러 단계의 AudioNode와
   연결(Modular Routing) 될 수 있다.

  이를 통해 중간 단계의 AudioNode를 통해 음량 조정, 필터 적용 등을 처리
   하게 된다.
브라우저 지원 여부
  사용하는 브라우저의 audio 지원과 범위를 확인할 수 있다.

  http://areweplayingyet.org/




                                Source : http://caniuse.com/audio-api
Basic usage : create and routing
  // Audio Context 생성
  var context = new webkitAudioContext();

  // 사운드 소스 생성
  var source = context.createBufferSource();
  source.buffer = 버퍼_데이터;

   직접 연결 :
  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
Basic usage : loading file
  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,

            // load callback
            function(buffer) {
                  ...
            },

            // error callback
            function(e) {
                   console.log(e);
            }
       );
  };

   request.send();
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

  BGM과 마찬가지로 비슷한 종류의 반복은 지루하고 짜증스럽다.

  이를 방지하기 위해 여러 종류의 사운드 풀을 준비해 사용할 수 있다.

  여러 캐릭터가 다수 등장하는 배틀 장면인 경우에는 동시에 수많은 이펙트가
   재생될 수 있다.


 // currentTime, starts at zero when the context is created and increases in real-time.
 var time = context.currentTime;

 for (var i = 0; i < rounds; i++) {
    var source = this.makeSource(this.buffers[M4A1]);
    source.noteOn(time + i * interval);
 }
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)에 기반한다.

  Distance model은 소스로부터의 거리에 따라 gain 값을 다르게 갖는다.
  Directional model은 외부 또는 내부 방향에 따라 gain 값을 다르게 갖는다.
Room effects and filters

   동일한 소리를 장소에 따라 다르게 녹음된 데이터를 생성하는 것은 많은
    비용을 필요로 한다.

   동일한 사운드가 환경에 따라 다르게 들리는 것은 임펄스 응답(Impulse
    Response)의 차이라 할 수 있다.

   ConvolverNode를 활용하면 임펄스 응답을 간단히 적용할 수 있다.

  var source = context.createBufferSource();
  source.buffer = 사운드_데이터;

  var convolver = context.createConvolver();
  convolver.buffer = 임펄스_데이터;

  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;
        }
     }
 }
몇 가지 기억할 사항

  시그널이 부드럽고 튀지 않도록 DynamicCompressorNode를 활용하라.




  페이지가 보이지 않는 경우에는 pageVisibility API를 활용해 불필요한 사운드
   재생을 막는 것이 좋다.
고맙습니다.

More Related Content

Similar to Developing game audio with the Web Audio API

Android Screen Recorder
Android Screen RecorderAndroid Screen Recorder
Android Screen RecorderSooHwan Ok
 
Windows Phone Mango 아키텍처-멀티태스킹(2)
Windows Phone Mango 아키텍처-멀티태스킹(2)Windows Phone Mango 아키텍처-멀티태스킹(2)
Windows Phone Mango 아키텍처-멀티태스킹(2)mosaicnet
 
리스펙토링 세미나 - 웹 브라우저 동작 개념, Node.js를 통한 서버 이해, REST API
리스펙토링 세미나 - 웹 브라우저 동작 개념, Node.js를 통한 서버 이해, REST API리스펙토링 세미나 - 웹 브라우저 동작 개념, Node.js를 통한 서버 이해, REST API
리스펙토링 세미나 - 웹 브라우저 동작 개념, Node.js를 통한 서버 이해, REST APIWooyoung Ko
 
Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신Circulus
 
Startup JavaScript 7 - Node.JS 기초
Startup JavaScript 7 - Node.JS 기초Startup JavaScript 7 - Node.JS 기초
Startup JavaScript 7 - Node.JS 기초Circulus
 
Puppet과 자동화된 시스템 관리
Puppet과 자동화된 시스템 관리Puppet과 자동화된 시스템 관리
Puppet과 자동화된 시스템 관리Keon Ahn
 
Python server-101
Python server-101Python server-101
Python server-101Huey Park
 
3D카툰메이커 완료세미나(복구됨)
3D카툰메이커 완료세미나(복구됨)3D카툰메이커 완료세미나(복구됨)
3D카툰메이커 완료세미나(복구됨)Daniel Shin
 
Audio data preprocessing and data loading using torchaudio
Audio data preprocessing and data loading using torchaudioAudio data preprocessing and data loading using torchaudio
Audio data preprocessing and data loading using torchaudioSeungHeon Doh
 
2023 GDG Sondo DevFest - Flutter/ Flavor, PlatformChannel, Environment variab...
2023 GDG Sondo DevFest - Flutter/ Flavor, PlatformChannel, Environment variab...2023 GDG Sondo DevFest - Flutter/ Flavor, PlatformChannel, Environment variab...
2023 GDG Sondo DevFest - Flutter/ Flavor, PlatformChannel, Environment variab...MaRoKim4
 
Hyperledger Fabric practice (v2.0)
Hyperledger Fabric practice (v2.0) Hyperledger Fabric practice (v2.0)
Hyperledger Fabric practice (v2.0) wonyong hwang
 
HTML5 & CSS3 - Video,Audio
HTML5 & CSS3 - Video,AudioHTML5 & CSS3 - Video,Audio
HTML5 & CSS3 - Video,Audiohyun soomyung
 

Similar to Developing game audio with the Web Audio API (13)

Android Screen Recorder
Android Screen RecorderAndroid Screen Recorder
Android Screen Recorder
 
Windows Phone Mango 아키텍처-멀티태스킹(2)
Windows Phone Mango 아키텍처-멀티태스킹(2)Windows Phone Mango 아키텍처-멀티태스킹(2)
Windows Phone Mango 아키텍처-멀티태스킹(2)
 
리스펙토링 세미나 - 웹 브라우저 동작 개념, Node.js를 통한 서버 이해, REST API
리스펙토링 세미나 - 웹 브라우저 동작 개념, Node.js를 통한 서버 이해, REST API리스펙토링 세미나 - 웹 브라우저 동작 개념, Node.js를 통한 서버 이해, REST API
리스펙토링 세미나 - 웹 브라우저 동작 개념, Node.js를 통한 서버 이해, REST API
 
Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신Startup JavaScript 9 - Socket.IO 실시간 통신
Startup JavaScript 9 - Socket.IO 실시간 통신
 
Startup JavaScript 7 - Node.JS 기초
Startup JavaScript 7 - Node.JS 기초Startup JavaScript 7 - Node.JS 기초
Startup JavaScript 7 - Node.JS 기초
 
Node.js at OKJSP
Node.js at OKJSPNode.js at OKJSP
Node.js at OKJSP
 
Puppet과 자동화된 시스템 관리
Puppet과 자동화된 시스템 관리Puppet과 자동화된 시스템 관리
Puppet과 자동화된 시스템 관리
 
Python server-101
Python server-101Python server-101
Python server-101
 
3D카툰메이커 완료세미나(복구됨)
3D카툰메이커 완료세미나(복구됨)3D카툰메이커 완료세미나(복구됨)
3D카툰메이커 완료세미나(복구됨)
 
Audio data preprocessing and data loading using torchaudio
Audio data preprocessing and data loading using torchaudioAudio data preprocessing and data loading using torchaudio
Audio data preprocessing and data loading using torchaudio
 
2023 GDG Sondo DevFest - Flutter/ Flavor, PlatformChannel, Environment variab...
2023 GDG Sondo DevFest - Flutter/ Flavor, PlatformChannel, Environment variab...2023 GDG Sondo DevFest - Flutter/ Flavor, PlatformChannel, Environment variab...
2023 GDG Sondo DevFest - Flutter/ Flavor, PlatformChannel, Environment variab...
 
Hyperledger Fabric practice (v2.0)
Hyperledger Fabric practice (v2.0) Hyperledger Fabric practice (v2.0)
Hyperledger Fabric practice (v2.0)
 
HTML5 & CSS3 - Video,Audio
HTML5 & CSS3 - Video,AudioHTML5 & CSS3 - Video,Audio
HTML5 & CSS3 - Video,Audio
 

More from Jae Sung Park

[SOSCON 2018] 오픈소스 개발: Behind the scenes
[SOSCON 2018] 오픈소스 개발: Behind the scenes[SOSCON 2018] 오픈소스 개발: Behind the scenes
[SOSCON 2018] 오픈소스 개발: Behind the scenesJae Sung Park
 
[DEVIEW 2018] JavaScript 배틀그라운드로부터 살아남기
[DEVIEW 2018] JavaScript 배틀그라운드로부터 살아남기[DEVIEW 2018] JavaScript 배틀그라운드로부터 살아남기
[DEVIEW 2018] JavaScript 배틀그라운드로부터 살아남기Jae Sung Park
 
[SOSCON 2017] 네이버의 FE 오픈소스: jindo에서 billboard.js까지
[SOSCON 2017] 네이버의 FE 오픈소스: jindo에서 billboard.js까지[SOSCON 2017] 네이버의 FE 오픈소스: jindo에서 billboard.js까지
[SOSCON 2017] 네이버의 FE 오픈소스: jindo에서 billboard.js까지Jae Sung Park
 
[DEVIEW 2017] 14일만에 GitHub 스타 1K 받은 차트 오픈소스 개발기
[DEVIEW 2017] 14일만에 GitHub 스타 1K 받은 차트 오픈소스 개발기[DEVIEW 2017] 14일만에 GitHub 스타 1K 받은 차트 오픈소스 개발기
[DEVIEW 2017] 14일만에 GitHub 스타 1K 받은 차트 오픈소스 개발기Jae Sung Park
 
Front end dev 2016 & beyond
Front end dev 2016 & beyondFront end dev 2016 & beyond
Front end dev 2016 & beyondJae Sung Park
 
[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjs
[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjs[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjs
[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjsJae Sung Park
 
How jQuery event works
How jQuery event worksHow jQuery event works
How jQuery event worksJae Sung Park
 
현실적 Angular js
현실적 Angular js현실적 Angular js
현실적 Angular jsJae Sung Park
 
가볍게 살펴보는 AngularJS
가볍게 살펴보는 AngularJS가볍게 살펴보는 AngularJS
가볍게 살펴보는 AngularJSJae Sung Park
 
Web Components & Polymer
Web Components & PolymerWeb Components & Polymer
Web Components & PolymerJae Sung Park
 
모바일 웹 디버깅
모바일 웹 디버깅모바일 웹 디버깅
모바일 웹 디버깅Jae Sung Park
 
혁신적인 웹컴포넌트 라이브러리 - Polymer
혁신적인 웹컴포넌트 라이브러리 - Polymer혁신적인 웹컴포넌트 라이브러리 - Polymer
혁신적인 웹컴포넌트 라이브러리 - PolymerJae Sung Park
 
우리가 몰랐던 크롬 개발자 도구
우리가 몰랐던 크롬 개발자 도구우리가 몰랐던 크롬 개발자 도구
우리가 몰랐던 크롬 개발자 도구Jae Sung Park
 
스마트 TV 앱 개발 맛보기
스마트 TV 앱 개발 맛보기스마트 TV 앱 개발 맛보기
스마트 TV 앱 개발 맛보기Jae Sung Park
 
How to create Aptana Ruble
How to create Aptana RubleHow to create Aptana Ruble
How to create Aptana RubleJae Sung Park
 

More from Jae Sung Park (20)

[SOSCON 2018] 오픈소스 개발: Behind the scenes
[SOSCON 2018] 오픈소스 개발: Behind the scenes[SOSCON 2018] 오픈소스 개발: Behind the scenes
[SOSCON 2018] 오픈소스 개발: Behind the scenes
 
[DEVIEW 2018] JavaScript 배틀그라운드로부터 살아남기
[DEVIEW 2018] JavaScript 배틀그라운드로부터 살아남기[DEVIEW 2018] JavaScript 배틀그라운드로부터 살아남기
[DEVIEW 2018] JavaScript 배틀그라운드로부터 살아남기
 
[SOSCON 2017] 네이버의 FE 오픈소스: jindo에서 billboard.js까지
[SOSCON 2017] 네이버의 FE 오픈소스: jindo에서 billboard.js까지[SOSCON 2017] 네이버의 FE 오픈소스: jindo에서 billboard.js까지
[SOSCON 2017] 네이버의 FE 오픈소스: jindo에서 billboard.js까지
 
[DEVIEW 2017] 14일만에 GitHub 스타 1K 받은 차트 오픈소스 개발기
[DEVIEW 2017] 14일만에 GitHub 스타 1K 받은 차트 오픈소스 개발기[DEVIEW 2017] 14일만에 GitHub 스타 1K 받은 차트 오픈소스 개발기
[DEVIEW 2017] 14일만에 GitHub 스타 1K 받은 차트 오픈소스 개발기
 
Front end dev 2016 & beyond
Front end dev 2016 & beyondFront end dev 2016 & beyond
Front end dev 2016 & beyond
 
[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjs
[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjs[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjs
[DEVIEW 2016] 네이버의 모던 웹 라이브러리 - egjs
 
현실적 PWA
현실적 PWA현실적 PWA
현실적 PWA
 
How jQuery event works
How jQuery event worksHow jQuery event works
How jQuery event works
 
iOS9 소개
iOS9 소개iOS9 소개
iOS9 소개
 
현실적 Angular js
현실적 Angular js현실적 Angular js
현실적 Angular js
 
가볍게 살펴보는 AngularJS
가볍게 살펴보는 AngularJS가볍게 살펴보는 AngularJS
가볍게 살펴보는 AngularJS
 
Web Components & Polymer
Web Components & PolymerWeb Components & Polymer
Web Components & Polymer
 
모바일 웹 디버깅
모바일 웹 디버깅모바일 웹 디버깅
모바일 웹 디버깅
 
혁신적인 웹컴포넌트 라이브러리 - Polymer
혁신적인 웹컴포넌트 라이브러리 - Polymer혁신적인 웹컴포넌트 라이브러리 - Polymer
혁신적인 웹컴포넌트 라이브러리 - Polymer
 
CSS Functions
CSS FunctionsCSS Functions
CSS Functions
 
우리가 몰랐던 크롬 개발자 도구
우리가 몰랐던 크롬 개발자 도구우리가 몰랐던 크롬 개발자 도구
우리가 몰랐던 크롬 개발자 도구
 
What's new in IE11
What's new in IE11What's new in IE11
What's new in IE11
 
스마트 TV 앱 개발 맛보기
스마트 TV 앱 개발 맛보기스마트 TV 앱 개발 맛보기
스마트 TV 앱 개발 맛보기
 
How to create Aptana Ruble
How to create Aptana RubleHow to create Aptana Ruble
How to create Aptana Ruble
 
Web Audio API
Web Audio APIWeb Audio API
Web Audio API
 

Developing game audio with the Web Audio API

  • 1. Developing game audio with the Web Audio API 2012_05_15 / nhn_박재성
  • 2. Index  Web Audio API  Modular routing  Basic usage  Background Music  Sound effects  3D Positional sound  Room effects and filters  Detect clipping
  • 3. 제한적인 <audio>  단순한 게임은 <audio>로 가능하지만, 제한적이다. <audio controls loop> <source src=“music.wav"> </audio> <audio> can’t :  No ability to apply filters to the sound signal  No way to access the raw PCM data  No concept of position and direction of sources and listeners  No fine-grained timing
  • 4. Web Audio API  High-level JavaScript API for processing and synthesizing audio in web application.  http://www.w3.org/TR/webaudio/  AudioContext는 모든 사운드 데이터를 관리 및 재생한다.  재생을 위해선 사운드 소스를 생성한 후, AudioContext 인스턴스와 연결해야 한다.
  • 5. Modular Routing  연결은 꼭 직접적일 필요는 없으며, 중간에 여러 단계의 AudioNode와 연결(Modular Routing) 될 수 있다.  이를 통해 중간 단계의 AudioNode를 통해 음량 조정, 필터 적용 등을 처리 하게 된다.
  • 6. 브라우저 지원 여부  사용하는 브라우저의 audio 지원과 범위를 확인할 수 있다.  http://areweplayingyet.org/ Source : http://caniuse.com/audio-api
  • 7. Basic usage : create and routing // Audio Context 생성 var context = new webkitAudioContext(); // 사운드 소스 생성 var source = context.createBufferSource(); source.buffer = 버퍼_데이터;  직접 연결 : 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
  • 8. Basic usage : loading file 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, // load callback function(buffer) { ... }, // error callback function(e) { console.log(e); } ); }; request.send();
  • 9. Background music  반복적이고 예측 가능한 BGM은 불편과 짜증을 유발할 수 있다.  특정 시점(마지막 보스와의 대결과 같은)에 BGM도 그에 따라 감성적으로 반영이 되어야 한다.  여러 사운드의 믹싱은 음악 프로그램에서 제공하는 기본적인 기능 중 하나이다.  Web Audio API를 활용해 XHR로 상황에 맞는 소스를 로딩해 재생할 수 있다.  로딩은 시간이 소요되므로, 최초 페이지 로딩시 또는 게임 진행 중 점진적으로 로딩을 하도록 한다.
  • 10. Background music  사용될 각 노드들에 대한 소스를 생성하고 이를 연결한다.  여러 개의 사운드가 반복 재생되는 상태에서, 특정 장면에 사용되는 사운드의 음량을 키우고 사용되지 않는 사운드의 음량을 줄여 cross-fade 한다.
  • 11. <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
  • 12. Sound effects  BGM과 마찬가지로 비슷한 종류의 반복은 지루하고 짜증스럽다.  이를 방지하기 위해 여러 종류의 사운드 풀을 준비해 사용할 수 있다.  여러 캐릭터가 다수 등장하는 배틀 장면인 경우에는 동시에 수많은 이펙트가 재생될 수 있다. // currentTime, starts at zero when the context is created and increases in real-time. var time = context.currentTime; for (var i = 0; i < rounds; i++) { var source = this.makeSource(this.buffers[M4A1]); source.noteOn(time + i * interval); }
  • 13. 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);
  • 14. 3D Positional sound  Positional model은 OpenAL(Open Audio Library)에 기반한다.  Distance model은 소스로부터의 거리에 따라 gain 값을 다르게 갖는다.  Directional model은 외부 또는 내부 방향에 따라 gain 값을 다르게 갖는다.
  • 15. Room effects and filters  동일한 소리를 장소에 따라 다르게 녹음된 데이터를 생성하는 것은 많은 비용을 필요로 한다.  동일한 사운드가 환경에 따라 다르게 들리는 것은 임펄스 응답(Impulse Response)의 차이라 할 수 있다.  ConvolverNode를 활용하면 임펄스 응답을 간단히 적용할 수 있다. var source = context.createBufferSource(); source.buffer = 사운드_데이터; var convolver = context.createConvolver(); convolver.buffer = 임펄스_데이터; source.connect(convolver); convolver.connect(context.destination);
  • 16. 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) { … }
  • 17. 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; } } }
  • 18. 몇 가지 기억할 사항  시그널이 부드럽고 튀지 않도록 DynamicCompressorNode를 활용하라.  페이지가 보이지 않는 경우에는 pageVisibility API를 활용해 불필요한 사운드 재생을 막는 것이 좋다.