AudioTrack采样率不一致

时间:2015-05-01 07:34:40

标签: java android audiotrack sample-rate

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

由于AudioTrack的允许采样率很难记录,我决定窥探AudioTrack的源代码并发现这个惊人的一行:

private static final int SAMPLE_RATE_HZ_MAX = 96000;

似乎AudioTrack实例正在应用96 KHz的硬限制,无论设备的实际播放能力如何。

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

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

使用setSampleRate()方法。现在这是 192 KHz 的硬限制。所以,传递&gt;进入AudioFormat(或它的构建器)的192KHz将导致来自IllegalArgumentException的{​​{1}}并且通过配置的192KHz&lt; 1&gt; x&lt;音频转换中的96 KHz采样率AudioFormat也会抛出AudioFormat

到目前为止,我发现最令人困惑的是AudioTrack中的方法IllegalArgumentException 实际上确实返回了正确的输出采样率(好吧,鉴于它并没有太大的惊喜)直接从本机层运行,但是不一致)。

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

  

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

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

setPlaybackRate()

在程序流程之后,当本机采样率&lt; 96 KHz ,代码打印出来:

  

原生流速率:48000 Hz
  跟踪创建成功(直接)

但是,当我连接具有 192 KHz 的播放功能的外部DAC时,我得到:

  

原生流速率:192000 Hz
  无法以本机速率创建AudioTrack!
  已成功创建跟踪(间接)

这些不一致是什么?并且,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"); } } 与传递给构造函数的采样率相同吗?

1 个答案:

答案 0 :(得分:1)

目前市场上大多数Android手机只支持一种采样率。我相信某些三星以48kHz的速度播放,几乎所有其他的播放频率为44.1kHz。这些值由硬件决定,虽然有改变原生速率的工具,但它的功能是继续证明,但主要是2.在运行时在SOFTWARE中重新采样所有音频。这是一项昂贵的任务,也有点破坏性。在192kHz(= 2 * 96kHz)存在硬限制的原因很可能是因为发送超过最大频率(96kHz)的两倍是对资源的大量浪费,因为您可能只是丢弃每一个样本以有效地下采样在你处于那个范围之前,系数为2。

最好避免指定非原生采样率。它将在软件中重新采样,充其量是浪费资源,最糟糕的是滞后源。

Or hear it from a Google engineer