[36m[39;49;00m
<[94mhtml[39;49;00m [36mlang[39;49;00m=[33m"de"[39;49;00m>
<[94mhead[39;49;00m>
<[94mmeta[39;49;00m [36mcharset[39;49;00m=[33m"UTF-8"[39;49;00m>
<[94mmeta[39;49;00m [36mname[39;49;00m=[33m"viewport"[39;49;00m [36mcontent[39;49;00m=[33m"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"[39;49;00m>
<[94mtitle[39;49;00m>Misa Kitara Mobile - Digital Synth[94mtitle[39;49;00m>
<[94mstyle[39;49;00m>[37m[39;49;00m
[37m [39;49;00m:[90mroot[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[31m--bg-color[39;49;00m:[37m [39;49;00m[34m#08080c[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[31m--panel-bg[39;49;00m:[37m [39;49;00m[34m#12121c[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[31m--accent-cyan[39;49;00m:[37m [39;49;00m[34m#00f0ff[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[31m--accent-magenta[39;49;00m:[37m [39;49;00m[34m#ff0055[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[31m--accent-gold[39;49;00m:[37m [39;49;00m[34m#ffcc00[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[31m--grid-line[39;49;00m:[37m [39;49;00m[34m#222233[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m*[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mbox-sizing[39;49;00m:[37m [39;49;00m[34mborder-box[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34muser-select[39;49;00m:[37m [39;49;00m[34mnone[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34m-webkit-[39;49;00m[34muser-select[39;49;00m:[37m [39;49;00m[34mnone[39;49;00m;[37m[39;49;00m
[37m [39;49;00mtouch-action:[37m [39;49;00m[34mnone[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[94mbody[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mbackground-color[39;49;00m:[37m [39;49;00m[32mvar[39;49;00m([31m--bg-color[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mcolor[39;49;00m:[37m [39;49;00m[34m#fff[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mfont-family[39;49;00m:[37m [39;49;00m-apple-system,[37m [39;49;00mBlinkMacSystemFont,[37m [39;49;00m[33m"Segoe UI"[39;49;00m,[37m [39;49;00mRoboto,[37m [39;49;00m[34mmonospace[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mmargin[39;49;00m:[37m [39;49;00m[34m0[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mpadding[39;49;00m:[37m [39;49;00m[34m8[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mheight[39;49;00m:[37m [39;49;00m[34m100[39;49;00m[36mvh[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mheight[39;49;00m:[37m [39;49;00m[34m100[39;49;00mdvh;[37m[39;49;00m
[37m [39;49;00m[34mdisplay[39;49;00m:[37m [39;49;00m[34mflex[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mflex-direction[39;49;00m:[37m [39;49;00m[34mcolumn[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mgap[39;49;00m:[37m [39;49;00m[34m8[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34moverflow[39;49;00m:[37m [39;49;00m[34mhidden[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m/* Top Header & Display */[39;49;00m[37m[39;49;00m
[37m [39;49;00m.[04m[32mheader[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mbackground[39;49;00m:[37m [39;49;00m[32mvar[39;49;00m([31m--panel-bg[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mborder[39;49;00m:[37m [39;49;00m[34m1[39;49;00m[36mpx[39;49;00m[37m [39;49;00m[34msolid[39;49;00m[37m [39;49;00m[34m#333[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mborder-radius[39;49;00m:[37m [39;49;00m[34m8[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mpadding[39;49;00m:[37m [39;49;00m[34m6[39;49;00m[36mpx[39;49;00m[37m [39;49;00m[34m10[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mdisplay[39;49;00m:[37m [39;49;00m[34mflex[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mjustify-content[39;49;00m:[37m [39;49;00m[34mspace-between[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34malign-items[39;49;00m:[37m [39;49;00m[34mcenter[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m.[04m[32mtitle[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mfont-size[39;49;00m:[37m [39;49;00m[34m0.9[39;49;00m[36mrem[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mfont-weight[39;49;00m:[37m [39;49;00m[34m900[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mcolor[39;49;00m:[37m [39;49;00m[32mvar[39;49;00m([31m--accent-cyan[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mletter-spacing[39;49;00m:[37m [39;49;00m[34m1[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m.[04m[32mstatus[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mfont-size[39;49;00m:[37m [39;49;00m[34m0.7[39;49;00m[36mrem[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mcolor[39;49;00m:[37m [39;49;00m[32mvar[39;49;00m([31m--accent-gold[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mfont-family[39;49;00m:[37m [39;49;00m[34mmonospace[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m/* Fretboard Matrix Area */[39;49;00m[37m[39;49;00m
[37m [39;49;00m.[04m[32mfretboard-container[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mbackground[39;49;00m:[37m [39;49;00m[32mvar[39;49;00m([31m--panel-bg[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mborder[39;49;00m:[37m [39;49;00m[34m1[39;49;00m[36mpx[39;49;00m[37m [39;49;00m[34msolid[39;49;00m[37m [39;49;00m[34m#333[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mborder-radius[39;49;00m:[37m [39;49;00m[34m8[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mpadding[39;49;00m:[37m [39;49;00m[34m6[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mdisplay[39;49;00m:[37m [39;49;00m[34mflex[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mflex-direction[39;49;00m:[37m [39;49;00m[34mcolumn[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mgap[39;49;00m:[37m [39;49;00m[34m4[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mflex-shrink[39;49;00m:[37m [39;49;00m[34m0[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m.[04m[32mstring-row[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mdisplay[39;49;00m:[37m [39;49;00m[34mflex[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34malign-items[39;49;00m:[37m [39;49;00m[34mcenter[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mgap[39;49;00m:[37m [39;49;00m[34m4[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mheight[39;49;00m:[37m [39;49;00m[34m28[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m.[04m[32mstring-label[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mwidth[39;49;00m:[37m [39;49;00m[34m24[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mfont-size[39;49;00m:[37m [39;49;00m[34m0.65[39;49;00m[36mrem[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mfont-weight[39;49;00m:[37m [39;49;00m[34mbold[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mcolor[39;49;00m:[37m [39;49;00m[32mvar[39;49;00m([31m--accent-cyan[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mtext-align[39;49;00m:[37m [39;49;00m[34mcenter[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m.[04m[32mfret-buttons[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mdisplay[39;49;00m:[37m [39;49;00m[34mflex[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mflex[39;49;00m:[37m [39;49;00m[34m1[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mgap[39;49;00m:[37m [39;49;00m[34m3[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mheight[39;49;00m:[37m [39;49;00m[34m100[39;49;00m[36m%[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m.[04m[32mfret-btn[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mflex[39;49;00m:[37m [39;49;00m[34m1[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mbackground[39;49;00m:[37m [39;49;00m[34m#1a1a26[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mborder[39;49;00m:[37m [39;49;00m[34m1[39;49;00m[36mpx[39;49;00m[37m [39;49;00m[34msolid[39;49;00m[37m [39;49;00m[34m#333[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mcolor[39;49;00m:[37m [39;49;00m[34m#888[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mfont-size[39;49;00m:[37m [39;49;00m[34m0.65[39;49;00m[36mrem[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mfont-weight[39;49;00m:[37m [39;49;00m[34mbold[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mborder-radius[39;49;00m:[37m [39;49;00m[34m4[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mdisplay[39;49;00m:[37m [39;49;00m[34mflex[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34malign-items[39;49;00m:[37m [39;49;00m[34mcenter[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mjustify-content[39;49;00m:[37m [39;49;00m[34mcenter[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mcursor[39;49;00m:[37m [39;49;00m[34mpointer[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m.[04m[32mfret-btn[39;49;00m.[04m[32mactive[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mbackground[39;49;00m:[37m [39;49;00m[32mvar[39;49;00m([31m--accent-magenta[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mcolor[39;49;00m:[37m [39;49;00m[34m#fff[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mborder-color[39;49;00m:[37m [39;49;00m[34m#ff6699[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mbox-shadow[39;49;00m:[37m [39;49;00m[34m0[39;49;00m[37m [39;49;00m[34m0[39;49;00m[37m [39;49;00m[34m8[39;49;00m[36mpx[39;49;00m[37m [39;49;00m[36mrgba[39;49;00m([34m255[39;49;00m,[37m [39;49;00m[34m0[39;49;00m,[37m [39;49;00m[34m85[39;49;00m,[37m [39;49;00m[34m0.6[39;49;00m);[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m/* Kitara XY Performance Touchpad */[39;49;00m[37m[39;49;00m
[37m [39;49;00m.[04m[32mpad-container[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mflex[39;49;00m:[37m [39;49;00m[34m1[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mposition[39;49;00m:[37m [39;49;00m[34mrelative[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mbackground[39;49;00m:[37m [39;49;00m[34m#040406[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mborder[39;49;00m:[37m [39;49;00m[34m2[39;49;00m[36mpx[39;49;00m[37m [39;49;00m[34msolid[39;49;00m[37m [39;49;00m[32mvar[39;49;00m([31m--accent-cyan[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mborder-radius[39;49;00m:[37m [39;49;00m[34m10[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34moverflow[39;49;00m:[37m [39;49;00m[34mhidden[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mbox-shadow[39;49;00m:[37m [39;49;00m[34minset[39;49;00m[37m [39;49;00m[34m0[39;49;00m[37m [39;49;00m[34m0[39;49;00m[37m [39;49;00m[34m20[39;49;00m[36mpx[39;49;00m[37m [39;49;00m[36mrgba[39;49;00m([34m0[39;49;00m,[37m [39;49;00m[34m240[39;49;00m,[37m [39;49;00m[34m255[39;49;00m,[37m [39;49;00m[34m0.15[39;49;00m);[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[94mcanvas[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mwidth[39;49;00m:[37m [39;49;00m[34m100[39;49;00m[36m%[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mheight[39;49;00m:[37m [39;49;00m[34m100[39;49;00m[36m%[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mdisplay[39;49;00m:[37m [39;49;00m[34mblock[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m/* FX Preset Control Bar */[39;49;00m[37m[39;49;00m
[37m [39;49;00m.[04m[32mcontrols-bar[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mdisplay[39;49;00m:[37m [39;49;00m[34mflex[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mgap[39;49;00m:[37m [39;49;00m[34m6[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mheight[39;49;00m:[37m [39;49;00m[34m36[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[94mselect[39;49;00m,[37m [39;49;00m[94mbutton[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mbackground[39;49;00m:[37m [39;49;00m[34m#1a1a26[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mcolor[39;49;00m:[37m [39;49;00m[34m#fff[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mborder[39;49;00m:[37m [39;49;00m[34m1[39;49;00m[36mpx[39;49;00m[37m [39;49;00m[34msolid[39;49;00m[37m [39;49;00m[34m#444[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mborder-radius[39;49;00m:[37m [39;49;00m[34m6[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mpadding[39;49;00m:[37m [39;49;00m[34m4[39;49;00m[36mpx[39;49;00m[37m [39;49;00m[34m8[39;49;00m[36mpx[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mfont-size[39;49;00m:[37m [39;49;00m[34m0.75[39;49;00m[36mrem[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mfont-weight[39;49;00m:[37m [39;49;00m[34mbold[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mflex[39;49;00m:[37m [39;49;00m[34m1[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[94mbutton[39;49;00m.[04m[32mactive[39;49;00m[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mbackground[39;49;00m:[37m [39;49;00m[32mvar[39;49;00m([31m--accent-cyan[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mcolor[39;49;00m:[37m [39;49;00m[34m#000[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m [39;49;00m[94mstyle[39;49;00m>
[94mhead[39;49;00m>
<[94mbody[39;49;00m>
<[94mdiv[39;49;00m [36mclass[39;49;00m=[33m"header"[39;49;00m>
<[94mdiv[39;49;00m [36mclass[39;49;00m=[33m"title"[39;49;00m>KITARA-MOBILE[94mdiv[39;49;00m>
<[94mdiv[39;49;00m [36mclass[39;49;00m=[33m"status"[39;49;00m [36mid[39;49;00m=[33m"status-display"[39;49;00m>TOUCH PAD TO PLAY[94mdiv[39;49;00m>
[94mdiv[39;49;00m>
<[94mdiv[39;49;00m [36mclass[39;49;00m=[33m"fretboard-container"[39;49;00m [36mid[39;49;00m=[33m"fretboard"[39;49;00m>[94mdiv[39;49;00m>
<[94mdiv[39;49;00m [36mclass[39;49;00m=[33m"pad-container"[39;49;00m [36mid[39;49;00m=[33m"pad-box"[39;49;00m>
<[94mcanvas[39;49;00m [36mid[39;49;00m=[33m"pad-canvas"[39;49;00m>[94mcanvas[39;49;00m>
[94mdiv[39;49;00m>
<[94mdiv[39;49;00m [36mclass[39;49;00m=[33m"controls-bar"[39;49;00m>
<[94mselect[39;49;00m [36mid[39;49;00m=[33m"synth-sound"[39;49;00m>
<[94moption[39;49;00m [36mvalue[39;49;00m=[33m"lead"[39;49;00m>Kitara Cyber Lead[94moption[39;49;00m>
<[94moption[39;49;00m [36mvalue[39;49;00m=[33m"acid"[39;49;00m>303 Distorted[94moption[39;49;00m>
<[94moption[39;49;00m [36mvalue[39;49;00m=[33m"poly"[39;49;00m>Digital PolySaw[94moption[39;49;00m>
<[94moption[39;49;00m [36mvalue[39;49;00m=[33m"sub"[39;49;00m>Sub Bass Heavy[94moption[39;49;00m>
[94mselect[39;49;00m>
<[94mbutton[39;49;00m [36mid[39;49;00m=[33m"delay-btn"[39;49;00m>DELAY: ON[94mbutton[39;49;00m>
[94mdiv[39;49;00m>
<[94mscript[39;49;00m>[37m[39;49;00m
[37m [39;49;00m[37m// Base Frequencies for 6 Standard Guitar Strings (E2, A2, D3, G3, B3, E4)[39;49;00m[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mbaseNotes[37m [39;49;00m=[37m [39;49;00m[[34m40[39;49;00m,[37m [39;49;00m[34m45[39;49;00m,[37m [39;49;00m[34m50[39;49;00m,[37m [39;49;00m[34m55[39;49;00m,[37m [39;49;00m[34m59[39;49;00m,[37m [39;49;00m[34m64[39;49;00m];[37m [39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mavailableFrets[37m [39;49;00m=[37m [39;49;00m[[34m0[39;49;00m,[37m [39;49;00m[34m1[39;49;00m,[37m [39;49;00m[34m3[39;49;00m,[37m [39;49;00m[34m5[39;49;00m,[37m [39;49;00m[34m7[39;49;00m,[37m [39;49;00m[34m8[39;49;00m,[37m [39;49;00m[34m10[39;49;00m,[37m [39;49;00m[34m12[39;49;00m];[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mstringStates[37m [39;49;00m=[37m [39;49;00m[[34m0[39;49;00m,[37m [39;49;00m[34m0[39;49;00m,[37m [39;49;00m[34m0[39;49;00m,[37m [39;49;00m[34m0[39;49;00m,[37m [39;49;00m[34m0[39;49;00m,[37m [39;49;00m[34m0[39;49;00m];[37m [39;49;00m[37m// Selected fret per string[39;49;00m[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mlet[39;49;00m[37m [39;49;00maudioCtx[37m [39;49;00m=[37m [39;49;00m[34mnull[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mlet[39;49;00m[37m [39;49;00mmasterGain,[37m [39;49;00mfilterNode,[37m [39;49;00mdriveNode,[37m [39;49;00mdelayNode,[37m [39;49;00mdelayFeedback;[37m[39;49;00m
[37m [39;49;00m[34mlet[39;49;00m[37m [39;49;00mdelayActive[37m [39;49;00m=[37m [39;49;00m[34mtrue[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mlet[39;49;00m[37m [39;49;00mactiveVoices[37m [39;49;00m=[37m [39;49;00m{};[37m [39;49;00m[37m// Tracks active touch sound voices[39;49;00m[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mmidiToFreq(midi)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mreturn[39;49;00m[37m [39;49;00m[34m440[39;49;00m[37m [39;49;00m*[37m [39;49;00m[36mMath[39;49;00m.pow([34m2[39;49;00m,[37m [39;49;00m(midi[37m [39;49;00m-[37m [39;49;00m[34m69[39;49;00m)[37m [39;49;00m/[37m [39;49;00m[34m12[39;49;00m);[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Audio Engine Setup[39;49;00m[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00minitAudio()[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(audioCtx)[37m [39;49;00m[34mreturn[39;49;00m;[37m[39;49;00m
[37m [39;49;00maudioCtx[37m [39;49;00m=[37m [39;49;00m[35mnew[39;49;00m[37m [39;49;00m([36mwindow[39;49;00m.AudioContext[37m [39;49;00m||[37m [39;49;00m[36mwindow[39;49;00m.webkitAudioContext)({[37m [39;49;00mlatencyHint:[37m [39;49;00m[33m'interactive'[39;49;00m[37m [39;49;00m});[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mmasterGain[37m [39;49;00m=[37m [39;49;00maudioCtx.createGain();[37m[39;49;00m
[37m [39;49;00mmasterGain.gain.value[37m [39;49;00m=[37m [39;49;00m[34m0.4[39;49;00m;[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mfilterNode[37m [39;49;00m=[37m [39;49;00maudioCtx.createBiquadFilter();[37m[39;49;00m
[37m [39;49;00mfilterNode.type[37m [39;49;00m=[37m [39;49;00m[33m'lowpass'[39;49;00m;[37m[39;49;00m
[37m [39;49;00mfilterNode.frequency.value[37m [39;49;00m=[37m [39;49;00m[34m2500[39;49;00m;[37m[39;49;00m
[37m [39;49;00mfilterNode.Q.value[37m [39;49;00m=[37m [39;49;00m[34m4[39;49;00m;[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mdriveNode[37m [39;49;00m=[37m [39;49;00maudioCtx.createWaveShaper();[37m[39;49;00m
[37m [39;49;00mdriveNode.curve[37m [39;49;00m=[37m [39;49;00mmakeDistortionCurve([34m60[39;49;00m);[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Delay FX[39;49;00m[37m[39;49;00m
[37m [39;49;00mdelayNode[37m [39;49;00m=[37m [39;49;00maudioCtx.createDelay();[37m[39;49;00m
[37m [39;49;00mdelayNode.delayTime.value[37m [39;49;00m=[37m [39;49;00m[34m0.25[39;49;00m;[37m [39;49;00m[37m// 1/8 note vibe[39;49;00m[37m[39;49;00m
[37m [39;49;00mdelayFeedback[37m [39;49;00m=[37m [39;49;00maudioCtx.createGain();[37m[39;49;00m
[37m [39;49;00mdelayFeedback.gain.value[37m [39;49;00m=[37m [39;49;00m[34m0.4[39;49;00m;[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mdelayNode.connect(delayFeedback);[37m[39;49;00m
[37m [39;49;00mdelayFeedback.connect(delayNode);[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Routing[39;49;00m[37m[39;49;00m
[37m [39;49;00mfilterNode.connect(driveNode);[37m[39;49;00m
[37m [39;49;00mdriveNode.connect(masterGain);[37m[39;49;00m
[37m [39;49;00mdriveNode.connect(delayNode);[37m[39;49;00m
[37m [39;49;00mdelayNode.connect(masterGain);[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mmasterGain.connect(audioCtx.destination);[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mmakeDistortionCurve(amount)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mlet[39;49;00m[37m [39;49;00mk[37m [39;49;00m=[37m [39;49;00mamount,[37m [39;49;00mn[37m [39;49;00m=[37m [39;49;00m[34m44100[39;49;00m,[37m [39;49;00mcurve[37m [39;49;00m=[37m [39;49;00m[35mnew[39;49;00m[37m [39;49;00m[36mFloat32Array[39;49;00m(n),[37m [39;49;00mdeg[37m [39;49;00m=[37m [39;49;00m[36mMath[39;49;00m.PI[37m [39;49;00m/[37m [39;49;00m[34m180[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mfor[39;49;00m[37m [39;49;00m([34mlet[39;49;00m[37m [39;49;00mi[37m [39;49;00m=[37m [39;49;00m[34m0[39;49;00m;[37m [39;49;00mi[37m [39;49;00m<[37m [39;49;00mn;[37m [39;49;00m++i)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mlet[39;49;00m[37m [39;49;00mx[37m [39;49;00m=[37m [39;49;00mi[37m [39;49;00m*[37m [39;49;00m[34m2[39;49;00m[37m [39;49;00m/[37m [39;49;00mn[37m [39;49;00m-[37m [39;49;00m[34m1[39;49;00m;[37m[39;49;00m
[37m [39;49;00mcurve[i][37m [39;49;00m=[37m [39;49;00m([34m3[39;49;00m[37m [39;49;00m+[37m [39;49;00mk)[37m [39;49;00m*[37m [39;49;00mx[37m [39;49;00m*[37m [39;49;00m[34m20[39;49;00m[37m [39;49;00m*[37m [39;49;00mdeg[37m [39;49;00m/[37m [39;49;00m([36mMath[39;49;00m.PI[37m [39;49;00m+[37m [39;49;00mk[37m [39;49;00m*[37m [39;49;00m[36mMath[39;49;00m.abs(x));[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m [39;49;00m[34mreturn[39;49;00m[37m [39;49;00mcurve;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Play Kitara Voice on String Trigger[39;49;00m[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mstartVoice(touchId,[37m [39;49;00mstringIndex,[37m [39;49;00mxRatio,[37m [39;49;00myRatio)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00minitAudio();[37m[39;49;00m
[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(audioCtx.state[37m [39;49;00m===[37m [39;49;00m[33m'suspended'[39;49;00m)[37m [39;49;00maudioCtx.resume();[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mmidiNote[37m [39;49;00m=[37m [39;49;00mbaseNotes[stringIndex][37m [39;49;00m+[37m [39;49;00mstringStates[stringIndex];[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mfreq[37m [39;49;00m=[37m [39;49;00mmidiToFreq(midiNote);[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mpreset[37m [39;49;00m=[37m [39;49;00m[36mdocument[39;49;00m.getElementById([33m'synth-sound'[39;49;00m).value;[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mosc1[37m [39;49;00m=[37m [39;49;00maudioCtx.createOscillator();[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mosc2[37m [39;49;00m=[37m [39;49;00maudioCtx.createOscillator();[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mvoiceGain[37m [39;49;00m=[37m [39;49;00maudioCtx.createGain();[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(preset[37m [39;49;00m===[37m [39;49;00m[33m'acid'[39;49;00m)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00mosc1.type[37m [39;49;00m=[37m [39;49;00m[33m'sawtooth'[39;49;00m;[37m [39;49;00mosc2.type[37m [39;49;00m=[37m [39;49;00m[33m'sawtooth'[39;49;00m;[37m[39;49;00m
[37m [39;49;00mosc2.detune.value[37m [39;49;00m=[37m [39;49;00m[34m12[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m [39;49;00m[34melse[39;49;00m[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(preset[37m [39;49;00m===[37m [39;49;00m[33m'poly'[39;49;00m)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00mosc1.type[37m [39;49;00m=[37m [39;49;00m[33m'sawtooth'[39;49;00m;[37m [39;49;00mosc2.type[37m [39;49;00m=[37m [39;49;00m[33m'square'[39;49;00m;[37m[39;49;00m
[37m [39;49;00mosc2.detune.value[37m [39;49;00m=[37m [39;49;00m-[34m7[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m [39;49;00m[34melse[39;49;00m[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(preset[37m [39;49;00m===[37m [39;49;00m[33m'sub'[39;49;00m)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00mosc1.type[37m [39;49;00m=[37m [39;49;00m[33m'triangle'[39;49;00m;[37m [39;49;00mosc2.type[37m [39;49;00m=[37m [39;49;00m[33m'sine'[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m [39;49;00m[34melse[39;49;00m[37m [39;49;00m{[37m [39;49;00m[37m// Kitara Lead[39;49;00m[37m[39;49;00m
[37m [39;49;00mosc1.type[37m [39;49;00m=[37m [39;49;00m[33m'sawtooth'[39;49;00m;[37m [39;49;00mosc2.type[37m [39;49;00m=[37m [39;49;00m[33m'square'[39;49;00m;[37m[39;49;00m
[37m [39;49;00mosc2.detune.value[37m [39;49;00m=[37m [39;49;00m[34m5[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mosc1.frequency.setValueAtTime(freq,[37m [39;49;00maudioCtx.currentTime);[37m[39;49;00m
[37m [39;49;00mosc2.frequency.setValueAtTime(freq,[37m [39;49;00maudioCtx.currentTime);[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mosc1.connect(voiceGain);[37m[39;49;00m
[37m [39;49;00mosc2.connect(voiceGain);[37m[39;49;00m
[37m [39;49;00mvoiceGain.connect(filterNode);[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Fast Attack Envelope[39;49;00m[37m[39;49;00m
[37m [39;49;00mvoiceGain.gain.setValueAtTime([34m0.01[39;49;00m,[37m [39;49;00maudioCtx.currentTime);[37m[39;49;00m
[37m [39;49;00mvoiceGain.gain.linearRampToValueAtTime([34m0.8[39;49;00m,[37m [39;49;00maudioCtx.currentTime[37m [39;49;00m+[37m [39;49;00m[34m0.01[39;49;00m);[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mosc1.start();[37m [39;49;00mosc2.start();[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mactiveVoices[touchId][37m [39;49;00m=[37m [39;49;00m{[37m [39;49;00mosc1,[37m [39;49;00mosc2,[37m [39;49;00mvoiceGain,[37m [39;49;00mstringIndex[37m [39;49;00m};[37m[39;49;00m
[37m [39;49;00mupdateSynthParameters(xRatio,[37m [39;49;00myRatio);[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mupdateVoice(touchId,[37m [39;49;00mxRatio,[37m [39;49;00myRatio,[37m [39;49;00mstringIndex)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(!activeVoices[touchId])[37m [39;49;00m[34mreturn[39;49;00m;[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Pitch shift if finger slides to another string zone[39;49;00m[37m[39;49;00m
[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(activeVoices[touchId].stringIndex[37m [39;49;00m!==[37m [39;49;00mstringIndex)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mmidiNote[37m [39;49;00m=[37m [39;49;00mbaseNotes[stringIndex][37m [39;49;00m+[37m [39;49;00mstringStates[stringIndex];[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mfreq[37m [39;49;00m=[37m [39;49;00mmidiToFreq(midiNote);[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mnow[37m [39;49;00m=[37m [39;49;00maudioCtx.currentTime;[37m[39;49;00m
[37m [39;49;00mactiveVoices[touchId].osc1.frequency.setTargetAtTime(freq,[37m [39;49;00mnow,[37m [39;49;00m[34m0.01[39;49;00m);[37m[39;49;00m
[37m [39;49;00mactiveVoices[touchId].osc2.frequency.setTargetAtTime(freq,[37m [39;49;00mnow,[37m [39;49;00m[34m0.01[39;49;00m);[37m[39;49;00m
[37m [39;49;00mactiveVoices[touchId].stringIndex[37m [39;49;00m=[37m [39;49;00mstringIndex;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mupdateSynthParameters(xRatio,[37m [39;49;00myRatio);[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mstopVoice(touchId)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(!activeVoices[touchId])[37m [39;49;00m[34mreturn[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00m{[37m [39;49;00mosc1,[37m [39;49;00mosc2,[37m [39;49;00mvoiceGain[37m [39;49;00m}[37m [39;49;00m=[37m [39;49;00mactiveVoices[touchId];[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mnow[37m [39;49;00m=[37m [39;49;00maudioCtx.currentTime;[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mvoiceGain.gain.cancelScheduledValues(now);[37m[39;49;00m
[37m [39;49;00mvoiceGain.gain.setTargetAtTime([34m0.001[39;49;00m,[37m [39;49;00mnow,[37m [39;49;00m[34m0.05[39;49;00m);[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00msetTimeout(()[37m [39;49;00m=>[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mtry[39;49;00m[37m [39;49;00m{[37m [39;49;00mosc1.stop();[37m [39;49;00mosc2.stop();[37m [39;49;00mosc1.disconnect();[37m [39;49;00mosc2.disconnect();[37m [39;49;00m}[37m [39;49;00m[34mcatch[39;49;00m(e){}[37m[39;49;00m
[37m [39;49;00m},[37m [39;49;00m[34m100[39;49;00m);[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[35mdelete[39;49;00m[37m [39;49;00mactiveVoices[touchId];[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mupdateSynthParameters(xRatio,[37m [39;49;00myRatio)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(!audioCtx)[37m [39;49;00m[34mreturn[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mnow[37m [39;49;00m=[37m [39;49;00maudioCtx.currentTime;[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// X-Axis controls Filter Cutoff (100 Hz - 8000 Hz)[39;49;00m[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mcutoff[37m [39;49;00m=[37m [39;49;00m[34m100[39;49;00m[37m [39;49;00m*[37m [39;49;00m[36mMath[39;49;00m.pow([34m80[39;49;00m,[37m [39;49;00mxRatio);[37m[39;49;00m
[37m [39;49;00mfilterNode.frequency.setTargetAtTime(cutoff,[37m [39;49;00mnow,[37m [39;49;00m[34m0.01[39;49;00m);[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Y-Axis controls Resonance & Distortion Gain[39;49;00m[37m[39;49;00m
[37m [39;49;00mfilterNode.Q.setTargetAtTime([34m2[39;49;00m[37m [39;49;00m+[37m [39;49;00m(yRatio[37m [39;49;00m*[37m [39;49;00m[34m16[39;49;00m),[37m [39;49;00mnow,[37m [39;49;00m[34m0.01[39;49;00m);[37m[39;49;00m
[37m [39;49;00m
[37m [39;49;00m[36mdocument[39;49;00m.getElementById([33m'status-display'[39;49;00m).innerText[37m [39;49;00m=[37m [39;49;00m
[37m [39;49;00m[33m`[39;49;00m[33mCUTOFF: [39;49;00m[33m${[39;49;00m[36mMath[39;49;00m.round(cutoff)[33m}[39;49;00m[33mHz | RES: [39;49;00m[33m${[39;49;00m[36mMath[39;49;00m.round([34m2[39;49;00m[37m [39;49;00m+[37m [39;49;00myRatio[37m [39;49;00m*[37m [39;49;00m[34m16[39;49;00m)[33m}[39;49;00m[33m`[39;49;00m;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Render Fretboard UI[39;49;00m[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mfretboardEl[37m [39;49;00m=[37m [39;49;00m[36mdocument[39;49;00m.getElementById([33m'fretboard'[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mstringNames[37m [39;49;00m=[37m [39;49;00m[[33m'E2'[39;49;00m,[37m [39;49;00m[33m'A2'[39;49;00m,[37m [39;49;00m[33m'D3'[39;49;00m,[37m [39;49;00m[33m'G3'[39;49;00m,[37m [39;49;00m[33m'B3'[39;49;00m,[37m [39;49;00m[33m'E4'[39;49;00m];[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mstringNames.forEach((name,[37m [39;49;00msIdx)[37m [39;49;00m=>[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mrow[37m [39;49;00m=[37m [39;49;00m[36mdocument[39;49;00m.createElement([33m'div'[39;49;00m);[37m[39;49;00m
[37m [39;49;00mrow.className[37m [39;49;00m=[37m [39;49;00m[33m'string-row'[39;49;00m;[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mlabel[37m [39;49;00m=[37m [39;49;00m[36mdocument[39;49;00m.createElement([33m'div'[39;49;00m);[37m[39;49;00m
[37m [39;49;00mlabel.className[37m [39;49;00m=[37m [39;49;00m[33m'string-label'[39;49;00m;[37m[39;49;00m
[37m [39;49;00mlabel.innerText[37m [39;49;00m=[37m [39;49;00mname[[34m0[39;49;00m][37m [39;49;00m+[37m [39;49;00mname[[34m1[39;49;00m];[37m[39;49;00m
[37m [39;49;00mrow.appendChild(label);[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mfretContainer[37m [39;49;00m=[37m [39;49;00m[36mdocument[39;49;00m.createElement([33m'div'[39;49;00m);[37m[39;49;00m
[37m [39;49;00mfretContainer.className[37m [39;49;00m=[37m [39;49;00m[33m'fret-buttons'[39;49;00m;[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mavailableFrets.forEach((fret)[37m [39;49;00m=>[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mbtn[37m [39;49;00m=[37m [39;49;00m[36mdocument[39;49;00m.createElement([33m'div'[39;49;00m);[37m[39;49;00m
[37m [39;49;00mbtn.className[37m [39;49;00m=[37m [39;49;00m[33m`[39;49;00m[33mfret-btn [39;49;00m[33m${[39;49;00mfret[37m [39;49;00m===[37m [39;49;00m[34m0[39;49;00m[37m [39;49;00m?[37m [39;49;00m[33m'active'[39;49;00m[37m [39;49;00m:[37m [39;49;00m[33m''[39;49;00m[33m}[39;49;00m[33m`[39;49;00m;[37m[39;49;00m
[37m [39;49;00mbtn.innerText[37m [39;49;00m=[37m [39;49;00mfret[37m [39;49;00m===[37m [39;49;00m[34m0[39;49;00m[37m [39;49;00m?[37m [39;49;00m[33m'O'[39;49;00m[37m [39;49;00m:[37m [39;49;00mfret;[37m[39;49;00m
[37m [39;49;00mbtn.dataset.string[37m [39;49;00m=[37m [39;49;00msIdx;[37m[39;49;00m
[37m [39;49;00mbtn.dataset.fret[37m [39;49;00m=[37m [39;49;00mfret;[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mbtn.addEventListener([33m'pointerdown'[39;49;00m,[37m [39;49;00m(e)[37m [39;49;00m=>[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00me.preventDefault();[37m[39;49;00m
[37m [39;49;00mstringStates[sIdx][37m [39;49;00m=[37m [39;49;00mfret;[37m[39;49;00m
[37m [39;49;00mrow.querySelectorAll([33m'.fret-btn'[39;49;00m).forEach(b[37m [39;49;00m=>[37m [39;49;00mb.classList.remove([33m'active'[39;49;00m));[37m[39;49;00m
[37m [39;49;00mbtn.classList.add([33m'active'[39;49;00m);[37m[39;49;00m
[37m [39;49;00m});[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mfretContainer.appendChild(btn);[37m[39;49;00m
[37m [39;49;00m});[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mrow.appendChild(fretContainer);[37m[39;49;00m
[37m [39;49;00mfretboardEl.appendChild(row);[37m[39;49;00m
[37m [39;49;00m});[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Touchpad & Canvas Performance Rendering[39;49;00m[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mpadBox[37m [39;49;00m=[37m [39;49;00m[36mdocument[39;49;00m.getElementById([33m'pad-box'[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mcanvas[37m [39;49;00m=[37m [39;49;00m[36mdocument[39;49;00m.getElementById([33m'pad-canvas'[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mctx[37m [39;49;00m=[37m [39;49;00mcanvas.getContext([33m'2d'[39;49;00m);[37m[39;49;00m
[37m [39;49;00m[34mlet[39;49;00m[37m [39;49;00mtouches[37m [39;49;00m=[37m [39;49;00m[];[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mresizeCanvas()[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00mcanvas.width[37m [39;49;00m=[37m [39;49;00mpadBox.clientWidth;[37m[39;49;00m
[37m [39;49;00mcanvas.height[37m [39;49;00m=[37m [39;49;00mpadBox.clientHeight;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m [39;49;00m[36mwindow[39;49;00m.addEventListener([33m'resize'[39;49;00m,[37m [39;49;00mresizeCanvas);[37m[39;49;00m
[37m [39;49;00mresizeCanvas();[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mgetPadCoordinates(e)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mrect[37m [39;49;00m=[37m [39;49;00mpadBox.getBoundingClientRect();[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mtouchList[37m [39;49;00m=[37m [39;49;00me.touches[37m [39;49;00m?[37m [39;49;00m[36mArray[39;49;00m.[34mfrom[39;49;00m(e.touches)[37m [39;49;00m:[37m [39;49;00m[e];[37m[39;49;00m
[37m [39;49;00m[34mreturn[39;49;00m[37m [39;49;00mtouchList.map(t[37m [39;49;00m=>[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mx[37m [39;49;00m=[37m [39;49;00m[36mMath[39;49;00m.max([34m0[39;49;00m,[37m [39;49;00m[36mMath[39;49;00m.min(rect.width,[37m [39;49;00mt.clientX[37m [39;49;00m-[37m [39;49;00mrect.left));[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00my[37m [39;49;00m=[37m [39;49;00m[36mMath[39;49;00m.max([34m0[39;49;00m,[37m [39;49;00m[36mMath[39;49;00m.min(rect.height,[37m [39;49;00mt.clientY[37m [39;49;00m-[37m [39;49;00mrect.top));[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mxRatio[37m [39;49;00m=[37m [39;49;00mx[37m [39;49;00m/[37m [39;49;00mrect.width;[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00myRatio[37m [39;49;00m=[37m [39;49;00m[34m1[39;49;00m[37m [39;49;00m-[37m [39;49;00m(y[37m [39;49;00m/[37m [39;49;00mrect.height);[37m[39;49;00m
[37m [39;49;00m[37m// 6 Virtual String Zones on Y-Axis[39;49;00m[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mstringIndex[37m [39;49;00m=[37m [39;49;00m[36mMath[39;49;00m.min([34m5[39;49;00m,[37m [39;49;00m[36mMath[39;49;00m.floor((y[37m [39;49;00m/[37m [39;49;00mrect.height)[37m [39;49;00m*[37m [39;49;00m[34m6[39;49;00m));[37m[39;49;00m
[37m [39;49;00m[34mreturn[39;49;00m[37m [39;49;00m{[37m [39;49;00mid:[37m [39;49;00mt.identifier[37m [39;49;00m??[37m [39;49;00m[33m'mouse'[39;49;00m,[37m [39;49;00mx,[37m [39;49;00my,[37m [39;49;00mxRatio,[37m [39;49;00myRatio,[37m [39;49;00mstringIndex[37m [39;49;00m};[37m[39;49;00m
[37m [39;49;00m});[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mhandleTouchStart(e)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00me.preventDefault();[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mcurrentTouches[37m [39;49;00m=[37m [39;49;00mgetPadCoordinates(e);[37m[39;49;00m
[37m [39;49;00mcurrentTouches.forEach(t[37m [39;49;00m=>[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00mstartVoice(t.id,[37m [39;49;00mt.stringIndex,[37m [39;49;00mt.xRatio,[37m [39;49;00mt.yRatio);[37m[39;49;00m
[37m [39;49;00m});[37m[39;49;00m
[37m [39;49;00mtouches[37m [39;49;00m=[37m [39;49;00mcurrentTouches;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mhandleTouchMove(e)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00me.preventDefault();[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mcurrentTouches[37m [39;49;00m=[37m [39;49;00mgetPadCoordinates(e);[37m[39;49;00m
[37m [39;49;00mcurrentTouches.forEach(t[37m [39;49;00m=>[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00mupdateVoice(t.id,[37m [39;49;00mt.xRatio,[37m [39;49;00mt.yRatio,[37m [39;49;00mt.stringIndex);[37m[39;49;00m
[37m [39;49;00m});[37m[39;49;00m
[37m [39;49;00mtouches[37m [39;49;00m=[37m [39;49;00mcurrentTouches;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mhandleTouchEnd(e)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00me.preventDefault();[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mremainingTouches[37m [39;49;00m=[37m [39;49;00mgetPadCoordinates(e);[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mremainingIds[37m [39;49;00m=[37m [39;49;00m[35mnew[39;49;00m[37m [39;49;00m[36mSet[39;49;00m(remainingTouches.map(t[37m [39;49;00m=>[37m [39;49;00mt.id));[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[36mObject[39;49;00m.keys(activeVoices).forEach(id[37m [39;49;00m=>[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(!remainingIds.has(id[37m [39;49;00m===[37m [39;49;00m[33m'mouse'[39;49;00m[37m [39;49;00m?[37m [39;49;00m[33m'mouse'[39;49;00m[37m [39;49;00m:[37m [39;49;00m[36mNumber[39;49;00m(id)))[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00mstopVoice(id);[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m [39;49;00m});[37m[39;49;00m
[37m [39;49;00mtouches[37m [39;49;00m=[37m [39;49;00mremainingTouches;[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00mpadBox.addEventListener([33m'touchstart'[39;49;00m,[37m [39;49;00mhandleTouchStart,[37m [39;49;00m{[37m [39;49;00mpassive:[37m [39;49;00m[34mfalse[39;49;00m[37m [39;49;00m});[37m[39;49;00m
[37m [39;49;00mpadBox.addEventListener([33m'touchmove'[39;49;00m,[37m [39;49;00mhandleTouchMove,[37m [39;49;00m{[37m [39;49;00mpassive:[37m [39;49;00m[34mfalse[39;49;00m[37m [39;49;00m});[37m[39;49;00m
[37m [39;49;00mpadBox.addEventListener([33m'touchend'[39;49;00m,[37m [39;49;00mhandleTouchEnd,[37m [39;49;00m{[37m [39;49;00mpassive:[37m [39;49;00m[34mfalse[39;49;00m[37m [39;49;00m});[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[34mlet[39;49;00m[37m [39;49;00misMouseDown[37m [39;49;00m=[37m [39;49;00m[34mfalse[39;49;00m;[37m[39;49;00m
[37m [39;49;00mpadBox.addEventListener([33m'mousedown'[39;49;00m,[37m [39;49;00m(e)[37m [39;49;00m=>[37m [39;49;00m{[37m [39;49;00misMouseDown[37m [39;49;00m=[37m [39;49;00m[34mtrue[39;49;00m;[37m [39;49;00mhandleTouchStart(e);[37m [39;49;00m});[37m[39;49;00m
[37m [39;49;00m[36mwindow[39;49;00m.addEventListener([33m'mousemove'[39;49;00m,[37m [39;49;00m(e)[37m [39;49;00m=>[37m [39;49;00m{[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(isMouseDown)[37m [39;49;00mhandleTouchMove(e);[37m [39;49;00m});[37m[39;49;00m
[37m [39;49;00m[36mwindow[39;49;00m.addEventListener([33m'mouseup'[39;49;00m,[37m [39;49;00m(e)[37m [39;49;00m=>[37m [39;49;00m{[37m [39;49;00m[34mif[39;49;00m[37m [39;49;00m(isMouseDown)[37m [39;49;00m{[37m [39;49;00misMouseDown[37m [39;49;00m=[37m [39;49;00m[34mfalse[39;49;00m;[37m [39;49;00mhandleTouchEnd(e);[37m [39;49;00m}[37m [39;49;00m});[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Visualizer Loop[39;49;00m[37m[39;49;00m
[37m [39;49;00m[34mfunction[39;49;00m[37m [39;49;00mdrawPad()[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00mrequestAnimationFrame(drawPad);[37m[39;49;00m
[37m [39;49;00mctx.fillStyle[37m [39;49;00m=[37m [39;49;00m[33m'#040406'[39;49;00m;[37m[39;49;00m
[37m [39;49;00mctx.fillRect([34m0[39;49;00m,[37m [39;49;00m[34m0[39;49;00m,[37m [39;49;00mcanvas.width,[37m [39;49;00mcanvas.height);[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Draw 6 Virtual String Bands (Kitara Style)[39;49;00m[37m[39;49;00m
[37m [39;49;00m[34mconst[39;49;00m[37m [39;49;00mbandHeight[37m [39;49;00m=[37m [39;49;00mcanvas.height[37m [39;49;00m/[37m [39;49;00m[34m6[39;49;00m;[37m[39;49;00m
[37m [39;49;00mctx.lineWidth[37m [39;49;00m=[37m [39;49;00m[34m1[39;49;00m;[37m[39;49;00m
[37m [39;49;00m[34mfor[39;49;00m[37m [39;49;00m([34mlet[39;49;00m[37m [39;49;00mi[37m [39;49;00m=[37m [39;49;00m[34m0[39;49;00m;[37m [39;49;00mi[37m [39;49;00m<[37m [39;49;00m[34m6[39;49;00m;[37m [39;49;00mi++)[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00mctx.strokeStyle[37m [39;49;00m=[37m [39;49;00m[33m'#181828'[39;49;00m;[37m[39;49;00m
[37m [39;49;00mctx.beginPath();[37m[39;49;00m
[37m [39;49;00mctx.moveTo([34m0[39;49;00m,[37m [39;49;00mi[37m [39;49;00m*[37m [39;49;00mbandHeight);[37m[39;49;00m
[37m [39;49;00mctx.lineTo(canvas.width,[37m [39;49;00mi[37m [39;49;00m*[37m [39;49;00mbandHeight);[37m[39;49;00m
[37m [39;49;00mctx.stroke();[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Highlight Active Fretted String Lines[39;49;00m[37m[39;49;00m
[37m [39;49;00mctx.strokeStyle[37m [39;49;00m=[37m [39;49;00m[33m'rgba(0, 240, 255, 0.15)'[39;49;00m;[37m[39;49;00m
[37m [39;49;00mctx.beginPath();[37m[39;49;00m
[37m [39;49;00mctx.moveTo([34m0[39;49;00m,[37m [39;49;00mi[37m [39;49;00m*[37m [39;49;00mbandHeight[37m [39;49;00m+[37m [39;49;00mbandHeight[37m [39;49;00m/[37m [39;49;00m[34m2[39;49;00m);[37m[39;49;00m
[37m [39;49;00mctx.lineTo(canvas.width,[37m [39;49;00mi[37m [39;49;00m*[37m [39;49;00mbandHeight[37m [39;49;00m+[37m [39;49;00mbandHeight[37m [39;49;00m/[37m [39;49;00m[34m2[39;49;00m);[37m[39;49;00m
[37m [39;49;00mctx.stroke();[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Draw Touch Pointers[39;49;00m[37m[39;49;00m
[37m [39;49;00mtouches.forEach(t[37m [39;49;00m=>[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00m[37m// Horizontal / Vertical Crosshair[39;49;00m[37m[39;49;00m
[37m [39;49;00mctx.strokeStyle[37m [39;49;00m=[37m [39;49;00m[33m'rgba(255, 0, 85, 0.4)'[39;49;00m;[37m[39;49;00m
[37m [39;49;00mctx.beginPath();[37m [39;49;00mctx.moveTo(t.x,[37m [39;49;00m[34m0[39;49;00m);[37m [39;49;00mctx.lineTo(t.x,[37m [39;49;00mcanvas.height);[37m [39;49;00mctx.stroke();[37m[39;49;00m
[37m [39;49;00mctx.beginPath();[37m [39;49;00mctx.moveTo([34m0[39;49;00m,[37m [39;49;00mt.y);[37m [39;49;00mctx.lineTo(canvas.width,[37m [39;49;00mt.y);[37m [39;49;00mctx.stroke();[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// Glowing Touch Point[39;49;00m[37m[39;49;00m
[37m [39;49;00mctx.fillStyle[37m [39;49;00m=[37m [39;49;00m[33m'#00f0ff'[39;49;00m;[37m[39;49;00m
[37m [39;49;00mctx.shadowColor[37m [39;49;00m=[37m [39;49;00m[33m'#00f0ff'[39;49;00m;[37m[39;49;00m
[37m [39;49;00mctx.shadowBlur[37m [39;49;00m=[37m [39;49;00m[34m12[39;49;00m;[37m[39;49;00m
[37m [39;49;00mctx.beginPath();[37m[39;49;00m
[37m [39;49;00mctx.arc(t.x,[37m [39;49;00mt.y,[37m [39;49;00m[34m16[39;49;00m,[37m [39;49;00m[34m0[39;49;00m,[37m [39;49;00m[36mMath[39;49;00m.PI[37m [39;49;00m*[37m [39;49;00m[34m2[39;49;00m);[37m[39;49;00m
[37m [39;49;00mctx.fill();[37m[39;49;00m
[37m [39;49;00mctx.shadowBlur[37m [39;49;00m=[37m [39;49;00m[34m0[39;49;00m;[37m[39;49;00m
[37m [39;49;00m});[37m[39;49;00m
[37m [39;49;00m}[37m[39;49;00m
[37m [39;49;00mdrawPad();[37m[39;49;00m
[37m[39;49;00m
[37m [39;49;00m[37m// UI Listeners[39;49;00m[37m[39;49;00m
[37m [39;49;00m[36mdocument[39;49;00m.getElementById([33m'delay-btn'[39;49;00m).addEventListener([33m'click'[39;49;00m,[37m [39;49;00m(e)[37m [39;49;00m=>[37m [39;49;00m{[37m[39;49;00m
[37m [39;49;00mdelayActive[37m [39;49;00m=[37m [39;49;00m!delayActive;[37m[39;49;00m
[37m [39;49;00mdelayFeedback.gain.value[37m [39;49;00m=[37m [39;49;00mdelayActive[37m [39;49;00m?[37m [39;49;00m[34m0.4[39;49;00m[37m [39;49;00m:[37m [39;49;00m[34m0[39;49;00m;[37m[39;49;00m
[37m [39;49;00me.target.innerText[37m [39;49;00m=[37m [39;49;00m[33m`[39;49;00m[33mDELAY: [39;49;00m[33m${[39;49;00mdelayActive[37m [39;49;00m?[37m [39;49;00m[33m'ON'[39;49;00m[37m [39;49;00m:[37m [39;49;00m[33m'OFF'[39;49;00m[33m}[39;49;00m[33m`[39;49;00m;[37m[39;49;00m
[37m [39;49;00me.target.classList.toggle([33m'active'[39;49;00m,[37m [39;49;00mdelayActive);[37m[39;49;00m
[37m [39;49;00m});[37m[39;49;00m
[94mscript[39;49;00m>
[94mbody[39;49;00m>
[94mhtml[39;49;00m>