30

再生に AudioTrack を使用すると、AudioTrack でサポートされているサンプル レートに準拠していないオーディオを再サンプリングする必要がある場合があります。そうすることで、現在のオーディオ構成の下で、現在のデバイスの下で、AudioTrack によってサポートされる最大サンプル レートを決定する必要があります。

AudioTrack の許容サンプル レートが十分に文書化されていないため、ソース コードを調べてみると、次の驚くべきAudioTrack行が見つかりました。

private static final int SAMPLE_RATE_HZ_MAX = 96000;

AudioTrackデバイスの実際の再生機能に関係なく、インスタンスは 96 KHz のハード リミットを適用しているように見えます。

さらに紛らわしいのは、次の行を含むAudioFormatのコンストラクター (API 21) に渡すクラスです。AudioTrack

if ((sampleRate <= 0) || (sampleRate > 192000)) {

そのsetSampleRate()方法で。これは192 KHzのハード リミットです。したがって、> 192 KHz を AudioFormat (またはそのビルダー) に渡すと、構成IllegalArgumentExceptionされAudioFormatた 192 KHz < x < 96 KHz サンプル レート AudioFormat を AudioTrack に渡すと、IllegalArgumentException.


私が見つけた最も紛らわしいのは、実際に正しい出力サンプリング レートgetNativeOutputSampleRate()を返す AudioTrack のメソッドです(まあ、ネイティブ レイヤーから直接実行されていることを考えると、それほど驚くことではありませんが、一貫性がありません)。

setPlaybackRate()さらに、次のように主張する方法:

有効なサンプル レートの範囲は、1 Hz から getNativeOutputSampleRate(int) によって返される値の 2 倍までです。

実際、私はそれを試してみましたが、うまくいきますか? 次のスニペットを検討してください。

int nativeRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);

android.util.Log.i("UI", "Native stream rate: " + nativeRate + " Hz");

// Build audio attributes

AudioAttributes.Builder attribBuilder = new AudioAttributes.Builder();

attribBuilder.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC);
attribBuilder.setUsage(AudioAttributes.USAGE_MEDIA);

AudioAttributes attrib = attribBuilder.build();

// Build audio format

AudioFormat.Builder afBuilder = new AudioFormat.Builder();

afBuilder.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO);
afBuilder.setEncoding(AudioFormat.ENCODING_PCM_16BIT);
afBuilder.setSampleRate(nativeRate);

try{
    AudioTrack trackTest = new AudioTrack(attrib, afBuilder.build(), nativeRate, AudioTrack.MODE_STREAM, 0);

    android.util.Log.i("UI", "Track created successfully (direct)");
}catch(Exception ex){
    android.util.Log.w("UI", "Failed to create AudioTrack at native rate!");

    // Use a random supported samplerate to get pass constructor
    afBuilder.setSampleRate(48000);

    try{
        AudioTrack trackTest = new AudioTrack(attrib, afBuilder.build(), nativeRate, AudioTrack.MODE_STREAM, 0);

        trackTest.setPlaybackRate(nativeRate);

        android.util.Log.i("UI", "Track created successfully (indirect)");
    }catch(Exception e){
        android.util.Log.w("UI", "Failed to create AudioTrack at 48 KHz");
    }
}

プログラム フローに従って、ネイティブ サンプリング レートが96 KHz 未満の場合、コードは次のように出力されます。

ネイティブ ストリーム レート: 48000 Hz
トラックが正常に作成されました (ダイレクト)

しかし、最大192 KHzの再生機能を備えた外部 DAC を接続すると、次のようになります。

ネイティブ ストリーム レート: 192000 Hz
ネイティブ レートで AudioTrack を作成できませんでした!
トラックが正常に作成されました (間接)

これらの矛盾は何ですか?そしてsetPlaybackRate()、コンストラクターに渡されたサンプルレートと同じですか?

4

1 に答える 1

2

現在、市場に出回っているほとんどの Android フォンは、1 つのサンプリング レートのみをサポートしています。特定の Samsung は 48kHz で再生し、他のほとんどすべての製品は 44.1kHz で再生すると思います。これらの値はハードウェアによって決定されます。ネイティブ レートを変更する機能はありますが、その機能は二次的に将来を保証することですが、主に 2. SOFTWARE で実行時にすべてのオーディオをリサンプリングします。これは高価な作業であり、やや破壊的でもあります。192kHz (= 2 * 96kHz) に厳しい制限がある理由は、最大周波数 (96kHz) の 2 倍以上を送信することは、リソースを大量に浪費するためである可能性があります。あなたがその範囲に入るまで2倍。

ネイティブでないサンプリング レートを指定することは避けるのが最善です。これはソフトウェアで再サンプリングされ、せいぜいリソースの浪費であり、最悪の場合は遅延の原因となります。

または Google のエンジニアから聞く

于 2015-07-20T18:06:41.047 に答える