オーディオのサンプリング

Android 5.0(Lollipop)以降、オーディオ リサンプラーは、Kaiser windowed-sinc 関数から派生した FIR フィルタを完全にベースにするようになりました。Kaiser windowed-sinc には、次のような特性があります。

  • 設計パラメータ(阻止域リップル、遷移帯域幅、遮断周波数、フィルタ長)の計算が単純明快である。
  • 総合エネルギーと比べ、阻止域エネルギーの削減にほぼ最適である。

P.P. Vaidyanathan 著『マルチレート信号処理とフィルタバンク』の 50 ページで、Kaiser 窓とその最適性、および Kaiser 窓と偏長回転楕円体窓の関係についての論考をご覧ください。

設計パラメータは、内部の品質測定と、望ましいサンプリング比に基づいて自動的に計算されます。設計パラメータに基づいて、windowed-sinc フィルタが生成されます。音楽に使用する場合、44.1~48 kHz のリサンプラー(逆の場合も同様)は、任意周波数変換よりも高い品質で生成されます。

オーディオ リサンプラーは、この品質を達成するために、品質だけでなく速度も向上します。ただし、リサンプラーは少量の通過域リップルとエイリアシング高調波ノイズを発生させることがあり、遷移帯域に高周波損失が生じる可能性があるため、不必要に使用することは避けてください。

サンプリングとリサンプリングのベスト プラクティス

このセクションでは、サンプリング レートに関する問題を回避するためのベスト プラクティスをいくつか紹介します。

端末に合ったサンプリング レートを選択する

一般的には、端末に合ったサンプリング レート(通常は 44.1 kHz~48 kHz)を選択することをおすすめします。リサンプラーはファイルの再生に使用する必要があるため、48 kHz を超えるサンプルレートを使用すると、通常は品質が低下します。

単純なリサンプリング比を使用する(固定ポリフェーズと補間ポリフェーズ)

リサンプラーは、以下のいずれか 1 つのモードで動作します。

  • 固定ポリフェーズ モード。各ポリフェーズのフィルタ係数が事前に演算されます。
  • 補間ポリフェーズ モード。各ポリフェーズのフィルタ係数が、最も近い 2 つの演算済みポリフェーズから補間される必要があります。

リサンプラーは、入力レートと出力レートの比率の L/M(最大公約数で除算した値)で M が 256 未満の場合、固定ポリフェーズ モードで最速になります。たとえば、44,100 から 48,000 の変換(L = 147、M = 160)の場合です。

固定ポリフェーズ モードでは、サンプリング レートはロックされ、変化しません。補間ポリフェーズ モードでは、サンプリング レートは概数になります。48 kHz の端末で再生するとき、サンプリング レートのドリフトは通常、数時間で 1 つのサンプルになります。近似誤差は、内部の水晶振動子、熱ドリフト、ジッターによる周波数誤差(一般的には数十 ppm)よりもずっと小さいため、通常は問題になりません。

AudioTrack で他のサンプリング レートとサンプリング比が使用可能な場合でも、48 kHz の端末で再生する場合は 24 kHz(1:2)や 32 kHz(2:3)などの単純な比率のサンプリング レートを選択してください。

サンプルレートを変更する際、ダウンサンプリングではなくアップサンプリングを使用する

サンプリング レートは臨機応変に変更できます。このような変更の粒度は、個々のサンプルではなく、内部バッファリング(通常は数百個のサンプル)に基づきます。これは、エフェクトに使用できます。

ダウンサンプリングする際は、サンプリング レートを動的に変更しないようにします。オーディオ トラックの作成後にサンプルレートを変更する場合、元のレートとの違いが 5~10% ほどあると、ダウンサンプリングの際にフィルタの再演算が行われることがあります(エイリアシングを適切に抑制するため)。これにより演算リソースが消費される場合があるため、フィルタがリアルタイムで交換されると、クリック雑音が発生することがあります。

ダウンサンプリングを 6:1 未満に制限する

ダウンサンプリングは通常、ハードウェア端末の要件によってトリガーされます。ダウンサンプリングにサンプルレート コンバーターを使用する場合、エイリアシングを適切に抑制するためにダウンサンプリングの比率を 6:1 未満に制限するようにしてください(たとえば、48,000 対 8,000 以上のダウンサンプリングは避けます)。フィルタ長は、ダウンサンプリング比に一致するように調整されますが、ダウンサンプリング比が高くなると、フィルタ長が過度に増加するのを避けるために、より多くの遷移帯域幅が犠牲になります。アップサンプリングには、エイリアシングに関して同様の問題はありません。なお、オーディオ パイプラインの一部によって、2:1 より大きいダウンサンプリングが妨害される場合があることに注意してください。

レイテンシの懸念がある場合は、リサンプリングしない

リサンプリングを実行すると、トラックが FastMixer パスに配置されなくなります。したがって、通常の Mixer パスに大きなバッファが追加されることにより、非常に大きなレイテンシが発生することになります。さらに、リサンプラーのフィルタ長から暗黙的な遅延が発生しますが、これは一般的には 1 ミリ秒未満の長さであり、通常の Mixer パスの追加バッファリング(通常は 20 ミリ秒)を超えることはありません。

浮動小数点オーディオを使用する

オーディオ データを表すのに浮動小数点数を使用すると、高パフォーマンスのオーディオ アプリの音質を大幅に向上することが可能です。浮動小数点を使用すると、以下の利点があります。

  • ダイナミック レンジが広くなる。
  • ダイナミック レンジ全体で精度が一貫する。
  • ヘッドルームが増えるので、中間計算中のクリッピングと過渡応答を回避できる。

浮動小数点は音質を向上することが可能ですが、以下のような欠点もあります。

  • 浮動小数点数はより多くのメモリを消費する。
  • 浮動小数点演算には予想外の性質がある(たとえば、加算が結合的ではないなど)。
  • 浮動小数点演算では、丸めアルゴリズムや数値的に不安定なアルゴリズムが原因で、ときとして計算精度が失われることがある。
  • 浮動小数点を効果的に使用して正確で再現可能な結果を得るためには、浮動小数点を深く理解する必要がある。

以前、浮動小数点は、使用できなかったり低速だったりして評判がよくありませんでしたが、今でもローエンドのプロセッサや埋め込みプロセッサに関しては同じことが言えます。しかし、最新のモバイル端末のプロセッサでは、整数と同様の(場合によっては整数より速い)パフォーマンスを実現するハードウェア浮動小数点が使われています。最新の CPU は SIMD(Single Instruction/Multiple Data)もサポートしているので、パフォーマンスをさらに向上することができます。

浮動小数点オーディオのベスト プラクティス

以下では、浮動小数点演算に関する問題を回避するためのベスト プラクティスを紹介します。

  • フィルタ係数の計算など、使用頻度の低い演算には倍精度浮動小数点を使用する。
  • 演算の順序に注意する。
  • 中間値に明示的な変数を宣言する。
  • かっこをふんだんに使用する。
  • NaN または infinity の結果を受け取った場合、その原因となった箇所を見つけるためにバイナリ検索を使用する。

浮動小数点オーディオでは、AudioFormat.ENCODING_PCM_FLOAT をエンコードするオーディオ形式が、AudioTrack データ形式を指定するため、ENCODING_PCM_16_BIT または ENCODING_PCM_8_BIT に対して同じように使用されます。対応するオーバーロードされたメソッド AudioTrack.write() は、データを提供するために浮動小数点配列を受け取ります。

Kotlin

fun write(
        audioData: FloatArray,
        offsetInFloats: Int,
        sizeInFloats: Int,
        writeMode: Int
): Int

Java

public int write(float[] audioData,
        int offsetInFloats,
        int sizeInFloats,
        int writeMode)

詳細情報

このセクションでは、サンプリングと浮動小数点に関する追加リソースをいくつか紹介します。

サンプリング

サンプルレート

リサンプリング

高ビット深度と高 kHz に関する議論

浮動小数点数

以下の Wikipedia のページは、浮動小数点オーディオについて理解するのに役立ちます。

以下の記事には、コンピュータ システム設計者に直接影響する、浮動小数点に関する情報があります。