Android は、さまざまなオーディオ データ形式を内部的に使用しています。これらのデータ形式のサブセットは、公開 API、ファイル形式、Hardware Abstraction Layer(HAL)で公開されています。
プロパティ
オーディオ データ形式はプロパティで分類されます。
- 圧縮
- 非圧縮、可逆圧縮、非可逆圧縮の 3 種類があります。PCM は最も一般的な非圧縮オーディオ形式です。FLAC は可逆圧縮形式で、MP3 と AAC は非可逆圧縮形式です。
- ビット深度
- オーディオ サンプルごとの有効ビット数を表します。
- コンテナサイズ
- サンプルの保存または送信時に使用されるビット数を表します。通常、コンテナサイズはビット深度と同じですが、アライメントのためにパディング ビットが追加されることがあります。たとえば、24 ビットのサンプルが 32 ビットワードに格納される場合があります。
- アライメント
- コンテナサイズとビット深度が完全に等しい場合は、「パック」と表現します。そうでない場合は、「アンパック」と表現します。サンプルの有効ビットは、通常、コンテナの左端(最上位)と右端(最下位)のいずれかに揃えられます。慣例として、「パック」および「アンパック」という用語は、ビット深度が 2 のべき乗ではない場合にのみ使用します。
- 符号属性
- サンプルが符号付きか符号なしかを表します。
- 表現
- 固定小数点または浮動小数点です。下記を参照してください。
固定小数点表現
固定小数点は、特にハードウェア インターフェースで、非圧縮 PCM オーディオ データの表現方法として最もよく使用されます。
固定小数点数では、小数点の前後に固定された(一定数の)桁があります。Android では、すべての表現で 2 進法を使用します。したがって、桁はビット、基数点は 2 進小数点(または単に小数点)と言い換えることができます。小数点の左側にあるビットは整数部で、小数点の右側にあるビットは小数部です。
通常、固定小数点値は整数値として格納および操作されるため、Android では「整数 PCM」という表現を使用します。固定小数点としての解釈は暗黙的に行われます。
Android では、すべての符号付き固定小数点表現で 2 の補数を使用します。したがって、すべての値が 1 LSB のユニットにある場合、次の式が成り立ちます。
|largest negative value| = |largest positive value| + 1
Q 表記と U 表記
固定小数点表現では、1 つの整数に複数の表記があります。Android では Q 表記を使用します。Qm.n では、m が整数部のビット数、n が小数部のビット数を表します。「Q」は 1 ビットとしてカウントされますが、値は 2 の補数で表現されます。 総ビット数は m + n + 1 です。
Um.n は、符号なしの数値に使用されます。m が整数部のビット数、n が小数部のビット数を表し、「U」は 0 ビットとしてカウントされます。総ビット数は m + n です。
整数部は、最終結果で使用されるか、または一時的に使用されます。後者の場合、整数部を構成するビットはガードビットと呼ばれます。ガードビットについては、最終値が範囲内にあるか範囲内に収まるようにクランプできる限り、中間計算中の桁あふれが許容されます。固定小数点のガードビットは左側にあります。これに対して、丸め誤差を減らすために使用する浮動小数点ユニットのガード ディジットは右側にあります。
浮動小数点表現
浮動小数点は固定小数点の代替表現で、小数点の位置が変動します。浮動小数点には以下のメリットがあります。
- ヘッドルームの大きさとダイナミック レンジの広さ。浮動小数点演算では、中間計算中に公称範囲を超えることが許容されます。また、値がクランプされるのは最後だけです。
- 無限大や NaN などの特別な値のサポート。
- 多くのケースでの使いやすさ。
かつて、浮動小数点演算は整数演算と固定小数点演算より低速でした。現在では、計算値に基づいて制御フローが決定されない場合、一般的には浮動小数点演算のほうが高速です。
Android でオーディオに使用される形式
Android でオーディオに使用される主な形式は以下のとおりです。
プロパティ | Q0.15 | Q0.7 1 | Q0.23 | Q0.31 | float | |
---|---|---|---|---|---|---|
コンテナ ビット |
16 | 8 | 24 または 32 2 | 32 | 32 | |
符号付き 有効ビット |
16 | 8 | 24 | 24 または 32 2 | 25 3 | |
ヘッドルーム (dB) |
0 | 0 | 0 | 0 | 126 4 | |
ダイナミック レンジ (dB) |
90 | 42 | 138 | 138~186 | 900 5 |
上記のすべての固定小数点形式の公称範囲は、-1.0~+1.0 - 1 LSB です。 2 の補数表現により、負の値は正の値よりも 1 だけ大きい値を表現できます。
注:
-
上記の形式はすべて、符号付きのサンプル値を表現しています。
8 ビット形式は一般に「符号なし」と呼ばれますが、実際には、
0.10000000
のバイアスを持つ符号付きの値です。 - Q0.23 は 24 ビット(3 つの 8 ビットバイト、リトル エンディアン)にパックされるか、32 ビットにアンパックされます。アンパックされた場合、有効ビットが LSB に向かって右揃えされ、MSB に向かって符号拡張パディングが行われるか(Q8.23)、MSB に向かって左揃えされ、LSB に向かってゼロ埋めが行われます(Q0.31)。理論上、Q0.31 の有効ビット数は最大 32 ですが、Q0.31 を受け入れるハードウェア インターフェースですべてのビットが使用されることはほとんどありません。
- 単精度浮動小数点は、23 個の明示的なビット、1 つの隠しビット、1 つの符号ビットで構成されます。つまり、有効ビット数の合計は 25 です。非正規数では有効ビット数が少なくなります。
- 単精度浮動小数点は ±1.7e+38 までの値を表現できます。これが大きなヘッドルームを確保できる理由です。
- ここで示しているダイナミック レンジは、公称最大値 ±1.0 までの非正規数に対応しています。なお、一部のアーキテクチャ固有の浮動小数点実装(NEON など)では、非正規数はサポートされません。
コンバージョン数
このセクションでは、各種の表現間のデータ変換について説明します。
浮動小数点変換
Qm.n 形式から浮動小数点形式に値を変換するには:
- 値を整数のように扱う(小数点を無視する)ことにより、浮動小数点数に変換します。
- 2-n を掛けます。
たとえば、Q4.27 の内部値を浮動小数点数に変換するには、次のようにします。
float = integer * (2 ^ -27)
浮動小数点から固定小数点への変換は、以下のルールに従います。
- 単精度浮動小数点の公称範囲は ±1.0 ですが、中間値の最大範囲は ±1.7e+38 です。外部表現(オーディオ機器への出力など)のために浮動小数点と固定小数点間の変換を行う場合は、公称範囲のみが考慮され、その範囲を超える値はクランプされます。特に、+1.0 を固定小数点形式に変換する場合は、+1.0 から 1 LSB を引いた値にクランプされます。
- 非正規数と + 0.0 および - 0.0 は表現内で許容されますが、処理中に暗黙的に 0.0 に変換される場合があります。
- 無限大は演算でパススルーされるか、暗黙的に +/- 1.0 にハードリミットされます。通常、後者の処理は固定小数点形式への変換に適用されます。
- NaN の動作が定義されていない場合、NaN はそのままの NaN として伝播されるか、デフォルトの NaN に変換されるか、暗黙的に +/- 1.0 にハードリミットされるか、暗黙的に 0.0 に変換されるか、またはエラーが返されます。
固定小数点変換
異なる Qm.n 形式間の変換は、以下のルールに従います。
- m が大きければ、左側の整数部が符号拡張されます。
- m が小さければ、整数部がクランプされます。
- n が大きければ、右側の小数部がゼロ拡張されます。
- n が小さければ、右側の小数部ビットの端数がディザリングされるか、丸められるか、切り捨てられます。
たとえば、(ディザリングも丸めもなしで)Q4.27 を Q0.15 に変換するには、Q4.27 の値を 12 ビット右にシフトして、16 ビットの符号付き範囲を超える結果をすべてクランプします。これにより、Q 表記の小数点が揃えられます。
Q7.24 を Q7.23 に変換するには、2 で符号付き除算を行います。言い換えると、Q7.24 の整数値に符号ビットを加えてから、1 ビット右に符号付きシフトします。 右に符号付きシフトするだけでは、2 で符号付き除算を行うことと等価になりません。
非可逆変換と可逆変換
変換が可逆的である場合、情報の損失は起こりません。この場合、A
を B
に変換し、次に C
に変換すると、A = C
になります。変換が非可逆的である場合、情報の損失が起こります。
可逆変換では、形式の往復変換が可能です。
有効ビット数が 25 以下の固定小数点表現から浮動小数点表現への変換は、可逆変換です。 浮動小数点表現から一般的な固定小数点表現への変換は、非可逆変換です。