りんけーじ - 開発資料 - PSX - SPU


この資料について

この資料は、エミュレータ開発の際に PlayStation SPU について行った解析結果をまとめたものです。
一部は推測に基づいており、必ずしも正しいものではありません。
また、それ以外でも間違いを含んでいる可能性があります。使用する方は十分に注意してください。

解析にあたって、ベースとなる資料を提供してくださった PSX SPU Development Project (EternalSPU Project)、 計算式を導いてくださった Takashi Yano 氏に感謝します。

SPU の基本動作

SPU は 44100Hz, 16bit の音声を出力しています。よって、
33868800Hz / 44100Hz = 768
より、CPU の 768 クロックごとに、1サンプルを生成しています。
データの領域として 512KB のメモリを持ち、DMA 転送が可能です。 音声データは 16bytes を1ブロックとし、ブロックあたり、ヘッダ 2 バイト、ADPCM データ 14 バイト、28 サンプルで構成されます。
チャンネル数は 24 で、1つ前のチャンネルの出力を Frequency Moduration のソースとして使用することもできます。
CD-DA および XA-Audio のミキシングも担当します。

エンベロープフィルタ

エンベロープフィルタは、キーオン・キーオフ時などに適用される、自動で音量をコントロールするフィルタです。
アタック (Attack)、ディケイ (Decay)、サスティン (Sustain)、リリース(Release) で構成されます。
キーオンされると、Attack Rate にしたがって Attack が行われ、指定音量まで音量が増加していきます。
続けて、ディケイが行われ、Sustain Level まで減少します。
最後に、Sustain Level からゆるやかな増加または減少が Sustain Rate と Sustain Mode にしたがって行われます。
キーオフ時は Release Rate にしたがって音量が 0 に向かって減少します。

どのエンベロープフィルタにおいても、処理は 768 CPU クロックごとに行われますが、非常に大きな Attack Rate (= 増加が遅い) など、 計算で求める値の変化が 4 よりも小さくなるような場合は、その数倍ごとに処理が行われます。

この資料では、この処理が行われる間隔を interval と呼び、0 で毎 768 CPU クロックごとに更新するものとします。

エンベロープフィルタ - アタック - リニア

Attack Rate と、最初に ADSR Vol. が変化したときのその値です。
Attack Rate 48 以降では interval が増加していると思われます。
ほかの解析結果と併せて行った推測によって求めた計算式を示します。

temp = 1 << (13 - (AR >> 2))
Δvolume = temp + (temp >> 2) * (AR & 3 ^ 3)
interval = 1 << ((AR >> 2) - 48) (ただし、AR ≧ 48)
Attack RateΔvolume
014336
112288
210240
38192
47168
56144
65120
74096
83584
93072
102560
112048
121792
131536
141280
151024
16896
17768
18640
19512
20448
21384
22320
23256
24224
25192
26160
27128
28112
2996
3080
3164
Attack RateΔvolume
3256
3348
3440
3532
3628
3724
3820
3916
4014
4112
4210
438
447
456
465
474
487
496
505
514
527
536
545
554
567
576
585
594
607
616
625
634

エンベロープフィルタ - アタック - 指数

データ量が減りますが、時間経過に伴う変化を示します。
最初の変化はリニアと変わっていないことが分かります。

縦が時間経過、横が Attack Rate

Attack Rate456789
000000
716861445120409635843072
143361228810240819271686144
21504184321536012288107529216
286722457620480163841433612288
304642611225600204801792015360
322562764826880245762150418432
327672918428160256002508821504
327673072029440266242598424576
327673225630720276482688025344
327673276732000286722777626112
327673276732767296962867226880
327673276732767307202956827648
327673276732767317443046428416
327673276732767327673136029184
327593276732767327673225629952
327593276732767327673276730720

リニアとの比較を示します。ただし、ΔADSRVol.(Exp) は 32767 に達する1つ前と2つ前の値の差です。
この表から、ある一定の値を超えると、
Δvolume(Exp) = Δvolume(Linear) / 4
となっていることが分かります。この値は 24576 であることがほかの解析によって確かめられています。
AttackRateΔvolume(Linear)Δvolume(Exp)
471681792
561441536
651201280
740961024
83584896
93072768

エンベロープフィルタ - ディケイ

ディケイの解析結果です。

shift = DR + 1 (ただし shift は最大 12)
Δvolume = ((-volume) >> shift)
interval = DR - 11 (ただし、DR ≧ 11)

縦が Decay Rate、横が時間経過

Decay Rate
0 16383 8191 4095 2047 ---
1 24575 18431 13823 10367 7775
2 28671 25087 21951 19207 16806
3 30719 28799 26999 25311 23729
4 31743 30751 29790 28859 27957
5 32255 31751 31254 30765 30284
6 32511 32257 32004 31753 31504
7 32639 32511 32384 32257 32130
8 32703 32639 32575 32511 32447
9 32735 32703 32671 32639 32607
10 32751 32735 32719 32703 32687
11 32759 32751 32743 32735 32727
12 32759 32759 32751 32751 32743
13 32759 32759 32759 32759 32751
14 32759 32759 32759 32759 32759
15 32759 32759 32759 32759 32759

サスティン - リニア

リニア時のサスティンの解析結果です。

shift = 11 - (SR >> 2) (ただし shift は最小 0)
Δvolume = ((4 | (SR & 3)) ^ 3) << shift
interval = 1 << ((SR >> 2) - 11) (ただし SR ≧ 44)

縦が Decay Rate、横が時間経過

Sustain Rate 増加間隔
0 2046 16382 30718 32767 14336 0
1 2046 14334 26622 32767 12288 0
2 2046 12286 22526 32766 10240 0
3 2046 10238 18430 26622 8192 0
4 2046 9214 16382 23550 7168 0
8 2046 5630 9214 12798 3584 0
9 2046 5118 8190 11262 3072 0
10 2046 4606 7166 9726 2560 0
11 2046 4094 6142 8190 2048 0
12 2046 3838 5630 7422 1792 0
13 2046 3582 5118 6654 1536 0
59 2046 2050 2050 2050 4 8
60 2046 2053 2053 2053 7 16
61 2046 2052 2052 2052 6 16
62 2046 2051 2051 2051 5 16
63 2046 2050 2050 2050 4 16
64 2046 2053 2053 2053 7 32

サスティン - 指数増加

指数増加モードのサスティンの解析結果です。
volume < 24576 においてはリニアと同じで、それ以降、増加幅が 1/4 となっていると推測されます。

縦が Sustain Rate、横が時間経過

Sustain Rate
0 2046 16382 30718 32767 32767
1 2046 14334 26622 29694 32766
2 2046 12286 22526 32766 32767
3 2046 10238 18430 26622 28670
4 2046 9214 16382 23550 30718
5 2046 8190 14334 20478 26622
6 2046 7166 12286 17406 22526
7 2046 6142 10238 14334 18430
8 2046 5630 9214 12798 16382
9 2046 5118 8190 11262 12798

サスティン - 指数減少

指数減少モードのサスティンの解析結果です。

temp = volume >> ((SR >> 2) + 1)
Δvolume = temp - (temp >> 3) * (SR & 3)

縦が Sustain Rate、横が時間経過

Sustain Rate
0 10224 5112 2556 1278 639
1 10224 5751 3234 1819 1023
2 10224 6390 3993 2495 1559
3 10224 7029 4832 3322 2283
4 10224 7668 5751 4313 3234
5 10224 7987 6239 4874 3807
6 10224 8307 6749 5483 4454
7 10224 8626 7278 6140 5180
8 10224 8946 7827 6848 5992
9 10224 9105 8109 7222 6432
10 10224 9265 8396 7608 6894
11 10224 9425 8688 8009 7383
12 10224 9585 8985 8423 7896
13 10224 9664 9135 8635 8162
14 10224 9744 9287 8851 8436
15 10224 9824 9440 9071 8716

リリース - リニア

リリースレートと、音量最大状態からの値の変化です。

shift = 11 - RR (ただし shift は最小 0)
interval = 1 << (RR - 12) (ただし、RR ≧ 12)

縦が Release Rate、横が時間経過

Release Rate
0 32767 16383 65535 0 0 0
1 32767 24575 16383 8191 65535 0
2 32767 28671 24575 20479 16383 12287
3 32767 30719 28671 26623 24575 25527
4 32767 31743 30719 29695 28671 27647
5 32767 32255 31743 31231 30719 30207
6 32767 32511 32255 31999 31743 31487
7 32767 32639 32511 32383 32255 32127

リリース - 指数

リリースレートと、音量最大状態からの値の変化です。

shift = RR + 1
Δvolume = (-volume) >> shift
interval = 1 << (RR - 12) (ただし、RR ≧ 12)

縦が Release Rate、横が時間経過

Release Rate
0 16383 8191 4095 2047 1023 511
1 24575 18431 13823 10367 7775 5831
2 28671 25087 21951 19207 16806 14705
3 30719 28799 26999 25311 23729 22245
4 31743 30751 29790 28859 27957 27083
5 32255 31751 31254 30765 30284 29810
6 32511 32257 32004 31753 31504 31257
7 32639 32511 32384 32257 32130 32004
8 32703 32639 32575 32511 32447 32383
9 32735 32703 32671 32639 32607 32575
10 32751 32735 32719 32703 32687 32671
11 32759 32751 32743 32735 32727 32719
12 32759 32759 32751 32751 32743 32743
13 32767 32759 32759 32759 32759 32751
14 32767 32767 32767 32767 32767 32767
15 32767 32767 32767 32759 32759 32759

キーオン・ディレイ

SPU のアタックレートと、キーオンから最初に音量が 0 以外でなくなったときまでの時間(CPU クロック数)です。
アタックレート以外の設定は以下の通りです。
ただし、リリースレート/モード以外は影響を与えていないことを確認しています。
アタックモード : リニア
ディケイレート : 15
サスティンモード : リニア増加
サスティンレベル : 0
サスティンレート : 0
リリースモード : リニア
リリースレート : 0
各レートについて、4 回ずつ計測した結果です。4 回目の結果はほとんどが 3 回目と等しいため、省略しています。
また、レート 0 から 10 は後の検証時に 1 回目の計測値が違う場合が多く、表ではレート 1 がそれを示しています。
注意:レートが 4 の倍数の場合の最初の計測値が異なっていますが、これはキーオフやエンベロープの終了方法によって異なることがありました。
Attack RateDelay(1)Delay(2)Delay(3)
0532852595292
1450052925292
2473152925292
3473152925292
4473152925292
5473152925292
6473152925292
7473152925292
8473152925292
9473152925292
10459952925292
11459952925292
12459952925292
13459952925292
14459952925292
15459952925292
16459952925292
17459952925292
18459952925292
19459952925292
20459945004500
21459945004500
22459945004500
23466545004500
中略
44469845004500
45466545004500
46469845004500
47466545004500
48545752925292
49615052925292
50615052925292
51615052925292
52539160516051
53621660516051
54621660516051
55521660516051
56466591209120
57928591209120
58928591209120
59928591209120
601235445009120
61928591209120
62928591209120
63928591209120
64276991680916809
65174031680916809
Attack RateDelay(1)Delay(2)Delay(3)
66174031680916809
67174031680916809
6851272139616809
69419881680916809
70419881680916809
71419881680916809
72365466594765947
73419886594765947
74419886594765947
75419886594765947
76189434161186161186
7738094164255161186
7838094164255161186
7938094164255161186
80332987357803357803
81234711357803357803
82234711357803357803
83234711357803357803
8438094754073751004
85627912751004751004
86627912751004751004
87627912751004751004
88102111315328191532819
89141012315328521532852
90141012315328191532819
91141012315328521532852
92219655831057223105722
93298299331057223105722
94298299331057223105722
95298299331057223105722
96455586362514296251429
97612870062514296251429
98612873362514296251429
99612870062514296251429
10029830591254287612538256
101124161211253828912538289
102124161211253828912538289
103124161211253028912538289
105249990152512118325121183
106249990152512118325121183
107249990152512118325121183
108249990152512118325121183
109249990152512118325121183
110249990152512118325121183
111249990152512118325121183
112249992462512118325121183