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