logo

ibnjs

Unnamed repository; edit this file 'description' to name the repository.
commit: c7522f2e5c5ae38c370310b0916472d491388dca
parent 62fe196b59881f172e7ee49b46b62e8af19eb420
Author: Adrian Siekierka <asiekierka@gmail.com>
Date:   Sat, 31 Dec 2011 11:34:51 +0100

AUDIO HAS BEEN IMPLEMENTED

Diffstat:

Mibniz.html273+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 169 insertions(+), 104 deletions(-)

diff --git a/ibniz.html b/ibniz.html @@ -7,10 +7,11 @@ Why u no canvas </canvas><br> <form> <input type="text" id="code" style="width: 256px"><br> -<input type="checkbox" id="pause">Pause <input type="checkbox" id="simpleGetPut">Simple memory access +<input type="checkbox" id="pause">Pause <input type="checkbox" id="simpleGetPut">Simple memory access<br> +<input type="checkbox" id="useAudio">Audio (experimental, firefox/chrome/safari) </form> <div id="fps"><b>FPS:</b> [loading...]</div> -<b>IBNIZ-js 0.7a</b><br> +<b>IBNIZ-js 0.8</b><br> <a href="https://github.com/asiekierka/ibnjs">Github repository</a><br> <a href="mailto:asiekierka@gmail.com">Contact</a><br> <script type="text/javascript"> @@ -67,7 +68,7 @@ Array.prototype.push2 = function(v){ Array.prototype.dpush2 = function(v){ this.push(v|0,v|0); } -function Parser(simpleGetPut) +function Parser(simpleGetPut,useAudio) { this.code = ""; this.parsedCode = new Array(); @@ -98,8 +99,9 @@ function Parser(simpleGetPut) var steps = (a>>16)&31; return ((b>>>steps)|(b<<(32-steps))); } - this.config = function(simpleGetPut) + this.config = function(simpleGetPut,useAudio) { + this.useAudio=useAudio; if(simpleGetPut) { this.get = function(addr) { return this.mem[addr]; } @@ -199,7 +201,7 @@ function Parser(simpleGetPut) } } } - this.config(simpleGetPut); + this.config(simpleGetPut,useAudio); this.load = function(c) { this.code=c; @@ -215,11 +217,11 @@ function Parser(simpleGetPut) this.pushmedia = function(x,y) { if(this.mode==0) this.compiledpm(x,y); - else this.stacka.push(this.t<<16); + else this.stacka.push(this.t<<16 | (y<<8) | x); } - this.pmaudio = function() + this.pmaudio = function(x,y) { - this.stacka.push(this.t<<16); + this.stacka.push(this.t<<16 | (y<<8) | x); } this.compilepushmedia = function() { @@ -248,19 +250,20 @@ function Parser(simpleGetPut) { // run audio, too this.videoout = this.stacka.pop(); - // No audio code yet! - /* - this.mode=1; - this.terminate = 0; - this.stack.clear(); - this.ip = 0; - this.pmaudio(); - while(this.terminate!=1) + if((this.useFFAudio || this.useChromeAudio) && this.useAudio && (x%128)==0) { - this.execOne(); - this.ip++; + if(this.stackmode==1) + this.audioout=this.videoout; // same stack data, skip the processing bulk + else + { + this.mode=1; + this.terminate = 0; + this.stacka.length=0; + this.ip = 0; + this.pmaudio(x,y); + this.exec(x,y); + } } - */ } if(this.mode==1) this.audioout = this.stacka.pop(); } @@ -427,7 +430,7 @@ function Parser(simpleGetPut) // push media context this.pm0(); // loop - this.exec(); + this.exec(0,0); if(this.stacka.length>1) this.stackmode = 1; this.compilepushmedia(); } @@ -442,6 +445,7 @@ function Parser(simpleGetPut) { var cmd; var a; + var stacka = this.stacka; while(this.terminate!=1) { if(this.ip>=this.parsedCode.length) @@ -457,78 +461,78 @@ function Parser(simpleGetPut) { // Math! case 43: - a = this.stacka.pop(); - this.stacka.dpush(a+this.stacka.pop()); + a = stacka.pop(); + stacka.dpush(a+stacka.pop()); break; case 45: - a = this.stacka.pop(); - this.stacka.dpush(this.stacka.pop()-a); + a = stacka.pop(); + stacka.dpush(stacka.pop()-a); break; case 42: - a = this.stacka.pop(); - this.stacka.dpush((a*this.stacka.pop())/65536); + a = stacka.pop(); + stacka.dpush((a*stacka.pop())/65536); break; case 47: - a = this.stacka.pop(); - this.stacka.dpush((this.stacka.pop()*65536)/a); + a = stacka.pop(); + stacka.dpush((stacka.pop()*65536)/a); break; case 37: - a = this.stacka.pop(); - this.stacka.push(this.stacka.pop()%a); + a = stacka.pop(); + stacka.push(stacka.pop()%a); break; case 38: - a = this.stacka.pop(); - this.stacka.push(a&this.stacka.pop()); + a = stacka.pop(); + stacka.push(a&stacka.pop()); break; case 124: - a = this.stacka.pop(); - this.stacka.push(a|this.stacka.pop()); + a = stacka.pop(); + stacka.push(a|stacka.pop()); break; case 94: - a = this.stacka.pop(); - this.stacka.push(a^this.stacka.pop()); + a = stacka.pop(); + stacka.push(a^stacka.pop()); break; case 108: - var steps = (this.stacka.pop()>>16)&63; - a = this.stacka.pop(); - this.stacka.push(steps<32 ? a<<steps : a>>(steps-32)); + var steps = (stacka.pop()>>16)&63; + a = stacka.pop(); + stacka.push(steps<32 ? a<<steps : a>>(steps-32)); break; case 114: - var steps = (this.stacka.pop()>>16)&31; - a = this.stacka.pop(); - this.stacka.push((a>>>steps)|(a<<(32-steps))); + var steps = (stacka.pop()>>16)&31; + a = stacka.pop(); + stacka.push((a>>>steps)|(a<<(32-steps))); break; case 97: - a = this.stacka.pop(); - this.stacka.dpush(Math.atan2(a,this.stacka.pop())*(65536/(2*Math.PI))); + a = stacka.pop(); + stacka.dpush(Math.atan2(a,stacka.pop())*(65536/(2*Math.PI))); break; case 115: - this.stacka.dpush(Math.sin(this.stacka.pop()*(2*Math.PI/65536))*65536); + stacka.dpush(Math.sin(stacka.pop()*(2*Math.PI/65536))*65536); break; case 113: - a = this.stacka.pop(); - this.stacka.dpush(0 > a ? 0 : 65536 * Math.sqrt(a / 65536)); + a = stacka.pop(); + stacka.dpush(0 > a ? 0 : 65536 * Math.sqrt(a / 65536)); break; case 60: - a = this.stacka.pop(); - this.stacka.push(0 > a ? a : 0); + a = stacka.pop(); + stacka.push(0 > a ? a : 0); break; case 62: - a = this.stacka.pop(); - this.stacka.push(0 < a ? a : 0); + a = stacka.pop(); + stacka.push(0 < a ? a : 0); break; case 61: - this.stacka.push(this.stacka.pop()==0); + stacka.push(stacka.pop()==0); break; case 126: - this.stacka.push(~this.stacka.pop()); + stacka.push(~stacka.pop()); break; // Exterior! case 77: // media context switch this.mode=1; - this.videoout = this.stacka.pop(); - this.stacka.clear(); + this.videoout = stacka.pop(); + stacka.clear(); this.pmaudio(); break; case 119: // where am I? well, where are you @@ -539,58 +543,58 @@ function Parser(simpleGetPut) break; // Stack! case 100: - this.stacka.dup(); + stacka.dup(); break; case 120: - this.stacka.exchange(); + stacka.exchange(); break; case 118: - this.stacka.trirot(); + stacka.trirot(); break; case 112: - this.stacka.pop(); + stacka.pop(); break; case 41: - this.stacka.push(this.stacka.gettop(0-this.rol16(this.stacka.pop()))); + stacka.push(stacka.gettop(0-this.rol16(stacka.pop()))); break; case 40: - a = this.rol16(this.stacka.pop()); - this.stacka.puttop(0-a,this.stacka.pop()); + a = this.rol16(stacka.pop()); + stacka.puttop(0-a,stacka.pop()); break; // Memory! case 64: - this.stacka.push(this.get(this.rol16(this.stacka.pop())&1048575)); + stacka.push(this.get(this.rol16(stacka.pop())&1048575)); break; case 33: - a = this.rol16(this.stacka.pop()); - this.put(a&1048575,this.stacka.pop()); + a = this.rol16(stacka.pop()); + this.put(a&1048575,stacka.pop()); break; // Return stack manipulation case 82: - this.stacka.push(this.rstacka.pop()); + stacka.push(this.rstacka.pop()); break; case 80: - this.rstacka.push(this.stacka.pop()); + this.rstacka.push(stacka.pop()); break; // Loops case 105: - this.stacka.push(this.rstacka.gettop(-1)); + stacka.push(this.rstacka.gettop(-1)); break; case 106: - this.stacka.push(this.rstacka.gettop(-3)); + stacka.push(this.rstacka.gettop(-3)); break; case 74: - this.ip = this.rol16(this.stacka.pop())-1; + this.ip = this.rol16(stacka.pop())-1; break; case 91: this.rstacka.push(this.rol16(this.ip+1)); break; case 93: - if(this.stacka.pop()!=0) this.ip=this.rol16(this.rstacka.gettop(0))-1; + if(stacka.pop()!=0) this.ip=this.rol16(this.rstacka.gettop(0))-1; else this.rstacka.pop(); break; case 88: - this.rstacka.push(this.stacka.pop()); + this.rstacka.push(stacka.pop()); this.rstacka.push(this.rol16(this.ip+1)); break; case 76: @@ -605,11 +609,11 @@ function Parser(simpleGetPut) break; case 86: this.rstacka.push(this.rol16(this.ip+1)); - this.ip = this.rol16(this.get(this.rol16(this.stacka.pop())&1048575))-1; + this.ip = this.rol16(this.get(this.rol16(stacka.pop())&1048575))-1; break; // Special case 128: // Double trirot - this.stacka.trirot2(); + stacka.trirot2(); break; default: break; @@ -628,11 +632,11 @@ function Parser(simpleGetPut) switch(cmd[1]) { case 123: - this.put(this.rol16(this.stacka.pop())&1048575,this.rol16(this.ip+1)); + this.put(this.rol16(stacka.pop())&1048575,this.rol16(this.ip+1)); this.ip = cmd[2]; break; case 63: - a = this.stacka.pop(); + a = stacka.pop(); if(a==0) this.ip = cmd[2]; break; case 58: @@ -644,64 +648,64 @@ function Parser(simpleGetPut) switch(cmd[2]) { case 43: - this.stacka.dpush(cmd[1]+this.stacka.pop()); + stacka.dpush(cmd[1]+stacka.pop()); break; case 45: - this.stacka.dpush(this.stacka.pop()-cmd[1]); + stacka.dpush(stacka.pop()-cmd[1]); break; case 42: - this.stacka.dpush((cmd[1]*this.stacka.pop())/65536); + stacka.dpush((cmd[1]*stacka.pop())/65536); break; case 47: - this.stacka.dpush((this.stacka.pop()*65536)/cmd[1]); + stacka.dpush((stacka.pop()*65536)/cmd[1]); break; case 37: - this.stacka.push(this.stacka.pop()%cmd[1]); + stacka.push(stacka.pop()%cmd[1]); break; case 38: - this.stacka.push(cmd[1]&this.stacka.pop()); + stacka.push(cmd[1]&stacka.pop()); break; case 124: - this.stacka.push(cmd[1]|this.stacka.pop()); + stacka.push(cmd[1]|stacka.pop()); break; case 94: - this.stacka.push(cmd[1]^this.stacka.pop()); + stacka.push(cmd[1]^stacka.pop()); break; case 108: - this.stacka.push(this.shl(cmd[1],this.stacka.pop())); + stacka.push(this.shl(cmd[1],stacka.pop())); break; case 114: - this.stacka.push(this.ror(cmd[1],this.stacka.pop())); + stacka.push(this.ror(cmd[1],stacka.pop())); break; case 97: - this.stacka.dpush(Math.atan2(cmd[1],this.stacka.pop())*(65536/(2*Math.PI))); + stacka.dpush(Math.atan2(cmd[1],stacka.pop())*(65536/(2*Math.PI))); break; case 115: - this.stacka.dpush(Math.sin(cmd[1]*(Math.PI/32768))*65536); + stacka.dpush(Math.sin(cmd[1]*(Math.PI/32768))*65536); break; case 113: - this.stacka.dpush(0 > cmd[1] ? 0 : 65536 * Math.sqrt(cmd[1] / 65536)); + stacka.dpush(0 > cmd[1] ? 0 : 65536 * Math.sqrt(cmd[1] / 65536)); break; case 126: - this.stacka.push(~cmd[1]); + stacka.push(~cmd[1]); break; case 100: - this.stacka.push2(cmd[1]); + stacka.push2(cmd[1]); break; case 40: - this.stacka.puttop(cmd[1],this.stacka.pop()); + stacka.puttop(cmd[1],stacka.pop()); break; case 41: - this.stacka.push(this.stacka.gettop(cmd[1])); + stacka.push(stacka.gettop(cmd[1])); break; case 74: this.ip = cmd[1]; break; case 64: - this.stacka.push(this.get(cmd[1])); + stacka.push(this.get(cmd[1])); break; case 33: - this.put(cmd[1],this.stacka.pop()); + this.put(cmd[1],stacka.pop()); break; case 86: this.rstacka.push(this.rol16(this.ip+1)); @@ -718,15 +722,15 @@ function Parser(simpleGetPut) break; // special case 128: // direct load - this.stacka.push(this.mem[cmd[1]]); + stacka.push(this.mem[cmd[1]]); break; case 129: // direct store - this.mem[cmd[1]]=this.stacka.pop(); + this.mem[cmd[1]]=stacka.pop(); break; } break; case 2: // imm - this.stacka.push(cmd[1]); + stacka.push(cmd[1]); break; default: break; @@ -734,7 +738,25 @@ function Parser(simpleGetPut) this.ip++; } } - this.drawToCanvas = function(c) + this.useFFAudio = false; + this.useChromeAudio = false; + this.buffer = new Float32Array(512); + if(Audio) + { + this.audioOut = new Audio(); + if(this.audioOut.mozSetup) + { + this.audioOut.mozSetup(1,512*60); + this.useFFAudio = true; + } + } + if(webkitAudioContext) + { + this.audioCtx = new webkitAudioContext(); + this.audioSR = this.audioCtx.sampleRate/60; + this.useChromeAudio = true; + } + this.render = function(c) { var idd = c.createImageData(256,256); var id = idd.data; @@ -744,7 +766,20 @@ function Parser(simpleGetPut) var cv = 0; for(var y=0;y<256;y++) { - for(var x=0;x<256;x++) + this.buffer[(y<<1)] = (((this.audioout&65535)^32768)-32768)/32768; + for(var x=0;x<128;x++) + { + this.run(x,y); + cy = (p.videoout>>>8)&255; + cu = (((p.videoout>>>16)&255)^0x80)-128; + cv = ((p.videoout>>>24)^0x80)-128; + id[imgpos++] = (298*cy + 409*cv + 128)>>8; + id[imgpos++] = (298*cy - 100*cu - 208*cv + 128)>>8; + id[imgpos++] = (298*cy + 516*cu + 128)>>8; + id[imgpos++] = 255; + } + this.buffer[(y<<1)+1] = (((this.audioout&65535)^32768)-32768)/32768; + for(var x=128;x<256;x++) { this.run(x,y); cy = (p.videoout>>>8)&255; @@ -757,9 +792,37 @@ function Parser(simpleGetPut) } } c.putImageData(idd,0,0); + if(this.useFFAudio) this.audioOut.mozWriteAudio(this.buffer); + else if(this.useChromeAudio) + { + if(this.audioOut.noteOff) this.audioOut.noteOff(0); + this.fixbuffer = new Float32Array(this.audioSR); + for(var i=0;i<this.audioSR;i++) + { + this.fixbuffer[i]=this.buffer[Math.round(i*512/this.audioSR)]; + } + this.aBuffer = this.audioCtx.createBuffer(1,this.audioSR,this.audioSR*60); + this.aBuffer.getChannelData(0).set(this.fixbuffer); + this.audioOut = this.audioCtx.createBufferSource(); + this.audioOut.buffer=this.aBuffer; + this.audioOut.connect(this.audioCtx.destination); + this.audioOut.noteOn(0); + this.audioOut.loop = true; + } + } + this.delayAudio = function(a) + { + if(this.useFFAudio) for(var b=0; b<a; b++) this.audioOut.mozWriteAudio(this.buffer); +/* else if(this.useChromeAudio) for(var b=0; b<a; b++) + { + this.audioOut = this.audioCtx.createBufferSource(); + this.audioOut.buffer=this.aBuffer; + this.audioOut.connect(this.audioCtx.destination); + this.audioOut.noteOn((b+1)/60); + }*/ } } -var p = new Parser(true); +var p = new Parser(false,false); var oldloop = new Date; var c = document.getElementById("ibniz").getContext("2d"); var runningCode = " "; @@ -769,17 +832,19 @@ var codeEdit = document.getElementById("code"); var fpsField = document.getElementById("fps"); var pause = document.getElementById("pause"); var simpleGetPut = document.getElementById("simpleGetPut"); +var useAudio = document.getElementById("useAudio"); function derp() { if(!pause.checked) { - p.drawToCanvas(c); + p.render(c); var newloop = new Date; var fps = 1000 / (newloop - oldloop); oldloop=newloop; - p.t+=Math.round(30/fps); + p.t+=Math.round(60/fps); + p.delayAudio(Math.round(60/fps)); p.configureStackmode(); - p.config(simpleGetPut.checked); + p.config(simpleGetPut.checked,useAudio.checked); fpsField.childNodes[1].nodeValue=fps.toFixed(2); if(runningCode!=codeEdit.value) {