ãã³ã¯ãã³ã§ãä½ã®åãã«ãããªã3Dãã³ãã§ã¼ãã
WebAudio Web MIDI API Advent Calendar 2016ã®19æ¥ç®ã§ãã
ã
ãã£ãã¡ãªäººã®ããã®ãã¢ãã¼ã¸ãªã³ã¯ãã¹ããï¼ã¤ã¤ãã³ã§èãã¦ã°ã«ã°ã«æ©ãåã£ã¦ãã ããã
http://aikelab.net/apan/
ã
Web Audio APIã§ã¯ã左右ã ãã§ãªã3Dã®ãã³ãç¨æããã¦ãã¾ããã¤ã¾ãé³ã®å®ä½ã䏿¬¡å
çã«é
ç½®ãããã¨ãã§ãã¾ãã
ãã¦ããã£ãã3Dãã³ãªã®ã§ãã¹ããã®å é度ã»ã³ãµã¼ã使ã£ã¦ãè´ã人ã®ä½ã®åãã«ããã空éçã«é³ãé
ç½®ãããããã«ãã¦ã¿ã¾ããããã¤ã¾ãããã¨ãã°ã¤ã¤ãã³ã§é³æ¥½ãè´ããªããæ¨ªãåãã¨ãããã¾ã§å·¦å³ããèããã¦ããé³ãåå¾ããèããã¦ãããã¨ãããããªãã¨ã§ãã
ã
ソースコードã¯ãããªæãã«ãªãã¾ãã
ã¾ãä½ã¯ãªãã¨ããªã¼ãã£ãªã³ã³ããã¹ãã®ä½æã
var ctx = new (window.AudioContext || window.webkitAudioContext)();
Playerã¯èªä½ã®BufferSourceNodeã©ããã¼ã§ãã詳ããã¯player.jsãè¦ã¦ãã ããã
var player = new Player(ctx, 'sound/apan.mp3');
ãã£ã³ãã«ã¹ããªãã¿ã¼ãã¼ãã§ã¹ãã¬ãªã½ã¼ã¹ã®å·¦chã¨å³chãå¥ã ã«åãåºãã¾ãã
var splitter = ctx.createChannelSplitter(2);
ãã³ãã¼ãã¼ãã§å·¦chã®é³ã¨å³chã®é³ã䏿¬¡å 空éã«é ç½®ãã¾ãã
var panL = ctx.createPanner(); panL.panningModel = "HRTF"; panL.setPosition(-1, 0, 0); var panR = ctx.createPanner(); panR.panningModel = "HRTF"; panR.setPosition(1, 0, 0);
ãã¼ãåå£«ã®æ¥ç¶ã¯ãããªæãã
// player ----splitter // ---- PanL ---- destination // ---- PanR ---- destination player.connect(splitter); splitter.connect(panL, 0); splitter.connect(panR, 1); panL.connect(ctx.destination); panR.connect(ctx.destination);
ãã³å転ç¨ã®setAngle颿°ã§ããè§åº¦ãã©ã¸ã¢ã³ã§åãåã£ã¦ãã³ãã¼ãã¼ãã®ä½ç½®ãY軸ãä¸å¿ã«å転ãã¾ãã
var setAngle = function(theta) { var sn = Math.sin(theta); var cs = Math.cos(theta); panL.setPosition(-cs, 0, sn); panR.setPosition(cs, 0, -sn); }
å é度ã»ã³ãµã¼ã®ã¤ãã³ãå¦çãå é度ã»ã³ãµã¼ã¯alphaãbetaãgammaã®ï¼ã¤ã®å¤ã§è¡¨ç¾ãããã¹ããã縦æã¡ããã¨ãã®Y軸å転ã¯alphaã«å¯¾å¿ãã¾ããå é度ã»ã³ãµã¼ã®å¤ã¯åº¦ãªã®ã§ã©ã¸ã¢ã³ã«å¤æãã¦ããåè¿°ã®setAngle颿°ã«æ¸¡ãã¦ãã¾ãã
window.addEventListener("deviceorientation", function(e){ if (e.alpha) { setAngle(e.alpha * Math.PI / 180); } });
ã
ãã¢ãã¼ã¸ã¯ãã¡ãã§ãã
http://aikelab.net/apan/
ã¹ããï¼ã¤ã¤ãã³ã§åçãã¾ãã
ãããªå§¿å¢ã§ã¹ãããæã£ãã¾ã¾ã°ã«ã°ã«æ©ãåã£ã¦ãã ããã

ã½ã¼ã¹ã³ã¼ãã¯ãã¡ãã
https://github.com/aike/AcceleroPanner