javascript - How do I capture a sequence of what button was pressed and when? -
i'm finding difficult understand how javascript works, when writing own code asked friend me out , provided me this.
var curtime = new date(); delaytime = curtime.gettime() - previoustime.gettime(); previoustime.settime( curtime.gettime()); temparray = new array; temparray.push( name ); temparray.push( delaytime ); recording.push( temparray);
but can't seem grasp concept of how links buttons , saves them array. able use recorded information playback user input, 1 step @ time.
if me next stage appreciated i'm lost on javascript.
fun question. consider fact each element may fire more 1 event handler given event. mean? can attach both (a) function 'real' work button (b) book-keeping function. (though, 1 can't guarantee order in they're called - they're not required called in order added - may have changed, haven't looked in around 6 months)
also, since i've attached event-handlers using .addeventlistener, this
keyword refers html element fired event in first place. - that's why can attach single 'generic' function buttons extract necessary information them.
so, need attach both functions element you'd log info for. here's quick'n'dirty example. hope helps.
<!doctype html> <html> <head> <script> function onbtn1(evt) { alert('you pressed button 1'); } function onbtn2(evt) { alert('btn2'); } function onbtn3(evt) { alert('pressed btn 3'); } function onshowrecordsbtn(evt) { var i, n = eventlist.length; var tgt = byid('outputtgt'); var msg = ''; (i=0; i<n; i++) { // entries except first 1 must preceded new-line if (i != 0) msg += "<br>"; // show id , time of each clicked button msg += "id: " + eventlist[i].elemid + " - time: " + eventlist[i].time; } tgt.innerhtml = msg; } // declare empty array hold list of events. var eventlist = []; function savebtnpressinfo(evt) { var currecord = { time: new date(), elemid: this.id}; // same preceding line of code // var currecord = { time: null, elemid: null}; // currecord.time = new date(); // currecord.elemid = this.id; eventlist.push(currecord); } window.addeventlistener('load', onpageloaded, false); function byid(e){return document.getelementbyid(e);} function onpageloaded(evt) { // add (unique) event handlers buttons byid('btn1').addeventlistener('click', onbtn1, false); byid('btn2').addeventlistener('click', onbtn2, false); byid('btn3').addeventlistener('click', onbtn3, false); // add event showevents 'button' - made inut element doesn't // found when list of <button> elements on page. (i don't want know when user asked button-press stats) byid('showrecordsbtn').addeventlistener('click', onshowrecordsbtn, false); // add record-keeping function each of buttons var btnlist = document.getelementsbytagname('button'); var i, n = btnlist.length; (i=0; i<n; i++) { btnlist[i].addeventlistener('click', savebtnpressinfo, false); } } </script> <style> </style> </head> <body> <button id='btn1'>button 1</button> <button id='btn2'>button 2</button> <button id='btn3'>button 3</button> <hr> <input id='showrecordsbtn' type='button' value='show btn-click activity'/> <div id='outputtgt'></div> </body> </html>
edit:
here's code uses (instrument)synth found in voxel bukkake. in code, i've played notes in response click on instrument's sample. memory, can use param of .noteon specify number of ms between when call made , when note should sounded.
<!doctype html> <html> <head> <script> function byid(e){return document.getelementbyid(e);} function newel(tag){return document.createelement(tag);} function newtxt(txt){return document.createtextnode(txt);} function toggleclass(element, newstr) { index=element.classname.indexof(newstr); if ( index == -1) element.classname += ' '+newstr; else { if (index != 0) newstr = ' '+newstr; element.classname = element.classname.replace(newstr, ''); } } function foreachnode(nodelist, func) { var i, n = nodelist.length; (i=0; i<n; i++) { func(nodelist[i], i, nodelist); } } var current_time = 0; function instrument(attack, delay, sustain, release, sustaintime, cutoff, resonance, lfofreq, lfoamp, detunesquare, detunesaw, squarevol, sawvol, noisevol) { // volume envelope this.a = attack; this.d = delay; this.s = sustain; this.r = release; this.sustaintime = sustaintime; this.cutoff = cutoff; this.resonance = resonance; this.lfo_freq = lfofreq; this.lfo_amp = lfoamp; this.square_detune = detunesquare; this.saw_detune = detunesaw; this.square_vol = squarevol; this.saw_vol = sawvol; this.noise_vol = noisevol; } function voice(pitch, pos, ins, vol, active) { this.pitch = pitch; this.pos = pos; // position in samples beginning this.ins = ins; // instrument this.vol = vol; this.xn = [0,0,0];//[1.0,1.0,1.0]; this.yn = [0,0,0];//[1.0,1.0,1.0]; this.active = 0; // 0 = inactive, (not 0) = active } function synth(v, len, mix_buf) { current_time = 100; var ins = v.ins; //var pitch_sine = v->pitch * ins->sine_detune; var pitch_square = v.pitch * ins.square_detune; var pitch_saw = v.pitch * ins.saw_detune; var vol, res, t; var i; var invsample_rate = 1 / 44100; var periodo_square = 1.0/pitch_square; v.pos = 0; (i=0; i<len; i++) { res=0; t = (v.pos+i)*invsample_rate; // t >>= 0; // first add oscillators // sine //res = ins->sine_vol * msin(dospi*pitch_sine*t); // square if ( (t % periodo_square) > (periodo_square/2.0)) res += ins.square_vol; else res -= ins.square_vol; // saw res += ins.saw_vol * ( ( (t*pitch_saw)% 2.0) - 1.0); // noise res += ins.noise_vol * (2.0*whitenoise()-1.0) ; // apply adsr vol = getamp(ins, t); res *= vol; // estimate value of applying cutoff lfo var cutoff, lfo_freq; if (ins.lfo_freq < 0) { lfo_freq = -ins.lfo_freq; t = current_time; } else { lfo_freq = ins.lfo_freq; } var dospi = 6.2831853071795862; cutoff= ins.cutoff + ins.lfo_amp * math.cos(dospi * lfo_freq * t); var r = ins.resonance; // calculate filter coefficients var c, c2,a1,a2,b1,b2; //we extract calculations redundant in hp , lp var pi_samplerate = 0.000071237928652829774; var param_tan = pi_samplerate * cutoff; if (cutoff > 0.0) // low-pass { c = 1.0 / math.tan(param_tan); c2 = c*c; a1 = 1.0 / ( 1.0 + r * c + c2); a2 = 2.0 * a1; b1 = 2.0 * ( 1.0 - c2) * a1; } else // high-pass { c = math.tan(-param_tan); c2 = c*c; a1 = 1.0 / ( 1.0 + r * c + c2); a2 = -2*a1; b1 = 2.0 * ( c2 - 1.0) * a1; } b2 = ( 1.0 - r * c + c2) * a1; v.yn[0] = (a1*res) + (a2*v.xn[1]) + (a1*v.xn[2]) - (b1*v.yn[1]) - (b2*v.yn[2]); v.xn[2]=v.xn[1]; v.xn[1]=res; v.yn[2]=v.yn[1]; v.yn[1]=v.yn[0]; // here filtering res mix_buf[i] += v.yn[0] * v.vol; } v.pos+=len; if (vol > 0.0) return 1; return 0; } // returns value of time pos adsr // linear interpolation // function getamp(instrument, pos) function getamp(i, pos) { var = i.a/100 + 0.00001; if (pos <= a) return (pos/a); pos -= a; var d = i.d / 100; var s = i.s / 100; if (pos <= d) return (1.0 - (pos * (1 - s)) / d); pos -= d; var sustain_time = i.sustaintime/100; if (pos <= sustain_time) return s; pos -= sustain_time; var r = i.r/100; if (pos < r) return s - s * (pos/r); else return 0; } function whitenoise() { return math.random(); } ////============================================================ window.addeventlistener('load', minit, false); var context; function minit() { context = new webkitaudiocontext(); var hihat = new instrument( 1,5,15,50,0, -12000,1.1, 1.500,8000, 1.0,0.5, 0.5,0.3, 1.2); var drum = new instrument( 1,15,40,5,0, 20, 1.0, 1.0, 200, 1.5,1.0, 1.0,0.5, 2.4); var low = new instrument( 1,15,40,5,0, 800,1.0, -0.500,-600, 1.0,1.0,0.4,0.7, 0.0); var organ = new instrument(50,30,45,100,20, -1150,1.0, -8.333,-950, 0.501,1.0, 0.5,0.7, 0.0); var lead = new instrument( 0,10,50,40,20, 900,1.0, 1.500, 900, 0.5,1.0, 0.8,0.4, 0.0); var simon = new instrument(10,10,50,75,70, 800,0.25, 1.500,700, 0.8,0.8, 0.5,0.5, 0.0); //function insrument(attack, delay, sustain, release, sustaintime, cutoff, resonance, lfofreq, lfoamp, detunesquare, detunesaw, squarevol, sawvol, noisevol) var start = new date(); addplayablegraph(hihat); // addplayablegraph(drum); // addplayablegraph(low); addplayablegraph(organ); addplayablegraph(lead); addplayablegraph(simon); var end = new date(); var diff = end-start; start = newtxt('calculation time: ' + diff + 'ms'); document.body.appendchild(start); var coords = newel('div'); coords.setattribute('id', 'coords'); document.body.appendchild(coords); } function addplayablegraph(instrument) { var note = 43; var pitch = 440.0 * math.pow(2.0, (note-45.0)/12.0); var pos = 0; var vol = 0.4; var active = 1.0; var voice = new voice(pitch, pos, instrument, vol, active); var buffer = []; var i, n=4410 * (20); (i=0; i<n; i++) buffer[i] = 0.0; voice.active = synth(voice, n, buffer); var canvas = newel('canvas'); canvas.height = 96; canvas.width = 1024; document.body.appendchild(canvas); drawfloatarray(buffer, canvas); canvas.mbuffer = buffer; canvas.onclick = function() { playsound(this.mbuffer, 44100, 100); }; canvas.onmousemove = function(e) { e = e || event; var str = 'pos: ' + (e.clientx/canvas.width)*2000 + ',' + e.clienty; byid('coords').innertext = str; } return canvas; } function drawfloatarray(samples, canvas) { var i, n = samples.length; var dur = (n / 44100 * 1000)>>0; canvas.title = 'duration: ' + dur / 1000.0 + 's'; var width=canvas.width,height=canvas.height; var ctx = canvas.getcontext('2d'); ctx.strokestyle = 'yellow'; ctx.fillstyle = '#303030'; ctx.fillrect(0,0,width,height); ctx.moveto(0,height/2); ctx.beginpath(); (i=0; i<n; i++) { x = (i*width) / n; y = (samples[i]*height/2)+height/2; ctx.lineto(x, y); } ctx.stroke(); ctx.closepath(); } function playsound(buffer, freq, vol) // buffer, 44100, 0-100 { var mbuffer = context.createbuffer(1, buffer.length, freq); var databuffer = mbuffer.getchanneldata(0); var soundbuffer = buffer; var i, n = buffer.length; (i=0;i<n;i++) databuffer[i] = soundbuffer[i]; var node = context.createbuffersource(); node.buffer = mbuffer; node.gain.value = 0.5 * vol/100.0; node.connect(context.destination); node.noteon(0); } </script> <style> </style> </head> <body> </body> </html>
lastly, @ http://www.iquilezles.org/apps/soundtoy/ approach uses 'simple' math equation instrument definitions. moe particularly - code allows single formula (instrument) produce sounds of different pitches (if need that)
you may need use param of .noteon play mp3s have. cant remember if i've played loaded sound this, or generated stuff.
lots of fun, browser-generated content, is.
Comments
Post a Comment