ゲーム音楽について

今度は少しプログラミングから離れてみま・・・・せん。
今回は、プログラムから使われることを前提とした音楽と、音楽を鳴らすことを前提としたプログラムについての話です。

最近ゲームのBGM用に作られたMIDI素材が多くありますね。
それに伴ってかその逆か、BGMのあるゲームも増えてきたようです。
しかし、ゲーム音楽は音楽としては少々変わり者です。
つまり、ゲーム音楽は他の音楽と違っていつ終わるかわからないのです。
音楽が終わるより早く演奏が終了されるのならば別に問題はありませんが、逆に音楽の長さより長く演奏を続ける時はループのことも考えなければなりません。


プログラムについて

MCIで鳴らすのもいいですが、DirectMusicを使った方が何かと都合がいいのでDirectMusicを使うことにします。
ここからはDirectMusicで音楽の再生くらいならできるという前提で話を進めていきます。

音楽をループするためには、DirectMusicSegmentのSetRepeats関数を使うのですが、しかし、ループするときのループ位置を決めるSetLoopPoints関数の使い方までわかっている人はどれほどいるでしょうか。
きっと沢山いるでしょうね。ですがそんな人は今回どうでもいいのです。
きっと知らない人も同じく沢山いるはずです。

SetLoopPointsとはこんな関数です。

HRESULT SetLoopPoints(
  MUSIC_TIME mtStart,
  MUSIC_TIME mtEnd
);

HRESULTだかMUSIC_TIMEなんかがありますがLongと内容は同じです。
ちなみに、MusicTimeとは四分音符の数×768のことです。
例えば、6/8拍子の音楽で20小節目から40小節目までループする場合、
mtStart=768*(6/8*4)*(20-1)
mtEnd=768*(6/8*4)*40
といった計算をしてMusicTimeを出します。


MIDIについて

しかし、折角プログラムが良くても、MIDIがプログラムから使われることを前提にしたものでなければどうしようもありません。
ゲーム音楽として意識しなければならないことはいくつかありますが、今はループの話なので今回はその部分だけにとどめておきます。

いきなり結論に入ってしまいますが、ゲーム音楽としてループさせるのに最も適していると思われるのは、Lをループ部分として、A→Lという構成になっている音楽です。
Aははじめに一回だけ演奏される部分で、後はLの部分が繰り返されてそれより後ろは演奏されません。
そう言う意味ではA→L→Bという構成になっている音楽ではBが演奏されないので無駄なことをしていることになります。
また、逆にAを省いたLだけの音楽はいいと思います。
つまり、音楽の終わりの部分が初めの部分につながっている音楽です。
これだと上に書いたSetLoopPointsの設定をしなくて済む分プログラムが楽に書けます。
そのほか、どこでもループさせることの出来ない音楽もありますね。
そういうものはゲーム音楽には向かないかといえばそうでもなく、ちゃんとした始まりの部分を終わりの部分があればそれはそれでいいと思います。
しかし、A→L(数回ループ)→L(フェードアウト)はいけません。
いけないことはなくても、できれば避けた方がいいです。
なぜなら、ループ位置を設定しないままフェードアウトで0になったボリュームのまま次の演奏に入ってしまうと・・・・どうなるかわかりますよね。

中途半端なところで次の内容に移りますが、今度はその「中途半端」の話です。
例えば、4/4拍子の音楽が20小節目から40小節目までループすると言われれば簡単にループ位置がわかりますが、はじめは23/8拍子で21小節目から11/16拍子でテンポアップしながら31小節目から41小節目まで9/4拍子で42小節目から7/8拍子で37小節目の五分音符の12個目から50小節目までループするからそのループ位置を計算しろと言われれば、簡単にループ位置がわかるでしょうか。
つまり、中途半端でわかりにくい場所でループするよりは、きりが良くてわかりやすい場所にループ位置を置きましょうということです。

最後になりましたが、当然ループ位置に来た瞬間は無音であることが望ましいです。


異常演奏への対策(02/10/10追加)

Anti「DirectMusicのススメ」で挙げた異常演奏の幾つかについて対策方法を見つけましたのでここに記しておきます。

音が消えないホールドイベントを削除すれば直りました
ピアノの音だけになるシステムエクスクルーシブイベントが悪さをしているようです
恐らくGSのソフトシンセにXGのリセット命令を送っているのが原因だと思われます
音が出ないプログラム側で音源をリセットしましょう
ボリュームが小さすぎるということもあります

本当はMIDIが悪いんでなくDirectMusicの方が悪いんですよ。