109 lines
3.7 KiB
HTML
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
|