1983年12月25日日曜日

[言語][BASIC] OMP(Ochame's Music Plug-in)~全ポケコン共通音階演奏ソフト

OMP使用例



[言語][BASIC] OMP(Ochame's Music Plug-in)~全ポケコン共通音階演奏ソフト
ポケコンゲームだって音楽くらい欲しい~~!!
全ポケコン共通音階演奏ソフト「OMP」
[Quick Link]使い方/リスト/MML2OMP
■「OMP」が必要な理由
ポケコンゲームにおいて「フォント書き換え」や「OPAS」などによりオールBASICでもグラフィックを重視したゲームを作ることが可能になりましたが、完全に遅れを取っているのは音楽の方です。
確かに「PLAY3」(Ryuさん作、PJ93年11月号掲載)などの高性能なマシン語プログラムによりポケコンとしては高度な和音演奏が出来るようにはなりましたが、実際のところ「PLAY3」を使ったゲームを不特定多数の人に配る訳(雑誌等に投稿も含む)にはいかないのです。
これは以前OPASのところでも書いていますが、ポケコンのゲームを配布する場合、可能な限り単独で実行できるプログラムが望ましいのです。というのもそのゲームをプレイする人、全員の手元にPLAY3のプログラムがあるとは限らないからです。しかも、PLAY3があることを前提にしたゲームの場合、そのゲームをプレイすらできないという事態にもなってしまいます。だから、PLAY3が必須のゲームで、不特定多数の人に配るのであれば、PLAY3のプログラムも自作のプログラムに組み込まなくてはなりません。
著作権の問題もありますが、仮に「PLAY3」のプログラムリストを自作のオールBASICのプログラムに組み込むとします。ところが、「PLAY3」だけで、4Kバイト以上あるのです。音を出すだけでリストが4Kバイトも大きくなっては、とても気軽に自作のゲームに組み込むことなどできませんね。まあ、プログラム本体が数10Kバイトという超大作なら「たかが4Kバイト」なのですが、ほんの数Kバイトのゲームにとってそれは致命的な大きさになります。
そういうことで、BEEPを複数並べていって音階演奏させたり、簡易的な音階演奏ルーチンを作りそれにり音階演奏で行っている人もいます。これにも実は問題があるのです。
BEEPを並べる方法ではデータを作る効率も悪いし、メモリ消費量が非常に大きく(別にそんなに音を鳴らさないのならばさほどではないですが)なってしまいます。また、他人が作ったゲーム中で使用している簡易的な音階演奏プログラムを自作ゲームで使おう思っても、気軽にそれを使うわけにはいかないのです。それは、著作権の問題もありますが、それ以前に、他人の簡易音階演奏プログラムの場合は仕様を独自で分析する能力が必要な上、分析したのはいいけど自分に満足のいくものであるという保証はあるとは限らないからです。そもそも、それだけの能力のある人ならすでに独自の簡易音階演奏プログラムを作っていることでしょう(笑)
そこで、私が考案したのが今回のプログラム「OMP」です。完全に使用フリーとし、自作のプログラムにどんどん使っても構いません。しかも、ほんの200バイト少々なので、数Kバイトのプログラムにも十分組み込み可能なのです。
OMP(Ochame's Music Plug-in)
このプログラムは先程も書いたように自作のゲームなどに組み込んでもらうことを前提(名称の「Plug-in」というのを見ても分かると思う)に作られています。したがって、機能面では必要最低限のもののみ搭載で、MMLも使いやすいものとは言えないかもしれません。しかし、リストパフォーマンス(リストの長さと内容との兼合い・・・NAKさん提唱)が高く、曲のデータの大きさも小さい上に、処理の高速化を駆使していますので単音ながらBASICでは最高に近い音質になっていると思います。
なお、今回はE500シリーズ用、G800シリーズ用、そして、ザウルス(DB-Z含)シリーズ用の3本を同時に発表します。データ形式は3本とも同一のためE500用に作った曲をそのままG800シリーズで鳴らすことが出来ます。
このメリットは自分が作った曲を1人でも多くの人に聞いて(使って)もらえることだけでなく、今まで難しかったEシリーズ-Gシリーズ間のゲームの移植の際の音楽の問題も容易になるのです。
つまり、BEEP音階表を見ながら手動で変換していかなくてもOMPのシステムプログラムを対応機種のものに変更するだけでその曲を使ったゲームを動作させることができるのです(もちろん音楽以外の手直しは必要です)
■使用方法
変数M$に曲のデータを入れ、「GOSUB*OMP」とするだけです。
音程をリアルタイム演算で求めていますので、事前に音程表などを配列変数に格納したりという面倒なことは一切不要です。
《注》G800シリーズ用を使用する人へ
Gシリーズ用に関しては以下のOMPのプログラムを実行前にプログラムのどこかで
DIMM$(0)*250
を実行しておく必要があります。
(別に「*250」でなくてもいいですが曲のデータが十分入る程の大きめの配列変数を確保する必要があります)
(例)
10 DIM M$(0)*250
20 M$(0)="$9:1ACE":GOSUB *OMP
30 END
また、説明中の「M$」はすべて「M$(0)」と置き換えて考えてください。
《曲のデータ作成について》
基本的に「音符の長さ・音程」というようにデータを並べていきます。
音符の長さについて
音符の長さは「1」が一番短く「2」が2倍の長さ、・・・「9」が9倍の長さとなります。詳しく言うと、アスキーコード49~64のものが使えるのです。つまり、「音の長さ=アスキーコード-48」となります。したがって、「@」(アスキーコード64)では16倍になります。
なお、1回指定すれば次回までその長さが維持されます。
(注)必ずデータの一番最初に長さを入れておいてください。
音程について
音程指定は少し一般的なものと異なります。
「A」が「低いド」になり、「Bが低い#ド」というように半音上がるごとにアスキーコードが1つずつ大きくなっていきます。
つまり、以下の通りです。
「A」は「低いド」で「M」が「普通のド」で「Y」が「高いド」になります。「Z」以降もBEEPが出せるまでの高さの音を出すことが可能です(BEEP音階表参照)。
なお、休符は「*」です。
例「8A」・・・低いドを8の長さ鳴らす
例「7*」・・・7の長さ休む
「オクターブ」とか「#(シャープ)」とか「CDEがドレミに対応」とかいった音楽の基礎知識がない人でも音の高さを感覚的に指定(ちょっと音の高さを変えたいという場合にアスキーコードを1つずつ変化させればよい)ができるために一般的なデータ形式よりもかえって初心者には使いやすいかもしれません。
テンポについて
テンポ1で長さ1の音符を1秒間鳴らせます。
テンポと曲の速さは(ほぼ)比例します。つまり、テンポが2倍になったら曲の速度は約2倍になります。
一般的な楽譜をこのOMPのテンポに直す場合、長さ1の音符が16分音符ならば、15で割った値(元の曲がテンポ120の場合OMPではテンポ8)になります(およその目安)。なお、小数によるテンポ指定も可能です。
例$15:4MOQテンポ15で「ドレミ」と鳴らす
例$7.65:1MOQテンポ7.65で「ドレミ」と鳴らす
(テンポは「$」と「:」で囲んでください)
なお、テンポ指定は曲の中で何回も変更可能ですが、処理に少し時間がかかります(一瞬、間ができる程度ですが)ので、なるべくデータの先頭のみに使用する方がよいでしょう。また、テンポのみの単独指定も出来るのでゲーム中のすべての曲のテンポが同じ場合
M$="$20":GOSUB *OMP
としてテンポのみ先に登録しておくとデータ1つ1つにテンポ指定をする必要がなく便利です。
(テンポの単独指定の場合はデータの最後の「:」は省略可能です。)
プログラム内で最初にOMPを使用する場合は必ず、テンポ指定をしてください。あとは、次の指定まで維持されます。
(注)テンポ指定のあとは必ず音符の長さの指定を行ってください(テンポの単独指定は除く)。
また、OMPは特殊なデータ構造のため少し長めのデータだとどこがどの音符に対応しているのか分かりづらいので、「/(スラッシュ)」や「スペース」などを入れてデータを見やすく区切ることができるようになっています。
1小節こと、音符10個ごとなど適当に使ってください(笑)
(注)区切りを入れると若干処理が遅くなります。
例8ABCDE/FGHIJ・・・「/」を入れた場合
例8ABCDE FGHIJ・・・スペースを入れた場合
アスキーコードが48より小さいものならば何でも使えます。数種類使い分けてもよいでしょう(ただし、将来OMPの命令が拡張したときのために「/」「スペース」以外はなるべく使わないようにしてください。)
これで、MMLが特殊であり視認性に乏しいということが少しはカバー出来ると思います(笑)。
実を言うと、もう少々プログラムサイズが大きくなってもよいのならば「ドレミ」を「CDE」と表記できる一般的なMMLに近いものにすることが可能になります。しかし、それをやらなかったのには理由があるのです。
まず、処理速度の問題です。今回のOMPは私の持つテクニックを駆使して究極の処理速度を実現し、音質もBASICながらそれなりに満足できるものとなっていますが、前述のようにすると処理速度が大幅にダウンしてしまい音質が落ちるために実用に耐えられないと判断したからです。これを阻止するためには現在のリアルタイムで音程を演算する方法ではなく予め音階データを配列変数などに格納する方法をとれば問題のないことですが、そうなるとプログラムサイズが大きくなり、使い勝手も大幅に下がって(OMPは事前に必要な処理がいらないお手軽設計)しまいます。
あと、「#」や「オクターブ」の処理の分だけ演奏する曲のデータサイズが大きくなってしまいます。そうなると「出来るだけ手軽でコンパクト」というOMPの基本理念に反してしまいます。
《OMPで作った曲を発表しよう》
この「OMP」を使った曲が出来たら発表してみませんか。なるべくオリジナルの曲がのぞましいですが、市販の曲をOMP用にコンバートしたものでも構いません。また、ゲームに使えそうなちょっとした音楽(ゲーム開始の効果音、クリアの効果音など)も募集します。
曲を投稿する場合、「おちゃめ~る」に投稿するのならこちらへ件名「おちゃめ~るサウンド」でお願いします。HP上に投稿するのであれば何でも質問箱へお願いします。
投稿する場合、曲名(市販の曲の場合アーティスト名も明記、自作の場合は自分で曲名を付けて「自作」と明記)をお願いします。ゲームミュージック等で曲名が良く分からない場合はゲーム名とその曲が使われている場面(「オープニングの曲」「ステージ1の曲」など)を書いて戴ければOKです。要は自作以外の場合は出典元が明らかになっていればいいわけです。 効果音の場合は「何に使えそう(クリアの効果音など)」とか「どんな感じの曲(明るい感じ)」とか書いて戴けると助かります。
ある程度投稿がたまったら「フリーの効果音集」としてこのおちゃめくらぶ上で発表します。それにより、「ゲームは作りたいけど音楽が作れないから・・・」と悩んでいる人の助けになるはずです。
《MML2OMP》
HiNaさんが視認性のよいMMLからOMP用のデータへ変換出来るプログラムを作って下さいました!
expand
http://www.vector.co.jp/soft/win95/art/se215165.html
皆さんぜひ使ってみてください!
いいものができたらぜひ投稿してください!!
《その他いろいろ》
演奏する音の周波数の計算のところはリアルタイム演算としては理論上最高速のアルゴリズムが採用されています。
X=6.13*TEN(0.02508*Z)
これで、出す音の周波数が計算できるのです。
具体的な解説についてはOMP徹底解説を読んでください。
なお、PC-1600Kをお持ちの人はわずかな改良でOMPを使用することができます(速度的にはかなリギリギリでしょうが)。PC-1500/01やPC-1360/Kの人もわずかな改良で済みますが現状のリアルタイム方式では全く処理がついて行かないと思いますので、音階データを配列変数に入れておく必要があるでしょう。これらの機種をお持ちの方は専用のOMPを作成しますのでご連絡ください。
また、カシオのポケコンをお持ちの人は何等かの形(マシン語プログラム等)で音の高さを変えることが可能ならばOMPを作成することができます。
ちなみに「OMP」は「オー・エム・ピー」でもいいですが親しみを込めて「オンプちゃん」(某魔法少女とは関係はありません(笑))と呼んでやってください(笑)
《プログラムリスト》
以下のプログラムの行番号は皆さんが自分で作ったプログラムに合わせて変えても構いません。
また、OMPでは変数T、X、Y、Zを使用していますので、この変数名を使ったプログラムでは正常に動作しません。したがって、皆さんのプログラムに応じてOMPで使用している変数名を変更しても構いません。ただ、M$だけはなるべく変えないようにお願いします。
E500シリーズ用
100 *OMP FOR I=&1TO LEN M$:Z=ASC MID$ (M$,I,1):IF Z>64LET X=6.13*TEN (0.02508*Z):BEEP 1,64000/X-22,X*Y/T ELSE IF Z>47LET Y=Z-48ELSE IF Z=36LET T=VAL RIGHT$ (M$,LEN M$-I)ELSE IF Z=42 FOR J=&1TO 730*Y/T+20:NEXT
110 NEXT :RETURN
G800シリーズ用
(注)圧電ブザーを自作で取り付けないと音は出ません。
また、G850では処理速度の違いにより130行の「535*Y/T」を「1111*Y/T」に変更してください。
100 *OMP FOR I=1 TO LEN M$(0):Z=ASC MID$ (M$(0),I,1):IF Z>64 LET X=6.13*TEN (0.02508*Z):BEEP 1,59091/X-7,X*Y/T:NEXT :RETURN
110 IF Z>47 LET Y=Z-48:NEXT :RETURN
120 IF Z=36 LET T=VAL RIGHT$ (M$(0),LEN M$(0)-I)
130 IF Z=42 FOR J=1 TO 535*Y/T+20:NEXT
140 NEXT :RETURN
ザウルス(ICカード使用可能機種)/PV-F1/DB-Z用
(注)PA-9C3(ハイパー関数プログラムカード)が必要です。
100 *OMP FOR I=&1TO LEN M$:Z=ASC MID$ (M$,I,1):IF Z>64 OR Z=42LET X=6.13*TEN (0.02508*Z),W=-73153*Y/T:BEEP 1,-(Z<>42)*36576/X,(Z<>42)*W,(Z=42)*W ELSE IF Z>47 LET Y=Z-48 ELSE IF Z=36LET T=VAL RIGHT$ (M$,LEN M$-I)
110 NEXT :RETURN
《サンプルデータ》
クレメンティ作曲ソナチネ作品36-1(序盤のみ)
$30:4M2QMH*MH*/4M2QMH*T*/RQOMLMLM/OMLJ4H*/M2QMH*H*/4Q2TQM*QM/OLMJLHJG/HJLMOQST/4J2V*V*V*/LMOQSTVX/4M2Y*Y*Y*/OTX[YXVT/SQTSVTRQ/QOMLOMLJ/8H*
やっぱり、ザウルスが一番演算速度が速い(E500の2倍速!)ので音質もいいです。自分の中では完璧と思っていたE500用もザウルス用のあと聞いてみたら見劣りしてしまいます(笑)。
最後にこのG800シリーズのテストプレイに協力下さったAijawaさん、OGAさん、ショウさん、NO1さんどうもありがとうございました。
      
おちゃめくらぶ ポケコン研究部
http://ww5.tiki.ne.jp/~ochame/E500/POCKECOM.HTM
http://ww5.tiki.ne.jp/~ochame/E500/POCKE1.HTM
http://ww5.tiki.ne.jp/~ochame/E500/TECH/OMP.HTM












 

0 件のコメント:

コメントを投稿