サブページ
$DFF0A0

オーディオの概要

Amigaのオーディオシステムは、Chip RAMからデジタル化された8ビットサウンドサンプルを再生できる4つの独立したDMAチャンネルで構成される。ステレオ出力で、チャンネルとスピーカーの対応は固定されている。

  • 左スピーカー: チャンネル0とチャンネル3
  • 右スピーカー: チャンネル1とチャンネル2

各チャンネルには独自のサンプルポインタ、長さカウンタ、ボリューム制御、ピリオド(サンプルレート)レジスタがある。ハードウェアがDMA経由で連続再生を自動的に処理するため、CPUはレジスタを設定してDMAを有効にするだけでよい。

サウンド生成の仕組み

Amigaはデジタル化された波形をメモリに8ビット符号付き値(2の補数、範囲-128〜+127)のシーケンスとして格納する。デジタル・アナログ変換器(DAC)がプログラム可能なレートでこれらのサンプルを読み取り、アナログ電圧出力を生成する。出力はローパスフィルタを通ってオーディオ出力ジャックに送られる。

サウンドサンプルは16ビットワードにパックされたバイトペアとしてChip RAMに格納される。DMAコントローラは一度に1ワードを読み込み、上位バイト(ビット15–8)が先に出力され、次に下位バイト(ビット7–0)が出力される。このため、波形データは常に偶数個のサンプルで構成する必要がある。

サウンドの3つの基本パラメータ — 周波数(ピッチ)、振幅(音量)、音色(波形の形状)— はすべてソフトウェアで制御可能である。周波数はピリオドレジスタ、振幅はボリュームレジスタで設定し、音色は波形データ自体で決まる。

$DFF0A0

チャンネルごとのレジスタ

各オーディオチャンネルには16バイトを占める5つのレジスタがある。4チャンネルは$DFF0A0から連続した16バイトオフセットに配置されている。

チャンネル0レジスタ
$DFF0A0AUD0LCH — サンプルポインタ、上位ワード(ビット16–18)
$DFF0A2AUD0LCL — サンプルポインタ、下位ワード(ビット0–15)
$DFF0A4AUD0LEN — サンプル長(ワード単位、1ワード=2サンプル)
$DFF0A6AUD0PER — サンプルピリオド(再生レート)
$DFF0A8AUD0VOL — ボリューム(0–64)
$DFF0AAAUD0DAT — オーディオデータレジスタ(書き込みでDMA転送をトリガー)
チャンネル1レジスタ
$DFF0B0AUD1LCH — サンプルポインタ、上位ワード
$DFF0B2AUD1LCL — サンプルポインタ、下位ワード
$DFF0B4AUD1LEN — サンプル長(ワード単位)
$DFF0B6AUD1PER — サンプルピリオド
$DFF0B8AUD1VOL — ボリューム(0–64)
$DFF0BAAUD1DAT — オーディオデータレジスタ
チャンネル2レジスタ
$DFF0C0AUD2LCH — サンプルポインタ、上位ワード
$DFF0C2AUD2LCL — サンプルポインタ、下位ワード
$DFF0C4AUD2LEN — サンプル長(ワード単位)
$DFF0C6AUD2PER — サンプルピリオド
$DFF0C8AUD2VOL — ボリューム(0–64)
$DFF0CAAUD2DAT — オーディオデータレジスタ
チャンネル3レジスタ
$DFF0D0AUD3LCH — サンプルポインタ、上位ワード
$DFF0D2AUD3LCL — サンプルポインタ、下位ワード
$DFF0D4AUD3LEN — サンプル長(ワード単位)
$DFF0D6AUD3PER — サンプルピリオド
$DFF0D8AUD3VOL — ボリューム(0–64)
$DFF0DAAUD3DAT — オーディオデータレジスタ

AUDxLC — サンプルポインタ

この18ビットレジスタペアはChip RAM内の波形データの先頭を指す。DMAコントローラはデータ取得を開始する前にこの値を内部アドレスレジスタにコピーするため、元のAUDxLC値は保持され、現在の再生を中断せずに次のサイクル用に更新できる。

AUDxLEN — サンプル長

長さはワード単位(バイトではない)で指定する。例えば、16サンプルの波形は8ワードを占める。

MOVE.W #(End-Start)/2,AUD0LEN(a5)

DMAコントローラがAUDxLENワードを出力し終えると、AUDxLCとAUDxLENを内部レジスタに再ロードし、先頭から再開してループを形成する。

AUDxPER — ピリオド(サンプルレート)

ピリオドレジスタは連続するサンプル出力間の時間を制御する。各単位は1バスサイクル=279.365ナノ秒(PALシステムの場合、3.579545 MHzクロックに相当)。

ピリオド値の計算式:

ピリオド = 1 / (周波数 * 1サイクルあたりのサンプル数 * 279.365e-9)

または同等の式:

ピリオド = 3,579,545 / (周波数 * 1サイクルあたりのサンプル数)

例: 16サンプルの波形で440 Hzの音を再生する場合:

ピリオド = 1 / (440 * 16 * 0.000000279365) = 508

実用的な最小ピリオドは124(約28,867 Hzのサンプルレート)である。これ以下では、DMAチャンネルがデータを十分な速度で取得できない(ラスタラインあたり1つのDMAスロットしかない)ため、サンプルが繰り返される可能性がある。最大ピリオドは65,535で、極めて低速な再生が可能。

AUDxVOL — ボリューム

ボリュームは0(無音)から64(最大)の範囲。64を超える値は64として扱われる。各チャンネルのボリュームは独立している。

MOVE.W #32,AUD0VOL(a5)    ; チャンネル0を半分の音量に

最良の音質を得るには、波形データを常に8ビットフル振幅(-128〜+127)で保持し、音量の制御にはボリュームレジスタを使用すること。波形の振幅を直接縮小すると相対的な量子化ノイズが増加する。

$DFF0A0

オーディオDMAと割り込み

オーディオDMAの有効化

オーディオDMAはDMACONレジスタ($DFF096)のビット0–3で制御される。

DMAコンビット 名前 チャンネル 説明
0AUD0ENチャンネル0オーディオチャンネル0のDMAを有効化
1AUD1ENチャンネル1オーディオチャンネル1のDMAを有効化
2AUD2ENチャンネル2オーディオチャンネル2のDMAを有効化
3AUD3ENチャンネル3オーディオチャンネル3のDMAを有効化

チャンネル0で再生を開始するには:

LEA     $DFF000,a5
MOVE.L  #SampleData,AUD0LCH(a5)   ; サンプルアドレスを設定
MOVE.W  #(SampleEnd-SampleData)/2,AUD0LEN(a5)  ; 長さを設定
MOVE.W  #508,AUD0PER(a5)          ; ピリオドを設定(16サンプルで440 Hz)
MOVE.W  #64,AUD0VOL(a5)           ; 最大ボリューム
MOVE.W  #$8201,DMACON(a5)         ; AUD0EN + DMAENを有効化

DMAサイクル

オーディオDMAが有効化されると、以下のシーケンスが実行される:

  1. AUDxLCとAUDxLENが内部レジスタにコピーされる
  2. オーディオ割り込みがトリガーされる(新しい値をロードできることをCPUに通知)
  3. DMAコントローラが内部アドレスからワードを取得(ラスタラインあたり1ワード)
  4. 各ワードの上位バイトが先に出力され、次に下位バイトがAUDxPERで設定されたレートで出力
  5. 内部ワードカウンタがゼロに達すると、AUDxLCとAUDxLENが再ロードされ、別の割り込みが発生

これにより、DMA動作中にCPUがAUDxLCとAUDxLENを更新できる。変更は次のサイクルの開始時に有効になる。2つのバッファを交互に使用することで、長いサンプルのシームレスなストリーミングが可能。

オーディオ割り込み

各チャンネルにはINTREQ/INTENAに専用の割り込みビットがある。

  • ビット7: オーディオチャンネル0
  • ビット8: オーディオチャンネル1
  • ビット9: オーディオチャンネル2
  • ビット10: オーディオチャンネル3

4つすべてがレベル4割り込みである。DMAコントローラがAUDxLC/AUDxLENをレジスタから再ロードするたびに割り込みが発生する。高周波のサウンドでは割り込みが非常に頻繁に発生するため、CPUの飽和を避けるために必要な場合のみ有効にすること。

$DFF0A0

変調

Amigaはチャンネル間の変調をサポートしており、あるオーディオチャンネルが次のチャンネルのピリオドやボリュームをリアルタイムで変更する。変調チャンネルの波形データはDACには送られず、対象チャンネルのピリオドまたはボリュームレジスタに直接書き込まれる。

変調チェーンは固定されている:

  • チャンネル0がチャンネル1を変調
  • チャンネル1がチャンネル2を変調
  • チャンネル2がチャンネル3を変調
  • チャンネル3はモジュレータとして設定可能だが対象がない(データは破棄)

チャンネルがモジュレータとして使用される場合、そのオーディオ出力は自動的に無効になる。

ADKCON — オーディオ/ディスク制御レジスタ

変調はADKCONレジスタ($DFF09E 書き込み / $DFF010 読み込み)で設定される。

ビット 名前 機能 説明
15SET/CLRセット/クリア1=リストされたビットをセット、0=クリア
14–8ディスク制御ディスクコントローラのビット(オーディオとは無関係)
7USE3PNCh 3 ピリオド変調チャンネル3は何も変調しない(対象なし)
6USE2P3Ch 2 -> Ch 3 ピリオドチャンネル2がチャンネル3のピリオドを変調
5USE1P2Ch 1 -> Ch 2 ピリオドチャンネル1がチャンネル2のピリオドを変調
4USE0P1Ch 0 -> Ch 1 ピリオドチャンネル0がチャンネル1のピリオドを変調
3USE3VNCh 3 ボリューム変調チャンネル3は何も変調しない(対象なし)
2USE2V3Ch 2 -> Ch 3 ボリュームチャンネル2がチャンネル3のボリュームを変調
1USE1V2Ch 1 -> Ch 2 ボリュームチャンネル1がチャンネル2のボリュームを変調
0USE0V1Ch 0 -> Ch 1 ボリュームチャンネル0がチャンネル1のボリュームを変調

ピリオド変調

ピリオド変調が有効な場合(例:USE0P1=1)、チャンネル0の波形データが16ビットピリオド値として解釈され、AUD1PERに直接書き込まれる。これによりビブラート効果が生まれる — チャンネル1のピッチがチャンネル0で再生される波形に従って振動する。

ボリューム変調

ボリューム変調が有効な場合(例:USE0V1=1)、チャンネル0のデータワードが7ビットボリューム値(ビット6–0に0–64)として解釈され、AUD1VOLに書き込まれる。これによりトレモロ効果が生まれ、また振幅エンベロープ(アタック/ディケイ/サスティン/リリース)の形成にも使用できる。

複合変調

同じチャンネルペアでピリオド変調とボリューム変調を同時に有効にできる。この場合、データワードは交互に使用される:

ワード番号 書き込み先
1 ボリューム
2 ピリオド
3 ボリューム
4 ピリオド
... ...

変調チャンネルのデータは2倍の速度で消費されるため、波形の長さをそれに合わせて計画すること。

$DFF0A0

ローパスフィルタ

Amigaには、DAC出力とオーディオ出力ジャック間にハードウェアローパスフィルタが搭載されている。このフィルタは約4 kHz以上の周波数を減衰させ、7 kHz以上を完全に遮断する。

目的

デジタル波形をアナログ信号として復元する際、サンプルレートと目的の周波数の和と差に等しい周波数でエイリアシングアーティファクトが発生する。ローパスフィルタがこれらのアーティファクトを除去し、よりクリーンなオーディオ出力を生成する。ただし、オーディオ帯域幅も制限され、複雑な波形(矩形波、鋸歯状波など)の高周波倍音が失われる。高いピッチの矩形波は正弦波のように聞こえ始める。

フィルタ制御

フィルタはCIA-AポートBのビット1($BFE001)で制御される。これは電源LEDの輝度を制御するのと同じビットである。

  • ビット1 = 0: フィルタ有効(LEDが明るい)— デフォルト状態
  • ビット1 = 1: フィルタ無効(LEDが暗い)
; ローパスフィルタを無効にする
BSET #1,$BFE001

プリフィルタ済みまたは高品質のサンプルを再生する場合、あるいは最大の周波数レンジが必要な場合はフィルタを無効にすべきである。単純な合成波形の場合は、可聴エイリアシングを避けるためにフィルタを有効のままにしておくこと。

サンプリングレートのガイドライン

フィルタを有効にしていても可聴エイリアシングを避けるために、以下のルールに従う:

サンプルレート > 最高周波数成分 + 7000 Hz

「最高周波数成分」には基本周波数だけでなく波形の倍音も含まれることに注意。1 kHzの矩形波は3 kHz、5 kHz、7 kHz以上に重要な倍音を持つ。