113 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
	
		
			4.5 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
 | |
| -->
 | |
| 
 | |
| <!-- with song
 | |
| 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
 | |
| -->
 | |
| 
 | |
| <!-- without song
 | |
| 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></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
 |