第7話 BEEP音源ドライバー(後編)

PC−8001でも二重和音が演奏できる!

和音が演奏できれば、単音しか使えなかったときと比べて、 音の表現力がまったく段違いになる。単音では 効果音くらいしかまともに表現できず、BGMなどを奏でようとすると、 「まあPC−8001だししょうがないね」 と妥協して聞くしかないような 可哀相な状態だった。それというのも、サブメロディーやリズムがまったく 使えず、主旋律だけの演奏になるため、なかなか音楽という感じには なりにくく、せいぜいゲームのイントロ音やゲームオーバー音などの 短いメロディーにしか使えなかったのである。
だが、二重和音が出せるというだけで、単なる効果音の延長から、 美しいハーモニーやリズムを伴なう本格的 (かどうかは個人の主観にも左右されるが) な楽曲を演奏することが可能となる。 私は、PC−8001があんな曲こんな曲をまさに「演奏」する様子 を思い描き、ワクワクした。

もう少し具体的な話をしよう。 例えば、主旋律が「ソー」、 対旋律が「 」といったメロディーならば、 「」と 「」を 連続して出せば実現できるはず。 この分割を必要な限り細かくしていくことによって、どんな楽曲だろうと この和音ルーチンだけで演奏できるはずだ。 そしてこの分割を人間が手動でやるのではなく、プログラムで 計算してくれるようにすれば、人間は各チャンネルのメロディーを記述するだけで、 プログラムのほうで勝手に「連続する和音」に置き換えてくれるので、 あたかもPSGやFM音源を搭載しているかの如く、MMLによる 簡単な楽曲記述が可能になる。

BEEPだけを使ってPC−8001が音楽を奏でるようになる! しかもMMLを使って、 PC−8801mkIISRのように楽曲を記述できる! 私はこのシステムに「BEEP音源ドライバー」と名付け、 開発を開始した。

まず考えたのは、和音数の拡大である。二重和音でもそれなりのことはできるが、 やはり楽曲を演奏するには、PSG機種のレベルである三重和音を実現したい。 果たして二重和音のときの理屈がそのまま通用するかは謎であったが、 とりあえずは同様のアルゴリズムで3音を平行に処理するルーチンを作ってみた。 ハンドアセンブルし、打ち込んで、実行。 「うーむ・・・」 さすがに三重和音となるとなかなか原理的にも処理速度的にも微妙なところとなり、 「なんとなく和音に聞こえないこともない」 というレベルにまで後退してしまった。

「もうちょっと良くならないかなあ」よりよい和音を得るため、 プログラムを効率化して実行速度を上げる、3音の処理時間のバランスが 均等になるようにプログラムを整理する・・・などのマイナーチェンジを施した。 あまり変わらなかったが、それでもなんとなくちょっと音が良くなった ような気もした。

とりあえずは音の質はこの程度にしておいて、次にMML解析ルーチンの制作である。 これまで作ったことのあるBGMルーチンといえば、「CDEFGAB」という各文字を 読んで対応する音を鳴らすだけの簡単なもので、せいぜい一重のループ機構を 備えている程度のものだった。しかし、今回作るそれは、 「V(ボリューム)」 「L(音長)」 「(・・H・)(5重までのリピート。最終回にHから抜ける)」 「Q(発音比率)」 「T(テンポ)」 「O,>,<(オクターブ指定)」 「{・・・}(連符)」 ・・・といった多彩な命令を持っていた。 解析プログラムは、このような命令を伴なうMMLを解析し、 「和音の連続」に分解してメモリに書き込んでゆく。

リアルタイムで演奏するわけではないので、ここはBASICで記述した。 これはちょうど簡単なインタプリタを作るのにも似ていて、なかなか面白い プログラミングだった。「Out of octave」とか「Sound buffer overflow」なんていう オリジナルのエラーメッセージまで用意して面白がっていた。 プログラムは程なく完成し、いよいよ実行する段階になった。 曲は「オールアバウトナムコ」から拾ってきたギャラガのスタートミュージック。 短いが、和音をうまく生かしたメロディーだ。

run。少し間があった。が、

「パーパパーパパーパパーパパーパパーパパーパパーパ パーパパーパパーパパーパパーパパーパパパパパパパ」

「おおー!」 感動を覚えた。意外にキレイな音が響いた。これなら確かに 和音によるメロディーに聞こえる。好調な立ち上がりである。 他にも自作の曲などをいくつか試したのだが、このギャラガが 特にきれいに聞こえた。

しかし、気になったのは、解析に予想以上に時間が掛かっていたことである。ギャラガくらい ならいいが、ちょっと長い楽曲を入れると、解析時間はべらぼうなものになった。 「バッカナール」(クラシックの曲)の一部を入れてみると、演奏開始までに なんと10分も待たされてしまう。 「これでは使い物にならん。」 解析時間への不満は徐々に大きくなり、ついに「いっそのことマシン語にしてしまえ」 という結論に達した。

既にBASICでプログラムが完成しているので、プログラムの流れは 考える必要はなく、ただBASICでの処理をマシン語に置き換えていくだけである。 割り算の処理が必要となるなど、ややマシン語では難しいところもあったが、 「マシン語でMMLインタプリタを作る」 という当時の私には とんでもなく困難に見えた仕事の割には順調に進み、完成した。

実行してみた。 ほぼ一瞬で解析が終わった。さすがだ。さすがはマシン語、 相変わらずの高速ぶりである。BASICで10分かかる処理が まったく待たずに終わるのは、なんとも胸のすく気持ち良さであった。

そして、和音ルーチンの改良にも取り組んだ。EXX命令などの、 「こんなの誰が使うんだ」 と今まで思っていたような命令も駆使し、 高速化を試みた。

PC−8001で三重和音。しかも強力なMMLによってまるでFM音源機種のような 音楽演奏が楽しめる。 「これが載らない筈がない!」 というほどの確信のもと、 ベーマガへの投稿を準備した。まえがきだけを紹介すると、

◎このプログラムは
BEEP音しか使えないP8(又は初代88)で音楽演奏をするという 感動的なルーチンです。音はきたないですが、4オクターブ3重和音の コンピューターサウンドが楽しめます。

とあり、自信の程がうかがえる。曲は、「ドラクエIV第2章」 「ギャラガ」「ドラクエIエンディング」「別れの曲」「バッカナール」 と聞き映えのした5曲を収録した。

おそらく投稿はNEVIOUSの翌月、発表は91年7月号だったと思う。 そして、結果は・・・没であった。

PC−8001の音楽ルーチンは 実用プログラムのくせに全然実用的でない うえ、上記の通り音も けっして奇麗とはいえないものだったのだが、 PC−8001の能力からすれば凄いプログラムだ、と一人悦に入っていたので、 この結果にも少なからずガッカリしたものだ。しかしまあ、 「PC−8001でもここまでできる」ということを示したという点では なかなか満足の行くプログラムであった。


BEEP音源ドライバー

画面写真を載せてもしょうがないので、wavファイルをどうぞ。

ちなみに、このルーチンをちょっと改造して、後に 「ドラクエIVエンディング」をミュージックプログラムコーナーに 投稿したこともあります。没でしたが。


ちなみにエミュレータ用ファイルはこちら。(t88,cmtファイルです。)
エミュレータはj80推奨です。

HAL8999さん が改良版を作って下さいました。BASIC部とマシン語部に分かれています。 cload後、mon+Lです。


参考までに、投稿時の原稿の内容を載せておきます。

【このプログラムは】
 BEEP音しか使えないP8(又は初代88)で音楽演奏するという感動的なルーチンです。 音はきたないですが、4オクターブ3重和音のコンピューターサウンドが楽しめます。

【つかいかた】
 940行以降がMMLデータになっています。RUNすると60行のRESTOREで指定した行の MMLから演奏をはじめ、「DATA −1」の行で終わります。
 よって、自分で曲を入力する時は、まず60行の値によって行番号を指定し、その行からMMLデータを 打ち込み、おわりに「DATA −1」の行を入れてください。
 なお、1回RUNさせた後はマシン語の書き込みは不要ですので、40行をGOSUB 260にしておいてください。

【MMLデータ形式】
 MMLデータは、<チャンネル数>、<チャンネル1>、(<チャンネル2>、<チャンネル3>)の順に入力します。
 コマンドは次の通りです。

【プログラムについて】
 和音発生ルーチンはAF00〜AF76Hです。しくみについて説明するスペースがないので、興味のある人は調べて下さい。
 膨大な量のマシン語は、実はほとんどMML解析ルーチンです。はじめオールBASICだったところ、異様に時間がかかるので こうしてしまいました。よって解析はほとんど不可能です。どうもすみません。

【つけたし】
 演奏中は、高速化のため画面が消えます。ご了承ください。

(マシン語のエリア)
A500H〜AEFFH…ワークエリア
AF00H〜AF76H…音出しルーチン
AF90H〜AFC4H…演奏ルーチン
B000H〜B573H…MML解析ルーチン
B600H〜E5FFH…サウンドバッファ