This commit is contained in:
parent
dc3811b5d5
commit
cbc23f8723
3 changed files with 360 additions and 66 deletions
|
@ -2,6 +2,14 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<title>qrplay</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
max-width: 40rem;
|
||||
margin: 0 auto;
|
||||
padding: 1rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
@ -10,92 +18,214 @@
|
|||
<h2>qrplay by nycki and SArpnt</h2>
|
||||
<p>a QR-code sized implementation of ZZT Play, which you may know from the <a href="https://chriskallen.com/zzt/hallofmusic.html">ZZT Hall of Music</a>.</p>
|
||||
|
||||
<p>I designed this because I wanted a program I could print on a business card, and <a href="https://git.disroot.org/SArpnt">SArpnt</a> found some clever ways to shrink it even further. The version on this page is commented, the version in the QR code is minified.</p>
|
||||
<p>I designed this because I wanted a program I could print on a business card, and <a href="https://git.disroot.org/SArpnt">SArpnt</a> found some clever ways to shrink it even further. The <a href="https://git.hatspace.net/nycki/nycki.net/src/branch/main/static/qrplay/index.html">source</a> on this page is commented, the source in the QR code is minified.</p>
|
||||
|
||||
<p>paste ZZT music code in this box, then click the button to #play!</p>
|
||||
|
||||
<!-- snip here -->
|
||||
<meta name="viewport" content="width=device-width initial-scale=1.0">
|
||||
<textarea id=f></textarea><br>
|
||||
<meta name=viewport content=initial-scale=1>
|
||||
<center>
|
||||
<p><a href=http://nycki.net/qrplay>qrplay v2c</a></p>
|
||||
<textarea id=f style=width:min(40em,99%);height:9lh>; #title nupa's theme
|
||||
; #authors nycki bsp
|
||||
z00
|
||||
@qcceg hcqeg dcdc d#h.d
|
||||
@qcceg hcqeg dcd#d wc
|
||||
z01
|
||||
@-wc b! a a!
|
||||
@-wc b! haqa!g w-c</textarea><p>
|
||||
<button onclick='
|
||||
/*qrplay v2, nycki & SArpnt, 2025*/
|
||||
f.A&&f.A.close();
|
||||
f.A=A=new AudioContext;
|
||||
v=f.value;
|
||||
T=[];Z=0; // channels
|
||||
B=new GainNode(A,{gain:0.1});
|
||||
B.connect(A.destination);
|
||||
s=`@`+f.value.toLowerCase();
|
||||
f.A?.close();
|
||||
A=f.A=new AudioContext;
|
||||
// per-channel data
|
||||
T=[];L=[];
|
||||
// tempo in beats per minute
|
||||
u=137;
|
||||
// volume. 40 is default, 35 is half, 30 is half again.
|
||||
v=40;
|
||||
for(
|
||||
i=o=k=t=0,l=1;
|
||||
c=v[i++],d=v[i],c;
|
||||
|
||||
z<0?0: // no match
|
||||
z>29?k=1: // start of comment. P, O, V, U, K, R, not implemented.
|
||||
z>28?k=0: // end of comment
|
||||
k?0: // comment
|
||||
z>27?(T[Z]=t,Z=+v.slice(i,i+=2),t=T[Z]||0): // change channel
|
||||
z>17?t+=l: // rest
|
||||
z<3? // @-+
|
||||
z?o+=g: // change octave
|
||||
(o=0,l=1/8): // @
|
||||
(console.log(z),z)&1?console.log(l=g): // change speed
|
||||
( // note
|
||||
a=new OscillatorNode(A,{
|
||||
c=t=k=Z=0;D=s[c+1],E=D+s[c+2],C=s[c++];
|
||||
// no match
|
||||
z<0?0:
|
||||
// comments
|
||||
z<2?k=z:k?0:
|
||||
// - + octave
|
||||
z<4?o+=C+1|0:
|
||||
// dots and triplets
|
||||
z<5?l*=3/2:
|
||||
z<6?l/=3:
|
||||
// note or rest
|
||||
z<14?(
|
||||
z-=6,
|
||||
O=new OscillatorNode(A,{
|
||||
type:`square`,
|
||||
detune:100*(g+o+(d==`#`)-(d==`!`)) // # sharp or ! flat
|
||||
detune:100*(z*2-(z>2)-(D==`!`)+(D==`#`)+12*o-9)
|
||||
}),
|
||||
a.connect(B),
|
||||
a.start(t*.4),
|
||||
t+=l,
|
||||
a.stop(t*.4)
|
||||
)
|
||||
)
|
||||
g=[,-12,12,4,-9,2,-7,1,-5,.5,-4,.25,-2,1/8,0,l/3,2,l*1.5][z=`@-+wchdqeifsgta3b.x012456789z\npovukr\x27`.indexOf(c.toLowerCase())]
|
||||
'>#play</button> <button onclick='f.A.close()'>#stop</button>
|
||||
G=new GainNode(A,{gain:z<7&&.5**(12-v/5)}),
|
||||
O.connect(G),
|
||||
G.connect(A.destination),
|
||||
O.start(t),
|
||||
O.stop(t+=7.5*l/u)
|
||||
):
|
||||
// percussion
|
||||
z<23?(
|
||||
// insert micronotes to match ZZTs drums. random numbers chosen in advance.
|
||||
s=`z99o06${[
|
||||
"+g",
|
||||
"-b+c#deff#gg#aa#b+cc#d",
|
||||
"g++ddb--g++ddb--g++ddb--g++ddb",
|
||||
,
|
||||
"+ea-g--b++g++c#----b++g+cd#-g+cec",
|
||||
"a#ga#g-a#+g-b+g",
|
||||
"-a++c#-aae+e--a++c#-aae+e--a++c#",
|
||||
"-fffeeed#d#dddc#c#c#",
|
||||
"dddddedc#ded#fee",
|
||||
"--ba#bb-a+a#-baaa+a#bb-a",
|
||||
][z-14]}z${Z} o${o+4} x`+s.slice(c),c=0,T[99]=t,L[99]=u/2**12
|
||||
):
|
||||
// reset octave and duration
|
||||
z<24?(o=0,l=1):
|
||||
// set note length
|
||||
z<31?l=2**(z-25):
|
||||
// change channel
|
||||
z<32?(
|
||||
T[Z]=t,L[Z]=l,
|
||||
t=T[Z=E|0]||0,l=L[Z]||l,
|
||||
c+=2
|
||||
):
|
||||
// change tempo
|
||||
z<33?u=E+s[c+=2,c++]:
|
||||
// change volume
|
||||
z<34?(v=E,c+=2):
|
||||
// set octave
|
||||
(o=E-4,c+=2)
|
||||
)z=`\n;-+.3cdefgabx012456789@jtsiqhwzuvo`.indexOf(C)
|
||||
'>#play</button> <button onclick=f.A.close()>#stop</button>
|
||||
<!-- stop snipping here -->
|
||||
|
||||
<button onclick='
|
||||
window.location.search = "?"+f.value.replaceAll(" ","%20").replaceAll("\n","%0a").replaceAll("#","%23");
|
||||
'>#save</button>
|
||||
</center>
|
||||
|
||||
<script>
|
||||
f.value=f.value||window.location.search.slice(1)||`'Solfeggettio in C Minor by JS Bach
|
||||
@i-e!ce!g+ce!dc-bgb+dgfe!de!
|
||||
@ice!g+ce!dcdc-bagfe!d
|
||||
@ie!ce!g+ce!dc-bgb+dgfe!d
|
||||
@i+e!ce!g+ce!dcdc-bagfe!d
|
||||
@i+e!c-ge!c++c-ge!a!--fa!+cfa!+ce!
|
||||
@i+d-b!fd-b!++b!fdg--e!gb!+dgb!+d
|
||||
@i+ge!dc-ge!dh.c`;
|
||||
f.value=f.value.replaceAll('%20', ' ').replaceAll('%0a','\n').replaceAll('%0A','\n').replaceAll('%23', '#');
|
||||
// set default value for input
|
||||
f.value=(
|
||||
window.location.search.slice(1)
|
||||
.replaceAll('%20', ' ')
|
||||
.replaceAll('%0a','\n')
|
||||
.replaceAll('%0A','\n')
|
||||
.replaceAll('%23', '#')
|
||||
.replaceAll('%27', "'")
|
||||
|| f.value
|
||||
);
|
||||
|
||||
// remove redundant title
|
||||
document.querySelector('center p').setAttribute('hidden', 'true');
|
||||
|
||||
// add save button
|
||||
document.querySelector('center p:last-child').innerHTML+=`
|
||||
<button onclick='
|
||||
window.location.search = "?"+f.value
|
||||
.replaceAll(" ","%20")
|
||||
.replaceAll("\\n","%0a")
|
||||
.replaceAll("#","%23")
|
||||
.replaceAll("\\x27","%27")
|
||||
'>#save</button>
|
||||
`;
|
||||
</script>
|
||||
|
||||
<hr>
|
||||
<h2>qr codes</h2>
|
||||
|
||||
<table style="text-align: center;">
|
||||
<tr><td>qrplay</td><td>Solfeggetio in C Minor</td></tr>
|
||||
<tr>
|
||||
<td>
|
||||
<img src="qrplay-v1.png">
|
||||
</td>
|
||||
<td>
|
||||
<img src="qrplay-solfeggettio.png">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><textarea>data:text/html,<meta%20name="viewport"%20content="width=device-width%20initial-scale=1.0"><textarea%20id=f></textarea><br><button%20onclick='/*qrplay%20v1,%20nycki%20&%20SArpnt,%202025*/v=f.value;T=[];Z=0;f.A=A=f.A||new%20AudioContext;B=new%20GainNode(A,{gain:0.4});B.connect(A.destination);for(i=o=k=t=0,l=1;c=v[i++],d=v[i],c;z<0?0:z>29?k=1:z>28?k=0:k?0:z>27?(T[Z]=t,Z=+v.slice(i,i+=2),t=T[Z]||0):z>17?t+=l:z<3?z?o+=g:(o=0,l=1/8):(console.log(z),z)&1?console.log(l=g):(a=new%20OscillatorNode(A,{type:`square`,detune:100*(g+o+(d==`%23`)-(d==`!`))}),a.connect(B),a.start(t*.4),t+=l,a.stop(t*.4)))g=[,-12,12,4,-9,2,-7,1,-5,.5,-4,.25,-2,1/8,0,l/3,2,l*1.5][z=`@-+wchdqeifsgta3b.x012456789z\npovukr\x27`.indexOf(c.toLowerCase())]'>%23play</button><button%20onclick='f.A.close();f.A=0'>%23stop</button></textarea></td>
|
||||
<td><textarea>'Solfeggettio in C Minor by JS Bach
|
||||
<p>for security reasons, your phone probably won't open these as links. you'll have to copy and paste the text into your browser by yourself. it requires no permissions or internet access to run.</p>
|
||||
|
||||
<details open>
|
||||
<summary>qrplay v2: added percussion, chords, volume control, sample song.</summary>
|
||||
<div style="text-align: center;">
|
||||
<p><strong>qrplay v2</strong></p>
|
||||
<img src="qrplay-v2-nupas-theme.png">
|
||||
<p><textarea>data:text/html,<meta%20name=viewport%20content=initial-scale=1><center><p><a%20href=http://nycki.net/qrplay>qrplay%20v2c</a></p><textarea%20id=f%20style=width:min(40em,99%);height:9lh>;%20%23title%20nupa's%20theme%0A;%20%23authors%20nycki%20bsp%0Az00%0A@qcceg%20hcqeg%20dcdc%20d%23h.d%0A@qcceg%20hcqeg%20dcd%23d%20wc%0Az01%0A@-wc%20b!%20a%20a!%0A@-wc%20b!%20haqa!g%20w-c</textarea><p><button%20onclick='s=`@`+f.value.toLowerCase();f.A?.close();A=f.A=new%20AudioContext;T=[];L=[];u=137;v=40;for(c=t=k=Z=0;D=s[c+1],E=D+s[c+2],C=s[c++];z<0?0:z<2?k=z:k?0:z<4?o+=C+1|0:z<5?l*=3/2:z<6?l/=3:z<14?(z-=6,O=new%20OscillatorNode(A,{type:`square`,detune:100*(z*2-(z>2)-(D==`!`)+(D==`%23`)+12*o-9)}),G=new%20GainNode(A,{gain:z<7&&.5**(12-v/5)}),O.connect(G),G.connect(A.destination),O.start(t),O.stop(t+=7.5*l/u)):z<23?(s=`z99o06${["+g","-b+c%23deff%23gg%23aa%23b+cc%23d","g++ddb--g++ddb--g++ddb--g++ddb",,"+ea-g--b++g++c%23----b++g+cd%23-g+cec","a%23ga%23g-a%23+g-b+g","-a++c%23-aae+e--a++c%23-aae+e--a++c%23","-fffeeed%23d%23dddc%23c%23c%23","dddddedc%23ded%23fee","--ba%23bb-a+a%23-baaa+a%23bb-a",][z-14]}z${Z}%20o${o+4}%20x`+s.slice(c),c=0,T[99]=t,L[99]=u/2**12):z<24?(o=0,l=1):z<31?l=2**(z-25):z<32?(T[Z]=t,L[Z]=l,t=T[Z=E|0]||0,l=L[Z]||l,c+=2):z<33?u=E+s[c+=2,c++]:z<34?(v=E,c+=2):(o=E-4,c+=2))z=`\n;-+.3cdefgabx012456789@jtsiqhwzuvo`.indexOf(C)'>%23play</button>%20<button%20onclick=f.A.close()>%23stop</button></textarea></p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>qrplay v1: proof of concept. musical notes only.</summary>
|
||||
<div style="text-align: center;">
|
||||
<p><strong>qrplay v1</strong></p>
|
||||
<img src="qrplay-v1.png">
|
||||
<p><textarea>data:text/html,<meta%20name="viewport"%20content="width=device-width%20initial-scale=1.0"><textarea%20id=f></textarea><br><button%20onclick='/*qrplay%20v1,%20nycki%20&%20SArpnt,%202025*/v=f.value;T=[];Z=0;f.A=A=f.A||new%20AudioContext;B=new%20GainNode(A,{gain:0.4});B.connect(A.destination);for(i=o=k=t=0,l=1;c=v[i++],d=v[i],c;z<0?0:z>29?k=1:z>28?k=0:k?0:z>27?(T[Z]=t,Z=+v.slice(i,i+=2),t=T[Z]||0):z>17?t+=l:z<3?z?o+=g:(o=0,l=1/8):(console.log(z),z)&1?console.log(l=g):(a=new%20OscillatorNode(A,{type:`square`,detune:100*(g+o+(d==`%23`)-(d==`!`))}),a.connect(B),a.start(t*.4),t+=l,a.stop(t*.4)))g=[,-12,12,4,-9,2,-7,1,-5,.5,-4,.25,-2,1/8,0,l/3,2,l*1.5][z=`@-+wchdqeifsgta3b.x012456789z\npovukr\x27`.indexOf(c.toLowerCase())]'>%23play</button><button%20onclick='f.A.close();f.A=0'>%23stop</button></textarea></p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>song: Solfeggettio in C Minor</summary>
|
||||
<div style="text-align: center;">
|
||||
<p><textarea>;; title Solfeggettio
|
||||
;; artist JS Bach
|
||||
@i-e!ce!g+ce!dc-bgb+dgfe!de!
|
||||
@ice!g+ce!dcdc-bagfe!d
|
||||
@ie!ce!g+ce!dc-bgb+dgfe!d
|
||||
@i+e!ce!g+ce!dcdc-bagfe!d
|
||||
@i+e!c-ge!c++c-ge!a!--fa!+cfa!+ce!
|
||||
@i+d-b!fd-b!++b!fdg--e!gb!+dgb!+d
|
||||
@i+ge!dc-ge!dh.c</textarea></td>
|
||||
</tr>
|
||||
</table>
|
||||
@i+ge!dc-ge!dh.c
|
||||
</textarea></p>
|
||||
<img src="qrplay-solfeggettio.png">
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<p>for security reasons, your phone probably won't open these as links. you'll have to copy and paste the text into your browser's uri input.</p>
|
||||
<details>
|
||||
<summary>song: We Will Rock You</summary>
|
||||
<div style="text-align: center;">
|
||||
<p><textarea>U137V40
|
||||
@s.9x9x6xxx9x9x6xxx9x9x6xxx9x9x6xxx
|
||||
@s.deedi.es.eei.des.de
|
||||
@s.edi.es.eeedi.eags.g-b+dx
|
||||
@s.ei.es.dexxdexexe
|
||||
@s.xxxdddxdd-bxage+eq.x
|
||||
@q.gf#eds.exex6xxx9x9x6xxx
|
||||
@q.gf#eds.exex6xxx9x9x6xxx
|
||||
@s.deedi.es.eei.des.de
|
||||
@s.edi.es.eeedi.eags.g-b+dx
|
||||
@s.ei.es.dexxdexexe
|
||||
@s.xxxdddxdd-bxage+eq.x
|
||||
@q.gf#eds.exex6xxx9x9x6xxx
|
||||
@q.gf#eds.exex6xxx9x9x6xxx
|
||||
@q.gf#eds.exex6xxx9x9x6xxx
|
||||
@q.gf#eds.exex6xxx9x9x6xxx
|
||||
</textarea></p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<h2>command reference</h2>
|
||||
|
||||
basic commands:
|
||||
|
||||
<ul>
|
||||
<li>cdefgab: play a note in the current octave.</li>
|
||||
<li>012456789: play one of various percussion effects. note that there is no effect 3.</li>
|
||||
<li>x: rest for the length of a note.</li>
|
||||
<li>-+ change octaves. default is the 4th octave, the one containing middle C.</li>
|
||||
<li>whqistj: change note length to whole, half, quarter, eigth, sixteenth, thirtytwoth, or sixtyfourth. default is t.</li>
|
||||
<li>3: cut the current note length into triplets. for instance, <em>q3ceg</em> would play three notes that are each 1/3 the length of a quarter note.</li>
|
||||
<li>.: dotted note. increases the current note length by 50%. for instance, <em>q.c</em> would play a note that lasts 1.5 times a quarter note.</li>
|
||||
<li>@: reset octave and note length to defaults.</li>
|
||||
</ul>
|
||||
|
||||
extended commands: this stuff wasn't in ZZT!
|
||||
<ul>
|
||||
<li>;: comment. everything from a semicolon until the end of the line is ignored. you can put the name of your song in here!</li>
|
||||
<li>znn: select track. you can use this to play two or more tracks at once! so for instance, <em>z00c z01+c</em> would play an octave chord. tracks greater than 15 are reserved for internal use.</li>
|
||||
<li>unnn: set tempo in beats per minute. for historic reasons, u137 is the default.</li>
|
||||
<li>vnn: set volume, from 00 to 99. this scales exponentially: 40 is the default, then 45 is double that, then 50 is double that, etc.</li>
|
||||
<li>onn: set octave, from -9 to 99, but you should really only use 00 thru 08. default is 04.</li>
|
||||
</ul>
|
||||
|
||||
not implemented:
|
||||
<ul>
|
||||
<li>loops! I'm thinking of implementing something brainfuck-esque so you can make turing machine music... we'll see.</li>
|
||||
<li>there's a known bug where you can't play two percussion effects on different channels at the same time. but like, if I hadn't told you, I don't think you would have noticed.</li>
|
||||
<li>change tuning! currently this is tuned to A440 but ZZT is actually slightly out of tune and it would be cool to replicate that.</li>
|
||||
<li>slides and bends. ZZT Ultra has these and I could probably figure them out but I'd have to rework it to fit in the qr code.</li>
|
||||
<li>compression: maybe I could rewrite this whole thing to use uppercase letters only so it fits in the QR alphanumeric mode? I'd have to escape every punctuation mark though. might experiment with this later.</li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
101
static/qrplay/index1.html
Normal file
101
static/qrplay/index1.html
Normal file
|
@ -0,0 +1,101 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>qrplay</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav><a href="/">home</a></nav>
|
||||
|
||||
<h2>qrplay by nycki and SArpnt</h2>
|
||||
<p>a QR-code sized implementation of ZZT Play, which you may know from the <a href="https://chriskallen.com/zzt/hallofmusic.html">ZZT Hall of Music</a>.</p>
|
||||
|
||||
<p>I designed this because I wanted a program I could print on a business card, and <a href="https://git.disroot.org/SArpnt">SArpnt</a> found some clever ways to shrink it even further. The version on this page is commented, the version in the QR code is minified.</p>
|
||||
|
||||
<p>paste ZZT music code in this box, then click the button to #play!</p>
|
||||
|
||||
<!-- snip here -->
|
||||
<meta name="viewport" content="width=device-width initial-scale=1.0">
|
||||
<textarea id=f></textarea><br>
|
||||
<button onclick='
|
||||
/*qrplay v2, nycki & SArpnt, 2025*/
|
||||
f.A&&f.A.close();
|
||||
f.A=A=new AudioContext;
|
||||
v=f.value;
|
||||
T=[];Z=0; // channels
|
||||
B=new GainNode(A,{gain:0.1});
|
||||
B.connect(A.destination);
|
||||
for(
|
||||
i=o=k=t=0,l=1;
|
||||
c=v[i++],d=v[i],c;
|
||||
|
||||
z<0?0: // no match
|
||||
z>29?k=1: // start of comment. P, O, V, U, K, R, not implemented.
|
||||
z>28?k=0: // end of comment
|
||||
k?0: // comment
|
||||
z>27?(T[Z]=t,Z=+v.slice(i,i+=2),t=T[Z]||0): // change channel
|
||||
z>17?t+=l: // rest
|
||||
z<3? // @-+
|
||||
z?o+=g: // change octave
|
||||
(o=0,l=1/8): // @
|
||||
(console.log(z),z)&1?console.log(l=g): // change speed
|
||||
( // note
|
||||
a=new OscillatorNode(A,{
|
||||
type:`square`,
|
||||
detune:100*(g+o+(d==`#`)-(d==`!`)) // # sharp or ! flat
|
||||
}),
|
||||
a.connect(B),
|
||||
a.start(t*.4),
|
||||
t+=l,
|
||||
a.stop(t*.4)
|
||||
)
|
||||
)
|
||||
g=[,-12,12,4,-9,2,-7,1,-5,.5,-4,.25,-2,1/8,0,l/3,2,l*1.5][z=`@-+wchdqeifsgta3b.x012456789z\npovukr\x27`.indexOf(c.toLowerCase())]
|
||||
'>#play</button> <button onclick='f.A.close()'>#stop</button>
|
||||
<!-- stop snipping here -->
|
||||
|
||||
<button onclick='
|
||||
window.location.search = "?"+f.value.replaceAll(" ","%20").replaceAll("\n","%0a").replaceAll("#","%23");
|
||||
'>#save</button>
|
||||
|
||||
<script>
|
||||
f.value=f.value||window.location.search.slice(1)||`'Solfeggettio in C Minor by JS Bach
|
||||
@i-e!ce!g+ce!dc-bgb+dgfe!de!
|
||||
@ice!g+ce!dcdc-bagfe!d
|
||||
@ie!ce!g+ce!dc-bgb+dgfe!d
|
||||
@i+e!ce!g+ce!dcdc-bagfe!d
|
||||
@i+e!c-ge!c++c-ge!a!--fa!+cfa!+ce!
|
||||
@i+d-b!fd-b!++b!fdg--e!gb!+dgb!+d
|
||||
@i+ge!dc-ge!dh.c`;
|
||||
f.value=f.value.replaceAll('%20', ' ').replaceAll('%0a','\n').replaceAll('%0A','\n').replaceAll('%23', '#');
|
||||
</script>
|
||||
|
||||
<hr>
|
||||
|
||||
<table style="text-align: center;">
|
||||
<tr><td>qrplay</td><td>Solfeggetio in C Minor</td></tr>
|
||||
<tr>
|
||||
<td>
|
||||
<img src="qrplay-v1.png">
|
||||
</td>
|
||||
<td>
|
||||
<img src="qrplay-solfeggettio.png">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><textarea>data:text/html,<meta%20name="viewport"%20content="width=device-width%20initial-scale=1.0"><textarea%20id=f></textarea><br><button%20onclick='/*qrplay%20v1,%20nycki%20&%20SArpnt,%202025*/v=f.value;T=[];Z=0;f.A=A=f.A||new%20AudioContext;B=new%20GainNode(A,{gain:0.4});B.connect(A.destination);for(i=o=k=t=0,l=1;c=v[i++],d=v[i],c;z<0?0:z>29?k=1:z>28?k=0:k?0:z>27?(T[Z]=t,Z=+v.slice(i,i+=2),t=T[Z]||0):z>17?t+=l:z<3?z?o+=g:(o=0,l=1/8):(console.log(z),z)&1?console.log(l=g):(a=new%20OscillatorNode(A,{type:`square`,detune:100*(g+o+(d==`%23`)-(d==`!`))}),a.connect(B),a.start(t*.4),t+=l,a.stop(t*.4)))g=[,-12,12,4,-9,2,-7,1,-5,.5,-4,.25,-2,1/8,0,l/3,2,l*1.5][z=`@-+wchdqeifsgta3b.x012456789z\npovukr\x27`.indexOf(c.toLowerCase())]'>%23play</button><button%20onclick='f.A.close();f.A=0'>%23stop</button></textarea></td>
|
||||
<td><textarea>'Solfeggettio in C Minor by JS Bach
|
||||
@i-e!ce!g+ce!dc-bgb+dgfe!de!
|
||||
@ice!g+ce!dcdc-bagfe!d
|
||||
@ie!ce!g+ce!dc-bgb+dgfe!d
|
||||
@i+e!ce!g+ce!dcdc-bagfe!d
|
||||
@i+e!c-ge!c++c-ge!a!--fa!+cfa!+ce!
|
||||
@i+d-b!fd-b!++b!fdg--e!gb!+dgb!+d
|
||||
@i+ge!dc-ge!dh.c</textarea></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>for security reasons, your phone probably won't open these as links. you'll have to copy and paste the text into your browser's uri input.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1 +1,64 @@
|
|||
<meta name="viewport" content="width=device-width initial-scale=1.0"><textarea id=f></textarea><br><button onclick='/*qrplay v1, nycki & SArpnt, 2025*/v=f.value;T=[];Z=0;f.A=A=f.A||new AudioContext;B=new GainNode(A,{gain:0.4});B.connect(A.destination);for(i=o=k=t=0,l=1;c=v[i++],d=v[i],c;z<0?0:z>29?k=1:z>28?k=0:k?0:z>27?(T[Z]=t,Z=+v.slice(i,i+=2),t=T[Z]||0):z>17?t+=l:z<3?z?o+=g:(o=0,l=1/8):(console.log(z),z)&1?console.log(l=g):(a=new OscillatorNode(A,{type:`square`,detune:100*(g+o+(d==`#`)-(d==`!`))}),a.connect(B),a.start(t*.4),t+=l,a.stop(t*.4)))g=[,-12,12,4,-9,2,-7,1,-5,.5,-4,.25,-2,1/8,0,l/3,2,l*1.5][z=`@-+wchdqeifsgta3b.x012456789z\npovukr\x27`.indexOf(c.toLowerCase())]'>#play</button><button onclick='f.A.close();f.A=0'>#stop</button>
|
||||
<meta name=viewport content=initial-scale=1>
|
||||
<center>
|
||||
<p><a href=http://nycki.net/qrplay>qrplay v2c</a></p>
|
||||
<textarea id=f style=width:min(40em,99%);height:9lh>; #title nupa's theme
|
||||
; #authors nycki bsp
|
||||
z00
|
||||
@qcceg hcqeg dcdc d#h.d
|
||||
@qcceg hcqeg dcd#d wc
|
||||
z01
|
||||
@-wc b! a a!
|
||||
@-wc b! haqa!g w-c
|
||||
</textarea><p>
|
||||
<button onclick='
|
||||
s=`@`+f.value.toLowerCase();
|
||||
f.A?.close();
|
||||
A=f.A=new AudioContext;
|
||||
T=[];L=[];
|
||||
u=137;
|
||||
v=40;
|
||||
for(
|
||||
c=t=k=Z=0;D=s[c+1],E=D+s[c+2],C=s[c++];
|
||||
z<0?0:
|
||||
z<2?k=z:k?0:
|
||||
z<4?o+=C+1|0:
|
||||
z<5?l*=3/2:
|
||||
z<6?l/=3:
|
||||
z<14?(
|
||||
z-=6,
|
||||
O=new OscillatorNode(A,{
|
||||
type:`square`,
|
||||
detune:100*(z*2-(z>2)-(D==`!`)+(D==`#`)+12*o-9)
|
||||
}),
|
||||
G=new GainNode(A,{gain:z<7&&.5**(12-v/5)}),
|
||||
O.connect(G),
|
||||
G.connect(A.destination),
|
||||
O.start(t),
|
||||
O.stop(t+=7.5*l/u)
|
||||
):
|
||||
z<23?(
|
||||
s=`z99o06${[
|
||||
"+g",
|
||||
"-b+c#deff#gg#aa#b+cc#d",
|
||||
"g++ddb--g++ddb--g++ddb--g++ddb",
|
||||
,
|
||||
"+ea-g--b++g++c#----b++g+cd#-g+cec",
|
||||
"a#ga#g-a#+g-b+g",
|
||||
"-a++c#-aae+e--a++c#-aae+e--a++c#",
|
||||
"-fffeeed#d#dddc#c#c#",
|
||||
"dddddedc#ded#fee",
|
||||
"--ba#bb-a+a#-baaa+a#bb-a",
|
||||
][z-14]}z${Z} o${o+4} x`+s.slice(c),c=0,T[99]=t,L[99]=u/2**12
|
||||
):
|
||||
z<24?(o=0,l=1):
|
||||
z<31?l=2**(z-25):
|
||||
z<32?(
|
||||
T[Z]=t,L[Z]=l,
|
||||
t=T[Z=E|0]||0,l=L[Z]||l,
|
||||
c+=2
|
||||
):
|
||||
z<33?u=E+s[c+=2,c++]:
|
||||
z<34?(v=E,c+=2):
|
||||
(o=E-4,c+=2)
|
||||
)z=`\n;-+.3cdefgabx012456789@jtsiqhwzuvo`.indexOf(C)
|
||||
'>#play</button> <button onclick=f.A.close()>#stop</button>
|
||||
|
|
Loading…
Add table
Reference in a new issue