VSTãã©ã°ã¤ã³ä½å®¶ã®ããã®Web Audio APIå ¥é ã adelayã®ä½æ
å
¨å½100人ãããã®VSTãã©ã°ã¤ã³ä½å®¶ã®æ¹ããã°ãã¯ãä»æ¥ã¯çããããªãã¿ã®adelayã®ã¦ã§ããã©ã¦ã¶ãã¼ã¸ã§ã³ãä½ã£ã¦ã¿ããã¨æãã¾ããæè¿ã®ã¦ã§ããã©ã¦ã¶ã¯Audio APIãæ¥éã«å
å®ãã¦ãã¦ç°¡åã«é³å£°ä¿¡å·å¦çãã§ããããã«ãªã£ã¦ãã¾ããã
ã
adelayã¨ããã°VST 2.X SDKã®ãµã³ãã«ã³ã¼ãã¨ãã¦å¤§å¤ãªãã¿æ·±ãããããªã·ã³ãã«ãªã³ã¼ãã§ãã®ãã£ã¬ã¤ãä½ãã¦ãã¾ãã®ãã¨ããã¤ã³ãã¯ããããããã©ã°ã¤ã³ä½å®¶ã§ããã°ã¢ã«ã´ãªãºã ãããã§æå±ã§ãããããä½ã«æã¿ä»ãã¦ãããã¨æãã¾ããï¼â大ããï¼
ã
ä¸æ¹ãWeb Audio APIã§ç¨æããã¦ããDelayNodeã¯åã«å
¥åä¿¡å·ãé
延ããã¦åçãããã®ã§Dry/Wetã®ãã©ã³ã¹è¨å®ãFeedbackãããã¾ããããã£ã¬ã¤ããã°ã©ã ã¯GainNodeãªã©ã¨çµã¿åããã¦ä½ããã¨ãæ³å®ããã¦ãããã®ã¨æãã¾ããå
¥éè
ãå¦ç¿ããã«ã¯ã¡ãã£ã¨é åãã®ããã«æãã¾ãã
ãããªããã§ä»åã¯DelayNodeã使ããã«ãæ±ç¨ã®ä¿¡å·å¦çã¢ã¸ã¥ã¼ã«JavaScriptNodeã使ã£ã¦adelayã¨åããã¸ãã¯ãç´ ç´ã«å®è£
ãã¦ã¿ã¾ãã
ã
æ¬é¡ã®ãã£ã¬ã¤ã«å
¥ãåã«ãã£ã¬ã¤ã¨ãã§ã¯ãããããé³æºãå¿
è¦ãªã®ã§å
ã«ãã£ã¡ãç¨æãã¾ãã
Ryoya KAWAIさんのOscillatorãå¾ç¶ãã¼ãã«æ¥ç¶ããããããã«æ¹é ããOscillatorクラスãç¨æãã¾ããããããªé¢¨ã«å¼ã³åºãã¨ï¼ç§ãã¨ã«ç©å½¢æ³¢ãé³´ããã¾ãã
$(function() { var ctx = new webkitAudioContext(); var osc = new Oscillator(ctx); osc.setOscType('square'); setInterval(function() { osc.noteOn(72); setTimeout(function() {osc.noteOff(72);}, 100); }, 3000); osc.connect(ctx.destination); });
http://aikelab.net/adelay/oscillator/ãï¼æ³¨ï¼ãã¼ã¸ãéãã¨æ°ç§å¾ã«é³ãåºã¾ããChrome/Safariã®ã¿ï¼
ã
ãã¦ãããã§ã¯ãã£ã¬ã¤ã®ä½æã§ããã¾ãã¯ä¿¡å·å¦çãããåä½ã1024ãµã³ãã«ãã¤ã¨ãã¾ãã
var Delay = function(ctx) { this.sampleFrames = 1024;
ãã£ã¬ã¤æåãè¨æ¶ããããã®ãããã¡ãç¨æãã¾ãããããã¡ãµã¤ãºã¯ä»¥ä¸ã®ããã«è¨ç®ã§ãã¾ãã
ããããã¡ãµã¤ãº = ãµã³ããªã³ã°ã¬ã¼ãï¼Hzï¼ * æ大ãã£ã¬ã¤ã¿ã¤ã ï¼ç§ï¼
ä»åã¯ã·ã³ãã«ã«æ大ãã£ã¬ã¤ã¿ã¤ã ã1ç§ã¨ãã¦ãªã¼ãã£ãªã³ã³ããã¹ãããåå¾ãããµã³ããªã³ã°ã¬ã¼ãã¨åããµã¤ãºã®ãããã¡ã確ä¿ãã¾ããcursorã¯ãããã¡ä¸ã®èªã¿åºãä½ç½®ãä¿æããå¤æ°ã§ãã
this.size = ctx.sampleRate; this.cursor = 0; this.buffer = new Float32Array(this.size);
ãã©ã¡ã¼ã¿ã¯ãã£ã¬ã¤ã¿ã¤ã ã®delayãfeedbackããã£ã¬ã¤æåã®é³éoutã®ï¼ã¤ã§ãããããã0.0ã1.0ã®å¤ãã¨ãã¾ãã
this.setDelay(0.5); this.setFeedback(0.5); this.setOut(0.75);
次ã«ãå ¥å1chãåºå2chã®JavaScriptNodeãä½ãã¾ãã
this.node = ctx.createJavaScriptNode(this.sampleFrames, 1, 2);
ãããããã¡ã¤ã³ã®ãã¸ãã¯ãonaudioprocessé¢æ°ã¯ãµã³ãã«ãã¬ã¼ã ï¼1024ãµã³ãã«ï¼ãã¨ã«å¼ã°ãã¾ãããã¹ã¦ã®ãµã³ãã«ãã¼ã¿ã«å¯¾ãã¦ãã©ã¤æå(x)ã¨ååã¾ã§ã®ãã£ã¬ã¤æå(y)ãå ç®ãã¦ãããã¡ã«æ ¼ç´ãã¾ããããã次åã®ãã£ã¬ã¤æåã«ãªãã¾ãã
var self = this; this.node.onaudioprocess = function(event) { var sampleFrames = self.sampleFrames; var in1 = event.inputBuffer.getChannelData(0); var out1 = event.outputBuffer.getChannelData(0); var out2 = event.outputBuffer.getChannelData(1); var n = 0; while (--sampleFrames >= 0) { var x = in1[n]; var y = self.buffer[self.cursor]; self.buffer[self.cursor++] = x + y * self.feedback; if (self.cursor >= self.delay) self.cursor = 0; out1[n] = y * self.out; out2[n] = y * self.out; n++; } }; };
ãã¨ã¯ãã©ã¡ã¼ã¿è¨å®ç¨é¢æ°ã¨ãã¼ãæ¥ç¶ç¨ã®é¢æ°ãç¨æããã°å®æã
// fDelay: 0.0 - 1.0 (0sec - 1.0sec) Delay.prototype.setDelay = function(fdelay) { this.cursor = 0; this.delay = Math.floor(fdelay * (this.size - 1)); }; // fFeedback: 0.0 - 1.0 Delay.prototype.setFeedback = function(ffeedback) { this.feedback = ffeedback; }; // fOut: 0.0 - 1.0 Delay.prototype.setOut = function(fOut) { this.out = fOut; }; Delay.prototype.getNode = function() { return this.node; }; Delay.prototype.connect = function(obj) { this.node.connect(obj); };
ãã£ãã®Oscillatorã«æ¥ç¶ããã¨ãããªæãã«ãªãã¾ãã
http://aikelab.net/adelay/simple/ãï¼æ³¨ï¼ãã¼ã¸ãéãã¨æ°ç§å¾ã«é³ãåºã¾ããChrome/Safariã®ã¿ï¼
ã
æå¾ã«GUIãã¤ãã¦ãããªãã®ã¨ãã§ã¯ã¿ã¼ã«ãã¦ã¿ã¾ãããããã¡ã2åç¨æãã¦Lch/Rchå¥ã
ã«ãããããã«ãã¾ãããã¾ãããã¨ãã¨ã®adelayã¯ãã©ã¤åºåããªãã£ãã®ã§ãã©ã¤ã¨ã¦ã§ãããæ··ãã¦åºåããããã«ãã¾ããã
Oscillatorã®ç©å½¢æ³¢ã®ä»£ããã«ã®ã¿ã¼ã®ãªãããµã³ããªã³ã°ããé³ã«æ¥ç¶ãã¦ã§ããããããããåãã¦éãã§ã¿ã¦ãã ããã
http://aikelab.net/adelay/ãï¼æ³¨ï¼ãã¼ã¸ãéãã¨æ°ç§å¾ã«é³ãåºã¾ããChrome/Safariã®ã¿ï¼ã
ãï¼ç°¡åã§ããã
Web Music Developers JP Advent Calendar 2012ï¼7æ¥ç®ï¼