りんけーじ - 開発資料 - 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 |
| 0 | 14336 |
| 1 | 12288 |
| 2 | 10240 |
| 3 | 8192 |
| 4 | 7168 |
| 5 | 6144 |
| 6 | 5120 |
| 7 | 4096 |
| 8 | 3584 |
| 9 | 3072 |
| 10 | 2560 |
| 11 | 2048 |
| 12 | 1792 |
| 13 | 1536 |
| 14 | 1280 |
| 15 | 1024 |
| 16 | 896 |
| 17 | 768 |
| 18 | 640 |
| 19 | 512 |
| 20 | 448 |
| 21 | 384 |
| 22 | 320 |
| 23 | 256 |
| 24 | 224 |
| 25 | 192 |
| 26 | 160 |
| 27 | 128 |
| 28 | 112 |
| 29 | 96 |
| 30 | 80 |
| 31 | 64 |
| Attack Rate | Δvolume |
| 32 | 56 |
| 33 | 48 |
| 34 | 40 |
| 35 | 32 |
| 36 | 28 |
| 37 | 24 |
| 38 | 20 |
| 39 | 16 |
| 40 | 14 |
| 41 | 12 |
| 42 | 10 |
| 43 | 8 |
| 44 | 7 |
| 45 | 6 |
| 46 | 5 |
| 47 | 4 |
| 48 | 7 |
| 49 | 6 |
| 50 | 5 |
| 51 | 4 |
| 52 | 7 |
| 53 | 6 |
| 54 | 5 |
| 55 | 4 |
| 56 | 7 |
| 57 | 6 |
| 58 | 5 |
| 59 | 4 |
| 60 | 7 |
| 61 | 6 |
| 62 | 5 |
| 63 | 4 |
エンベロープフィルタ - アタック - 指数
データ量が減りますが、時間経過に伴う変化を示します。
最初の変化はリニアと変わっていないことが分かります。
縦が時間経過、横が Attack Rate
| Attack Rate | 4 | 5 | 6 | 7 | 8 | 9 |
| 0 | 0 | 0 | 0 | 0 | 0 |
| 7168 | 6144 | 5120 | 4096 | 3584 | 3072 |
| 14336 | 12288 | 10240 | 8192 | 7168 | 6144 |
| 21504 | 18432 | 15360 | 12288 | 10752 | 9216 |
| 28672 | 24576 | 20480 | 16384 | 14336 | 12288 |
| 30464 | 26112 | 25600 | 20480 | 17920 | 15360 |
| 32256 | 27648 | 26880 | 24576 | 21504 | 18432 |
| 32767 | 29184 | 28160 | 25600 | 25088 | 21504 |
| 32767 | 30720 | 29440 | 26624 | 25984 | 24576 |
| 32767 | 32256 | 30720 | 27648 | 26880 | 25344 |
| 32767 | 32767 | 32000 | 28672 | 27776 | 26112 |
| 32767 | 32767 | 32767 | 29696 | 28672 | 26880 |
| 32767 | 32767 | 32767 | 30720 | 29568 | 27648 |
| 32767 | 32767 | 32767 | 31744 | 30464 | 28416 |
| 32767 | 32767 | 32767 | 32767 | 31360 | 29184 |
| 32759 | 32767 | 32767 | 32767 | 32256 | 29952 |
| 32759 | 32767 | 32767 | 32767 | 32767 | 30720 |
リニアとの比較を示します。ただし、ΔADSRVol.(Exp) は 32767 に達する1つ前と2つ前の値の差です。
この表から、ある一定の値を超えると、
Δvolume(Exp) = Δvolume(Linear) / 4
となっていることが分かります。この値は 24576 であることがほかの解析によって確かめられています。
| AttackRate | Δvolume(Linear) | Δvolume(Exp) |
| 4 | 7168 | 1792 |
| 5 | 6144 | 1536 |
| 6 | 5120 | 1280 |
| 7 | 4096 | 1024 |
| 8 | 3584 | 896 |
| 9 | 3072 | 768 |
エンベロープフィルタ - ディケイ
ディケイの解析結果です。
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 Rate | Delay(1) | Delay(2) | Delay(3) |
| 0 | 5328 | 5259 | 5292 |
| 1 | 4500 | 5292 | 5292 |
| 2 | 4731 | 5292 | 5292 |
| 3 | 4731 | 5292 | 5292 |
| 4 | 4731 | 5292 | 5292 |
| 5 | 4731 | 5292 | 5292 |
| 6 | 4731 | 5292 | 5292 |
| 7 | 4731 | 5292 | 5292 |
| 8 | 4731 | 5292 | 5292 |
| 9 | 4731 | 5292 | 5292 |
| 10 | 4599 | 5292 | 5292 |
| 11 | 4599 | 5292 | 5292 |
| 12 | 4599 | 5292 | 5292 |
| 13 | 4599 | 5292 | 5292 |
| 14 | 4599 | 5292 | 5292 |
| 15 | 4599 | 5292 | 5292 |
| 16 | 4599 | 5292 | 5292 |
| 17 | 4599 | 5292 | 5292 |
| 18 | 4599 | 5292 | 5292 |
| 19 | 4599 | 5292 | 5292 |
| 20 | 4599 | 4500 | 4500 |
| 21 | 4599 | 4500 | 4500 |
| 22 | 4599 | 4500 | 4500 |
| 23 | 4665 | 4500 | 4500 |
| 中略 |
| 44 | 4698 | 4500 | 4500 |
| 45 | 4665 | 4500 | 4500 |
| 46 | 4698 | 4500 | 4500 |
| 47 | 4665 | 4500 | 4500 |
| 48 | 5457 | 5292 | 5292 |
| 49 | 6150 | 5292 | 5292 |
| 50 | 6150 | 5292 | 5292 |
| 51 | 6150 | 5292 | 5292 |
| 52 | 5391 | 6051 | 6051 |
| 53 | 6216 | 6051 | 6051 |
| 54 | 6216 | 6051 | 6051 |
| 55 | 5216 | 6051 | 6051 |
| 56 | 4665 | 9120 | 9120 |
| 57 | 9285 | 9120 | 9120 |
| 58 | 9285 | 9120 | 9120 |
| 59 | 9285 | 9120 | 9120 |
| 60 | 12354 | 4500 | 9120 |
| 61 | 9285 | 9120 | 9120 |
| 62 | 9285 | 9120 | 9120 |
| 63 | 9285 | 9120 | 9120 |
| 64 | 27699 | 16809 | 16809 |
| 65 | 17403 | 16809 | 16809 |
| Attack Rate | Delay(1) | Delay(2) | Delay(3) |
| 66 | 17403 | 16809 | 16809 |
| 67 | 17403 | 16809 | 16809 |
| 68 | 5127 | 21396 | 16809 |
| 69 | 41988 | 16809 | 16809 |
| 70 | 41988 | 16809 | 16809 |
| 71 | 41988 | 16809 | 16809 |
| 72 | 36546 | 65947 | 65947 |
| 73 | 41988 | 65947 | 65947 |
| 74 | 41988 | 65947 | 65947 |
| 75 | 41988 | 65947 | 65947 |
| 76 | 189434 | 161186 | 161186 |
| 77 | 38094 | 164255 | 161186 |
| 78 | 38094 | 164255 | 161186 |
| 79 | 38094 | 164255 | 161186 |
| 80 | 332987 | 357803 | 357803 |
| 81 | 234711 | 357803 | 357803 |
| 82 | 234711 | 357803 | 357803 |
| 83 | 234711 | 357803 | 357803 |
| 84 | 38094 | 754073 | 751004 |
| 85 | 627912 | 751004 | 751004 |
| 86 | 627912 | 751004 | 751004 |
| 87 | 627912 | 751004 | 751004 |
| 88 | 1021113 | 1532819 | 1532819 |
| 89 | 1410123 | 1532852 | 1532852 |
| 90 | 1410123 | 1532819 | 1532819 |
| 91 | 1410123 | 1532852 | 1532852 |
| 92 | 2196558 | 3105722 | 3105722 |
| 93 | 2982993 | 3105722 | 3105722 |
| 94 | 2982993 | 3105722 | 3105722 |
| 95 | 2982993 | 3105722 | 3105722 |
| 96 | 4555863 | 6251429 | 6251429 |
| 97 | 6128700 | 6251429 | 6251429 |
| 98 | 6128733 | 6251429 | 6251429 |
| 99 | 6128700 | 6251429 | 6251429 |
| 100 | 2983059 | 12542876 | 12538256 |
| 101 | 12416121 | 12538289 | 12538289 |
| 102 | 12416121 | 12538289 | 12538289 |
| 103 | 12416121 | 12530289 | 12538289 |
| 105 | 24999015 | 25121183 | 25121183 |
| 106 | 24999015 | 25121183 | 25121183 |
| 107 | 24999015 | 25121183 | 25121183 |
| 108 | 24999015 | 25121183 | 25121183 |
| 109 | 24999015 | 25121183 | 25121183 |
| 110 | 24999015 | 25121183 | 25121183 |
| 111 | 24999015 | 25121183 | 25121183 |
| 112 | 24999246 | 25121183 | 25121183 |