今回はYM2151ライブラリの使い方についてメモします。ライブラリというよりはMDXシーケンサの実装に伴ない必要な物をまとめただけといった感もありますが、レジスタ裸の状態ですと音を出すまで結構大変なので理解の助けになればと思います。リファレンスはこのページにまとめています。
YM2151Library
まずは基本のお約束、HelloOpmWorld!
Arduinoの各ライブラリの例に漏れず、YM2151.cpp/YM2151.h/Common.hの3点を使いたいスケッチのディレクトリにコピーした後YM2151.hをインクルードするだけです、内容はサンプル3点で同一です。Common.hはマクロを2点定義しているだけなのでお好きなように再定義してください。最低限音を出すのに必要なコードをまとめたのがこちらです。
uint8_t channel = 0;
YM2151.begin();
YM2151.loadTimbre(channel,(uint16_t)SampleTimbre01);
YM2151.setVolume(channel,0xf,0);
YM2151.setPanpot(channel,0x3);
YM2151.setTone(channel,0x20,0); // 音階=0x20
YM2151.noteOn(channel);
まずbegin()メソッドを呼び初期化する必要があります、やや時間がかかる処理ですのでsetup()の中で1度だけ呼ぶのがベターだと思います。以降チャンネルごとに設定していきますが、ご存知の通りYM2151は8音同時に出力が可能なので0~7まで同じように設定していきます。
- loadTimbre(uint8_t,uint16_t)で音色パラメータをセットします、この関数はMDXフォーマット形式で定義されたPROGMEM prog_uchar配列のアドレスを渡します。パラメータについてはさらに分りやすい方法を用意しましたので後述します。
- setVolume(uint8_t,uint8_t,uint16_t)でボリュームを設定します、範囲は0~15で15が音量最大です。ハードの制約上音色の組み方によりボリュームを下げると破綻する場合があります。
- setPanpot(uint8_t,uint8_t);でパンポットを設定し、左右どちらに発音するか設定します。ハードの制約上、デジタルな鳴り分けしかできません。
- setTone(uint8_t,uint8_t,int16_t)で音程を設定します、オクターブ0のD#を0として音階を設定します。3番目のkfは音階の微調整です、6bitで設定しますが、音階と合成しているので連続変化音を作りたい場合はこちらのみで大丈夫です。
- noteOn(uint8_t)で発音します。
setVolume、setPanpotは一見不要に見えますが、関連レジスタの設定も行っているので音色の再設定を行った後は必ず呼んでください。特にリセット直後はレジスタ初期値0なので呼ばないと全く鳴りません、noteOff(uint8_t)で発音を止めます。
お手軽音色設定関数について
まだFM音源が現役だった頃から難易度が高かったのが音色設定です。倍音を多重合成して音を出しているのでほんの僅かなパラメータの違いにより大きく出力が変わる上、数も多いので当時から沢山の音色設定ツールが作られた程です。そこで、VAL-SOUNDさんが、
FM-Sound Library
にかなり大量の音色を公開していらっしゃるので、そのままロードできるよう関数を追加しました。記述としては、
PROGMEM prog_uchar AnalogBass[]={
6, 7, 31, 0, 0,12, 1,18, 1, 1, 0,0,
31, 0, 1,12, 1, 4, 1, 2, 0,0,
31, 0, 0, 9, 0, 3, 0, 1, 7,0,
31, 0, 0, 9, 0, 3, 0, 1, 3,0
};
YM2151.loadSeparationTimbre(channel,(uint16_t)AnalogBass);
このような感じです、但しOPN/OPNAもサポートする音色な為、パラメータが若干増えているYM2151は微妙に使いきれない状態となります。
以上全体的に説明をやや端折ってしまいましたので、分かりにくい点がありましたらコメントやメールで遠慮無くお願いします。
いろいろ更新しました
転送ツール他を29日に更新し、若干機能強化を行いました。サポートページにまとめてあります。
YM2151シールドサポートページ