System.Include(stdmsg.h)
System.MeasureShift(1);
ResetGM();
TrackSync;
TrackName={"メロディ風鈴改"}
Copyright={"森と泉"}
MetaText={"乱数を使って毎回違ったメロディを奏でます。下側タブに演奏中のMMLが出ます。"}
System.TimeBase=48
Int AA;Int A9;         //音番号、旧の音番号（o5cはn60です）
Int N;Int N9; Int NX; //コード、旧のコード、次コード、0 A7,1 Am,2 B7,3 C,4 C7,5 D7,6 Dm,7 E7,8 Em,9 F,10 Fm,11 G7
Int BB;                //1小節内何番目の音
Int CC;                //音長
Int CZ;                //旧音長
Int DD;                //何小節目
Int DD1;
Int EE; 
Int E9;               
Int GG;
Int GG1=100;            //前後の音の高さの差をチェックする回数。
Int Z=6;              //前後の音の高さの差を半音何個以内に制限。チェック回数を超えてしまったらそのまま鳴らす。
Int W;                //タイ率
Int X;                //ベロシティ
Int OO;               //オクターブ
Int OO9=5;            //旧オクターブ
Int SL=0;             //小節最後のSlur
Str PP;               //音符またはオクターブ付き音符
Str P9;               //前回の音符またはオクターブ付き音符
Array AR=({c},{c+},{d},{d+},{e},{f},{f+},{g},{g+},{a},{a+},{b})
Str MD;               //Melody
Str MC;               //ギターMML
Str MB;               //ベースMML
Str BR="
";                    //改行
Str MML;
Str Am={[8 'ace']};Str Dm={[8 'dfa']};Str Em={[8 'egb']};Str Fm={[8 'fg+c']};Str C={[8 'ceg']};
Str F={[8 'fac']};Str A7={[8 'ac+eg']};Str B7={[8 'bd+f+a']};Str C7={[8 'cega+']};
Str D7={[8 'df+ac']};Str E7={[8 'eg+bd']};Str G7={[8 'gbdf']};
Str A1={[4 a]};Str B1={[4 b]};Str C1={[4 c]};Str D1={[4 d]};Str E1={[4 e]};Str F1={[4 f]};Str G1={[4 g]};

MML={"System.Include(stdmsg.h)
System.MeasureShift(1);
ResetGM();
TrackSync;
TrackName={"メロディ風鈴改"}
Copyright={"森と泉"}
System.TimeBase=48"}+BR;

MML=MML+"Str Am={[8 'ace']};Str Dm={[8 'dfa']};Str Em={[8 'egb']};Str Fm={[8 'fg+c']};"+BR;
MML=MML+"Str C={[8 'ceg']};Str F={[8 'fac']};Str A7={[8 'ac+eg']};Str B7={[8 'bd+f+a']};"+BR;
MML=MML+"Str C7={[8 'cega+']};Str D7={[8 'df+ac']};Str E7={[8 'eg+bd']};Str G7={[8 'gbdf']};"+BR;
MML=MML+"Str A1={[4 a]};Str B1={[4 b]};Str C1={[4 c]};Str D1={[4 d]};"+BR;
MML=MML+"Str E1={[4 e]};Str F1={[4 f]};Str G1={[4 g]};"+BR;
Tempo=120
/*
TR=1 CH=1 @5 q98 V(100) P(64) o5 r1 l8 v100 TrackKey=6 
TR=2 CH=2 @33 q98 V(100) P(32) o3 r1 l4 v100 v.onNote(100,80,90,70) TrackKey=6 
TR=3 CH=3 @26 q33 V(50) P(96) o6 r1 l8 v80 v.onCycle(!8,80,60,80,80,60,80,80,80) TrackKey=6
TR=8 CH=10 l16 V(70) P(27) o3  l8 [4 n31 r] l16  
TR=9 CH=10 l16 V(70) P(27) o3 r1
TR=10 CH=10 l32 V(70) P(27) o3 r1*/
//TR=1

N9=1;A9=60;MD={};MC={};MB={};
   
FOR(DD=0; DD<100; DD++){               　　　 //100小節以内演奏する
IF(DD==0){N=3;}ELSE{N=NX;} //1小節目はC、2小節以降は次コード(NX)から始める
CC=RandomSelect(2,3,4,4,4,6,8,8,8,8,12,16) //出したい音符をいくつでも指定。多く出したい音符はダブらせて。
                               //3,6,12は3連2分、3連4分、3連8部音符です。
l(CC)
X=127-CC*3
v(X)                           //ベロシティ(2分音符はv121・・・16分音符はv79)
W=CC*3;                       //タイ率   (2分音符は6%  ・・・16分音符は48%)

IF(Random(2)=0&DD!=0){MD=MD+"&";SL=1}ELSE{SL=0}
IF(CZ!=CC){MD=MD+BR+"l"+CC+"v"+X;}ELSE{MD=MD+" | ";}

//TR=8 cr8.r4crcrr4 TR=9 [r4dr8.] TR=10 [16 f+r]
SWITCH(N){ 
CASE(0){MB=MB+" A1" MC=MC+" A7" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0} ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(49,52,55,57,61,64,67,69,73,76,79,81);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(6);}
CASE(1){MB=MB+" A1" MC=MC+" Am" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0}ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(48,52,57,60,64,69,72,76,81);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(0,3,6,8);}
CASE(2){MB=MB+" B1" MC=MC+" B7" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0} ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(51,54,57,59,63,66,69,71,75,78,81,83);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(7);}
CASE(3){MB=MB+" C1" MC=MC+" C" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0}ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(48,52,55,60,64,67,72,76,79);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(1,3,4,5,7,8,9,9);}
CASE(4){MB=MB+" C1" MC=MC+" C7" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0}ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(48,52,55,58,60,64,67,70,72,76,79,82);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(9);}
CASE(5){MB=MB+" D1" MC=MC+" D7" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0}ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(48,50,54,57,60,62,66,69,72,74,78,81);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(11);}
CASE(6){MB=MB+" D1" MC=MC+" Dm" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0}ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(50,53,57,62,65,69,74,77,81);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(1,2,7,8,9,11);}
CASE(7){MB=MB+" E1" MC=MC+" E7" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0}ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(50,52,56,59,62,64,68,71,74,76,80,83);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(1,3,11);}
CASE(8){MB=MB+" E1" MC=MC+" Em" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0}ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(52,55,59,64,67,71,76,79,83);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(1,3,6,9);}
CASE(9){MB=MB+" F1" MC=MC+" F" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0}ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(48,53,57,60,65,69,72,77,81);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(3,3,5,6,9,10,11,11);}
CASE(10){MB=MB+" F1" MC=MC+" Fm" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0}ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(48,53,56,60,65,68,72,77,80);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(3,6,9,11);}
CASE(11){MB=MB+" G1" MC=MC+" G7" FOR(BB=0; BB<CC; BB++){
        IF(SL=1){MD=MD+P9;SL=0}ELSE{FOR(GG=0; GG<GG1;GG++)        
        {AA = RandomSelect(50,53,55,59,62,65,67,71,74,77,79,8);IF((AA-A9)*(AA-A9)<=Z*Z){EXIT;}}
        IF(Random(100)<W&BB!=0){PP="^"}
        ELSE{OO=AA/12;EE=AA-OO*12;E9=EE;P9=AR(EE);IF(OO==OO9){PP=P9}ELSE{PP="o"+OO+P9}}
        A9=AA;MD=MD+PP;OO9=OO;}}NX=RandomSelect(3,3,3,3,3,7,7,7,9,9,9,11);}
DEFAULT{r1}}
CZ=CC;
IF(DD==24|DD==49|DD==74){MB=MB+BR;MC=MC+BR;}
IF(DD>60 & N==3 & N9==11){DD++;EXIT;}   //60小節以上でG7→Cとなったら終了
N9=N;}
//TR=8 cr8.r4crcrr4 TR=9 [r4dr8.] TR=10 [16 f+r]
DD1=DD+1
MML=MML+"Tempo=120"+BR
MML=MML+"TR=1 CH=1 @5 q98 V(100) P(64) o5 r1 l8 v100 TrackKey=6"
MML=MML+MD+BR
MML=MML+"TR=2 CH=2 @33 q98 V(100) P(32) o3 r1 l4 v100 v.onNote(100,80,90,70) TrackKey=6"+BR
MML=MML+MB+BR
MML=MML+"TR=3 CH=3 @26 q33 V(40) P(96) o6 r1 l8 v80 v.onCycle(!8,80,60,80,80,60,80,80,80) TrackKey=6"+BR
MML=MML+MC+BR
MML=MML+"TR=8 CH=10 l16 V(70) P(27) o3  l8 [4 n31 r] l16 ["+DD1+" cr8.r4crcrr4]"+BR
MML=MML+"TR=9 CH=10 l16 V(70) P(27) o3 r1 ["+DD1+" [2 r4dr8.]]"+BR
MML=MML+"TR=10 CH=10 l32 V(70) P(27) o3 r1 ["+DD1+"[16 f+r]]"
Print(MML);Print(DD)
MML;
/*
メロディ風鈴改は乱数を使って毎回違ったメロディを奏でます。
今回、演奏中のMMLが下側タブに出るようにしました。

メロディ風鈴の設定をいろいろ変えてみよう！(MML出力の方も同様に変えて下さい)

■前後2音の差を半音いくつ以内に抑えたいか
Int Z=6;
↓
Int Z=7;など

■音長の選択肢(2,3,4,6,8,12,16)
それぞれ2分音符、3連2分音符、4分音符、3連4分音符、8分音符、3連8分音符、16分音符です。
CC=RandomSelect(2,3,4,4,4,6,8,8,8,8,12,16)
↓
CC=RandomSelect(2,3,4,6,8,8,8,8,8,12,16)
や
CC=RandomSelect(4,4,6,8,8,16)
や
CC=RandomSelect(3,6,12)など
多く使いたい音符はだぶらせ、あまり使いたくない音符は減らす。

■次コードの選択肢(0〜11)
それぞれ0 A7,1 Am,2 B7,3 C,4 C7,5 D7,6 Dm,7 E7,8 Em,9 F,10 Fm,11 G7です。

NX=RandomSelect(1,3,4,5,7,8,9,9);
↓
NX=RandomSelect(1,1,3,4,4,5,7,8,9);など
多く使いたいコードはだぶらせ、あまり使いたくないコードは減らす。
次コードには適するものを選んで下さい。
次コードがない、無限ループ、などないようして下さい

■ベロシティ(0〜127)

X=127-CC*3;　     2分音符はv121・・・16分音符はv79
↓
X=127-CC*2;　　　 2分音符はv123・・・16分音符はv95
や
X=91+CC*2;など    2分音符はv95・・・16分音符はv123

■タイ率(0〜100)
W=CC*3;  　　　　 2分音符は6%・・・16分音符は48%   
↓
W=CC*2;　　     　2分音符は4%・・・16分音符は32%   
↓
W=CC;など 　    　2分音符は2%・・・16分音符は16%
*/