part 1 高速化処理について
(1)低い「ラ」の音が440Hzの高さである。
(2)1オクターブ高くなるごとに周波数が2倍になる。
1オクターブと言うのは低い「ラ」から中の「ラ」の間の差のことです。
また、1オクターブと言うのはピアノの鍵盤12個分になります。つまり、「半音12個分で周波数が2倍になる」ということです。
OMPはこの半音の計算がすごく簡単に出来るようなデータになっています。半音高くなるごとにアスキーコードが1大きくなるだけなのです。
今、「低いド」を「A」(アスキーコード65)になるように設定しています。だから、440Hzの「低いラ」は「J」(アスキーコード74)になります(BEEP音階表参照)。
つまり、アスキーコードから周波数を求める式は次のようになります。
X=440*2^((Z-74)/12) ・・・(1) (周波数をX、アスキーコードをZとする) |
では、式(1)を次のように変形します。
X=440*2^(Z/12-74/12) =440*2^(Z/12)/2^(74/12) ・・・(2) |
X=6.124928697*2^(Z/12) ・・・(3) |
X=6.125*2^(Z/12) ・・・(4) |
ワンポイントテクニックに書かれている「べき乗演算の高速化」を使えばまだ速くできます。
X=6.125*TEN (0.02508*Z) ・・・(5) |
X=6.13*TEN (0.02508*Z) ・・・(6) |
この周波数をBEEPで鳴らすための音の高さ(8ビット整数値)に変換するのですが、これにも公式があります。
E500シリーズ 高さ=(256000/周波数-90)/4 G800シリーズ 高さ=(1300000/周波数-166)/22 |
part2 OMPをBGMとして利用する
要はこんな感じです。
100 *MAIN ・ ・ ・ 200 M$=MID$ (A$,N,1):GOSUB *OMP 210 GOTO *MAIN ・ ・ ・ 500 *OMP 〜(以下省略) |
《バックグランドOMP プログラムリスト》
E500シリーズ用
100 *BOMP Z=ASC B$: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$ (B$,LEN B$-1)ELSE IF Z=42 FOR J=&1TO 730*Y/T+20:NEXT 110 RETURN |
100 *BOMP Z=ASC B$:IF Z>64 LET X=6.13*TEN (0.02508*Z):BEEP 1,59091/X-7,X*Y/T:RETURN 110 IF Z>47 LET Y=Z-48:RETURN 120 IF Z=36 LET T=VAL RIGHT$ (B$,LEN B$-1) 130 IF Z=42 FOR J=1 TO 535*Y/T+20:NEXT 140 RETURN |
そういう人は次のリストを入力(行番号は適当でいいです)してみてください。
*OMP FOR I=1 LEN M$:B$=MID$ (M$,I,1):GOSUB *BOMP:NEXT :RETURN (注)G800シリーズの人はM$をM$(0)に変更してください。 |
(テンポ指定の例) B$="$15":GOSUB *BOMP (注)面倒ならば直接変数Tにテンポを入れてもいいです(あまり推奨はしませんが)。 |
このバックグランドOMPを使用する方法が分からない人もいることと思いますので、これを利用したBGM演奏サブルーチンのサンプルを用意しましたので、皆さんのプログラム内でご自由に使用ください。
《BGMプログラム(バックグランドOMP必須)》
(注)行番号は適当につけてください
*BGM B$=MID$ (M$,P,1):GOSUB *BOMP:Q=LEN M$:P=P+1+(P=Q)*(Q-1):RETURN |
まず、BGMを鳴らす前にP=1として、M$には音階データを入れておいてください。
あとは、メインルーチン内で「GOSUB *BGM」とすればOKです。
G800シリーズをご使用の方はM$に8文字以上の音階データを入れる場合にはM$の代わりにM$(0)としてください。その際にはプログラムの最初に「DIM M$(0)*250」を実行しておいてください。
《サンプルプログラム(BGMサブルーチン必須)》
10 CLS :B$="$30":GOSUB *BOMP:M$="1TRQOMOMOQQ":A=1:P=1 20 LOCATE 5,0:PRINT MID$ ("OCHAME CLUB OCHAME CLUB",A,8):GOSUB *BGM:A=A+1+(A=11)*10:GOTO 20 |
まだまだ、OMPには様々な使いかたがありますが、これくらいにしておきましょう。
石板「o」
《最後に》
実を言うとOMPの原型はすでに10年以上前にありました。当時はE500を買ってそれほどたって無い頃で、音階演奏させるためにBEEPの音程をDATAに羅列してそれをREADすることにより行っていました。
多少それが煩わしくなって、自作の音階演奏ソフトをBASICで作りましたが非常に長く(1Kバイト以上)になり使い物にならないので、データ形式を簡略化することで作られたのがOMPの原型です。
ところが、それでも、音質が悪い(PC-1350では自作のマシン語音階演奏ルーチンを使っていた)ので、速度最重要視の独自音階演奏ルーチンを現在まで使ってきました(まあOMPも独自だけどね)。
希望があれば、その仕様を公開しますが、速度(音質)以外はすべてOMPが勝っていますからね。今更、汎用性の全くないルーチンなんて・・・でも、先程のBGMに関しては使えるかもしれません。
まあ、そうやって出来たOMPですが、昔の2倍以上の速度で動いているわけですからすごいと思いませんか?