■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ソースファイル