※このテキストは「MS ゴシック」など、等幅のフォントで見ることを想定しています。
なお、この文章に書いてある内容は独自の検証結果を基に書いており、正確な仕様書のまとめではないことをご了承ください。



＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝

　　　　　　GBA サウンドフォーマットについてのまとめ資料
				Ver. 1.6a
　　　　　　　　　　　　　　　　　　　Written by nagona◆DKG4NAGONA
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝

1. はじめに

この資料は、ゲームボーイアドバンス（以下GBA）のサウンド周りの実装を説明するものです。
Web を漁ってみても、このような情報がなかなか見つからなかったため、自分で検証し
動作を確認した結果を記録しています。
対象は、sappy で曲が再生できるものすべてですが、ここでは FR を対象に話を進めていきます。

なお、この資料は以下のことについてある程度わかっている人向けの内容となっております。

-Gameboy Advance のハードの知識が多少
-Sappy 2006 の使い方がわかっている（曲を差し替えるための操作ができる）
-MIDI のことをある程度わかっている
-わかってなくても自力でググって理解を深められる

出来るだけ難しい内容を省いて説明していきたいと思いますが、内容が内容だけに、難しい部分も多いと思います。
最低限、2進数、16進数を知っていて、バイナリエディタが扱える程度の能力は必要と思ってください。
なお、この資料で使われている名称は、nagona が勝手に呼称しているだけで、正しいものではありません。

この資料が、より完成度の高い BGM の作成に繋がりますように。


なお、この資料で使用しているツールは以下の４つです。

-MID2GBA
-sappy2006
-バイナリエディタ
-Audacity



2. FR でのサウンドについて

2.1 GBA の音源について

GBAは以下の６個のサウンド発生機能を持っています。

1. パルス波音源１
2. パルス波音源２
3. 波形メモリ音源
4. ノイズ
5. DirectSound１
6. DirectSound２

それぞれ以下のような特性の音源となっています。

パルス波音源１，２：
　　　　ファミコンと同様のピコピコ音。4種類の音が出せる
波形メモリ音源　　：
　　　　小規模な PCM 音源のようなもの。FR では任意の 4bit 32 サンプルの波形を設定することができる。
ノイズ　　　　　　：
　　　　ノイズ。ホワイトノイズ。ドラムのハイハットや、効果音によく使われる。
DirectSound１，２ ：
　　　　GBA のキモ。PCM っぽいことができる。ってか FR では PCM と思ってくれてかまわない。

パルス波音源、波形メモリ音源、ノイズは、旧来の GB 由来の音源です。
それぞれの音源で、独立して左、中央、右の3種類のパンを行うことができます。
FR では DirectSound は、 2 つを同期して使うことでステレオPCM音源として使われています。


2.2 FR での発音について

FR では、上記4種類6音源を統合して扱える、一種のソフトウェア MIDI とも言える音源ドライバを使用して、
BGM だけでなく、様々な効果音も含めて音を鳴らしています。

FR では BGM や効果音は、すべて「曲テーブル」と呼ばれる、リストのようなもので管理されています。
ゲームプログラムからの演奏要求は、何番目の曲を演奏するかという情報と共に音源ドライバに送られ、
それを元に、どの曲を演奏すればいいのかを判断しています。

このアドレスの情報から、次に曲情報が読み込まれます。
この曲情報には、これから演奏しようとしている曲のトラック数、ボイスグループとシーケンスデータの所在などが書かれています。
参照を繰り返すことで、曲に必要な情報を集め、すべての情報を集めてから演奏が始まるのです。

曲の再生のために必要な情報を集めるために、ドライバは曲テーブルから順に以下のような情報を読み込みます。

　　　　　　　┌─────┐
　　　　　　　│曲テーブル│
　　　　　　　└─────┘
　　　　　　　　　　↓
　　　　　　　　　(参照)
　　　　　　　　　　↓
　┌─────────────────┐
　│　　　　　曲情報(Header)　　　　　│
　└─────────────────┘
 　　　　↓　　　　　　　　　 ↓
 　　　(参照) 　　　　　　　(参照)
 　　　　↓　　　　　　　　　 ↓
┌────────┐┌─────────┐
│シーケンスデータ││　ボイスグループ　│
└────────┘└─────────┘
　　　　　　　　　　　　│　│　│　│
     　　 ┌─ (参照) ─┘  │　│　└（参照）┐
    　　　↓　              │　│　　　　　　↓
┌──────────┐　　│　│　　┌───────────┐
│ドラムボイスグループ│　(参照)│    │出力ボイス指定テーブル│
└──────────┘　　│　│    └───────────┘
　　　　　│　　　　　　　　│　│
　　　　　└ (参照) ┐　　　│　└ (参照) ┐
　　　　　　　　　　↓　　　↓　　　　　　↓
　　　　　　　　┌───────┐┌────────┐
       　　     │ボイス実データ││波形メモリデータ│
                └───────┘└────────┘


曲テーブルは、 1 曲あたり 8 バイトのバイナリデータが連なったデータとなっています。

FR では、この曲テーブルが 467f0ch から始まっており、全部で 347 曲分の情報が書き込まれています。
この領域は特にいじる必要は無いと思いますが、もし 曲テーブルを拡張する必要がある場合は、以下を参考にしてください。

2.2.1 曲テーブル

8 バイトの内訳は以下の通りです。

1～4バイト目 (+0h～+3h)
	シーケンスの曲情報アドレス（ヘッダアドレス）
5～6バイト目 (+4h～+5h)
	出力ターゲット：0000h…BGM , 0001h…効果音、鳴き声 , 0002h…ジングル（レベルアップ等） , 0003h…HP警告音等、BGMとは別に鳴り続ける必要のある音
7～8バイト目(+6h～+7h)
	5～6バイト目と同じものが入る？（0000h でも問題ないみたい…？）

シーケンスの曲情報アドレスとは、簡単に言うと MID2AGB で MIDI を変換したときに、 .s ファイルの末尾にある情報領域を指します。
Sappy2006 でいう、 Header に表示されるアドレスです。

出力ターゲットは、曲情報アドレスで指定した曲が何に当たるかによって値を変える必要があります。
曲の差し替えの場合、元の曲と使用目的が同じため変更する必要は無いのですが、曲テーブルを拡張して新しい曲を入れる場合、
指定を間違うと効果音で BGM が途絶えたり、そもそも正常に音が鳴らない等の問題が発生します。
なお、ターゲットごとに使えるトラック数に制限があります。これ以上のトラックを使用しても無視されますので注意してください。
00h では 10 トラック、 01h では 3 トラック、 02h では⑨トラック、03h では 1 トラックとなります。
それ以外の値を入れても何も鳴りませんので注意してください。


2.2.2 曲情報(Header)

以下のような情報が書き込まれています。

・シーケンストラック数
・マスターリバーブ
・優先度
・使用するボイスグループのアドレス
・各トラックのシーケンスの先頭アドレス

これについてはシーケンスデータの説明で詳しく書きます。

2.2.3 シーケンスデータ

簡単に言うと演奏に使う楽譜です。
MIDI のシーケンストラックとほぼ同等です。
詳細は 4 シーケンスデータ (.sファイル) について をご覧ください。

2.2.4 ボイスグループ

シーケンスデータで指定する音色番号で何を鳴らすかが記述されています。
このテーブルを作成、変更することで新しい音色を作成できます。
ここから必要に応じて、下のドラムボイスグループ、出力ボイス指定テーブル、
ボイス実データ、波形メモリデータが読み込まれます。
詳しくは 3.1 ボイスグループ を参照してください。

2.2.5 ドラムボイスグループ

ボイスグループでドラム用の指定が行われた場合に参照されるボイスグループです。
ドラム用なので、 VOICE 命令ごとでなく、ノートナンバーごとの音色として扱われます。
基本的には通常のボイスグループと同じように書かれています。
違うところは、一部ドラムボイスグループ用のフラグがあったり、
パルス波を指定しても無視（無音）されるところです。

2.2.6 出力ボイス指定テーブル

ボイスグループで音域指定された場合に参照されるテーブルです。
ノートナンバーごとにどの音色を鳴らすかを指定します。

2.2.7 ボイス実データ

実際に鳴る音色そのものです。
8bit モノラルの wav データに相当します。

2.2.8 波形メモリデータ

波形メモリ音源で使われる 16 バイトの波形データです。




3. 音色（ボイス）


3.1 ボイスグループ

FR の音源ドライバでは、曲ごとに最大 128 種類（セット）の音色を設定しておくことができます。
この音色のことをボイスと呼び、128 種類のセットをボイスグループといいます。

ボイスは 1 つにつき12バイトで、ボイスグループではこれが 128 個分、合計 1536 バイトの連続したデータとして記述されます。
ボイスには、どの音源をどの波形で鳴らすか、どのような強弱で鳴らすかという情報が書かれています。

例として、初期設定の状態を書き出すと、以下のようになっています。

　　01 3C 00 00 02 00 00 00 00 00 0F 00

これはパルス波音源１でデューティー比 50% の音を発音から消音まで最大音量で出力するという意味を持っています。
何がなにやらさっぱりだと思いますが、下で説明していきます。

なお、音色の作成は、上で説明した音源ごとに内容が違いますので、それぞれ説明していきます。


3.2 パルス波音源の音色作成

ボイスの先頭1バイトのうち下から3ビットが 001b もしくは 010b の場合、パルス波を鳴らす指定となります。

パルス波音源は 2 チャンネルありますが、独立していてそれぞれの同時発音数は１です。
同じチャンネルのパルス波音源を複数のトラックで使用しても同時に1音しか鳴りません。
和音を鳴らしたい場合などは、2つのトラックに分けて1音ずつ鳴らす必要があります。

ボイスのバイナリデータは以下のような意味を持ちます。

1バイト目(+00h)
	bit2-0 : 出力音源 001:パルス波１, 010:パルス波２
	bit3   : 謎（FRでは 1 が使われるが 0 でも問題なし）
	bit7-4 : 未使用
2バイト目(+01h)
	謎。調べた限り常に 3ch
3バイト目(+02h)
	謎。常に 00h ?
4バイト目(+03h)
	謎
5バイト目(+04h)
	デューティー比 (00h = 12.5%, 01h = 25%, 02h = 50%, 03h = 75%)
6～8バイト目((+05h～+07h)
	常に 00h
9バイト目(+08h)
	アタックタイム：00h(最速)-ffh(最遅)
10バイト目(+09h)
	ディケイタイム：00h(最速)-ffh(最遅)
11バイト目(+0ah)
	サスティンレベル： 00h(mute)-0fh(最大)
12バイト目(+0bh)
	リリースタイム: 00h(最速)-ffh(最遅)

なお、理由は不明ですが、実際にパルス波音源を定義する場合、先頭の1バイトは 09h もしくは 0ah を使用しています。
01h や 02h を使用しても問題なく鳴るようですが、ほとんどの場合は 09h, 0ah を使用していますので、
特に理由が無い限り 09h, 0ah を使用したほうがいいと思います。

1.6追記： 値が 8 増えた場合、発音終了時に非常に小さなプチノイズが入るようです。
　　　　　　連続で同じ音を鳴らす場合、切れ目がわかるようになるようです。

※デューティー比について

GBA のパルス波音源は、エンベロープという値をいじることで以下の4種類の音色を出すことができます。
一般的に、波形が上側になっているところが全体の何％になっているかで表現します。これをデューティー比と言います。

デューティー比 12.5%　　　-_______-________
えぐいです。耳に突き刺さるような音が特徴です。

デューティー比  25%　　--______--______
50% の素直さと、12.5% のえぐさのちょうど中間です。比較的目立つ割にきつくない音なので、メインメロディに使われることが多いです。

デューティー比  50%　　----____----____
素直な音色です。特徴が一番ないとも言えるかも。

デューティー比  75%　　------__------__
25%の上と下の長さが逆転したもので、音の聞こえかたは 25% と同じになります。
波形が逆転しているため、 25% の波形と干渉しにくくなっています。
2 つのパルス波音源で両方 25% の音色を使いたい場合は、片方を 75% にしておくと両方の音が干渉しにくくなります。

アタック・ディケイ・サスティン・リリースについては、ぐぐってください。 ADSR でぐぐると幸せになれます。


3.3 波形メモリ音源の音色作成

波形メモリとは、端的に言うと規模のとても小規模な PCM 音源です。
振幅16段階(4bit) で 32 サンプルの波形を繰り返すことで音を出します。

ボイスの先頭1バイトのうち下から3ビットが 011b の場合、波形メモリ音源を鳴らす指定となります。

波形メモリ音源の同時発音数は１です。
同じチャンネルのパルス波音源を複数のトラックで使用しても1音しか鳴りません。
また、音量が非常におおざっぱです。
GBA のハード仕様を見る限り、 0%、25%、50%、100% の音量しか指定できません。
ADSR で徐々に音量が小さくなるような指定をしても上の制限に縛られることに注意してください。

ボイスのバイナリデータは以下のような意味を持ちます。

1バイト目(+00h)
	bit2-0 : 出力音源 011b 
	bit3   : 謎
	bit7-4 : 未使用
2バイト目(+01h)
	謎。調べた限り常に 3ch
3-4バイト目(+02h～03h)
	謎。調べた限り常に 00h
5～8バイト目(+05h～+07h)
	波形参照先アドレス
9バイト目(+08h)
	アタックタイム：00h(最速)-ffh(最遅)
10バイト目(+09h)
	ディケイタイム：00h(最速)-ffh(最遅)
11バイト目(+0ah)
	サスティンレベル： 00h(mute)-0fh(最大)
12バイト目(+0bh)
	リリースタイム: 00h(最速)-ffh(最遅)

波形参照先アドレスとは

先に説明したように、　波形メモリは、小さな Wave デバイスになっています。
つまり、元となる Wave が必要です。
それを書いたのがどこか指し示したのがこの場所にある情報です。

例： 00 ac 01 08 → 0801ac00 番地の情報を読み込む

なお、 FR では最上位バイトは必ず 08h なのですが、これは GBA でカートリッジのデータが 08000000h から配置されるからです。
そんな訳で、アドレス情報があった場合は 08000000h を引いて考えてください。

参照先には、以下のような16バイトのデータがあります。

ff ee dd cc bb aa 99 88 77 66 55 44 33 22 11 00

上の例は、以下のような波形として認識されます

f  ++
e    ++
d      ++
c        ++
b          ++
a            ++
9              ++
8  ______________++________________
7                  ++
6                    ++
5                      ++
4                        ++
3                          ++
2                            ++
1                              ++
0                                ++

実際に鳴る音は、この波形が繰り返されたものとなります。

また、このようなデータなら

01 24 7a de fe da 74 21 01 24 7a de fe da 74 21

f         +               +         
e        + +             + +          
d       +   +           +   +         
c                                 
b                                 
a      +     +         +     +        
9                                 
8__________________________________
7     +       +       +       +       
6                                 
5                                 
4    +         +     +         +      
3                                 
2   +           +   +           +     
1  +             + +             +    
0 +               +                 


サイン波のような音を出せます。

ちなみにですが、波形の横幅を半分に縮めると1オクターブ高い音になりますので、
上のサイン波を

02 7d fd 72 02 7d fd 72 02 7d fd 72 02 7d fd 72

f     +       +       +       +       
e                                
d    + +     + +     + +     + +          
c                                
b                                
a                                
9                                
8 __________________________________
7   +   +   +   +   +   +   +   +         
6                                
5                                
4                                
3                                
2  +     + +     + +     + +     +        
1                                
0 +       +       +       +           


というようにすると、同じシーケンスデータで1オクターブ高い演奏が出来ます。
逆に

00 11 23 45 68 ab cd ee ff ee dc ba 86 54 32 11

f                 ++                
e               ++  ++                
d              +      +             
c             +        +            
b            +          +           
a           +            +          
9                                 
8 _________+______________+_______ 
7                                 
6         +                +        
5        +                  +       
4       +                    +      
3      +                      +     
2     +                        +    
1   ++                          +    
0 ++                                

とすると、1オクターブ低い演奏になります。

FR では、同じ波形を2回繰り返す書き方をした波形が標準（想定したオクターブで演奏できる）形のようです。


3.3 ノイズの音色作成

ボイスの先頭1バイトのうち下から3ビットが 100b の場合、ノイズを鳴らす指定となります。

ノイズは直訳すれば雑音ですが、ゲーム機ではいろいろな用途に使われています。
出力されるのは疑似ホワイトノイズです。
ホワイトノイズについての詳しい説明はぐぐってください。

ノイズの同時発音数は１です。
ノイズを複数のトラックで同時に使用しても1音しか鳴りません。

1バイト目(+00h)
	bit2-0 : 出力音源 100b
	bit3   : 謎
	bit7-4 : 未使用
2バイト目(+01h)
	謎。調べた限り常に 3ch
3バイト目(+02h)
	謎。常に 0x00 ?
4バイト目(+03h)
	謎
5バイト目(+04h)
	00h もしくは 01h。音質が変わります。
6～8バイト目(+05h～07h)
	常に 00h
9バイト目(+08h)
	アタックタイム：00h(最速)-ffh(最遅)
10バイト目(+09h)
	ディケイタイム：00h(最速)-ffh(最遅)
11バイト目(+0ah)
	サスティンレベル： 00h(mute)-0fh(最大)
12バイト目(+0bh)
	リリースタイム: 00h(最速)-ffh(最遅)

ノイズは ADSR 以外の指定はありません。
ホワイトノイズとは言いますが、実は疑似的なホワイトノイズです。
疑似的（偏りがある）なため、シーケンスで音程を指定することで、低い音のノイズから、高い音のノイズまで出すことができます。

3.4 DirectSound 用音色の作成

ボイスの先頭1バイトのうち下から3ビットが 000b の場合、DirectSound の音色指定となります。

DirectSound 用の音色は、簡単に言えば生の音を使用した音源です。
新しく音色を作成する場合、 .wav ファイルに近いものを準備することになります。

ただし、当然のように Windows で扱えるフォーマットではありません。

※ 拙作の Sappy2006 mod 版を使用すると、無圧縮の wav ファイルをインポートすることができます。
　 この場合、下記の 3.4.1 から 3.4.7 までの作業が簡単にできます。お試しください。

ここでは Audacity を使った音色の作成方法を書いていきます。

3.4.1 Audacity による音色作成

Audacity はフリーのミキシングソフトです。
普通にインストールしてください。

3.4.2 初期設定

編集(E)→設定...(P)→ファイル形式タブ→非圧縮書き出しフォーマットを「AIFF (Apple/SGI 8bit PCM)」に変更
ビュー(V)→選択フォーマットを設定→サンプル (サンプル化) を選択

3.4.3 編集

自分の使いたい音色を読み込んだり、録音してください。
音の基準はノートナンバー 60 の音(261.6Hz)です。この音程になるように録音・調整してください。
このとき、Wav の最初から音の鳴り始めまでの無音部分など、不必要な場所を消して短くしてください。
（発音が遅れると、テンポズレしてるような演奏になります）

3.4.4 ループの作成

音によってはループを作成する必要があります。

準備したWavや録音素材は有限の長さです。
演奏で使った場合、音長が足りなくて切れてしまうかもしれません。
それを回避するために、Wavそのものの長さはある程度のところで切り、そのWavの途中から繰り返し無限にWavがあるようにみせかけることで
演奏で使っても切れることのない音を作成することができます。

先ほど Audacity で開いた Wav の途中から最後までを選択します。
Shift を押しながら再生ボタンをクリックするとループモードで再生してくれます。
Wavの切れ目が目立たないループになる位置が見つかるまでWav途中の方の選択位置をずらしながら繰り返します。（選択はかならずWavの最後までとすること！）
自分がいいと思う位置が見つかったら、Audacityのステータスバーに表示されている「Selection: xxxxx - yyyyy」の xxxxx の部分をメモっておきます。

3.4.5 保存

ファイル(F)→別名で書き出し(E) AIFF... を選択して保存します。

3.4.6 バイナリエディタによるヘッダ作成とWave合成

ここからバイナリエディタの出番です。

Directsound用の音色は以下のようなヘッダを持っています。

1バイト目(+00h)
	見た限り、通常の音色は 00h 、鳴き声は 01h 。上の手順で音を作成してきたなら 00h です。
		00h の場合、無圧縮 PCM を使用する。
		01h の場合、圧縮 PCM(ADPCM) を使用する。 ADPCM が何なのかはぐぐってください。ここでは ADPCM については割愛します（鳴き声にしか使わないので）
2バイト目(+01h)
	00h
3バイト目(+02h)
	00h
4バイト目(+03h)
	bit5-0 : 見た限り全部 0 
	bit6   : 音色ループを使用する場合 1
	bit7   : 見た限り 0 
5～8バイト目(+04h～07h)
	Wav の周波数 ( / 1024 Hz、Waveの周波数を1024倍したものを記述する)
9～12バイト目(+08h～+0bh)
	ループ位置。ループする位置を wav 実体の開始位置からのバイト数で記述する。
	ループの必要の無い場合は 00h で埋める。
13～16バイト目(+0ch～0fh)
	Wav 実体のサイズ。リピートしない音色場合は実体のサイズから 1 を引いた値を書き込む。
17バイト目以降(+10h～)
	Wav 実体（8bit signed mono.）

ヘッダを上記のように16バイト作成し、その後ろに今作ったaiffファイルの先頭から +2eh 以降をペーストします。
ループを必要とする場合は、先ほどメモした xxxxx を +08h のアドレスへ16進数で書き込み、 4 バイト目の bit6 に 1 をたててください。

3.4.7 FR に組み込む

バイナリエディタで FR を開き、今作った音色ファイルを空き領域にペーストします。
これで組み込み完了です。
ループする音色の場合は、ペーストしたデータの後ろ1バイトに、リピート位置の1バイトをコピーしてください。
GBA の音源仕様で、このようにしないと音にゴミが入ります。

3.4.8 ボイスグループに登録

※通常の音色の場合はこちらです。ドラム用の音色の場合は 3.4.9 を参照のこと
実際の演奏に使うためボイスグループに登録します。
使いたい音色番号の位置に以下のようにボイスデータを記入します。

1バイト目
	bit2-0 : 出力音源 000b
	bit3   : 音程固定出力にする。どの音程のノートもそのままの音程で鳴る。
	bit7-4 : 未使用
2バイト目
	常に 3ch
3バイト目
	常に 00h
4バイト目
	常に 00h
5～8バイト目
	波形参照先アドレス
9バイト目
	アタックスピード：00h(最遅)-ffh(最速)
10バイト目
	ディケイタイム：00h(最速)-ffh(最遅)
11バイト目
	サスティンレベル： 00h(mute)-ffh(最大)
12バイト目
	リリースタイム: 00h(最速)-ffh(最遅)

波形参照先アドレスには、先ほど作ったWavをペーストした先頭アドレスを記入します。
9バイト目のアタックが、タイムでなくスピードになっていることに注意してください。
ピアノのように即立ち上がる音色は 00h でなく ffh を記入してください。
また11バイト目のサスティンレベルが、 00h～0fh でなく、00h～ffh　になっていますので、こちらも注意してください。


3.4.9 ドラムボイスグループに登録

作成した音色がドラム用の音色ならば、ドラム用のボイスグループに登録します。

使いたいノートナンバーの位置に以下のようにボイスデータを記入します。

1バイト目
	bit2-0 : 出力音源 000b
	bit3   : 音程固定音色にする。登録した音がそのまま鳴ります。
	bit4   : 不明
	bit7-5 : 未使用
2バイト目
	発音する音程
	登録した音色鳴らしたい音程ををノートナンバーで記述。
	Cn3（3ch）で登録した音がそのままの音程で鳴ります。 
	値の範囲は 00h～3ch～7fh 3ch を基準に数値を1増やすごとに1半音高く鳴り、1減らすごとに1半音低く鳴ります。
	1バイト目の bit3 が 1 の場合、この設定は無視されます。
3バイト目
	謎。常に 0x00 ?
4バイト目
	パンポット設定
	bit6-0 : パンポット強制時のパン位置 (左0～64～127右)
	bit7   : 1 = パンポット強制 , 0 = パンポット位置はシーケンスで指定
5～8バイト目
	波形参照先アドレス
9バイト目
	アタックスピード：00h(最遅)-ffh(最速)
10バイト目
	ディケイタイム：00h(最速)-ffh(最遅)
11バイト目
	サスティンレベル： 00h(mute)-ffh(最大)
12バイト目
	リリースタイム: 00h(最速)-ffh(最遅)

波形参照先アドレスには、先ほど作ったWavをペーストした先頭アドレスを記入します。
9バイト目のアタックが、タイムでなくスピードになっていることに注意してください。
ピアノのように即立ち上がる音色は 00h でなく ffh を記入してください。
また11バイト目のサスティンレベルが、 00h～0fh でなく、00h～ffh　になっていますので、こちらも注意してください。



4 シーケンスデータ (.sファイル) について

4.1 拡張子 s のファイル

FR の曲差し替えには、もっぱら MID2AGB による MIDI 変換したものを使用していると思います。
この際に拡張子 s のファイル（以下 .s ファイルと呼ぶ)が出来ます。

このファイルの実体は何なのかというと、GBA に搭載されている CPU 、 ARM のアセンブラソースです。
ここでは、この .s ファイルの構造を説明します。
MIDI から変換した場合でも、対応していない設定を追加したり、ループを作成する場合には
.s ファイルの直接変更が必要になります。

4.2 ソースファイルの構造

基本的に

	命令	引数[, 引数 …]

というものがずっと続きます。
ここでは MID2AGB が出力する命令だけに絞って説明します。

4.2.1 .byte

	.byte	0x00-0xff [, 0x00-0xff …]

1バイトのデータを置きます。置くことのできる数値は 0～255、もしくは 0x00～0xff となります。


4.2.2 .word
	.word	00000000h-fffffffh [, 00000000h-ffffffffh …]

4バイト(1ワード)のデータを置きます。
ただし、 Sappy ではラベルしか指定できません。
なお、 GBA はリトルエンディアンのため、実際にアセンブルされたときにはバイト並びが逆になります。
例）
	.word 0x1234abcd		@ アセンブルすると  CD AB 34 12 というバイト列になる


4.2.3 .align
	.align 2

4バイトのアライメント（位置揃え）をします。
つまり4バイト境界にまたがらないようにします。
この命令の入っている次の命令は、アドレスの一番下が 0h、4h、8h、ch の場所から始まるようにアセンブラに命令します。
sappy 2006 内蔵アセンブラでは無視してるっぽいです。
そのおかげでしばしば曲を差し替えたときに鳴らないという問題が発生するわけですが、それはまた別のお話。

4.2.4 .end

	.end

ソースプログラムの最後を宣言する命令で、最終行に記述します。 
アセンブラに終了を知らせるための疑似命令で、アセンブル結果には出力されません。

4.2.5 .equ

	.equ	xxx , yyy

xxx に yyy という定数を定義します。
つまり

	.equ	test_mvl , 127

とあったら、これ以降に test_mvl が出てきたら 127 と置き換えなさいという意味になります。
これも .end と同様に疑似命令で、これ自体はアセンブル時に何も出力されません。

4.2.6 .section

	.section rodata

ARM CPU ではデータ領域をいくつかに分けていますが、この命令は読み込み専用のデータ領域に配置することを宣言しています。
ぶっちゃけ sappy では音楽用の .s ファイルしかアセンブルしないので無視していると思います。

4.2.7 .global

	.global test

ARM のアセンブリソースでは必須です。アセンブルする .s ファイルのプロジェクト名を入れます。
sappy ではおまじない程度に考えてください。
ただし項目としては必須なので、省略しないでください。

2.4.8 .include

	.include "MPlayDef.s"

この場所で、指定のファイルの内容を読み込みます。
sappy でアセンブルするとき、 MPlayDef.s が無いと言われて出来ないことがありますが、ここで指定しているからです。
なお、この MPlayDef.s の中には、このソースファイルをアセンブルするために必要な情報が詰まっています。


4.2.9 ラベル

	test:

文字列＋":" で記述される行のことです。
命令の場所（アドレス）に名前を付けたい時に記述します。
サブルーチンの分岐先等の名前として、プログラムの任意の行につけることができます。
.equ 命令は、指定の「値」に別名をつける感じですが、ラベルは、指定の「位置」に別名をつけている感じと思ってください。


4.3 定数の説明

先ほど .equ の説明を書きましたが、 MID2AGB で変換した .s ファイルには
先頭にいくつか .equ 命令が出てきます。以下に例を示します。

	.equ	test_grp, voicegroup000
	.equ	test_pri, 0
	.equ	test_rev, 0
	.equ	test_mvl, 100
	.equ	test_key, 0
	.equ	test_tbs, 1
	.equ	test_exg, 0
	.equ	test_cmp, 1

この中で必要となる定数を説明します。
説明していない定数は、sappy で使う分には必要がないため、省略しました。

4.3.1 【ファイル名】_grp

ここでボイスグループのアドレスの指定をしています。
MID2AGB で変換すると「voicegroup000」という値になっていますが、
Sappy で変換するときには自動で置き換えるので、変更しないようにしてください。


4.3.2 【ファイル名】_pri

優先度を指定します。デフォルトは 0 です。
優先度とは、曲が同時に2曲以上鳴る場合（BGM+効果音なども含む）に、どちらの曲の音を優先して鳴らすかを決めるための数値です。
たとえば、壁に当たると、壁に当たっていることを表す音がしますが、 BGM が鳴っていても、その音を1音削って鳴りますね。
これは、 BGM よりも壁に当たる効果音の優先度が高く指定されているからです。
逆に BGM を効果音でどうしても切りたくない場合は、優先度を上げることで効果音を鳴らなくすることも可能です。
なお、この優先度はパルス波など、鳴る音数が限定されている音源でのみ有効で、両方の曲で同時に同じ音源が指定された場合に働きます。
優先度があっても、BGM と効果音などで、同じ音源が指定されていない場合はどちらも普通に鳴ります。


4.3.3 【ファイル名】_rev

BGMのマスターリバーブ値を指定します。 デフォルトは 0 です。
128 が中央値で 255 が最大です。1 が最小です。 0 は無効となり、前に鳴っていたシーケンスの値をそのまま使用します。
曲全体のリバーブを指定できます。が、効果音などで、別の音の初期化が来るとそちらのリバーブ値に置き換えられてしまうので、
実質的に意味のない定数になっています。


4.3.4 【ファイル名】_mvl

曲全体の音量を指定する定数です。
0が最低(mute)、127が最大になります。デフォルトは127
MID2AGB で MIDI を変換すると、 VOL 命令にこの定数がくっついてきます。
そのため、この定数を減らすと、曲全体の音量が変わります。
曲を作ったはいいものの、効果音が聞こえないくらい大きかったら、この値を小さくすることで簡単に音量調整画可能です。


4.3.5 【ファイル名】_tbs

テンポの指定を変更する定数です。デフォルトは 1 です。
MID2AGB で MIDI を変換すると、下で説明する TEMPO 命令にこの定数がくっついてきます。


4.3.6 【ファイル名】_key

キーシフトを行います。
MIDI でいう キー・トランスポーズ に相当する KEYSH 命令に影響します。
キーシフト自体は KEYSH 命令で説明します。



4.4 ファイル末尾にある曲情報（ヘッダ）

4.3 で説明した、ファイル先頭にある定数定義のほかに、ファイル末尾には、FR が演奏するために必要な曲情報が含まれています。
Sappy 等ではヘッダと呼ばれるのになぜ一番最後にあるのかというと、アセンブラの構造上、最初に置けないからだと思われます。

以下に例を示します。
これは、 MIDI トラックが6つある test.mid を変換した状態です。

test:
	.byte	6		@ NumTrks
	.byte	0		@ NumBlks
	.byte	test_pri	@ Priority
	.byte	test_rev	@ Reverb.

	.word	test_grp

	.word	test_1
	.word	test_2
	.word	test_3
	.word	test_4
	.word	test_5
	.word	test_6

	.end

なお、ソースの中で @ 以降に書いてある文字はコメントとして、アセンブラからは無視されます。
	.byte	6		@ NumTrks
とあった場合、アセンブラからは
	.byte	6
と見なされます。


4.4.1 トラック数

	.byte	6		@ NumTrks
のところです。
変換前の MIDI ファイルを MID2AGB が精査して、トラック数が全部でいくつあるか判断しています。
ここにはそれが記述されています。
変換前に比べて .s ファイルのトラック数が異様に増えていたりする場合、 MIDI ファイルが正しくないかもしれません。

4.4.2 ブロック数

	.byte	0		@ NumBlks
のところです。
用途不明です。常に0でいいと思います。

4.4.3 優先度

	.byte	test_pri	@ Priority
の部分です。
4.3.1 で説明した、 【ファイル名】_pri の定数がそのまま入ります。

4.4.4 マスターリバーブ

	.byte	test_rev	@ Reverb.
の部分です。
4.3.2で説明した 【ファイル名】_rev の定数がそのまま入ります。

4.4.5 ボイスグループ指定

	.word	test_grp
の部分です。
ここにはこの曲で使用するボイスグループのアドレスを記述します。
sappy 2006 で使う場合は特に意識する必要はありません。（アセンブル時に指定するため）

4.4.6 各トラックの先頭位置xトラック数

	.word	test_1
	.word	test_2
	.word	test_3
	.word	test_4
	.word	test_5
	.word	test_6
の6行のことです。
ここには各トラックの演奏開始位置を記述します。
基本的にラベルで指定されているので、変更する必要はありません。


余談

ちなみにに、上のヘッダ部分は以下のようなバイナリデータにアセンブルできます。

06 00 00 00 44 78 44 08 48 02 68 08 7d 02 68 08
a8 02 68 08 e4 02 68 08 05 03 68 08 46 03 68 08

上のバイナリの場合、各ラベルは以下の値に置き換わったことになっています。

test_pri = 0
test_rev = 0
test_grp = 08447844h
test_1   = 08680248h
test_2   = 0868027dh
test_3   = 086802a8h
test_4   = 086802e4h
test_5   = 08680305h
test_6   = 08680346h



4.5 各命令の簡単な説明

上では、先頭と末尾の情報の説明をしました。
ここでは、残った中央部の説明を行います。

中央部は、シーケンスデータそのものです。
基本的にどれも .byte もしくは .word の後に書かれているので、それは省略します。



4.5.1 KEYSH (Key shift)

次に続く1バイトでトラック全体の音程変更の指定をします。値の範囲は　80h(-128)～00h(0)～7fh(+127) です。
1ごとに半音ずつ上下します。

0 が中央値(キーシフト無し）で、1上がるごとに半音上がり、1下がるごとに半音下がります。
-128(80h) が最小です。 0 は無効です。127(7fh) が最大です。
カラオケにある音程変更と同じようなものです。
使用する場合は、ノートナンバーが 0～127 の範囲を超えないように注意してください。


4.5.2 TEMPO

次に続く1バイトでテンポを指定します。
１つのトラックで指定すると、すべてのトラックに影響します。

MID2AGB で変換した .s ファイルには、TEMPO 命令の引数に [BPM値]*【ファイル名】_tbs/2 という式が入ります。
MID2AGB に -X 引数を与えずに変換すると【ファイル名】_tbs に 1 が入り、計算結果は BPM/2 となりますが、これには理由があります。

FR に実装されているサウンドドライバはタイムベース(分解能) 48 で動作します。
しかし、普通に曲を作る場合、タイムベースは 48 も必要がないことが多いです。
そこで MID2AGB では通常テンポを半分にし、見かけのタイムベースを半分にすることで
シーケンスサイズやマシンパワーの節約をするようになっています。
実用的な用途としては、テンポの遅い曲で分解能あげる場合が考えられます。


4.5.3 VOICE

次に続く1バイトで次の命令から使用するボイスを指定します。
値の範囲は0～127。
ボイスを指定していないトラックでは全く音が鳴りません。
必ず発音前に VOICE 命令が入っているか確認してください。


4.5.4 PAN (Panpot)

次に続く1バイトでパンポットの指定を行います。
値の範囲は0（最も左）～64（中央）～127（最も右）
MID2AGB で変換したソースの場合は、 MPlayDef.s で定義されている c_v 定数(値は64)を使って、 c_v-64(=0)～c_v+0(=64)～c_v+63(=127) のように指定されます。
DirectSoundは左から右までリニアに、それ以外の音源では3方向（「左(0～31)」「中央(32～95)」「右(96～127)」）に振り分けられます。


4.5.5 MOD (Modulation)

次に続く1バイトでモジュレーション強度を表します
値の範囲は0～127です。
デフォルトではピッチベンドに適用され、ビブラートの深さの指定になります。
モジュレーションの速度や適用先を決定するには、下の MODT LFOS LFODL を使用します。


4.5.6 MODT (Modulation Type)

次に続く1バイトでモジュレーションの適用先を指定します。

0…ピッチベンド指定
	これ以降の MOD はピッチベンドに適用され、ビブラートのような音の揺れを簡単に表現できます。
1…ボリューム指定
	これ以降の MOD はボリュームに適用され、トレモロのような音量の揺れを簡単に表現できます。
2…パンポット指定
	これ以降の MOD はパンポットに適用されます。左右へ一定周期で揺れる音源を簡単に表現できます。

実際の指定は、MPlayDef.s 内の .equ 定数定義によって、以下のように指定できます。

ピッチベンド指定。
	.byte	MODT , mod_vib
ボリューム指定。
	.byte	MODT , mod_tre
パンポット指定。
	.byte	MODT , mod_pan


4.5.7 LFOS (LFO Speed)

次に続く1バイトで LFO の速度を決定します。
LFO とは、 Low Frequency Oscillator の略で、直訳すると低周波発生器となります。
低周波発生器では、非常に遅い揺れをもつ波を作り出します。
これにより発生させた低周波はそれ単体で使うわけではなく、
MODT で各出力に繋ぐことで曲の表現力を高めることが出来ます。

LFOS 命令は、その振幅速度を指定します。
速度は曲のテンポに依存し、以下の式で表現されます。
　　　　　　　 256
振幅速度 ＝ ----------
　　　　　　　指定値
速度の単位はステップタイムです。
MID2AGB の標準では 4 分音符＝24 ステップタイムなので、
指定値に 11 を入れると、上の式の答えが 23.2 となり、だいたい4分音符に1回程度の振幅が表現できることになります。

+　 ++　　　　　　++
|　+　+　　　　　+
| +　　+　　　　+
0+------+------+----->時間
| 　　　 +　　+
| 　　　　+　+
-　　　　　++　
 |--振幅速度---|

上の例の 11 だとこの時間が 23.2 ステップタイムとなる。
初期値は 22 。


4.5.8 LFODL (LFO Delay)

次に続く1バイトをステップタイムとし、 LFO の入力を指定ステップタイム分遅らせます。

デフォルトは 0 で無効となっています。
1 以上の値を指定すると、発音のたびに LFO の入力がリセットされ（パンポットで言えば中央に戻される）、
指定されたステップタイムの後に LFO による振幅がスタートするようになります。

これにより、 MOD 値をいちいち指定しなくても、一定の発音後にビブラートをかける処理を自動で行うことができます。


4.5.9 BEND (Pitch bend)

次に続く1バイトでピッチベンドを変化させます。 MIDI の Pitchbend と同等ですが、
値の範囲が小さいため MIDI ほどの細かい制御はできません。
値の範囲は0～64～127。MID2AGB で変換したソースの場合 c_v-64～c_v+0～c_v+63 で表現されます。
デフォルトでは c_v-64 で -2 半音、 c_v+63 で +2 半音分のベンドが可能。
振幅範囲を指定するには下の BENDR を使用します。


4.5.10 BENDR (Bend Range)

次に続く1バイトで BEND で使用するピッチベンドの範囲を指定します。MIDI の Pitchbend Sensitivity と同等です。

値の範囲は 0～255。デフォルト値は 2 。実用的な範囲は 12 程度まで。
1 で最大±1半音分、12 で最大±12半音（つまり±1オクターブ）分のピッチベンドを行うことができます。


4.5.11 PATT (Pattern) & PEND (Pattern End)

PATT の次に続く4バイトのアドレスにジャンプ、PEND でリターンします。
なお、PATT によるジャンプをしていないときの PEND は無視されます。
PATT でジャンプ中にさらに PATT が入る動作（入れ子の関係）は、3段まで可能です。

この機能は、簡単に言うと同じ演奏パターンが繰り返し出てくる時、
それを 1 度だけ記述して、以後はその部分を演奏しなさいという命令に置き換えるものです。
この機能により、シーケンスデータのサイズを減らすことができます。
MID2AGB では、この機能は標準で有効で、ラベルと PATT 、PEND が自動的に挿入されるため
通常は気にする必要はありません。

気にする必要が出てくるのは、シーケンスデータを決まった容量以下に押さえる必要がある場合等です。

MID2AGB が自動生成するパターン命令は小節単位になっていますが、仕様上はそれ以上やそれ以下のパターンを作ることも可能です。
パターンの作成方法は、以下のようにします。

(1)パターンの先頭となる部分にラベルを記述
(2)パターン終了となる部分に PEND 命令を記述
(3)パターンを演奏したい部分に PATT 命令 + ラベルを記述

@ 010 ----------
pattern_1:			@ (1) パターン開始位置にラベル配置
	.byte 　　 N12 , Cn3 , v100
	.byte W12
	.byte　　        Cn3
	.byte W12
	.byte　　        Dn3
	.byte W12
	.byte　　        En3
	.byte W12
	.byte 　　 N36 , Fn3
	.byte W48
@ 011 ----------
	.byte 　　 N12 , Gn3
	.byte W12
	.byte 　　       Gn3
	.byte W12
	.byte 　　       An3
	.byte W12
	.byte 　　       Bn3
	.byte W12
	.byte 　　 N36 , Cn4
	.byte W48
	.byte PEND		@ (2) パターン終了位置に PEND
@ 012 ----------
～～～～～～～～～～～～～～～
～～～～～～～～～～～～～～～
@ 020 ----------
	.byte PATT		@ (3) 指定パターンを演奏したい部分に PATT＋ラベルを記述
	.word pattern_1
@ 022 ----------


【注意点】
PATT を自分で設定する場合に注意点がいくつかあります。

(1)
パターン開始位置直後のノートの省略に注意してください。
パターンジャンプをした場合、直前のノートの違いにより省略したノートの鳴り方が変わる可能性があります。

以下のシーケンスデータをみてください。

	.byte 　　 N36 , Fn3 , v100
	.byte W48
@ 016 ----------
pattern_2:
	.byte 　　     　Cn3　　　　 @ パターン開始位置にノート省略形
	.byte W36
	.byte 　　 N12 , Cn3
	.byte W12
	.byte　　        As3
	.byte W12
	.byte　　        An3
	.byte W12
	.byte　　  N18 , An3
	.byte W24
	.byte PEND　　 　　　　　　　@ パターン終了位置
@ 017 ----------
～～～～～～～～～～～～～～～
～～～～～～～～～～～～～～～
	.byte　　  N12 , Gn3 , v127
	.byte W12
@ 023 ----------
	.byte PATT　　　　　　　　　 @ PATT 指定
	.word pattern_2
@ 024 ----------

16小節目の最初がパターン開始になっていますが、最初のノートが省略形を使っています。
16小節目がはじめに再生されるときは、一つ前に演奏したノートが
	.byte  N36 , Fn3 , v100
のため、該当のノートは
	.byte  N36 , Cn3 , v100
と補完されます。
しかし、23小節目の PATT による繰り返し演奏時には、一つ前に演奏したノートが
	.byte  N12 , Gn3 , v127
です。そうなると、ジャンプ直後のノートは
	.byte  N12 , Cn3 , v127
となり、ゲートタイムが36→12、ボリュームが 100→127 となってしまいました。
こうならないために、MID2AGB ではパターン開始位置のノートは省略せずに記述しているようです。
1バイトでも削りたいというような場合を除き、ジャンプ前のノートの省略は避けましょう。

(2)
ジャンプ命令は5バイト消費します。5バイト以下のパターンを作成してジャンプしても、容量が無駄になります。

(3)
PATT/PEND は 3 段までネスト（入れ子）することが出来ます。
おそらくエラートラップは無いので、それ以上のネストがかかるとバグります。


4.5.12 GOTO

次に続く4バイトのアドレスへジャンプします。
PATT と違い、ジャンプ先から戻ることはなく、指定アドレスから再生が続けられます。
BGM など、ずっと演奏し続ける曲のループに指定します。
ジャンプ命令のため、PATT を設定する場合と同じようにノートの省略には細心の注意を払ってください。

GOTOの作成方法は、以下のようにします。

(1)GOTOでジャンプしたい位置の直前にラベルを記述
(2)ループしたい位置に GOTO 命令 + ラベルを記述

	.byte W12
@ 002 ----------
loop_1:				@ (1) ループ開始の直前にラベル配置
	.byte 　　 N12 , Cn3 , v100
	.byte W12
	.byte 　　       Cn3
	.byte W12
	.byte 　　       Dn3
	.byte W12
	.byte 　　       En3
	.byte W12
	.byte 　　 N36 , Fn3
	.byte W48
@ 003 ----------
～～～～～～～～～～～～～～～
～～～～～～～～～～～～～～～
	.byte W06
@ 020 ----------
	.byte GOTO		@ (2) ループしたい部分に GOTO＋ラベルを記述
	.word loop_1


4.5.13 FINE

ループも無くこの命令にたどり着いた場合、曲の演奏が終了します。
GOTO によるループ演奏曲の場合は無くても動作に支障はありません。
ただし、 sappy 2006 の Export tracks 機能では、これを曲（トラック）の終了位置としているらしく
FINE 命令で終わっていないトラックは正常に抜き出せなくなります。
ちなみに、×ファイン→○フィーネ


4.5.14 REPT (Repeat)

次に続く1バイトの回数、その次に続く4バイトのアドレスとの間を繰り返し演奏します。
書き方は以下のようになります。

@ 002 ----------
loop_1:				@ (1) ループしたい位置の直前にラベル配置
	.byte 　　 N12 , Cn3 , v100
	.byte W12
	.byte 　　       Cn3
	.byte W12
	.byte 　　       Dn3
	.byte W12
	.byte 　　       En3
	.byte W12
	.byte 　　 N36 , Fn3
	.byte W48
@ 003 ----------
	.byte REPT , 3
	 .word loop_1

上記では、 loop_1 と REPT の間が 3 回繰り返します。
この「3」回は、初回（REPT による繰り返しが開始する前）を含みます。
そのため REPT,1 とすると REPT 命令は何もしませんし、 REPT,0 とすると無限ループになりますので、注意してください。

4.5.15 XCMD (extend command)

次に続く 1 バイトで特殊な命令を指定、さらに次の 1 バイトでその命令に対する値を指定します。
特殊命令には次の2つだけが定義されています。
	xIECV : エコー音量
	xIECL : エコーの深さ
この命令を使用すると、トラックごとのエコーを指定することができます。
2 つで 1 セットで使用します。デフォルトではどちらも 0 です。
以下のように指定を行います。

@ 001 ---------------
	.byte XCMD , xIECV , 16    @ echo Volume = 16
	.byte XCMD , xIECL , 8     @ echo Length = 8

値によりエコーのかかり方が変わりますが、強度は各自で判断してください。
拡張命令というところから、おそらく対応した ROM でのみ使用可能ではないかと思われますが、どれで使用可能かはわかりません。
※ FR では使用可能です。

4.6 ノート、ステップタイム（デルタタイム）の表記方法


4.6.1 ステップタイム（デルタタイム） 

ステップタイムとは、次のステップに行くまでの時間のことです。
タイムベースが 24 の場合は 24 で 4 分音符の長さになります。

	.byte  W24       @ 4分音符1つ分待つ

値の範囲は 0～96 ですが、すべてを指定できるわけではありません。
使える値は以下の通りです。
W00,W01～W24,W28,W30,W32,W36,W40,W42,W44,W48,W52,W54,
W56,W60,W64,W66,W68,W72,W76,W78,W80,W84,W88,W90,W92,W96
これ以外の長さを指定する場合には、表記を2つ以上連ねる必要があります。

例）W25 を実現したい場合

        .byte   W24
        .byte   W01

ちなみに W00 という定義はあっても使われません。


4.6.2 ノート命令

音を鳴らします。

以下のような 3 バイト、もしくは 4 バイトで１つの音を表します.

	.byte   ゲートタイム , 音程 , ベロシティ [, gate+ ]


4.6.2.1 ゲートタイム（音の長さ）

MIDI のゲートタイムと同等です、指定された長さ分の音を鳴らします。
頭に N をつけた数値で表します。 N01 等
ステップタイムと同様に、タイムベースと同じ値が 4 分音符の長さになります。
とりえる値は 1～96 ですが、1～96 までのすべての値を持っているわけではありません。
取りえる値は以下の通りです。
N01～N24,N28,N30,N32,N36,N40,N42,N44,N48,N52,N54,
N56,N60,N64,N66,N68,N72,N76,N78,N80,N84,N88,N90,N92,N96

これ以外の値を扱いたい場合、後述する 4 つめの引数の gate+ や TIE 表記を使います。


4.6.2.2 音程（ノートナンバー）

指定した音程の音が鳴ります。
とりえる値は CnM2(00h)～Gn8(7fh) です。
表記の仕方が MIDI と多少違います。

 .s  | MIDI | ノートナンバー
-----+------+----------------
CnM2 | C-2  | 00h (  0)
GsM1 | G#-1 | 14h ( 20) 
Dn0  | D0   | 1ah ( 26)
Cn3  | C3   | 3ch ( 60)
Fs3  | F#3  | 42h ( 66)
Gn8  | G8   | 7fh (127)

ノートナンバーとの対応は Cn3 = 60 です。


4.6.2.3 ベロシティ（音の強さ）

MIDI そのままです。大きいほど音が強く鳴ります。
とりえる値は 0(弱)～127(強) で、0 は鳴りません。


4.6.2.4 gate+

MIDI ではゲートタイムは 0 以上の任意の整数をとることができますが、
FR のサウンドドライバでは前述のように、ある決まった値しか指定することが出来ません。
これはファイルサイズの節約という意味では非常に有用ですが、反面、音楽の表現力は乏しくなってしまいます。
そこで gate+ という値を用いることによって、その中間値を作ることができるようになっています。
gate+ は、通常は記述しない 4 つ目の値のことで、以下のように記述します。

	.byte	N24 , Cn3 , v100 , gtp1

gate+ は、 gtp1 , gtp2 , gtp3 の 3 つの値を取ることができ、それぞれ +1 , +2 , +3 だけゲートタイムに加算することができます。
上の例では 24+1 となり、ゲートタイム 25 のノートと解釈されます。

なお、 MID2AGB にオプション -E をつけて MIDI を変換すると、gate+ を使用した .s ファイルを出力します。
（-E オプション無しで変換した場合、短くなる方向で一番近い値へ切り詰められます。上のゲートタイム 25 の場合だと 24 になります。）


4.6.3 特殊なベロシティ指定 TIE , EOT

特殊なベロシティ表記として、 TIE , EOT があります。これは楽譜でいうタイを表現するものです。
ゲートタイムとして TIE を指定した場合、その音は EOT が来るまで鳴り続けます。

以下のように記述します。

	.byte		TIE , Gn3 , v100	@ G3 、ベロシティ 100 で発音
	.byte	W96
	.byte	W48
	.byte		EOT , Gn3 , v100	@ G3 、ベロシティ 100 で発音している音を消す

これでゲートタイム 144 で Gn3 の音を鳴らすことができます。


4.7 ノート・命令の省略（ランニングステータス）

ノートは一部の引数を省略することができます。
ひとつ前の音と同じゲートタイム、音程、ベロシティ の場合に、同じ部分はデータを省略することができます。
この省略方式を MIDI の用語では「ランニングステータス」と呼びます。

たとえば

	.byte	　　 N24 , Cn3 , v100
	.byte	W24
	.byte	　　 N24 , Dn3 , v100
	.byte	W24
	.byte	　　 N24 , En3 , v100
	.byte	W24
	.byte	　　 N24 , Fn3 , v100
	.byte	W24
	.byte	　　 N24 , Gn3 , v100

というシーケンスが合ったとした場合、
この5つのノートは、音程だけ違い、音長、音の強さは変わっていません。
このように、一つ前のノートと同じところがある場合は省略ができます。
上記のシーケンスの場合、2つ目以降のノートの N24 と v100 を省略し

	.byte   　　 N24 , Cn3 , v100
	.byte	W24
	.byte         　　 Dn3
	.byte	W24
	.byte         　　 En3
	.byte	W24
	.byte         　　 Fn3
	.byte	W24
	.byte         　　 Gn3

と書くことができます。
間にステップタイムが入ってもノートの省略は有効です。

なお、 TIE、EOT を使ったノートも、他のノート命令と同じく省略した書き方が可能です。

	.byte		TIE , Gn3 , v100	@ G3 、ベロシティ 100 で発音
	.byte	W96
	.byte	W48
	.byte		EOT			@ G3 、ベロシティ 100 で発音している音を消す


前のノートとベロシティだけが違う場合、ベロシティだけ書くことはできません。必ず音程とセットにしてください。
ひとつ前とまったく同じ場合は最低限、ゲートタイムか音程のどちらかを記述する必要があります。

	.byte	　　 N24 , Cn3 , v100
	.byte	W24
	.byte	　　 N24 , Cn3 , v075
	.byte	W24
	.byte	　　 N24 , En3 , v100
	.byte	W24
	.byte	　　 N24 , En3 , v100

　　　　　　　　　↓↓↓

	.byte	　　 N24 , Cn3 , v100
	.byte	W24
	.byte	　　       Cn3 , v075   @ 違うのはベロシティ値のみだが、音程も書く
	.byte	W24
	.byte	　　       En3 , v100
	.byte	W24
	.byte	　　 N24                @ 一つ前と同じだが、ゲートタイムのみ書く。

ただし、 gate+ を使う場合は、省略形の表記が制限されます。
gate+ にはランニングステータスは適用されません。

	.byte　　　　N32 , En4 , v068 , gtp1	@ ゲートタイム 33
	.byte	W36
	.byte	     N32 , En4 , v068 , gtp1	@ ゲートタイム 33
	.byte	W36
	.byte　　　　N06 , As3 , v068		@ ゲートタイム 6
	.byte	W06
	.byte　　　　N06 , Bn3 , v068		@ ゲートタイム 6

　　　　　　　　　↓↓↓

	.byte　　　　N32 , En4 , v068 , gtp1
	.byte	W36
	.byte　　　　　　　En4 , v068 , gtp1　　@ 一つ前とまったく同じノートだが、ゲートタイムしか省略できない
	.byte	W36
	.byte　　　　N06 , As3　　　　　　　　　@ ボリューム省略。 gate+ は指定されたノートでのみ有効で、
	.byte	W06　　　　　　　　　　　　　　 @ 省略されているからといって次のノートへは影響しません。
	.byte　　　　　　　Bn3　　　　　　　　　@ 逆に、必要なノートにはすべて gate+ を記述する必要があります。



同様に、一部の命令でも省略形を使うことができます。
以下のものが連続した場合には、命令を省略することができます。

	.byte VOICE
	.byte VOL
	.byte PAN
	.byte BEND
	.byte BENDR
	.byte LFOS
	.byte LFODL
	.byte MOD
	.byte MODT
	.byte XCMD

ボリュームやパン位置を連続で値を変化させる場合に有用です。

例１）パンポットを連続で変化させる場合

	.byte PAN , c_v+63
	.byte PAN , c_v+20
	.byte PAN , c_v-20
	.byte PAN , c_v-64

	　　　↓↓↓

	.byte PAN , c_v+63
	.byte       c_v+20
	.byte       c_v-20
	.byte       c_v-64

ノートと同じように、間にステップタイムを挟んでも省略は有効です。

例２）4分音符1拍ごとにパンポットを連続変化させる場合

	.byte       PAN , c_v+63
	.byte W24
	.byte       PAN , c_v+20
	.byte W24
	.byte       PAN , c_v-20
	.byte W24
	.byte       PAN , c_v-64

               ↓↓↓

	.byte       PAN , c_v+63
	.byte W24
	.byte             c_v+20
	.byte W24
	.byte             c_v-20
	.byte W24
	.byte             c_v-64

例３）省略できない場合

とあるドラムパート

	.byte       N05 , Cn1 , v088
	.byte W12
	.byte       N05 , Cn1 , v088
	.byte       N05 , Cs1 , v068
	.byte W24

               ↓↓↓

	.byte       N05 , Cn1 , v088
	.byte W12
	.byte       N05               @ N05 , Cn1 , v088 を想定
	.byte             Cs1 , v068  @ N05 , Cs1 , v068 を想定
	.byte W24

この場合の省略状態には間違いがあります。これでは、3行目と4行目が正しく処理されません。

.s ファイルでは、「改行」によって隔てられていますが
アセンブルすると、これらはすべて一連のバイナリデータとなります。
人が見やすいように1命令、1音ずつ改行をしていますが、実際には

	.byte  N05 , Cn1 , v088 , W12 , N05 , Cs1 , v068 , W24

という表記と同じなのです。
これを見ると、3行目と4行目だったところが繋がってしまい、1つの省略なしのノートになっています。
再び改行を入れて見やすくすると、

	.byte       N05 , Cn1 , v088
	.byte W12
	.byte       N05 , Cs1 , v068 @ もともと2つだったノートが 1 つとして解釈されてしまった
	.byte W24

このように、バイナリにした時に繋がって 1 音になってしまうような省略はできません。

この場合は

	.byte       N05 , Cn1 , v088
	.byte W12
	.byte             Cn1         @ N05 , Cn1 , v088 を想定
	.byte             Cs1 , v068  @ N05 , Cs1 , v068 を想定
	.byte W24

このように、省略形の前後で残す部分を同じにするか、省略をしないで書く必要があります。


----

付録．各音源についての解釈

それぞれの音源ごとに同時発音数が決まっているということは 2.2 でちょっと触れましたが、
以下のように各音源がそれぞれ独立したMIDIの音源のような動作をすると考えてもらうと
わかりやすいんじゃないかと思います。

それぞれ独立しているので、他の音源から発音数を借りることはできません。

                 　　     シーケンス　　　　　　　　　　　　　　　　
　ボイスグループ       　　 トラックのボイス設定 　  　　 音源　　　同時発音数
┌───────┐          ┌─────┐
│0.DSドラム　　│────→│　   0    │─┐
├───────┤          └─────┘  │
│1.DS Piano  　│─┐      ┌─────┐  │      ┌──────┐
├───────┤  └──→│　   1    │─┼──→│Direct Sound│同時発音数５
│13.DS Xylophon│          └─────┘  │      └──────┘(ROMの1c1085hのbit3-0で増減可能)
├───────┤          ┌─────┐  │
│47.DS Timpani │────→│　  47    │─┘
├───────┤          └─────┘
│73.DS flute 　│          ┌─────┐          ┌──────┐
├───────┤  ┌──→│　  80    │────→│ パルス波１ │同時発音数１
│80.パルス1　　│─┘      └─────┘          └──────┘
├───────┤          ┌─────┐          ┌──────┐
│81.パルス2　　│────→│　  81    │────→│ パルス波２ │同時発音数１
├───────┤          └─────┘          └──────┘
│82.パルス1　　│          ┌─────┐          ┌──────┐
├───────┤  ┌──→│　 126    │─┬──→│ 　ノイズ　 │同時発音数１
│126.ノイズ　　│─┘      └─────┘  │      └──────┘
├───────┤          ┌─────┐  │      ┌──────┐
│127.ノイズ　　│────→│　 127    │─┘      │ 波形メモリ │同時発音数１
└───────┘          └─────┘          └──────┘

上の例では、ボイスグループには同じ音源に対する設定が複数設定されており、また、シーケンストラックでもそれを同時に設定しています。
ところが、ボイス 126 と 127 のように、同時発音数１音のはずの旧来からの GB 音源に対して複数のトラックに指定することもできます。
一見意味が無いように見えるのですが、それぞれのボイスで ADSR の指定を変えれば、たとえばノイズ音源ならハイハットとシンバルのような鳴り分けをすることができます。
あくまで各音源の同時発音数を超えなければ問題が無いので、同時に鳴らさないという条件のもと、このような指定が可能なのです。
同じ要領でパルス波の音色（デューティー比）などを複数作り、曲中で鳴り分けるといったことも可能です。




----

参考情報

（１）sappy 2006 で .s ファイルをアセンブルすると一部の音長が正しく解釈されない？？？

※ この症状は拙作の Sappy2006 mod 版を使用することで回避できます。

自分の環境では、以下のような症状が発生しました。

今のところ、W40, N40, v040, v041 のそれぞれが W16, N16, v016, v017 と認識されてしまいます。
また c_v-40,c_v-41,c_v+40,c_v+41 も c_v-16,c_v-17,c_v+16,c_v+17 に変わってしまうようです。
そのため、これらの値が .s ファイル中に出てきた場合は、他の値、もしくは TIE 等を使って実現したほうがいいかもしれません。

例１）
	.byte	W40

　　　　　↓↓↓

	.byte	W36
	.byte	W04

例２）
	.byte        PAN , c_v+40
	.byte	     N40 , Cn3 , v040

　　　　　↓↓↓

	.byte        PAN , c_v+39	@ 40 を避けて 39 に
	.byte	     TIE , Cn3 , v039	@ 40 を避けて 39 に
	.byte	W36
	.byte	W04
	.byte	     EOT		@ N40 を TIE で表現

　　　　　または

	.byte        N36 , Cn3 , v039 , gtp3 @ N39 で表現

MIDI では問題ないのに、変換したらずれたという人は、これらの値を使っていないか確認してみてください。
なんか 40,41 の即値が全部 16,17 に置き換わってるような気がします…（汗


（２）音量の限界について

GBA の音源のうち DirectSound は、本文中にも書いた通りソフトウェア MIDI のような動作をしています。
出力される波形はソフトウェアで合成しています。
最終的な合成波形は、単純な足し算を波形の数だけ繰り返し行うことで生成されますが、その計算結果が計算できる限界値を超えてしまうことがあります。
これをオーバーフローと呼びます。いわゆる桁あふれのことで、電卓で桁数オーバーでエラーになるようなものです。
エラーであればそれを補正する方向に処理してくれればいいのですが、 GBA ではエラーのあるままにそのまま音源へ送信されます。

限界を超えた波形は、そのままの波形が反対側に出てきてしまいます。
プラス側にオーバーフローした場合マイナスへ、マイナス側にオーバーフローした場合プラス側にはみ出るため、
まったく意図しない波形となり、結果、これは雑音となってしまいます。
はみ出方が多少であれば、それはプチノイズとして聞こえる程度ですが、
盛大にはみ出ると、もはや音ではない、単なる雑音になってしまいます。

これは GBA のボリュームつまみをいじっても解消されないため、シーケンス側の音量を下げることが必要になります。


（３）各人形の鳴き声について

鳴き声は DirectSound 経由で鳴ります。
基本的には DirectSound の音色と同じように書かれていますが、実体は圧縮されています。
圧縮方式は ADPCM で、 64 バイトを 1 単位として 33 バイトに圧縮しています。
圧縮されたボイスが BGM 用の音色として使えるかは検証していませんが、仮に使えたとしても
圧縮ボイスは同時に 2 音までしか鳴らせないらしい上、鳴き声ともかぶりますので、実質的には使えないと思います。
なお、鳴き声の変更については、拙作のツール「Pokemon Cry Import Tool」を使用してください。


（４）Sappy でアセンブルしたときに音が鳴らない現象について

Sappy2006 で曲をインポートしたときに、Sappy2006 自体では曲は鳴るのに、実際にゲーム中では鳴らないという現象が発生することがあります。
この現象は、 GBA に搭載されている ARM 系の CPU がメモリの読み込み位置を制限しているからです。
特定の場所からの読み込みにしか対応しない分、 CPU の構造を簡単にでき、消費電力を下げられるからです。もとからモバイルなどの小型端末を想定した CPU のためです。
（現在のパソコンの標準である Intel 系の CPU では、制限が無い代わりに CPU の構造は複雑です）
そのために、読み込み位置をプログラム側で正しく指示しなければ、 CPU はメモリからデータを読み込むことが出来ないのです。

簡単に言えば、曲リスト、ボイスグループ、ボイスなどを配置する時には、開始アドレスの下1桁が必ず 0h , 4h , 8h , ch になっている必要があります。
（シーケンスデータだけは読み込み方の違いでどこから始まっても問題ありません）

本来なら、本文中で説明したように .s ファイルに書かれた .aglin 2 命令によりそれが行われる（適当に隙間を空けて
アドレス下1桁を 0h,4h,8h,ch の位置にする）のですが、どうやら Sappy 2006 ではこれを無視している様子。
その結果、曲を差し替えた時に鳴らないということが起こり、再配置（Export Tracks で書き出して、書き換え前のものに Import Tracks で再書き込み）が必要になるのです。
書き換え前のファイルへ Import Tracks をすることで、ヘッダ位置の項目が自動的に差し替え前の曲のアドレス（つまり、正しくBGMが鳴るヘッダアドレス）になるため、
この制限を知らずに回避していることになります。

なお、拙作の Sappy2006 mod 版では align 命令を正しく処理するため、（意図的でない限り）この問題は発生しません。

※追記：最新仕様の ARM CPU ではどの番地からのメモリ操作も可能になっているそうです。


-----

履歴
Ver. 1.0 初版
Ver. 1.1 LFO 関連の記述を追加、 PATT-PEND と GOTO の記述を詳細にした。そのほかちょこちょこ追記
Ver. 1.2 波形メモリ音源の音量についての記述を追加。gate+ についての記述を追加。誤字脱字修正。同時発音数の概念を図式化してみた。
Ver. 1.3 ボイスグループの2バイト目、4バイト目の記述を変更。同時発音数や最大トラック数についての記述を追加。ほかもいろいろ更新。＼ながい／
Ver. 1.4 VOL,PAN,MOD,BEND の省略について記述。一部表記ミスを修正。音量の限界などの参考情報を拡充。
Ver. 1.5 省略形の省略できない場合について記述
Ver. 1.5a  DirectSound 音色を自分で作るときのデータの扱いをちょこっと更新。処理速度稼ぐためにいろいろ例外が…
Ver. 1.6 とりあえず、sappy を改造しててわかった内容をちょこちょこと追加。REPT 命令記述。
Ver. 1.6a 一部説明追加。






あとがき


       ＼もうだめぽ／

　　 　 ＿　,,,_／|　　
　 　　＼,.≧─ -､| 　 
 　　　　ｲ　　　　`、　
 　　　　i　 ル､从　｝ 
 　　　　j ( ┃ ┃!<　 
 　　.-（ ヾ.､ r,ｨﾉァ  
 　　｀x,>^^ヾﾊ ﾊ^<フ  
　　 　 ヽ ﾉ  ^ ^ヽﾒ 　


まさか1400行超えとか…。って言ってたら1500になった（汗）……ってか1600じゃん……
本気で長くてすいません…orz

「ここはこうしたほうがいい」とか「ここは違うわﾎﾞｹ」など、何かあれば意見プリーズ。














-----

おまけ

ここから下は、テキストをまとめる際に作っている自分用のメモです。
上で書いてないことも書いてあったりします。
なぜ全部をまとめてないかというと、用途不明の値があるからです。


↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓


VOICEグループ先頭 0x44e8cc - 0x467cb7
	ポケモン鳴き声テーブル(20) 0x451554 - 0x452783
	ポケモン鳴き声テーブル(30) 0x452784 - 0x4539b3
謎の領域 0x467cb8 - 0x467e2b
波形メモリ音源テーブル 0x467e2c - 0x467edb
レイヤ情報（トラック情報保持アドレス１，２、最大トラック数） 0x467edc - 0x467f07
シーケンステーブル 0x467f08 - 0x4689e7

Wave table 位置
例：0x4689e8
+0	00 00 00 : 謎
+3      40 : bit6 : ループフラグ 1=ループ有り, 0=ループ無し
+4	00 43 34 00： Wave 周波数 ( / 1024 Hz )
+8	bb 02 00 00 ：ループ位置。ノート OFF まで鳴らす場合にこの位置からのWaveを繋ぐ
+C	92 06 00 00 ：サイズ（もしかしたらサイズ＋１が実サイズかもしれない）
+10～	：Wave実体 8bit signed mono.
テーブルヘッダは4バイトのアライメントが必要

ポケモン鳴き声
+0	01 00 00：謎。特に最初の 0x01 が謎。鳴き声だけについてるっぽい。
+3	00 : bit6 : ループフラグ 1=ループ有り, 0=ループ無し
+4	00 43 34 00： Wave 周波数 ( / 1024 Hz )
+8	00 00 00 00 ：ループ位置 （鳴き声にループは無いので 00 ？)
+C	92 06 00 00 ：サイズ（もしかしたらサイズ＋１が実サイズかもしれない）
+10～	：Wave実体 8bit signed mono.
テーブルヘッダは4バイトのアライメントが必要

Wave table 終了 0x67a27f 

シーケンスデータ位置 0x67a280 - 0x6c0ae3
先頭ヘッダ位置 0x67a280 00 00 00 a8 cc e8 44 08 ：無音。トラック数0、VOICEグループ定義しかない。
最終ヘッダ位置 6c0acc 最終シーケンス位置 0x6c0a10

----

40 VOICE セットについて

音域指定用セット。
ノートナンバーごとに、使う音色を指定する。
下の 80 VOICE セットとの違いは、80 指定はノートナンバーごとに音色の実データを指定するが、
40 指定では、数個の音色の実データの定義と、ノートナンバーごとにその数個の音色のどれを使うかを指定する。
音程調整は行われるので、低い音と高い音で違う音色実データを使いたいといった時に使用する。

例：ピアノ音（40 00 00 00 48 f1 44 08 94 7c 46 08）
+4	48 f1 44 08 ： VOICE Table (alt)
+8	94 7c 46 08 ： 使用音色テーブル

使用音色テーブル
ノートナンバー 0 から 1 バイトずつ 128 個、使用する音色の定義。
0なら0番目、1なら1番目…

FRに定義されている 40 のセット
40 00 00 00 78 f1 44 08 dc 7c 46 08
40 00 00 00 9c f1 44 08 24 7d 46 08
40 00 00 00 c0 f7 44 08 78 7d 46 08
40 00 00 00 d8 f7 44 08 c0 7d 46 08

-----

80 VOICE セットについて

VOICEテーブルの参照先から128個のドラム用VOICEテーブル定義を読み込む。
ドラム用VOICEテーブルは通常のVOICEテーブルとほぼ同じ。通常のVOICEテーブルとしては使われない部分もある。
各音色には楽器ごとにパンやピッチの指定ができるようだ。楽器ごとの音量はできるのか謎。
また、セット内でグループを作れるのかも謎。

FRに定義されている 80 セット
80 00 00 00 b4 eb 44 08 00 00 00 00
80 00 00 00 10 ed 44 08 00 00 00 00
80 00 00 00 98 78 46 08 00 00 00 00
80 00 00 00 74 39 46 08 00 00 00 00

なお、VOICEテーブルのデフォルト音色（パルス波1）ではノートオンを送っても何も鳴らない.



----

音色出力設定
00(0000 0 000) : DirectSound
01(0000 0 001) : パルス波1 --- VOICEテーブルの初期値 → 01 3c 00 00 02 00 00 00 00 00 0f 00
02(0000 0 010) : パルス波2 --- 02 3c 00 00 03 00 00 00 02 07 00 00
03(0000 0 011) : 波形メモリ音源 --- 03 3c 00 00 2c 7e 46 08 00 07 0f 01
04(0000 0 100) : NOISE ---   04 3c 00 00 00 00 00 00 02 07 0f 00　＃曲番45,109で使用
08(0000 1 000) : DirectSound --- 08 3c 00 00 cc 4f 4b 08 ff f9 00 a5 (ボイスデータ参照)
09(0000 1 001) : パルス波1
0A(0000 1 010) : パルス波2
0B(0000 1 011) : 波形メモリ音源
0C(0000 1 100) : NOISE
10(0001 0 000) : DirectSound : 10 3c 00 00 cc 4f 4b 08 ff 00 ff a5 (ボイスデータ参照)
20(0010 0 000) : VOICE (pokemon voice 1) --- 20 3c 00 00 04 48 4d 08 ff 00 ff 00 (鳴き声データ参照)
30(0011 0 000) : VOICE (pokemon voice 2) --- 30 3c 00 00 04 48 4d 08 ff 00 ff 00 (鳴き声データ参照)
40(0100 0 000) : DirectSound with part
80(1000 0 000) : Drum

1バイト目
	bit2-0 : 出力音源 (0:DirectSound, 1:パルス波1, 2:パルス波2, 3:波形メモリ音源, 4:Noise、5～7はやってないけと未定義だと思うから指定しちゃだめ)
	bit3   : 音程固定 ドラムパート用か(1=on 0=off)※DirectSound以外では別の意味を持つ？
	bit4   : 強制ループOFF？（サウンドフォント側でループが指定されていてもOFFられる？）FR では自転車のベル音定義等に指定されている。
	bit5   : 不明。 ON にすると何も音が聞こえなくなる…？ ポケモンの鳴き声のみに使用されているビット。でも30は鳴るのよね…。
	bit6   : 音域指定出力。fmTOWNSのPMB方式に近い…と言ってわかる人はどれだけいるのか…
	bit7   : ドラム方式
2バイト目
	基準音 ( 0x3c = Cn3 ？)でも通常VOICEテーブルで変えても音程変わらない。
	ドラム時の音程か？そっちだと 0x40 とかあるし。
3バイト目
	謎。常に 0x00 ?
4バイト目
	bit0-6 : パン情報
		0000000 -> -64（左）
		1000000 -> 0（中央）
		1111111 -> +63（右）
	bit7   : このバイトの情報を使用するフラグ。 （1:有効 0:無効）
5-8バイト目
	1-bit2-0 = 000
		Waveテーブル参照アドレス
	1-bit2-0 = 011
		波形参照アドレス (参照先から 16 バイトの波形データを使用する)
	1-bit2-0 = 010 or 001
		デューティー比 (0x00000000 = 12.5%, 0x00000001 = 25%, 0x00000002 = 50%, 0x00000003 = 75%)
	1-bit2-0 = 100
		0x00000000
9-12バイト目
	1-bit7-6 = 00
		9:アタック
			1-bit2-0 = 000：Attack Speed 255(最速)-1(最遅),0(mute)
			1-bit2-0 = other：Attack Time 0(最速)-255(最遅)
		10: ディケイタイム 0(最速)-255(最遅)
		11: サスティンレベル
			1-bit2-0 = 000 : 0(mute)-255(最大)
			1-bit2-0 = それ以外 : 0(mute)-15(最大)
		12: リリースタイム 0(最速)-255(最遅)
	1-bit7-6 = 01
		音域指定参照アドレス
	1-bit7-6 = 10
		0x00000000
	1-bit7-6 = 11
		音域指定参照アドレス　だけどこれ使う必要ないと思われｗ
		つーか使われたの見たことない。

VOICEテーブルは容量削減のために、重複した領域を使ったり、
使わないことを前提に、別のデータ領域から参照指定をしていることがある。

bit3 の on を通常VOICEテーブルで使用しても、sappy2006 では無視される。
パルス波、波形メモリ音源 部の Attack Time は sappy2006 では無視される。
ドラムパートでの初期状態の音色( 01 3c … ) は無視されるようだが、sappy2006 では パルス波1 が鳴ってしまう。

GBA のサウンド出力はシステムクロック周波数そのままの PWM である。
なお、FR のサウンドシステムでは 65536Hz をサンプリング周波数として使用している。これは 65536Hz / 8bit の PCM に相当する。

シーケンスごとにヘッダでプライオリティ指定ができる（ヘッダ +2H 低い00h-ffh強）
曲の再生中に、それよりプライオリティ値の高い曲の割り込みが合った場合、そちらの曲が優先される。
両方の曲で音源の競合が無かった場合は優先度に関わらず両方が鳴る。
（下で説明しているのリバーブ値は、実際に曲が鳴らなかった場合でも適用されてしまう）

シーケンスごとにヘッダで曲全体のリバーブ強度を指定できる（ヘッダ+3H 弱01h-80h-ffh強、00h無効）
ただし、壁にぶつかる等、別の音の初期化が入ると、その音のリバーブ指定が適用されたままになる。
（曲がリセットされない限り、元のリバーブ値に戻らない）これはプライオリティ指定により、実際に音が鳴らなかった場合にも適用される。
ちなみにリバーブ値 240(f0h) 以上は音がほとんど消えなくなるので大変なことに。

DirectSound の Delay・Release Rate はパルス波の 2 と同等にするなら d8h くらい。1 だと b2h くらいか。
DirectSound の同時発音数は FR では 5 。それ以上鳴らそうとすると、古い音から強制的にオフにされる。
sappy2006 の再生機能では GB 由来の音源についてのサスティン値が正しく認識されない（DirectSoundと同等に扱われてしまう）

動作中のメモリ追ってみたら、DirectSound同時発音数は 5 に制限されてた。（すべてのレイヤで共用）
しかし、メモリバッファは12音分用意されていて、VBA のメモリビュアーで 03005fa6 番地を 0ch に書き換えると同時発音数が12になる。
ROM 側では 1c1085h を C5 から CC に変更すると、0ch で初期化されるようになる。
ただし今までうまく鳴っていたのに、リバーブや音色のリリースタイムが変に作用して変に聞こえることもあり。
同時発音数を変更した場合、曲によってはボイステーブルやシーケンスデータから見直す必要があるかもしれない。

レイヤ0：10トラック
レイヤ1：3トラック
レイヤ2：9トラック
レイヤ3：1トラック

Direct Sound は、音を重ねすぎて振幅がオーバーフローした場合、最大・最小値で丸められずにオーバーフローしたまま再生してしまうようだ。

0c1085h の bit3-0 は同時発音数だったが、 bit 7-4 は DirectSound のマスターボリュームだった。0(mute)-15(最大)
ただしGB由来の音源の音量はそのままなのでむやみにいじっても曲のバランスがくずれる。


音周りの情報を持っているアドレスの一覧

0x44e5a8～0x44e637 : 謎のアドレステーブル
0x44e638～0x44e647 : ADPCM デコード用テーブル
0x44e648～0x44e6fc : 謎 (14-int((address-0x44e648)/12))<<4|((address-0x44e648)%12)
0x44e6fc～0x44e743 : 謎すぎる
0x44e744～0x44e7c8 : 謎 int(address-0x44e744/12)<<4|((address-0x44e744)%12)
0x44e82c～0x44e85d : シーケンスデータの音長とデルタタイムの参照テーブル。このあたりの情報は BIOS にも入ってるから GBA の BIOS 使える環境なら
　　　　　　　　　　　そっち使えば秒あたり数十クロック処理速度稼げる気がする。(BIOS - 1clock , ROM - 5clock なので)
0x44e860～0x44e893 : 謎
0x44e894～0x44e8cb : 謎のアドレステーブル 1c2461 1c2475 1c24bd 1c2461 1c24d1 1c24e5 1c24f9 1c250d 1c2521 1c252d 1c2539 1c254d 1c2561 1c25a9
---- ここからボイステーブル
/*addr*/ /* Song No. */
0x44e8cc 0
0x44ebb4 ドラム
0x44ed10 ドラム
0x44f148 40 ボイスセット
0x44f178 40 ボイスセット
0x44f19c 40 ボイスセット
0x44f1c0 未使用？
0x44f7c0 40 ボイスセット
0x44f7d8 40 ボイスセット
0x44f7f0 256 257 258 259 260 261 262 268 269 270 271
0x44fcb8 263 264 
0x4500b4 265
0x4504f8 266 
0x45093c 267
0x450954 1～10 12～17 19 21～26 28～33 36 39～41 45 53 65 66 72 83 88 96 101～105 109 255
0x450f54 11 18 20 27 34 35 37 38 42～44 46～52 54～64 67～71 73～82 84～87 89～95 97～100 106～108 110～240 254
0x4539b4 241～253
0x453fb4 未使用？
0x4545b4 272 332
0x454bb4 273 326 327 330
0x4551b4 274
0x4557b4 275 344
0x455bec 276
0x455fd0 277
0x4565d0 278
0x456bd0 279
0x4571d0 280
0x4577d0 281
0x457800 282
0x457e00 283
0x4581f0 284
0x4587f0 285 342
0x458df0 286
0x4593f0 287 334
0x4599f0 288 331
0x459de0 289
0x45a3e0 290
0x45a83c 291
0x45ae3c 292
0x45b25c 293
0x45b85c 294
0x45be5c 295
0x45c2b8 296
0x45c8b8 297
0x45ceb8 298 340 341
0x45d4b8 299
0x45dab8 300 345
0x45e0b8 301
0x45e4d8 302
0x45ead8 303 328
0x45ef34 304
0x45f534 305
0x45fb34 306 338
0x460134 307
0x460734 308
0x460d34 309
0x461334 310
0x461934 311 322
0x461d24 312
0x462168 313
0x462768 314 335
0x462d68 315 316
0x4634c4 317
0x463974 ドラム
0x463dac 318
0x4641cc 319
0x4645ec 320
0x464bec 321
0x464e20 322 323 324
0x465240 329
0x465840 343
0x465c48 339
0x466248 346
0x466848 333
0x466e48 336
0x467448 337
0x467898 ドラム
0x467a48 ドラム
----ここまでボイステーブル
0x467cb8～0x467e2c：音域設定用のデータアドレス
0x467e2c～0x467edb：波形メモリ用音色
0x467edc～0c467f0b：使用できるトラック数の予約設定リスト
0x467f0c～0x4668ec：曲テーブル

0x4689e8～ 楽器音色データ
0x4d4804～0x662b1d ：鳴き声ADPCMデータ
0x662b20～ 楽器音色データ
0x67a280～0x6c0ae3 シーケンスデータ＋ヘッダ
0x6c0ae4～0x6c0b53 謎のアドレステーブル

0x6c0b54 : 'FLASH1M_V103'　/ セーブタイプ文字列。これ以降はeカードや通信のプログラムっぽい。




















・ なにか

まさかこんなにやるとは思っても見ませんでした。

初めは、自転車と殿堂入りのBGMが sappy でエラーになるのを直したい、
そんな程度の気持ちから始まったものなのに、気づけば鳴らない音の修正をして
さらには音声全般の解析までやって、しまいには Sappy 2006 の改造と
鳴き声インポートツールの作成までやってしまいました。

久し振りに解析魂に火がついたという感じです。
そういう気持ちにさせてくれた東方人形劇にはとても感謝しています。

東方人形劇を作成されたへもぐろびんA1C氏、
BGMを作成された紫苑氏、そのほか東方人形劇に関わった全ての方、
本当にありがとうございます。
楽しい時間を過ごせました。

いや、違いますね。
楽しい時間を過ごせています。ですねｗ

今回の Ver.1.5 で、音楽の解析は一旦終了かなと思います。

この解析した結果を使ってもらって、もっといい BGM を作って欲しい。
人形劇に合った鳴き声を入れて欲しい。
そういう風に思っています。

え？自分で曲は作らないのかって？
そりゃないですよ。解析してる方が楽しいのですからｗ

……まあ、いつかは作ってみたいですけれど。


↑↑↑↑ Ver.1.5のテキスト ↑↑↑
----------------------------------
↓↓↓↓ Ver.1.5aのテキスト ↓↓↓


上で
「今回の Ver.1.5 で、音楽の解析は一旦終了かなと思います。」
なんて書いたわけですが、微妙に更新し続けてますね。
もうちょっとだけ続きそうですｗ


↑↑↑↑ Ver.1.5aのテキスト ↑↑↑
----------------------------------
↓↓↓↓ Ver.1.6aのテキスト ↓↓↓


どこまで続くんだこのやろう（挨拶

sappy mod の更新を細々と続けている関係で
このテキストも微妙に更新がかかり続けています。

本家も Ver.1.8 系がリリースされ、自分もテンション大幅アップです。

まだまだちまちまと更新し続けることでしょう。

