///////////////////////////////////////////////////////////////////////////////
// title:        "rmelody.h" ver 0.26
// description:  単音をランダムな音量とタイミングで演奏するインクルードファイル(2015/11/24)
// keywords:     SAKURA Function     by ななこっち★ @nanakochi123456
// HP:           http://nano.daiba.cx/
///////////////////////////////////////////////////////////////////////////////
// rmelody.h メロディー等をランダムなタイミングで演奏する
///////////////////////////////////////////////////////////////////////////////
// Function RMDINIT(rmin, rmax, vmin, vmax)
// 休符乱数値の最小値、最大値、最小、最大音量設定する。両方0にすると、同一タイミングで演奏します。
// 
// Function RMDR(rmin, rmax)
// 休符乱数値の最小値、最大値の設定のみする
//
// Function RNDV(rmin, rmax)
// 音量乱数値の最小値、最大値の設定のみする。
// 同一の値を設定を両方に行うと、固定音量となる。
// rmaxを省略すると、rmin、rmax共に加算、または減算を行なう
//
// rmin, rmaxは与える休符値、vmin, vmaxは与える音量値
// Function RMD(mml)
// ランダムに演奏したいメロディーのMMLを入力する
///////////////////////////////////////////////////////////////////////////////
// Example
// Include(rchord.h)
// RMDINIT(53,513,90,110)
// l4 RMD(ceg)
// RMDV(5)
// l8 RMD(<b>fg)
// RMDV(-5)
// l8 RMD(ceg)
///////////////////////////////////////////////////////////////////////////////
// テストする場合、コメントアウトを消してください。
//Int TEST=1
///////////////////////////////////////////////////////////////////////////////

Int RMD_RMIN=192
Int RMD_RMAX=768
Int RMD_VMIN=95
Int RMD_VMAX=100
Int RMD_CRESC=0
Int RMD_ENABLE=1

Function RMDENABLE(Int FLG) {
	RMD_ENABLE=FLG
}

Function RMDINIT(Int RMIN, Int RMAX, Int VMIN, Int VMAX) {
	RMD_RMIN=RMIN
	RMD_RMAX=RMAX
	RMD_VMIN=VMIN
	RMD_VMAX=VMAX
	RMD_CRESC=0
}

Function RMDCresc(Str STEP) {
	RMD_CRESC=STEP
}

Function RMDR(Int RMIN, Int RMAX) {
	RMD_RMIN=RMIN
	RMD_RMAX=RMAX
}

Function RMDV(Int VMIN, Int VMAX) {
	IF(VMAX=0) {
		Int TMPMIN=RMD_VMIN
		Int TMPMAX=RMD_VMAX
		TMPMIN=TMPMIN+VMIN
		TMPMAX=TMPMAX+VMIN
		IF(TMPMIN < 0) {
			TMPMIN=0
		}
		IF(TMPMIN > 127) {
			TMPMAX=127
		}
		IF(TMPMAX < 0) {
			TMPMAX=0
		}
		IF(TMPMAX > 127) {
			TMPMAX=127
		}
		RMD_VMIN=TMPMIN
		RMD_VMAX=TMPMAX
	} ELSE {
		RMD_VMIN=VMIN
		RMD_VMAX=VMAX
	}
}

Function RMD(Str MML) {
	Str BUF=""
	Str FIRST=""
	Str ML=""
	Str M
	Str R
	Str VL
	Str RRMML
	Str RMML
	Str FM=""
	Int C=0
	Str LenStr
	Int TOKEN=0
	Int TO=0
	BUF=""
	R=""
	IF(RMD_ENABLE=0) {
		BUF=MML
	} ELSE {
		For(Int i=1; MID(MML, i, 1)!=""; i++) {
			M=MID(MML, i, 1)
	//		Print("Start Str="+M)
			IF((ASC(M)>=48 && ASC(M)<=57) || M="r"||M="."||M="^") {
				IF(TO>=1) {
					LenStr=LenStr+M
	//Print("LenADD:"+LenStr)
				}
				ML=ML+M
			} ELSE {
				IF((ASC(M)>=97 && ASC(M)<=103)) {
	//Print("Note:"+M)
					TOKEN++
					TO=1
					FM=RRMML+VL+ML+RMML
					IF(TOKEN>1) {
						C++
						IF(FM!="") {
							BUF=BUF+"Sub{"+FM+"}r"+LenStr
						}
	//					TO=0
						TOKEN=0
					} ELSE {
						BUF=BUF+ML
					}
					LenStr=""
					ML=M
					IF(RMD_RMAX>0) {
						R=Random(RMD_RMIN, RMD_RMAX)
						IF(Random(0,10)<5) {
							RRMML="r-"+R
							RMML="r"+R
						} ELSE {
							RRMML="r"+R
							RMML="r-"+R
						}
					}
					VL="v"+Random(RMD_VMIN, RMD_VMAX)
					RMDV(RMD_CRESC,0)
				} ELSE {
	//Print("Other:"+M)
					ML=ML+M
					IF(TO=1) {
						TO=2
					}
					IF((ASC(M)>=97 && ASC(M)<=103) || M="r" || (ASC(M)>=48 && ASC(M)<=57) || M="." ||M="^"|| M="-"||M="#") {
					} ELSE {
						TO=0
					}
				}
			}
			IF(DEBUG=1||TEST=1) {
				Print("Token "+ TOKEN + " Count "+ C + " Str="+M+" ML="+ML+" Len="+LenStr+" TO="+TO+" BUF="+BUF)
			}
		}
		FM=RRMML+VL+ML+RMML
		IF(FM!="") {
			BUF=BUF+"Sub{"+FM+"}r"+LenStr
		}

		IF(DEBUG=1 || TEST=1) {
			Print(BUF)
		}
	}
	BUF
}

IF(TEST=1) {
	#basemml={
		l8
		[4 RMD(cdefgfed)  RMDV(-5)]
		RMDV(15)
		RMD(c4g4f4d4)
	}
	TR(1)
		Tempo 120
		o6

		// 下手過ぎあひゃひゃ
		RMDINIT(32,40,70,110)
		#basemml

		// まぁまぁ
		RMDINIT(96,425,70,110)
		#basemml

		// 上手
		RMDINIT(193,765,100,110)
		#basemml

		// DTM
		RMDINIT(0,0,110,110)
		#basemml

	TR(2)
		Tempo 120
		o4

		// 下手過ぎあひゃひゃ
		RMDINIT(32,40,70,110)
		#basemml

		// まぁまぁ
		RMDINIT(96,425,70,110)
		#basemml

		// 上手
		RMDINIT(193,765,100,110)
		#basemml

		// DTM
		RMDINIT(0,0,110,110)
		#basemml

	TR(10)
		$M{n(MetronomeBell),}
		$m{n(MetronomeClick),}
		[40
			Rythm{M4m4m4m4}
		]

}
