プチコンMML with OSP2

【mkII 専用】 2012年3月25日 公開

これはMML演奏プログラム「プチコンMML」「棒歌ロイドOSP2」の機能を追加したものです。プチコンMMLでの演奏に合わせて自動的に歌ってくれます。

CLS
M$="T120L999>CE<G4E4E2>FG<F4D4D2>CE<C4D4E4F4>G<G4G4G2
K$="チョ:ウ:チョ:チョ:ウ:チョ:ナ:ノ:ハ:ニ:ト:マ:レ:
GOSUB @MML
M$="T120L999>CE<G4E4E4E4>FG<F4D4D4D4>CE<C4E4G4G4>G<E4E4E2
K$="ナ:ノ:ハ:ニ:ア:キ:タ:ラ:サ:ク:ラ:ニ:ト:マ:レ:
GOSUB @MML
END

@MML
Q=LEN (M$)-1:M=0:N=22:V=127:F=1
A$="09110002040507":T=120:O=2
VSYNC 0:X=0:FOR I=0TO Q
A=ASC(MID$ (M$,I,1))
M=M+(A==43)+(A==35)-(A==45)
O=O+(A==60)-(A==62):A=A-65
IF A>=0 AND A<7 THEN GOSUB @S
IF A==-19THEN F=1.5
IF A==-1 THEN GOSUB @N
IF A==11 THEN GOSUB @L
IF A==14 THEN GOSUB @O
IF A==17 THEN GOSUB @R
IF A==19 THEN GOSUB @T
IF A==21 THEN GOSUB @V
NEXT:RETURN
@S
GOSUB @P
B=VAL (MID$ (A$,A*2,2))
R=L:IF P THEN R=P
Z=O*12+M+B-24:M=0
Y=R/F:IF Y<999THEN GOSUB @OSP
@BP
BEEP N,341.3*Z,V
GOTO @W
@L
GOSUB @P:L=P:RETURN
RETURN
@N
GOSUB @P:N=P:RETURN
@O
GOSUB @P:O=P:RETURN
@R
GOSUB @P
R=L:IF P THEN R=P
GOTO @W
@T
GOSUB @P:T=P:RETURN
@V
GOSUB @P:V=P:RETURN
@P
P=VAL (MID$ (M$,I+1,Q-I))
RETURN
@W
VSYNC 14400/R/T*F:F=1:RETURN

@OSP
K=LEN(K$)
W=INSTR(RIGHT$(K$,K-X),":")
N$=MID$(K$,X,W)+"-"*(16/Y)
E=185000/T/Y/(LEN(N$)-4/Y)
T$="@T"+STR$(0OR E)+"@E16@N"
TALK T$+STR$(Z*58+1447)+N$
?N$:X=X+W+1:RETURN

QRコード(ファイル名:OCHAMMLS)


《 使用方法 》

変数M$にMMLデータ、変数K$に歌詞データを入れてGOSUB @MMLとすれば音階演奏に合わせてTALK命令を使って自動的に歌います。OSPによって1文字ごとにピッチや速度の設定やタイミングを合わすためのウエイト調整などを行う必要が無くなるため誰でも簡単に音符に合わせて歌わせることができます。
また、リスト中にあるBEEPを削除するか、コメントアウトすればBGMPLAYで演奏する曲に合わせて歌わせることもできます。
MMLの文法は「プチコンMML」、歌詞データの構成は「棒歌ロイドOSP2」を見てください。
データ作成例として童謡「ちょうちょ」の前半部分のMMLデータと歌詞データをリスト中の冒頭部分に記しているのでデータ作成の参考にしてみてください。(簡易和音演奏機能が使われています)

《 OSP2の組み込み方 》

 本プログラムはすでにOSP2が組み込んだ状態になっています。
 非常に簡単なことですが、皆さんの手元にある使い慣れたMML演奏プログラムでも組み込むことが誰でもできるように詳細を書いておきます。

 組み込み方は非常に簡単でBEEP命令で作られたMML演奏プログラムにおいてBEEPで音を鳴らす代わりにGOSUB @OSPとするだけです。しかし、OSP2を利用するには下記の4つの変数の内容をOSP2に受け渡す必要があります。

変数T(テンポ)その曲のテンポ
変数X(歌詞データの位置)その歌詞データの最初から歌う場合はOSPを呼び出す前にX=0<とする
変数Y(音長)一般的なMMLの音長指定に準ずる
変数Z(音高)「低いド(C3)が0」で半音上がるごとに1大きくなる。

 テンポに関してはプチコンMMLでは一般的なテンポに準じており、さらに変数名Tをそのまま使っているため何の変更もありません。これがテンポの長さが変数名TMPに格納されているならばT=TMPとする必要があります。(もしくは、OSP側の変数名をTからTMPに書き換えても良い)
 歌詞データに関しては呼び出すごとにデータの先頭から歌うためプチコンMMLの実行して初期設定の段階でX=0を入れています。
 音長に関しては本MMLでは変数Rに格納されており、付点の有無は変数Fに格納されています。(付点ありF=1.5、付点無しF=1)
付点処理が無ければY=Rとなるのですが、付点がある場合はその分だけ音長が変わるためY=R/Fとする必要があります。(これが付点ありF=1、付点無しF=0というプログラムならば、Y=R/(F/2+1)となる)
 音高に関してはBEEP命令で演奏する場合は低いドが第2引数が0になる関係上、音高指定に使っている「半音いくつ分か」という値をそのまま使用することができます。当MMLではOSPと同じ変数Zにその値を格納しているため変更する必要はありませんでした。

 以上の変更を行いBEEPで音を鳴らす時に>GOSUB @OSPを入れれば組み込みは完了・・・と言いたいところですが、OSPと組み込むMML演奏プログラムで同じ変数が使われてないか注意する必要があります。
OSPでは上記4つの変数以外ではK、N、W、N$、T$、X$が使用されています。
 もしもこれらとダブって使用している場合は、MML側、もしくはOSP側の変数名を変える必要があります。今回はプチコンMMLでは変数Nを使用していたのでOSP側を未使用の変数Eに変えています。逐次チェックするのが大変ならばOSP側の変数名を他のプログラムでは使用しないような変数名に変えるといいかもしれません。(プチコンのBASICにはローカル変数の概念がないのですが、変数名の最初にアンダースコア(_)を付けてやるなどの命名規則の徹底化によって様々な場所から持ってきたサブルーチンをAPPENDで繋ぎ合わせた場合も変数名が重なる心配をすることが減少すると思います)

これで無事完了です。
 「プチコンMML」では複数トラックでの演奏はサポートしていないとはいえ、簡易和音演奏機能による和音演奏が可能になっています。簡易和音演奏は同じトラック内で音長0の音を連続して鳴らすことで単トラックながら和音演奏を行っているためこれをOSPを組み込んだ状態で実行するとすべての音に対して発声することりなってしまいます。
 TALK命令は重ね合わせができないので音長0の場合は発声しないので問題はなさそうですが、無声状態で歌詞データのみ読み進めてしまうた発音するデータが異なるものになってしまいます。そのため、事実上簡易和音演奏機能が使えなくなります。これが複数トラックでの和音演奏が可能なMML演奏プログラムならば1つのトラックをOSPに割り当てれば簡単に解決できます。
 では、簡易和音演奏機能はOSPを組み込んだ状態では使用できないかというとそういうわけではありません。要するに音長0(指定値999)の音符は発声しないように判定するだけで良いのです。IF Y<999THEN GOSUB @OSPというIF文によって音長0以外(999未満)はOSPを実行するようにしたためプチコンMMLの機能の1つである簡易音階演奏機能は使えるようになりました。

 上記のプログラムリストはOSP組み込みの際に変更した部分に関しては赤字になっています。


RETURN/RETURN *MAIN

inserted by FC2 system