了解 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 误解,如果不是误用的话。 (†)
这个明显的修复背后的原因是具有相同的大小确保 audioBuffer
在 mAudioPlayer.write(audioBuffer, 0, audioBuffer.length)
期间被完整复制,每次,每次。
崩溃的实际原因是 audioBuffer
,当大于 minBufferSize
时,可能没有完整复制,然后在 mAudioPlayer.write(audioBuffer, 0, audioBuffer.length)
有机会完成之前被丢弃。
解决方案
- 检查
audioBuffer
分配和解除分配
- 在多线程或异步环境中,确保
audioBuffer
已在分配之间消耗。
(†)
AudioTrack
缓冲区大小 > audioBuffer
大小:
您可能有许多小数据包不规律地到达,可以利用 AudioTrack
缓冲系统来补偿这些不规律性
AudioTrack
缓冲区大小 == audioBuffer
大小:
1对1比赛; mAudioPlayer.write
几乎可以保证在返回
时将 audioBuffer
准确地复制到 AudioTrack
缓冲区中
AudioTrack
缓冲区大小 < audioBuffer
大小:
轨道将根据需要遍历 audioBuffer
; audioBuffer
生命周期越长越好
在所有情况下,audioBuffer
必须保持分配直到被消耗,并且 new 缓冲区在用完之前呈现给 mAudioPlayer.write
的数据以避免播放间隙。
在我的 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 误解,如果不是误用的话。 (†)
这个明显的修复背后的原因是具有相同的大小确保 audioBuffer
在 mAudioPlayer.write(audioBuffer, 0, audioBuffer.length)
期间被完整复制,每次,每次。
崩溃的实际原因是 audioBuffer
,当大于 minBufferSize
时,可能没有完整复制,然后在 mAudioPlayer.write(audioBuffer, 0, audioBuffer.length)
有机会完成之前被丢弃。
解决方案
- 检查
audioBuffer
分配和解除分配 - 在多线程或异步环境中,确保
audioBuffer
已在分配之间消耗。
(†)
AudioTrack
缓冲区大小 >audioBuffer
大小:
您可能有许多小数据包不规律地到达,可以利用AudioTrack
缓冲系统来补偿这些不规律性
时将AudioTrack
缓冲区大小 ==audioBuffer
大小:
1对1比赛;mAudioPlayer.write
几乎可以保证在返回audioBuffer
准确地复制到AudioTrack
缓冲区中AudioTrack
缓冲区大小 <audioBuffer
大小:
轨道将根据需要遍历audioBuffer
;audioBuffer
生命周期越长越好
在所有情况下,audioBuffer
必须保持分配直到被消耗,并且 new 缓冲区在用完之前呈现给 mAudioPlayer.write
的数据以避免播放间隙。