简体   繁体   English

了解 Android 中的 AudioTrack 断言

[英]Understanding AudioTrack Assertion in Android

In my Android app, I'm using the AudioTrack API to output audio bytes that I receive from a RFCOMM Bluetooth connection.在我的 Android 应用程序中,我使用 AudioTrack API 输出从 RFCOMM 蓝牙连接接收的音频字节。 The audio plays as expected and is very clear.音频按预期播放并且非常清晰。 However, the app occasionally crashes due to the following assertion in AudioTrackShared.cpp:但是,由于 AudioTrackShared.cpp 中的以下断言,应用程序偶尔会崩溃:

stepCount <= mUnreleased && mUnreleased <= mFrameCount

I'm not really sure of what this assertion entails, but does anyone have an idea of what could cause this issue?我不太确定这个断言意味着什么,但有没有人知道是什么导致了这个问题? I can provide additional source code if needed:如果需要,我可以提供额外的源代码:

My setup for AudioTrack:我的 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);

Hidden Bug隐藏的错误

The error is not directly related to the audioBuffer size vs. minBufferSize .该错误与audioBuffer大小与minBufferSize没有直接关系。 Assuming that these two must be identical is an API misunderstanding, if not misuse.假设这两个必须相同是 API 误解,如果不是误用。 (†) (†)

The reason behind this apparent fix is that having identical sizes ensures that the audioBuffer is copied in full during mAudioPlayer.write(audioBuffer, 0, audioBuffer.length) , each time, every time.这种明显修复背后的原因是,具有相同的大小可确保audioBuffer都在mAudioPlayer.write(audioBuffer, 0, audioBuffer.length)期间完整复制mAudioPlayer.write(audioBuffer, 0, audioBuffer.length)

The actual reason for the crash is that audioBuffer , when larger than minBufferSize , may not have been copied in full, then discarded before mAudioPlayer.write(audioBuffer, 0, audioBuffer.length) had a chance to complete.崩溃的实际原因是当audioBuffer大于minBufferSize ,可能没有被完整复制,然后在mAudioPlayer.write(audioBuffer, 0, audioBuffer.length)有机会完成之前被丢弃。

Solutions解决方案

  • Check audioBuffer allocations and deallocations检查audioBuffer分配和解除分配
  • In a multi-threaded or async environment, ensure that audioBuffer has been consumed in between allocations.在多线程或异步环境中,确保在audioBuffer分配之间消耗了audioBuffer

(†) (†)

  1. AudioTrack buffer size > audioBuffer size: AudioTrack缓冲区大小 > audioBuffer缓冲区大小:
    you may have many small packets arriving irregularly and can take advantage of the AudioTrack buffering system to compensate for these irregularities您可能有许多不规则到达的小数据包,可以利用AudioTrack缓冲系统来补偿这些不规则

  2. AudioTrack buffer size == audioBuffer size: AudioTrack缓冲区大小 == audioBuffer缓冲区大小:
    1 to 1 match ; 1对1匹配; mAudioPlayer.write is pretty much guaranteed to have copied audioBuffer exactly into AudioTrack buffer when returning mAudioPlayer.write几乎可以保证在返回时将audioBuffer完全复制到AudioTrack缓冲区中

  3. AudioTrack buffer size < audioBuffer size: AudioTrack缓冲区大小 < audioBuffer大小:
    the track will iterate through the audioBuffer as needed ;轨道将根据需要遍历audioBuffer audioBuffer life cycle better lasts long enough audioBuffer生命周期更好地持续足够长的时间

In all cases, audioBuffer must remain allocated until consumed, and a new buffer presented to mAudioPlayer.write before it runs out of data to avoid gaps in playback.在所有情况下, audioBuffer必须保持分配状态直到被消耗,并且在数据mAudioPlayer.write之前向mAudioPlayer.write提供一个缓冲区以避免播放中断。

Make AudioTrack buffer size the same you get from minBufferSize.使 AudioTrack 缓冲区大小与从 minBufferSize 获得的大小相同。 That could fix your issue.那可以解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM