再生に 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()
、コンストラクターに渡されたサンプルレートと同じですか?