问题
In my Android app, I'm using the AudioTrack API to output audio bytes that I receive from a RFCOMM Bluetooth connection. The audio plays as expected and is very clear. However, the app occasionally crashes due to the following assertion in 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:
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);
回答1:
Make AudioTrack buffer size the same you get from minBufferSize. That could fix your issue.
回答2:
Hidden Bug
The error is not directly related to the audioBuffer
size vs. minBufferSize
. Assuming that these two must be identical is an API misunderstanding, if not misuse. (†)
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.
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.
Solutions
- Check
audioBuffer
allocations and deallocations - In a multi-threaded or async environment, ensure that
audioBuffer
has been consumed in between allocations.
(†)
AudioTrack
buffer size >audioBuffer
size:
you may have many small packets arriving irregularly and can take advantage of theAudioTrack
buffering system to compensate for these irregularitiesAudioTrack
buffer size ==audioBuffer
size:
1 to 1 match ;mAudioPlayer.write
is pretty much guaranteed to have copiedaudioBuffer
exactly intoAudioTrack
buffer when returningAudioTrack
buffer size <audioBuffer
size:
the track will iterate through theaudioBuffer
as needed ;audioBuffer
life cycle better lasts long enough
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.
来源:https://stackoverflow.com/questions/35999854/understanding-audiotrack-assertion-in-android