了解Android中的AudioTrack断言

在我的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获得的大小相同。 这可以解决你的问题。

隐藏的Bug

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

这个明显修复背后的原因是,相同的大小确保audioBuffer都在mAudioPlayer.write(audioBuffer, 0, audioBuffer.length)期间完全复制mAudioPlayer.write(audioBuffer, 0, audioBuffer.length)

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

解决方案

  • 检查audioBuffer分配和解除分配
  • 在multithreading或异步环境中,确保在分配之间消耗了audioBuffer

(†)

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

  2. AudioTrack缓冲区大小== audioBuffer大小:
    1对1匹配; 很可能保证AudioTrack在返回时将audioBuffer完全复制到AudioTrack缓冲区中

  3. AudioTrack缓冲区大小< audioBuffer大小:
    轨道将根据需要迭代audioBuffer ; audioBuffer生命周期更好,持续时间足够长

在所有情况下, audioBuffer必须保持分配直到消耗,并且在数据mAudioPlayer.write之前向mAudioPlayer.write提供缓冲区以避免播放中的间隙。