mcelp 1.0.1

Mitsubishi CELP speech codec: a 3.6 kbit/s speech encoder and decoder
Documentation
# 短期予測

短期予測器はスペクトル包絡——大まかには声道が与える形——を模擬します。10次の
全極フィルタ

```
          1                       1
H(z) = ------ = ---------------------------------
        A(z)     1 + a₁z⁻¹ + a₂z⁻² + … + a₁₀z⁻¹⁰
```

であり、係数はフレームごとに1組送られます。

## 分析

エンコーダは **400標本の窓**で自己相関を取ります。320標本のフレームより長い
ので、前フレームまで遡ることになります。窓は非対称でテーパが掛かっており、この
重なりがフレーム間でフィルタが飛ぶのを防ぎます。

自己相関には次に*ラグ窓*が掛かります。各ラグに1をわずかに下回る係数(ラグが
大きいほど小さい)を掛けるもので、スペクトルの峰をわずかに広げます。これが
Levinson-Durbin 再帰が鋭すぎて鳴くフィルタを作るのを防ぎます。

Levinson-Durbin は11個の自己相関から11個の予測係数を求め、その過程で10個の
反射係数を生みます。最初の2つの反射係数は保持されます。聴覚重み付けフィルタの
形状がそこから決まるためで、詳細は [weighting.md](weighting.md) にあります。

なお分析が走るのは**雑音抑圧後**の信号であって、入力そのものではありません。
[noise-suppression.md](noise-suppression.md) を参照してください。

## 線スペクトル周波数

予測係数は量子化に向きません——わずかな誤差でフィルタが不安定になりえます——
ので、まず*線スペクトル周波数*に変換します。`A(z)` を対称多項式と反対称多項式に
分解し、

```
F₁(z) = A(z) + z⁻¹¹A(z⁻¹)      F₂(z) = A(z) − z⁻¹¹A(z⁻¹)
```

これらの根はすべて単位円上にあり、交互に並びます。その根の角度が LSF です。
交互性が効いてくる性質で、量子化後の値が昇順かつ最小間隔を保っている限り、
量子化誤差がどうであれ戻したフィルタは安定です。

根は、各多項式を単位円上のグリッド点で評価して符号変化を探し、挟み込んだ区間で
4回2分することで求めます。

コード中には3つの表現が現れます。取り違えが最も多い箇所です。

| 名称 | 意味 | 形式 |
|---|---|---|
| LSF | 線スペクトル*周波数*、ラジアン | Q13、π = 25736 |
| LSP | 線スペクトル**、すなわち cos(LSF) | Q15 |
| LPC | 直接形係数 | Q12、`a[0] = 4096` |

## 量子化器

予測型の2段構成です。

```
LSF ──(予測を減算)──► 残差 ──► 第1段: 128エントリ × 10  ─► 7 ビット
                              第2段: 64エントリ。ベクトルの
                                     前半・後半に別々に適用  ─► 6+6 ビット
```

予測は過去3フレームの量子化残差に対する3次の移動平均です。予測器の組は2種類
あり、歪みが小さい方をエンコーダが選んで1ビットで送ります——フィールド0の
モードビットです。第2段を前半と後半に分割することで、64エントリで本来4096
エントリ分の表現力を得ています。

歪みは係数ごとの重み付きで測ります。隣と近接している LSF は鋭いフォルマントを
表しており重要度が高いので、重みが大きくなります。

逆量子化の後、デコーダはこの表現が依存する順序性を強制します——隣接 LSF 間の
最小間隔と、範囲両端でのクランプ——そのうえで LPC に戻します。

## 補間

フレームあたり1組の線スペクトルでは4サブフレームに足りないので、残りは補間で
作ります。補間は LSP 領域で行います。安定な2ベクトルの線形混合はそれ自体安定
だからです。

- 前半フレームは、前フレームのスペクトルと今回のスペクトルの**中点**に対して
  重み付けされる;
- 後半フレームは今回のスペクトルをそのまま使う;
- 半フレーム内では、第1サブフレームがやはり中点、第2サブフレームが端点を使う。

例外規定があります。2つのスペクトルが大きく異なる場合——過渡部——両者の間を
補間すると、どちらにも当てはまらないフィルタを表すことになります。エンコーダは
復号後フィルタの反射係数を検査し、そのフレームの補間を無効にできます。その場合
両半フレームとも現フレームのスペクトルを使います。デコーダも同じ値に対して同じ
検査を行うため、伝えられなくても同じ判断に至ります。