了解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
。
(†)
-
AudioTrack
缓冲区大小>audioBuffer
大小:
您可能会有许多不规则到达的小数据包,并可以利用AudioTrack
缓冲系统来弥补这些不规则性 -
AudioTrack
缓冲区大小==audioBuffer
大小:
1对1匹配; 很可能保证AudioTrack
在返回时将audioBuffer
完全复制到AudioTrack
缓冲区中 -
AudioTrack
缓冲区大小<audioBuffer
大小:
轨道将根据需要迭代audioBuffer
;audioBuffer
生命周期更好,持续时间足够长
在所有情况下, audioBuffer
必须保持分配直到消耗,并且在数据mAudioPlayer.write
之前向mAudioPlayer.write
提供新缓冲区以避免播放中的间隙。