AudioTrack采样率不一致



使用AudioTrack进行播放时,我有时需要对不符合AudioPrack支持的采样率的音频进行重新采样。在这样做的过程中,我需要确定AudioTrack在当前设备和当前音频配置下支持的最大采样率。

由于AudioTrack的允许采样率记录不足,我决定窥探AudioTrack的源代码,发现了这条令人震惊的线:

private static final int SAMPLE_RATE_HZ_MAX = 96000;

看起来CCD_ 2实例正在应用96KHz的硬限制,而与设备的实际回放能力无关。

更令人困惑的是AudioFormat类,其中我传递给AudioTrack的构造函数(API 21),其中包含以下行:

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

在CCD_ 5方法中。现在这是一个192 KHz的硬限制。因此,将>192KHz传递到AudioFormat(或其构建器)将导致AudioFormat中的IllegalArgumentException,并将配置的192KHz<x<96 KHz采样率AudioFormat转换为AudioTrack也将抛出IllegalArgumentException


到目前为止,我发现最令人困惑的是AudioTrack中的方法getNativeOutputSampleRate(),它实际上返回了正确的输出采样率(好吧,这并不奇怪,因为它是直接从原生层运行的,但非常不一致)。

最重要的是,方法setPlaybackRate()声称:

有效的采样率范围从1 Hz到getNativeOutputSampleRate(int)返回值的两倍。

事实上,我确实尝试过,它有效吗?考虑以下片段:

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()与传递到构造函数的采样率相同吗?

目前市场上大多数安卓手机只支持一种采样率。我相信某些三星以48kHz的频率播放,几乎所有其他三星以44.1kHz的频率播放。这些值是由硬件决定的,尽管有更改本地速率的功能,但它的功能是次要的,但主要是2。在软件运行时对所有音频重新采样。这是一项昂贵的任务,也有一定的破坏性。192kHz(=2*96kHz)有一个硬限制的原因可能是,发送超过最大频率(96kHz)两倍的频率是对资源的巨大浪费,因为你还可以丢弃每一秒的样本,以有效地将样本减少2倍,直到达到这个范围。

最好避免指定非本地采样率。它将在软件中重新采样,往好了说是浪费资源,往坏了说是滞后的来源。

或者从谷歌工程师那里听到

相关内容

  • 没有找到相关文章

最新更新