■10.音楽データ
1.トラック
2.曲における音符と命令
3.モジュレーション定義
4.効果音における音符と命令
5.音関連のユーティリティ




10.音楽データ
サウンド関連は$30000から
ドライバを弄らない場合はそこを無視する。
あらかじめnsfをつくってそれをエディットする方が楽。
その場合は毎回データをリロードするNSFplayを使う事。
他のプレイヤではバッファからしか読まない可能性がある。
http://www.geocities.co.jp/SiliconValley/1145/(わいわい氏のサイト)

サウンドテスト用IPSパッチこんなのもある。





10.1 トラック(曲、効果音)

$30A50   から音楽トラックの先頭アドレス(1トラックにつき2byte)。効果音も入っている。
$30A50 : D6 8A は$8AD6と読み、$30AD6($8AD6)の$0Fを指す。(以下、適宜$28000足して下さい)

    例) $30A50 : D6 8A : 曲番号$00の先頭アドレス$8AD6
        $30A52 : 1D 8E : 曲番号$01の先頭アドレス$8E1D

ちなみに
曲番号$00-$20 h は曲、
曲番号$21-$42 h は効果音、
曲番号$FC-$FF h はメインプログラム側からの制御命令。

アドレス表

先頭アドレスを見てみると、そこにはトラックの設定が在る
    曲の場合 [トラック設定は$0B(11)byte構成]
        例)  曲番号$00の場合
             $8AD6 : (をダンプすると...)
             0F    → 属性。曲の場合は常に0F
             E1 8A → SQ1
             F1 8B → SQ2
             A9 8C → TRI
             83 8D → NOI
             15 8E → Modulation Definition
 
        0Fの次の$0A(10)byteは2byteずつでそれぞれ
        矩形波1($8AE1)、矩形波2($8BF1)、
        三角波($8CA9)、ノイズ($8D83)、モジュレーション定義($8E15)
        のアドレスを指す。(ファイルオフセットとは$28000の差がある)
    
    効果音の場合 [トラック設定は$02(2)byte構成]
        例)  曲番号$21(33)の場合
             $BB22 : (をダンプすると...)
             50    → 属性。$X0の形。Xは効果音上書き優先順位。大きいほど強く、上書きされにくい。
             0A    → 効果音を鳴らすチャンネル (+01:SQ1, +02:SQ2, +04:TRI, +08:NOI
    
        次のアドレス($BB24)からが効果音のデータになる。




10.2 曲における音符と命令
曲では、テンポや繰り返し処理などが、各チャンネルごとに完全に独立している。

各チャンネルの最初は$00命令で始まる。
$00〜$3Fは命令コード、
$40〜$FFは音符データ。

音符データ(矩形派、三角派)
    Y0(40,60,80,A0,C0,E0) + XX(00〜1F)
    音符一個につき1byte
    Yで音符の長さ(60は40の2倍)
    XXで音の高さ
    $05 XXで決めたキーにXXをプラスする。
    XXが$00の場合は休符となる。
    $4Fがドの16分音符だとしたら$50はド#の16分音符となり、6Fはドの8分音符となる。
    
    詳細)
        音長テーブル
          Y0= |(00 20) 40 60 80 A0 C0 E0
        --------------------------------
        $8975:| 00 00  02 04 08 10 20 40 ←(通常
        $897D:| 00 00  03 06 0c 18 30 60 ←(付点音符命令$06時
    
        この音長とテンポを掛け算した値が、音長カウンタに入る値。
        その値はフレームごとに、(通常)4ずつ減少していく。カウンタが0になったら、次の音符や命令を処理する。

音符データ(ノイズ)
    Y0(40,60,80,A0,C0,E0) + 0X(00〜0F)
    音符一個につき1byte
    Yで音長
    0Xで音の種類

曲における命令コード表
    $00 XX : テンポ(XXが大きいほど遅くなる)。オリジナルでは$05〜$0Bの値が使用されていた。
    $01 XX : ピッチエンベロープ。XXはフレーム毎の変化量、1byteで表せる符号有り10進数換算で-128〜+127。0にすると無効。
             レジスタ$4002,$4003等に作用するので、正の値は音が低くなっていき、負の値だと音が高くなっていく。
    $02 XX : 使用音色。使える値は$00,$40,$80,C0。NOIでは$00,$80。
             レジスタ$4000,$4004のbit7-6、$400Eのbit7に基く
    $03 XX : SQ1,SQ2,NOIでは音量上限、通常$3Xの形、Xは音量を示し値は$1〜$F($0不可)、
                 レジスタ$4000,$4004,$400Cのbit5-0。
             TRIでは$XXそのものをレジスタ$4008に入れるので、音の歯切れよさに影響、
                 +$8Xでは持続音、それ以外は断続音。
    $04 YY XX ZZ : $ZZXXで示すアドレス($28000を忘れない)へジャンプ、それをYY回行う(00の場合は無限)
    $05 XX : 基本となる、キーの高さ(1につき1半音ずつ上がる)。キー値対応表
    $06    : 一つ後ろの音符の長さを1.5倍にする、付点音符の効果。
    $07 XX Y0 : 音量エンベロープ。
                XX : bit7   変化の向き 0:増, 1:減、
                   「増」は音量0から音量上限まで(音楽には不向き)、
                   「減」は音量上限から0まで。
                XX : bit6-0 変化の周期 [単位はフレーム]。0にすればエンベロープ無効。
                Y0 : bit7-4 音量の変化量、0にすればエンベロープ無効。bit3-0は未使用かと。
                詳細) 「減」の場合は、プログラムは音量の初期値は$Fから数えている。
                       しかし、出力音量は音量上限を超えられない。、
                       その結果、上限値が続いてから$0へ向かうことになる。
    $08 XX : モジュレーション定義XX番を呼びこむ。定義してない場合は使用してはいけない。
             XXは技術的には$00〜$3Fが許されると思うが、
             実用的には$00〜$01程度。
    $09    : 音を止める終曲命令。ループしない曲ではデータの最後に必ず置く。
    
    $2X    : 一つ後ろの音符と、それ以降の音符をタイで結ぶ(音長をつなげる)。Xは$1〜$7でタイの個数。
             例)   22 41 42 43 ⇒ ♪^♪^♪ のように音高1番で、音長4番が3個分鳴る。つなげられた方の音高は無視される。
             テク) 21 41 08 01 41 とやると音の途中からモジュレーションをかけられる。
    $30    : 一つ後ろの音符の長さを少し短くして連符の効果を得る。3連符、2連符、4連符...etc 
             (何連符になるかは拍子やテンポ次第。)
             詳細) 普段は音長カウンタをフレーム毎に4ずつ減らしていくが、
                   命令$30された場合は、4,8,4,8,....という風に交互に減らしていくので音長が短くなる。

使用必須な命令と - チャンネルごとに使用できる命令
    $00 : 必須 - ALL
    $01 : 任意 - ALL (NOIでは工夫次第で特殊な効果を生める。
    $02 : 任意?- SQ1,SQ2,NOI (NOIは00,80。置いた方がイイ。
    $03 : 必須?- ALL (TRIでは役目が違う)。置いた方がイイが、NOIでの特殊な場合は未使用のまま鳴らすこと有り。
    $04 : 任意 - ALL
    $05 : 必須 - SQ1,SQ2,TRI。TRIでは元々1オクターヴ低く発音される仕様に注意。
    $06 : 任意 - ALL
    $07 : 任意?- SQ1,SQ2,NOI。置かないとカッコワルイ。
    $08 : 上記 - SQ1,SQ2,TRI,(NOIでも使っても大丈夫、なはず)
    $09 : 上記 - ALL
    $2X : 任意 - ALL(たぶん
    $30 : 任意 - ALL



10.3 モジュレーション定義 : WW XX YY ZZ [4byte単位] 
    $8e15等のこと。
    
    WW XX がピッチモジュレーション(音高のうねり)[曲で普通に使える]
    YY ZZ が音量モジュレーション  (音量のうねり)[音量上限と音量$0の間で変化する仕様の為、曲では使いにくい。効果音向け]
            (両者あわせてLFOと呼ばれてるもののこと)
    
    WW : bit6-0 : ピッチの変化周期。[単位はフレーム]
         bit7   : 未使用
         
    XX : bit4-0 : 最大変位(の回数)。[実際の変位の仕方は ±(変化量)×(最大変位)]
         bit7-5 : ピッチの変化量。[単位は音高レジスタ$4002,$4003等のもの]

    YY : bit6-0 : 音量の変化周期。[単位はフレーム]
         bit7   : 初期変化方向。
                  0: 音量上がってから下がる
                  1: 音量下がってから上がる
    
    ZZ : bit7-0 : 音量の変化量。
                  1byte符号あり16進換算で-$F〜+$Fが妥当。他の値-128〜127も使えるかと、細切れになった音が出るはず。
                  また、符号はプログラムが勝手に反転してくれるので、あまり気にしなくてイイ。

    それぞれ、変化量や周期を0にすれば、効果は無効に。

    例) 曲番号$00の場合
        $8e15 : 00 00 80 00 02 62 80 00
        ここでは2個定義されている事になる。
            00 00 80 00 はピッチ/音量共にモジュレーション無効。無効の時はこのデータ列にすべし。
            02 62 80 00 はピッチモジュレーションのみが有効、周期2,変化量3,最大変位2。
        このような定義の場合、命令08の使い方は次のとおり
            08 00 41 : モジュレーション無効な音符$41。
            08 01 41 : 音符$41にピッチモジュレーションがかかる。






10.4 効果音における音符と命令
曲とは違い、効果音データは次のように(平行でなく)直線的なデータ構造を採る。
    
    (例. SQ2以外のチャンネルを鳴らす場合)
    命 命...命 Reg値  命 命...命 Reg値  命 長...命 Reg値      命 命...命 Reg値  命 命...
    +--------------+  +--------------+  +--------------+      +--------------+  +-------  (略
           SQ1               TRI             NOI(最後)               SQ1               TRI
    +--------------------------------------------------+      +-----------------------------------(略
                     1つ目の音長処理単位               +------+                2つ目の音長処理単位
                                                     音長分だけ待つ

命    = 各種効果音命令(初期設定時以外は省略可と思われ)
Reg値 = 2byte構成。音高レジスタ($4002,$4003等)に入れる値など。省略不可。
長    = 命令$00。事実上省略不可と思われ。

1音長処理単位分のデータをまとめて処理する。
NOI(最後)と書いてあるが、音長処理単位の最後に鳴らすチャンネルのデータ内には、
命令$00 XXを置く。すると、XXフレーム待ってから次の音長処理単位分のデータが処理される。

Reg値 とは、基本的には、音高レジスタ($4002,$4003等)に入れる11bitの値のこと。
Reg値 : XX YY とすると、XXは$4003等、YYはそのまま$4002等に入れられる。
        YY の範囲 $00〜$FF
        XX に$80〜$87を入れると音高レジスタに書き込みが行われ、音が鳴る。
        XX に$8Fを入れると、その音長処理単位には命令以外何もしない(YY無視)。つまり、鳴ったままor無音のまま。
        
        (XX YYあわせて$000を入れると音が止まる、はず)。
        (プログラム改造しなければ、$4001,$4005への書き込みはできません。)
        
効果音における命令コード表
    $00 XX : 次の音長処理単位までの待ち時間XX[単位はフレーム]。$00〜$FF($01はダメ?)。
    $01 XX : ピッチエンベロープ。曲の場合と同じ。
    $02 XX : 使用音色。曲の場合と同じかと。
    $03 XX : SQ1,SQ2,NOIでは音量上限。
             TRIでは歯切れ。曲の場合と同じかと。
    $04 YY XX ZZ : $ZZXXで示すアドレス($28000を忘れない)へジャンプ、それをYY回行う(00の場合は無限)
                   音長処理単位の間に置くべきかと!? データまで調べてないからシラネ。
    $05 WW XX YY ZZ : モジュレーション定義。
                      WW XX がピッチmod , YY ZZが音量mod。曲の定義方法と同じかと。
    $06    : 効果音データの終了/全チャンネルを停止






10.5 音関連のユーティリティ

アドレス表
キー値対応表
メモリ用途
1byte符号あり数の変換表
サウンドテスト用IPSパッチ
おまけのバグ入りMIDIとMMLソースファイル