nycki.net/static/qrplay/golf3.html
nycki c1bd32fba4
All checks were successful
/ build (push) Successful in 3m2s
v3e based on SArpnt's golf3
2025-07-13 00:52:22 -07:00

109 lines
3.7 KiB
HTML

<!--
new parser, not zzt compatible, but conversion is easy
commands, must be uppercase
ABCDEFG play note
* sharp (modifier for note letter)
: flat (modifier for note letter)
X rest
JTSIQHW set note duration (J:sixtyfourth, Thirtysecond, Sixteenth, eIghth, Quarter, Half, Whole)
. increase note duration by 50% (persistent)
3 divide note duration by 3 (persistent)
+ octave up (persistent)
- octave down (persistent)
R reset note duration, octave, volume
Vxx set volume
Uxxx set bpm
$x.../ set sample
012456789: play sample
to convert:
make all letters uppercase
replace other simple commands with their new counterparts
#* !: @R
organize all Z channels in order
turn each channel into a sample that immediately plays (like $0.../0)
at the top of the file, define samples for drums 12456789
in each channel sample, define drum 0 inside, at the top
source variables
A: Audio context
C: Command Character from V
D: character after C (or other temporary Data)
F: function that plays notes, also stores samples
G: Gain node
H: textarea Html element
I: Index into V
J: `indexOf`
L: note Length
M: Music text
N: semitone Note offset for octave changes
O: Oscillator
Q: numeric command id
S: Sample function
T: note Time
U: Bpm
Z: channel
-->
<!--
DATA:TEXT/HTML,<META NAME=VIEWPORT CONTENT=INITIAL-SCALE=1><CENTER><H1><A HREF=HTTP://NYCKI.NET/QRPLAY>QRPLAY 3S</A></H1><TEXTAREA ID=H STYLE=WIDTH:MIN(40EM,99%);HEIGHT:9LH>U023%0A$0%0A$4D*/$5E/$6C*/%0A$7-B+4F*-JBT+4F*/%0A$8C*5GJC*T5G/%0A$9T7XX.XT7XX.XT4F*/%0A+9QX%0AT8XX.XT8XX.XT5G%0A9QX-%0ATA+6E-JAT+6E- F*6AJF*T6A 6A%0A/%0A$1-%0A$4JB+F*BF*/%0A$5JC*G+C*-GTC*+C*/%0A$6-4SXTB+B-4SX/%0AI6.X JED*E-B+%0AI5X5X%0A6.X JD*EF*G%0ATA-A+JATE .F*T-F*+F*-F*%0A/%0AW0X10X10X</TEXTAREA><P><BUTTON ONCLICK='H.A=A=new AudioContext,F=(M=``,T=0,L,N,I=0,S=D=>D?S(D+(M[++I]==C)-(M[I]==`/`)):I)=>{for(;C=M[I++];D=M[I],Q>7?(Q-=9)?Q>9?L/=+C||2/3:Q>7?(D=D+M[++I,I++]|0)?Q>8?U=D+M[I++]:G=new GainNode(A,{gain:2**(D/5-11)}):0:L=~Q?1<<Q:N=4:F[D]=M.slice(++I,S(1)):~Q?(O=new OscillatorNode(A,{type:`square`,detune:100*(Q*2-(Q>3)+(D==`*`)-(D==`:`)-N-7)}),Q&&O.connect(G,G.connect(A.destination)),O.start(T),O.stop(T+=L/U*15/8)):C-3|C>`_`?F(F[C],T,L,N):N-=C+12|0)Q=`XCDEFGABR$JTSIQHWVU3.`.indexOf(C)},F(`RU137V30`+H.value)'>PLAY</BUTTON> <BUTTON ONCLICK=H.A.close()>STOP
-->
<META NAME=VIEWPORT CONTENT=INITIAL-SCALE=1>
<CENTER>
<H1><A HREF=HTTP://NYCKI.NET/QRPLAY>QRPLAY 3S</A></H1>
<TEXTAREA ID=H STYLE=WIDTH:MIN(40EM,99%);HEIGHT:9LH>U023
$0
$4D*/$5E/$6C*/
$7-B+4F*-JBT+4F*/
$8C*5GJC*T5G/
$9T7XX.XT7XX.XT4F*/
+9QX
T8XX.XT8XX.XT5G
9QX-
TA+6E-JAT+6E- F*6AJF*T6A 6A
/
$1-
$4JB+F*BF*/
$5JC*G+C*-GTC*+C*/
$6-4SXTB+B-4SX/
I6.X JED*E-B+
I5X5X
6.X JD*EF*G
TA-A+JATE .F*T-F*+F*-F*
/
W0X10X10X</TEXTAREA>
<P><BUTTON ONCLICK='
H.A=A=new AudioContext,
F=(M=``,T=0,L,N,I=0,S=D=>D?S(D+(M[++I]==C)-(M[I]==`/`)):I)=>{for(
;
C=M[I++];
D=M[I],
Q>7?
(Q-=9)?
Q>9?L/=+C||2/3: /* DECREASE Q! and multiply note duration (3.) */
Q>7?
(D=D+M[++I,I++]|0)? /* get two digits */
Q>8?U=D+M[I++]: /* set bpm (U) */
G=new GainNode(A,{gain:2**(D/5-11)}): /* set Volume */
0:
L=
~Q?1<<Q: /* set note duration (JTSIQHW) */
N=4: /* Reset */
F[D]=M.slice(++I,S(1)): /* set sample ($x.../) */
~Q?( /* play note or rest (XCDEFGAB) */
O=new OscillatorNode(A,{
type:`square`,
detune:100*(Q*2-(Q>3)+(D==`*`)-(D==`:`)-N-7) /* pitch with sharp/flat (*:) */
}),
Q&&O.connect(G,G.connect(A.destination)),
O.start(T),
O.stop(T+=L/U*15/8)
):
C-3|C>`_`? /* numbers, whitespace, lowercase letters, some symbols */
F(F[C],T,L,N): /* play sample */
N-=C+12|0 /* change octave or nop */
)Q=`XCDEFGABR$JTSIQHWVU3.`.indexOf(C)},
F(`RU137V30`+H.value)
'>PLAY</BUTTON> <BUTTON ONCLICK=H.A.close()>STOP