2

私はサウンドを生成するアプリを構築しています (現在はほとんど実験的なものです)。それを Android フォンで再生します。

今のところ、単純な正弦波サウンド (440 Hz) を再生しようとしています。最初は Audiotrack で試しましたが、バッファ アンダーランが発生しました。そこで、OpenSL を調べてみることにしました。

今、私はこれに関する多くのチュートリアルとブログ投稿を読み、最終的には Android Simple Buffer Queue を備えた OpenSL エンジンを使用して独自の実装を作成しました。

バッファ コールバックで、新しいバッファ データを生成してキューに追加しますが、遅延はオーディオ トラックよりもはるかに悪くなります (各バッファ間のギャップが聞こえます)。

私の質問は、OpenSL で生成されたサウンドのベスト プラクティス/アーキテクチャは何ですか? 別のスレッドでバッファーを埋める必要がありますか (その場合、バッファー コールバックとの同期プロセスが必要です)。

生成されたサウンドの OpenSL ES に関するチュートリアルはまだ見つかりません (ほとんどは、オーディオ ファイルの再生またはオーディオ入力のオーディオ出力へのリダイレクトに関するものです)。

4

1 に答える 1

4

レイテンシーに関して : デバイスに適したサンプリング レートとバッファ サイズを選択することが重要です。Android SDK の AudioManager (API レベル 17 からのみ利用可能) を使用して推奨値をデバイスにクエリし、PROPERTY_OUTPUT_SAMPLE_RATEその PROPERTY_OUTPUT_FRAMES_PER_BUFFER値を NDK アプリケーションに渡すことができます。

// getting the samplerate and buffer size
if ( android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 )
{
    AudioManager am = ( AudioManager ) aContext.getSystemService( Context.AUDIO_SERVICE );
    int sampleRate = Integer.parseInt( am.getProperty( AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE ));
    int bufferSize = Integer.parseInt( am.getProperty( AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER ));
}

サンプル レートを正しく設定することの重要性は、デバイスの優先サンプル レート (48 kHz を使用するものもあれば 44.1 kHz を使用するものもある) と異なる場合、オーディオはハードウェアによって出力される前にシステム リサンプラーを経由してルーティングされることです。レイテンシ。さらに、適切なバッファサイズを取得することの重要性は、いくつかのバッファコールバックの後にサンプル/フレームがドロップされるのを防ぐことです。これにより、コールバック間でギャップ/グリッチが発生する場所で説明した問題が発生する可能性があります。倍数 (2 のべき乗) を使用してバッファー サイズを増減し、より安定したエンジン (より高いバッファー サイズ) とより高速な応答 (より低いバッファー サイズ) を試すことができます。

まさにこれを行ういくつかの単純な Android アプリを作成したので、上記の推奨事項と、音楽関連アプリケーションの基本的なシーケンス エンジンを構築する方法をもう少し詳しく説明する小さな記事を書きました。ただし、このページは基本的なアーキテクチャにすぎません。概説されており、ニーズによってはまったく役に立たない場合があります > OpenSL の Android オーディオ エンジン

于 2014-01-27T09:28:09.367 に答える