了解 Android 中的 AudioTrack 断言

Understanding AudioTrack Assertion in Android

在我的 Android 应用程序中,我使用 AudioTrack API 来输出我从 RFCOMM 蓝牙连接接收到的音频字节。音频按预期播放并且非常清晰。但是,由于 AudioTrackShared.cpp 中的以下断言,该应用偶尔会崩溃:

stepCount <= mUnreleased && mUnreleased <= mFrameCount

我不太确定这个断言意味着什么,但是有人知道是什么导致了这个问题吗?如果需要,我可以提供额外的源代码:

我的 AudioTrack 设置:

int minSize = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_8BIT);
mAudioPlayer = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_8BIT, minSize * 4, AudioTrack.MODE_STREAM);

使 AudioTrack 缓冲区大小与从 minBufferSize 获得的大小相同。这可能会解决您的问题。

隐藏的错误

错误 audioBuffer 大小与 minBufferSize 没有直接关系。假设这两个必须相同是 API 误解,如果不是误用的话。 (†)

这个明显的修复背后的原因是具有相同的大小确保 audioBuffermAudioPlayer.write(audioBuffer, 0, audioBuffer.length) 期间被完整复制,每次,每次。

崩溃的实际原因是 audioBuffer,当大于 minBufferSize 时,可能没有完整复制,然后在 mAudioPlayer.write(audioBuffer, 0, audioBuffer.length) 有机会完成之前被丢弃。

解决方案

  • 检查 audioBuffer 分配和解除分配
  • 在多线程或异步环境中,确保 audioBuffer 已在分配之间消耗。

(†)

  1. AudioTrack 缓冲区大小 > audioBuffer 大小:
    您可能有许多小数据包不规律地到达,可以利用 AudioTrack 缓冲系统来补偿这些不规律性

  2. AudioTrack 缓冲区大小 == audioBuffer 大小:
    1对1比赛; mAudioPlayer.write 几乎可以保证在返回

    时将 audioBuffer 准确地复制到 AudioTrack 缓冲区中
  3. AudioTrack 缓冲区大小 < audioBuffer 大小:
    轨道将根据需要遍历 audioBufferaudioBuffer生命周期越长越好

在所有情况下,audioBuffer 必须保持分配直到被消耗,并且 new 缓冲区在用完之前呈现给 mAudioPlayer.write的数据以避免播放间隙。