« とっても大事に | トップページ | 仕様変更 »

2013年3月16日 (土)

サウンドドライバ

FM音源を鳴らす前に、PSGで音楽を演奏することにした。
秋月電子で買ったYAMAHA YMZ294というICがその互換品らしい。ちょうどいい練習になるだろう。
テンポは192まで対応することにした。
最短となる192分音符は4分音符の1/48の音長である。よって、テンポ192における、192分音符の演奏時間は以下の式で求められる。

    60000ms / 192 / (192/4) = 6.510416666666667ms

PICマイコンを内蔵クロックの8MHzで動作させるとすれば、1/8000000=0.000125msとなる。音程(音の周波数)を決める処理は音源ICがやってくれるから、処理速度は問題なさそうだ。

さっそくサウンドドライバを設計してみよう。
私はPICマイコンに、MMLを直接演奏させたいのだ。
たとえばファミマ入店音は、こんな感じのMMLで表すことができる。

     musicPlay("t120o4 g8d#8<a#8>d#8f8a#4<f8>f8g8f8<a#8>d#2r1");

しかし、文字列(MML)をリアルタイムに変換しながら演奏するのは大変なので、まとめて変換した結果を、いったん内部のバッファに格納する。
以後、このバッファをトラックと呼ぶ。
トラックに格納されるのは、short=2bytesの固定長とする。

(1)最上位bitが1なら音符データとする。
(2)音符データは、7bitの音程+8bitの音長で表す。
(3)最上位bitが0ならコマンドデータとする。
(4)コマンドデータは以下のようになっている。

1ttt = テンポttt
200v = 音量v
300q = Quantize
4rnn = r=レジスタ、nn=値
5??? = ソフトウエア的なフラグのON/OFF
    音色の指定、タイ(スラー)、クォンタイズ、トレモロ、ビブラート等

とりあえずはこんな感じでいいか。
リアルタイムに変換するのは後回しにして、直接値をセットして演奏して見よう。テスト用にこんな感じのデータを演奏させてみた。

int track[] = {
    0x1080,            // テンポ=128
    0x200f,            // 音量=15
    0xb030,            // ド♪(オクターブ4)
    0xb230,            // レ♪
    0xb430,            // ミ♪
    0xb530,            // ファ♪
    0xb730,            // ソ♪
    0x0000,            // MMLの最後
};

これはすぐに完成。我ながらいい調子だ。

« とっても大事に | トップページ | 仕様変更 »

お仕事」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/24707/50888370

この記事へのトラックバック一覧です: サウンドドライバ:

« とっても大事に | トップページ | 仕様変更 »

最近のトラックバック